1use ed25519_dalek::{Signer, SigningKey as Ed25519SigningKey, VerifyingKey};
2use rand_core::OsRng;
3use x25519_dalek::{PublicKey as X25519PublicKey, StaticSecret};
4
5use crate::{
6 did::Did,
7 error::{MaError, MaResult as Result},
8 multiformat::{public_key_multibase_decode, public_key_multibase_encode},
9};
10
11pub const ASSERTION_METHOD_KEY_TYPE: &str = "Multikey";
12pub const KEY_AGREEMENT_KEY_TYPE: &str = "Multikey";
13
14pub const X25519_PUB_CODEC: u64 = 0xec;
16pub const ED25519_PUB_CODEC: u64 = 0xed;
17pub const EDDSA_SIG_CODEC: u64 = 0xd0ed;
18
19#[derive(Clone)]
39pub struct SigningKey {
40 pub did: Did,
41 pub key_type: String,
42 secret_key: Ed25519SigningKey,
43 pub public_key_multibase: String,
44}
45
46impl SigningKey {
47 pub fn generate(did: Did) -> Result<Self> {
48 let signing_key = Ed25519SigningKey::generate(&mut OsRng);
49 let public_key_multibase =
50 public_key_multibase_encode(ED25519_PUB_CODEC, signing_key.verifying_key().as_bytes());
51
52 Ok(Self {
53 did,
54 key_type: ASSERTION_METHOD_KEY_TYPE.to_string(),
55 secret_key: signing_key,
56 public_key_multibase,
57 })
58 }
59
60 #[must_use]
61 pub fn sign(&self, data: &[u8]) -> Vec<u8> {
62 self.secret_key.sign(data).to_bytes().to_vec()
63 }
64
65 #[must_use]
66 pub fn verifying_key(&self) -> VerifyingKey {
67 self.secret_key.verifying_key()
68 }
69
70 #[must_use]
71 pub fn private_key_bytes(&self) -> [u8; ed25519_dalek::SECRET_KEY_LENGTH] {
72 self.secret_key.to_bytes()
73 }
74
75 pub fn from_private_key_bytes(
76 did: Did,
77 private_key: [u8; ed25519_dalek::SECRET_KEY_LENGTH],
78 ) -> Result<Self> {
79 let signing_key = Ed25519SigningKey::from_bytes(&private_key);
80 let public_key_multibase =
81 public_key_multibase_encode(ED25519_PUB_CODEC, signing_key.verifying_key().as_bytes());
82
83 Ok(Self {
84 did,
85 key_type: ASSERTION_METHOD_KEY_TYPE.to_string(),
86 secret_key: signing_key,
87 public_key_multibase,
88 })
89 }
90
91 pub fn validate(&self) -> Result<()> {
92 Did::validate(&self.did.id())?;
93
94 if self.key_type != ASSERTION_METHOD_KEY_TYPE {
95 return Err(MaError::InvalidKeyType);
96 }
97
98 let (codec, key_bytes) = public_key_multibase_decode(&self.public_key_multibase)?;
99 if codec != ED25519_PUB_CODEC {
100 return Err(MaError::InvalidMulticodec {
101 expected: ED25519_PUB_CODEC,
102 actual: codec,
103 });
104 }
105
106 if key_bytes.len() != ed25519_dalek::PUBLIC_KEY_LENGTH {
107 return Err(MaError::InvalidKeyLength {
108 expected: ed25519_dalek::PUBLIC_KEY_LENGTH,
109 actual: key_bytes.len(),
110 });
111 }
112
113 Ok(())
114 }
115}
116
117#[derive(Clone)]
137pub struct EncryptionKey {
138 pub did: Did,
139 pub key_type: String,
140 private_key: StaticSecret,
141 pub public_key: X25519PublicKey,
142 pub public_key_multibase: String,
143}
144
145impl EncryptionKey {
146 pub fn generate(did: Did) -> Result<Self> {
147 let private_key = StaticSecret::random_from_rng(OsRng);
148 let public_key = X25519PublicKey::from(&private_key);
149 let public_key_multibase =
150 public_key_multibase_encode(X25519_PUB_CODEC, public_key.as_bytes());
151
152 Ok(Self {
153 did,
154 key_type: KEY_AGREEMENT_KEY_TYPE.to_string(),
155 private_key,
156 public_key,
157 public_key_multibase,
158 })
159 }
160
161 #[must_use]
162 pub fn shared_secret(&self, other: &X25519PublicKey) -> [u8; 32] {
163 self.private_key.diffie_hellman(other).to_bytes()
164 }
165
166 #[must_use]
167 pub fn private_key_bytes(&self) -> [u8; 32] {
168 self.private_key.to_bytes()
169 }
170
171 pub fn from_private_key_bytes(did: Did, private_key: [u8; 32]) -> Result<Self> {
172 let private_key = StaticSecret::from(private_key);
173 let public_key = X25519PublicKey::from(&private_key);
174 let public_key_multibase =
175 public_key_multibase_encode(X25519_PUB_CODEC, public_key.as_bytes());
176
177 Ok(Self {
178 did,
179 key_type: KEY_AGREEMENT_KEY_TYPE.to_string(),
180 private_key,
181 public_key,
182 public_key_multibase,
183 })
184 }
185
186 pub fn validate(&self) -> Result<()> {
187 Did::validate(&self.did.id())?;
188
189 if self.key_type != KEY_AGREEMENT_KEY_TYPE {
190 return Err(MaError::InvalidKeyType);
191 }
192
193 let (codec, key_bytes) = public_key_multibase_decode(&self.public_key_multibase)?;
194 if codec != X25519_PUB_CODEC {
195 return Err(MaError::InvalidMulticodec {
196 expected: X25519_PUB_CODEC,
197 actual: codec,
198 });
199 }
200
201 if key_bytes.len() != 32 {
202 return Err(MaError::InvalidKeyLength {
203 expected: 32,
204 actual: key_bytes.len(),
205 });
206 }
207
208 Ok(())
209 }
210}