Package: didcomm
DIDComm PythonBasicDIDComm v2support in Python.Installationpip install didcommDIDComm + peerdid DemoSeehttps://github.com/sicpa-dlab/didcomm-demo.Assumptions and LimitationsPython >= 3.7.In order to use the library,SecretsResolverandDIDResolverinterfaces 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.For private keys in Base58 and Multibase formats, the verification material value contains both private and public parts (concatenated bytes).In Multibase format, bytes of the verification material value is prefixed with the corresponding Multicodec code.Key IDs (kids) used inSecretsResolvermust match the corresponding key IDs from DID Doc verification methods.Key IDs (kids) in DID Doc verification methods and secrets must be a fullDID Fragment, that isdid#key-id.Verification methods referencing another DID Document are not supported (seeReferring to Verification Methods).The following curves and algorithms are supported:Encryption:Curves: X25519, P-384, P-256, P-521Content 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+A256KWSigning:Curves: Ed25519, Secp256k1, P-256Algorithms: EdDSA (with crv=Ed25519), ES256, ES256KForward protocol is implemented and used by default.DID rotation (fromPriorfield) is supported.DIDComm has been implemented under the followingAssumptionsExamplesSeedemo scriptsfor details.A general usage of the API is the following:Sender Side:Build aMessage(plaintext, payload).Convert a message to a DIDComm Message for further transporting by calling one of the following:pack_encryptedto build an Encrypted DIDComm messagepack_signedto build a Signed DIDComm messagepack_plaintextto build a Plaintext DIDComm messageReceiver side:Callunpackon receiver side that will decrypt the message, verify signature if needed
and return aMessagefor further processing on the application level.1. Build an Encrypted DIDComm message for the given recipientThis 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) thathides its content from all but authorized recipients(optionally) discloses and proves the sender to only those recipientsprovides message integrity guaranteesIt is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm
applications, and is the safest format for storing DIDComm data at rest.Seepack_encrypteddocumentation for more details.Authentication encryptionexample (most common case):# ALICE
message = Message(
    body={"aaa": 1, "bbb": 2},
    id="1234567890",
    type="my-protocol/1.0",
    frm=ALICE_DID,
    to=[BOB_DID],
)
pack_result = await pack_encrypted(
    resolvers_config=resolvers_config_alice,
    message=message,
    frm=ALICE_DID,
    to=BOB_DID,
    pack_config=PackEncryptedConfig(),
)
packed_msg = pack_result.packed_msg
print(f"Sending ${packed_msg} to ${pack_result.service_metadata.service_endpoint}")

# BOB
unpack_result = await unpack(resolvers_config_bob, packed_msg)
print(f"Got ${unpack_result.message} message")Anonymous encryptionexample:message = Message(
    body={"aaa": 1, "bbb": 2},
    id="1234567890",
    type="my-protocol/1.0",
    frm=ALICE_DID,
    to=[BOB_DID],
)

pack_result = await pack_encrypted(
    resolvers_config=resolvers_config_alice,
    message=message,
    to=BOB_DID,
    pack_config=PackEncryptedConfig(),
)Encryption with non-repudiationexample:message = Message(
    body={"aaa": 1, "bbb": 2},
    id="1234567890",
    type="my-protocol/1.0",
    frm=ALICE_DID,
    to=[BOB_DID],
)

pack_result = await pack_encrypted(
    resolvers_config=resolvers_config_alice,
    message=message,
    frm=ALICE_DID,
    sign_frm=ALICE_DID,
    to=BOB_DID,
    pack_config=PackEncryptedConfig(),
)2. Build an unencrypted but Signed DIDComm messageSigned messages are only necessary whenthe origin of plaintext must be provable to third partiesor 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.Seepack_signeddocumentation for more details.# ALICE
message = Message(
    body={"aaa": 1, "bbb": 2},
    id="1234567890",
    type="my-protocol/1.0",
    frm=ALICE_DID,
    to=[BOB_DID],
)
pack_result = await pack_signed(
    resolvers_config=resolvers_config_alice,
    message=message,
    sign_frm=ALICE_DID
)
packed_msg = pack_result.packed_msg
print(f"Publishing ${packed_msg}")

# BOB
unpack_result = await unpack(resolvers_config_bob, packed_msg)
print(f"Got ${unpack_result.message} message signed as ${unpack_result.metadata.signed_message}")3. Build a Plaintext DIDComm messageA DIDComm message in its plaintext form thatis not packaged into any protective envelopelacks confidentiality and integrity guaranteesrepudiableThey are therefore not normally transported across security boundaries.# ALICE
message = Message(
    body={"aaa": 1, "bbb": 2},
    id="1234567890",
    type="my-protocol/1.0",
    frm=ALICE_DID,
    to=[BOB_DID],
)
pack_result = await pack_plaintext(resolvers_config=resolvers_config_alice, message)
print(f"Publishing ${pack_result.packed_msg}")

# BOB
unpack_result = await unpack(resolvers_config_bob, pack_result.packed_msg)
print(f"Got ${unpack_result.message} message")ContributionPRs are welcome!The following CI checks are run against every PR:all tests must passflake8checks must passcode must be formatted byBlack