owned this note
owned this note
Published
Linked with GitHub
# General Peer DID Library Spec
The purpose of this doc is to describe what we mean when we say "write a library that provides static peer DID support."
## Key Assumptions
1. The peer DID method spec is relatively complete, but not all parts of it hang together well. I (Daniel) am the principal author of the method, and I can get changes to the method spec approved. So if we find ourselves stuck on a problem with the spec, I can solve it quickly.
2. "Static peer DID support" means support for the features [described as "Layer 2a" and "Layer 2b" by the peer DID spec](https://identity.foundation/peer-did-method-spec/index.html#layers-of-support). This includes the ability to create peer DIDs and to resolve peer DIDs received from others. It does NOT include the ability to update the state of a peer DID, or to receive and act upon updates from the peer DIDs of others.
3. Peer DIDs support arbitrary key types. However, our libraries only need to support ed25519/curve25519 keys and secp256k1 keys.
4. The `authorization` section of a peer DID doc is out of scope. Hence we do not need a dependency on SGL, and we do not need to support deltas. Whatever keys are declared under `verificationMethod` are the ones we use for DIDComm in this version of the libs.
5. Libraries should be very lightweight and, beyond crypto, have as few dependencies as possible.
6. Libraries will be published using standard package manager(s) for their respective languages: `pypi`, `npmjs`, `maven`, `crates.io`, etc.
7. DID state may be cached, and may be resolved in parallel on many threads. Because this version of the libs is static, no state can change -- so cached state is unlikely to create concurrency problems, and we do not need to mutex anything in a special way.
8. There is a primitive python library located at https://github.com/evernym/pypeerdid/blob/master/peerdid/simple2.py. It is stale (was written before numalgo 2 was added to the spec, and maybe before some other changes). But it gives a good sense of what's needed for these libs (except that it lacks a "create" function). The other python files in this folder lay the foundation for dynamic peer DIDs and may be fancier than what we need.
9. Peer DID data is stored under `~/.did:peer` by default, but this location should be configurable.
## Required features
1. Create a new peer DID using numeric algorithm 0 (see "Method 0" under [section 2.4 of peer DID spec](https://identity.foundation/peer-did-method-spec/index.html#generation-method)): `create_numalgo_0(inception_key) -> DID`. This DID cannot have an endpoint and is thus problematic for DIDComm unless it is communicated over an already-open channel (e.g., an open socket) and DIDComm's `return_route` feature is used.
2. Create a new peer DID using numeric algorithm 2 (see "Method 2" under [section 2.4 of peer DID spec](https://identity.foundation/peer-did-method-spec/index.html#generation-method)): `create_numalgo_2(inception_key, encryption_keys[], signing_keys[], endpoint) -> DID`. This is the way to create a non-updatable peer DID with a custom endpoint and custom keys. It will be common in DIDComm use cases.
3. [Optional, nice to have] Create a new peer DID using numeric algoritm 1 (see "Method 1" under [section 2.4 of peer DID spec](https://identity.foundation/peer-did-method-spec/index.html#generation-method)): `create_numalgo_1(inception_key, genesis_doc) -> DID`. This will be the most complex creation method to code, and we may end up deferring it out of the work for Gemini 1. It allows for arbitrary genesis documents and rich permissions as supported by SGL, and lays the foundation for a DID to become updatable in the future. (It is not a mistake that the number of this method is "1", but it's the most advanced. Methods were numbered by order of invention, not by increasing futures.)
3. Resolve a DID to its DID doc. `resolve(peer_did, version_id=None) -> did_doc`
4. Save the DID for a DID doc, so it can be resolved later. `save(did, did_doc, version_id)`
5. [Optional] Get the recipient keys that should be used to encypt if we want to sent a message to Alice's DID (or that would be used to check whether a message encrypted by Alice used a key we consider valid. This requires parsing Alice's DID doc and looking for items in the `keyAgreement` section. `get_recipient_keys(did_doc) -> keys[]` (Note: having keys in a DID doc be authorized both for encrypting and decrypting is a bit of a suboptimal posture from a security perspective. It might be nice to have a key that can only decrypt, but not encrypt and thus authcrypt as Alice. That might be good for auditors, for example. Such a feature is not currently described by DIDComm, but it might be good to leave room for it to be added in the future.)
6. [Optional] Get the signing keys that are authorized for Alice's DID. This requires parsing Alice's DID doc and looking for items in the `authenticate` section (I think).