DIDComm Rust
Basic DIDComm v2 support in Rust.
Usage
To use didcomm, add this to your Cargo.toml:
[]
= "0.2"
Run examples
Use cargo run --example {example-name} for example cargo run --example basic.
Assumptions and Limitations
- Rust 2018 edition is required.
- In order to use the library,
SecretsResolverandDIDResolvertraits must be implemented on the application level. Implementation of that traits is out of DIDComm library scope, but we provide 2 simple implementationExampleDIDResolverandExampleSecretsResolverthat allows resolve locally known DID docs and secrets for tests/demo purposes.- Verification materials are expected in JWK.
- Key IDs (kids) used in
SecretsResolvermust match the corresponding key IDs from DID Doc verification methods. - Key IDs (kids) in DID Doc verification methods and secrets must be a full DID Fragment, that is
did#key-id. - Verification methods referencing another DID Document are not supported (see Referring to Verification Methods).
- The following curves and algorithms are supported:
- Encryption:
- Curves: X25519, P-256
- 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
- Encryption:
- DIDComm has been implemented under the following Assumptions
Features that will be supported in next versions
- Base58 and Multibase (internally Base58 only) formats for secrets and verification methods.
- Forward protocol.
- DID rotation (
fromPriorfield).
Examples
See examples 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:
Message::pack_encryptedto build an Encrypted DIDComm messageMessage::pack_signedto build a Signed DIDComm messageMessage::pack_plaintextto build a Plaintext DIDComm message
- Build a
- Receiver side:
- Call
Message::unpackon receiver side that will decrypt the message, verify signature if needed and return aMessagefor further processing on the application level.
- Call
1. Build an Encrypted DIDComm message for the given recipient
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
- hides its content from all but authorized recipients
- (optionally) discloses and proves the sender to only those recipients
- provides message integrity guarantees
It 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.
See Message::pack_encrypted documentation for more details.
Authentication encryption example (most common case):
// --- Build message from ALICE to BOB ---
let msg = build
.to
.from
.finalize;
// --- Pack encrypted and authenticated message ---
let did_resolver = new;
let secrets_resolver = new;
let = msg
.pack_encrypted
.await
.expect;
println!;
// --- Send message ---
println!;
// --- Unpacking message ---
let did_resolver = new;
let secrets_resolver = new;
let = unpack
.await
.expect;
println!;
println!;
Anonymous encryption example:
let = msg
.pack_encrypted
.await
.expect;
Encryption with non-repudiation example:
let = msg
.pack_encrypted
.await
.expect;
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 Message::pack_signed documentation for more details.
// ALICE
let msg = build
.to
.from
.finalize;
let = msg
.pack_signed
.await
.expect;
// BOB
let = unpack
.await
.expect;
3. Build a Plaintext DIDComm message
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.
// ALICE
let msg = build
.to
.from
.finalize;
let msg = msg
.pack_plaintext
.expect;
// BOB
let = unpack
.await
.expect;
Contribution
PRs are welcome!
The following CI checks are run against every PR:
- No warnings from
cargo check --all-targets - All tests must pass with
cargo tests - Code must be formatted by
cargo fmt --all