1use crate::Algorithm;
3use crate::did::prefix_did_key;
4use crate::error::Result;
5use ecdsa::elliptic_curve::{
6 AffinePoint, CurveArithmetic, FieldBytesSize, PrimeCurve, Scalar,
7 generic_array::ArrayLength,
8 ops::Invert,
9 sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint},
10 subtle::CtOption,
11};
12use ecdsa::hazmat::{DigestPrimitive, SignPrimitive};
13use ecdsa::signature::{Signer, rand_core::CryptoRngCore};
14use ecdsa::{Signature, SignatureSize, SigningKey};
15use k256::Secp256k1;
16use p256::NistP256;
17
18pub struct Keypair<C>
20where
21 C: PrimeCurve + CurveArithmetic,
22 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
23 SignatureSize<C>: ArrayLength<u8>,
24{
25 signing_key: SigningKey<C>,
26}
27
28impl<C> Keypair<C>
29where
30 C: PrimeCurve + CurveArithmetic,
31 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
32 SignatureSize<C>: ArrayLength<u8>,
33{
34 pub fn create(rng: &mut impl CryptoRngCore) -> Self {
42 Self { signing_key: SigningKey::<C>::random(rng) }
43 }
44 pub fn import(bytes: &[u8]) -> Result<Self> {
46 Ok(Self { signing_key: SigningKey::from_slice(bytes)? })
47 }
48}
49
50impl<C> Keypair<C>
51where
52 C: PrimeCurve + CurveArithmetic,
53 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
54 SignatureSize<C>: ArrayLength<u8>,
55 AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
56 FieldBytesSize<C>: ModulusSize,
57{
58 fn compressed_public_key(&self) -> Box<[u8]> {
59 self.signing_key.verifying_key().to_encoded_point(true).to_bytes()
60 }
61}
62
63impl<C> Keypair<C>
64where
65 C: PrimeCurve + CurveArithmetic + DigestPrimitive,
66 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
67 SignatureSize<C>: ArrayLength<u8>,
68{
69 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>> {
76 let signature: Signature<_> = self.signing_key.try_sign(msg)?;
77 Ok(signature.normalize_s().unwrap_or(signature).to_bytes().to_vec())
78 }
79}
80
81pub trait Did<C> {
83 fn did(&self) -> String;
84}
85
86pub trait Export<C> {
88 fn export(&self) -> Vec<u8>;
89}
90
91impl<C> Export<C> for Keypair<C>
92where
93 C: PrimeCurve + CurveArithmetic,
94 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
95 SignatureSize<C>: ArrayLength<u8>,
96{
97 fn export(&self) -> Vec<u8> {
98 self.signing_key.to_bytes().to_vec()
99 }
100}
101
102pub type P256Keypair = Keypair<NistP256>;
104
105impl Did<NistP256> for P256Keypair {
106 fn did(&self) -> String {
107 prefix_did_key(&Algorithm::P256.format_mulikey_compressed(&self.compressed_public_key()))
108 }
109}
110
111pub type Secp256k1Keypair = Keypair<Secp256k1>;
113
114impl Did<Secp256k1> for Secp256k1Keypair {
115 fn did(&self) -> String {
116 prefix_did_key(
117 &Algorithm::Secp256k1.format_mulikey_compressed(&self.compressed_public_key()),
118 )
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::{P256Keypair, Secp256k1Keypair};
125 use crate::Algorithm;
126 use crate::did::{format_did_key, parse_did_key};
127 use crate::verify::Verifier;
128 use rand::rngs::ThreadRng;
129
130 #[test]
131 fn p256_did() {
132 let keypair = P256Keypair::create(&mut ThreadRng::default());
133 let did = {
134 use super::Did;
135 keypair.did()
136 };
137 let formatted =
138 format_did_key(Algorithm::P256, &keypair.signing_key.verifying_key().to_sec1_bytes())
139 .expect("formatting to did key should succeed");
140 assert_eq!(did, formatted);
141
142 let (alg, public_key) = parse_did_key(&did).expect("parsing did key should succeed");
143 assert_eq!(alg, Algorithm::P256);
144 assert_eq!(
145 public_key,
146 keypair.signing_key.verifying_key().to_encoded_point(false).as_bytes()
147 );
148 }
149
150 #[test]
151 fn secp256k1_did() {
152 let keypair = Secp256k1Keypair::create(&mut ThreadRng::default());
153 let did = {
154 use super::Did;
155 keypair.did()
156 };
157 let formatted = format_did_key(
158 Algorithm::Secp256k1,
159 &keypair.signing_key.verifying_key().to_sec1_bytes(),
160 )
161 .expect("formatting to did key should succeed");
162 assert_eq!(did, formatted);
163
164 let (alg, public_key) = parse_did_key(&did).expect("parsing did key should succeed");
165 assert_eq!(alg, Algorithm::Secp256k1);
166 assert_eq!(
167 public_key,
168 keypair.signing_key.verifying_key().to_encoded_point(false).as_bytes()
169 );
170 }
171
172 #[test]
173 fn p256_export() {
174 let keypair = P256Keypair::create(&mut ThreadRng::default());
175 let exported = {
176 use super::Export;
177 keypair.export()
178 };
179 let imported = P256Keypair::import(&exported).expect("importing keypair should succeed");
180 {
181 use super::Did;
182 assert_eq!(keypair.did(), imported.did());
183 }
184 }
185
186 #[test]
187 fn secp256k1_export() {
188 let keypair = Secp256k1Keypair::create(&mut ThreadRng::default());
189 let exported = {
190 use super::Export;
191 keypair.export()
192 };
193 let imported =
194 Secp256k1Keypair::import(&exported).expect("importing keypair should succeed");
195 {
196 use super::Did;
197 assert_eq!(keypair.did(), imported.did());
198 }
199 }
200
201 #[test]
202 fn p256_verify() {
203 let keypair = P256Keypair::create(&mut ThreadRng::default());
204 let did = {
205 use super::Did;
206 keypair.did()
207 };
208 let (alg, public_key) = parse_did_key(&did).expect("parsing did key should succeed");
209 assert_eq!(alg, Algorithm::P256);
210
211 let verifier = Verifier::default();
212 let msg = [1, 2, 3, 4, 5, 6, 7, 8];
213 let signature = keypair.sign(&msg).expect("signing should succeed");
214 let mut corrupted_signature = signature.clone();
215 corrupted_signature[0] = corrupted_signature[0].wrapping_add(1);
216 assert!(
217 verifier.verify(alg, &public_key, &msg, &signature).is_ok(),
218 "verifying signature should succeed"
219 );
220 assert!(
221 verifier.verify(alg, &public_key, &msg[..7], &signature).is_err(),
222 "verifying signature should fail with incorrect message"
223 );
224 assert!(
225 verifier.verify(alg, &public_key, &msg, &corrupted_signature).is_err(),
226 "verifying signature should fail with incorrect signature"
227 );
228 assert!(
229 verifier.verify(Algorithm::Secp256k1, &public_key, &msg, &signature).is_err(),
230 "verifying signature should fail with incorrect algorithm"
231 );
232 }
233
234 #[test]
235 fn secp256k1_verify() {
236 let keypair = Secp256k1Keypair::create(&mut ThreadRng::default());
237 let did = {
238 use super::Did;
239 keypair.did()
240 };
241 let (alg, public_key) = parse_did_key(&did).expect("parsing did key should succeed");
242 assert_eq!(alg, Algorithm::Secp256k1);
243
244 let verifier = Verifier::default();
245 let msg = [1, 2, 3, 4, 5, 6, 7, 8];
246 let signature = keypair.sign(&msg).expect("signing should succeed");
247 let mut corrupted_signature = signature.clone();
248 corrupted_signature[0] = corrupted_signature[0].wrapping_add(1);
249 assert!(
250 verifier.verify(alg, &public_key, &msg, &signature).is_ok(),
251 "verifying signature should succeed"
252 );
253 assert!(
254 verifier.verify(alg, &public_key, &msg[..7], &signature).is_err(),
255 "verifying signature should fail with incorrect message"
256 );
257 assert!(
258 verifier.verify(alg, &public_key, &msg, &corrupted_signature).is_err(),
259 "verifying signature should fail with incorrect signature"
260 );
261 assert!(
262 verifier.verify(Algorithm::P256, &public_key, &msg, &signature).is_err(),
263 "verifying signature should fail with incorrect algorithm"
264 );
265 }
266}