xdid_method_key/keys/
mod.rs

1use jose_jwk::Jwk;
2use multibase::Base;
3use thiserror::Error;
4use xdid_core::did::{Did, MethodId, MethodName};
5
6use crate::NAME;
7
8#[cfg(feature = "p256")]
9pub mod p256;
10#[cfg(feature = "p384")]
11pub mod p384;
12
13pub trait Signer {
14    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, SignError>;
15}
16
17pub trait DidKeyPair: Signer {
18    /// Generate a new pair of keys.
19    fn generate() -> Self;
20
21    fn public(&self) -> impl PublicKey;
22
23    /// Raw public key bytes.
24    fn public_bytes(&self) -> Box<[u8]>;
25    /// Raw secret key bytes.
26    fn secret_bytes(&self) -> Box<[u8]>;
27}
28
29#[derive(Error, Debug)]
30pub enum SignError {
31    #[error("signing failed")]
32    SigningFailed,
33}
34
35pub trait PublicKey: WithMulticodec {
36    /// Read the public key as DID-ready bytes.
37    /// This may be different from the raw public key bytes, as some algorithms
38    /// require compression.
39    /// https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm
40    fn as_did_bytes(&self) -> Box<[u8]>;
41    fn to_jwk(&self) -> Jwk;
42
43    fn to_did(&self) -> Did {
44        let bytes = self.as_did_bytes();
45        let code = self.codec().code();
46
47        let mut inner = Vec::with_capacity(code.len() + bytes.len());
48        inner.extend(code);
49        inner.extend(bytes);
50
51        let id = multibase::encode(Base::Base58Btc, inner);
52
53        Did {
54            method_name: MethodName(NAME.to_string()),
55            method_id: MethodId(id),
56        }
57    }
58}
59
60pub trait Multicodec {
61    fn code_u64(&self) -> u64;
62    fn code(&self) -> Vec<u8> {
63        let mut buffer = unsigned_varint::encode::u64_buffer();
64        unsigned_varint::encode::u64(self.code_u64(), &mut buffer).to_vec()
65    }
66}
67
68pub trait WithMulticodec {
69    fn codec(&self) -> Box<dyn Multicodec>;
70}
71
72pub trait KeyParser: WithMulticodec {
73    fn parse(&self, public_key: Vec<u8>) -> Box<dyn PublicKey>;
74}