Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
# set the same as 'black' uses
max-line-length = 88
# TODO mention the reasons why we ignore the following
# E203 slice notation whitespace
# E501 line length
# W503 line break before binary operator
# W504 line break after binary operator
# F841 local variable name is assigned to but never used
ignore = E203,E501,W503,W504,F841
# E203: slice notation whitespace
# E501: line length
# W503: line break before binary operator
# W504: line break after binary operator
# F841: local variable name is assigned to but never used
# E231: false positives from colon-format specifiers inside f-strings
# (we use format width/precision in test/perf strings, e.g. `{time:7.3f}`)
# W604: backticks used in docstrings for inline code examples; pyflakes
# warns about deprecated backtick usage but project keeps these docs.
ignore = E203,E231,E501,W503,W504,F841,W604
25 changes: 12 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ on:
env:
PKG_NAME: didcomm


jobs:

checks:
Expand All @@ -26,16 +25,16 @@ jobs:
release_info: ${{ steps.release_info.outputs.release_info }}
asset_tgz_url: ${{ steps.release_info.outputs.asset_tgz_url }}
asset_whl_url: ${{ steps.release_info.outputs.asset_whl_url }}
upload_url: ${{ steps.release_info.outputs.upload_url }}
upload_url: ${{ steps.release_info.outputs.upload_url }}
already_in_pypi: ${{ steps.check_in_pypi.outputs.pypi_versions != '' }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Python
id: setup
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: '3.x'
python-version: '3.13'
- name: Install dependencies
run: pip install tomli
- name: Get current version
Expand Down Expand Up @@ -74,7 +73,7 @@ jobs:
out="$(pip install --use-deprecated=legacy-resolver ${{ env.PKG_NAME }}== 2>&1 \
| grep -E "Could not find .* ${{ steps.current_version.outputs.current_version }}(,|\))")"
echo "::set-output name=pypi_versions::$out"
shell: bash {0} # to opt-out of default fail-fast behavior
shell: bash {0} # to opt-out of default fail-fast behavior

release-github:
name: GitHub Release
Expand All @@ -87,10 +86,10 @@ jobs:
- name: Install poetry
run: pipx install poetry

- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
id: setup
with:
python-version: '3.x'
python-version: '3.13'
cache: 'poetry'

- name: Install dependencies
Expand Down Expand Up @@ -155,7 +154,7 @@ jobs:
name: Deploy to PyPI
if: github.ref == 'refs/heads/stable' && needs.checks.outputs.already_in_pypi == 'false'
runs-on: ubuntu-latest
needs: [checks, release-github]
needs: [ checks, release-github ]
steps:
- uses: actions/checkout@v3

Expand All @@ -171,9 +170,9 @@ jobs:
| wget -i -
ls

- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
with:
python-version: '3.x'
python-version: '3.13'

- name: Publish to PyPI
env:
Expand All @@ -196,10 +195,10 @@ jobs:
- name: Install poetry
run: pipx install poetry

- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
id: setup
with:
python-version: '3.x'
python-version: '3.13'
cache: 'poetry'

- name: Install dependencies
Expand Down
28 changes: 15 additions & 13 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
name: verify

on:

pull_request:
# paths:
# - '**.py'
# paths:
# - '**.py'

push:
branches: [ main ]

env:
PKG_NAME: didcomm


jobs:

release-ready:
Expand All @@ -18,10 +20,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
- uses: actions/setup-python@v6
id: setup
with:
python-version: '3.x'
python-version: '3.13'

- name: Install dependencies
run: pip install tomli
Expand Down Expand Up @@ -56,11 +58,11 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Set up Python 3.7
- name: Set up Python 3.13
id: setup
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: '3.7'
python-version: '3.13'

- name: Install black
run: pipx install black
Expand All @@ -73,11 +75,11 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Set up Python 3.7
- name: Set up Python 3.13
id: setup
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: '3.7'
python-version: '3.13'

- name: Install flake8
run: pipx install flake8
Expand All @@ -88,15 +90,15 @@ jobs:
unit:
strategy:
matrix:
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ]
python-version: [ '3.10', '3.11', '3.12', '3.13', '3.14' ]
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
id: setup
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

Expand Down
58 changes: 33 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@
Basic [DIDComm v2](https://identity.foundation/didcomm-messaging/spec) support in Python.

## Installation
```

```bash
pip install didcomm
```

## DIDComm + peerdid Demo
See https://github.com/sicpa-dlab/didcomm-demo.

See <https://github.com/sicpa-dlab/didcomm-demo>.

## Assumptions and Limitations
- Python >= 3.7.
- In order to use the library, `SecretsResolver` and `DIDResolver` interfaces must be implemented on the application level.

- Python >= 3.10.
- In order to use the library, `SecretsResolver` and `DIDResolver` interfaces must be implemented on the application level.
Implementation of that interfaces is out of DIDComm library scope.
- Verification materials are expected in JWK, Base58 and Multibase (internally Base58 only) formats.
- In Base58 and Multibase formats, keys using only X25519 and Ed25519 curves are supported.
Expand All @@ -27,31 +30,31 @@ See https://github.com/sicpa-dlab/didcomm-demo.
- Verification methods referencing another DID Document are not supported (see [Referring to Verification Methods](https://www.w3.org/TR/did-core/#referring-to-verification-methods)).
- The following curves and algorithms are supported:
- Encryption:
- Curves: X25519, P-384, P-256, P-521
- Content encryption algorithms:
- XC20P (to be used with ECDH-ES only, default for anoncrypt),
- A256GCM (to be used with ECDH-ES only),
- A256CBC-HS512 (default for authcrypt)
- Key wrapping algorithms: ECDH-ES+A256KW, ECDH-1PU+A256KW
- Curves: X25519, P-384, P-256, P-521
- Content encryption algorithms:
- XC20P (to be used with ECDH-ES only, default for anoncrypt),
- A256GCM (to be used with ECDH-ES only),
- A256CBC-HS512 (default for authcrypt)
- Key wrapping algorithms: ECDH-ES+A256KW, ECDH-1PU+A256KW
- Signing:
- Curves: Ed25519, Secp256k1, P-256
- Algorithms: EdDSA (with crv=Ed25519), ES256, ES256K
- Forward protocol is implemented and used by default.
- DID rotation (`fromPrior` field) is supported.
- DIDComm has been implemented under the following [Assumptions](https://hackmd.io/i3gLqgHQR2ihVFV5euyhqg)

- DIDComm has been implemented under the following [Assumptions](https://hackmd.io/i3gLqgHQR2ihVFV5euyhqg)

## Examples

See [demo scripts](tests/demo) for details.

A general usage of the API is the following:

- Sender Side:
- Build a `Message` (plaintext, payload).
- Convert a message to a DIDComm Message for further transporting by calling one of the following:
- `pack_encrypted` to build an Encrypted DIDComm message
- `pack_signed` to build a Signed DIDComm message
- `pack_plaintext` to build a Plaintext DIDComm message
- `pack_encrypted` to build an Encrypted DIDComm message
- `pack_signed` to build a Signed DIDComm message
- `pack_plaintext` to build a Plaintext DIDComm message
- Receiver side:
- Call `unpack` on receiver side that will decrypt the message, verify signature if needed
and return a `Message` for further processing on the application level.
Expand All @@ -60,7 +63,8 @@ A general usage of the API is the following:

This is the most common DIDComm message to be used in most of the applications.

A DIDComm encrypted message is an encrypted JWM (JSON Web Messages) that
A DIDComm encrypted message is an encrypted JWM (JSON Web Messages) that

- hides its content from all but authorized recipients
- (optionally) discloses and proves the sender to only those recipients
- provides message integrity guarantees
Expand All @@ -72,7 +76,7 @@ See `pack_encrypted` documentation for more details.

**Authentication encryption** example (most common case):

```
```py
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
Expand All @@ -98,7 +102,7 @@ print(f"Got ${unpack_result.message} message")

**Anonymous encryption** example:

```
```py
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
Expand All @@ -117,7 +121,7 @@ pack_result = await pack_encrypted(

**Encryption with non-repudiation** example:

```
```py
message = Message(
body={"aaa": 1, "bbb": 2},
id="1234567890",
Expand All @@ -139,16 +143,17 @@ pack_result = await pack_encrypted(
### 2. Build an unencrypted but Signed DIDComm message

Signed messages are only necessary when

- the origin of plaintext must be provable to third parties
- or the sender can’t be proven to the recipient by authenticated encryption because the recipient is not known in advance (e.g., in a
broadcast scenario).

Adding a signature when one is not needed can degrade rather than enhance security because it
relinquishes the sender’s ability to speak off the record.

See `pack_signed` documentation for more details.

```
```py
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
Expand All @@ -172,14 +177,15 @@ print(f"Got ${unpack_result.message} message signed as ${unpack_result.metadata.

### 3. Build a Plaintext DIDComm message

A DIDComm message in its plaintext form that
A DIDComm message in its plaintext form that

- is not packaged into any protective envelope
- lacks confidentiality and integrity guarantees
- repudiable

They are therefore not normally transported across security boundaries.
They are therefore not normally transported across security boundaries.

```
```py
# ALICE
message = Message(
body={"aaa": 1, "bbb": 2},
Expand All @@ -197,9 +203,11 @@ print(f"Got ${unpack_result.message} message")
```

## Contribution

PRs are welcome!

The following CI checks are run against every PR:

- all tests must pass
- [flake8](https://github.com/PyCQA/flake8) checks must pass
- code must be formatted by [Black](https://github.com/psf/black)
- code must be formatted by [Black](https://github.com/psf/black)
1 change: 0 additions & 1 deletion didcomm/core/defaults.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from didcomm.common.algorithms import AnonCryptAlg, AuthCryptAlg


DEF_ENC_ALG_AUTH: AuthCryptAlg = AuthCryptAlg.A256CBC_HS512_ECDH_1PU_A256KW
DEF_ENC_ALG_ANON: AnonCryptAlg = AnonCryptAlg.XC20P_ECDH_ES_A256KW
Loading