xdid_method_key/keys/
p256.rs1use jose_jwk::Jwk;
2use p256::{
3 SecretKey,
4 elliptic_curve::{
5 rand_core::OsRng,
6 sec1::{FromEncodedPoint, ToEncodedPoint},
7 },
8};
9use ring::{
10 rand::SystemRandom,
11 signature::{ECDSA_P256_SHA256_ASN1_SIGNING, EcdsaKeyPair},
12};
13
14use super::{DidKeyPair, KeyParser, Multicodec, PublicKey, SignError, Signer, WithMulticodec};
15
16#[derive(Clone, PartialEq, Eq)]
17pub struct P256KeyPair(SecretKey);
18
19impl DidKeyPair for P256KeyPair {
20 fn generate() -> Self {
21 let mut rng = OsRng;
22 let secret = SecretKey::random(&mut rng);
23 Self(secret)
24 }
25
26 fn public(&self) -> impl PublicKey {
27 P256PublicKey(self.0.public_key())
28 }
29 fn public_bytes(&self) -> Box<[u8]> {
30 self.0.public_key().to_sec1_bytes()
31 }
32 fn secret_bytes(&self) -> Box<[u8]> {
33 self.0.to_bytes().to_vec().into()
34 }
35}
36
37impl Signer for P256KeyPair {
38 fn sign(&self, message: &[u8]) -> Result<Vec<u8>, SignError> {
39 let rng = SystemRandom::new();
40
41 let signer = EcdsaKeyPair::from_private_key_and_public_key(
42 &ECDSA_P256_SHA256_ASN1_SIGNING,
43 &self.0.to_bytes(),
44 &self.0.public_key().to_sec1_bytes(),
45 &rng,
46 )
47 .unwrap();
48
49 signer
50 .sign(&rng, message)
51 .map(|v| v.as_ref().to_vec())
52 .map_err(|_| SignError::SigningFailed)
53 }
54}
55
56#[derive(Clone, PartialEq, Eq)]
57struct P256PublicKey(p256::PublicKey);
58
59impl PublicKey for P256PublicKey {
60 fn as_did_bytes(&self) -> Box<[u8]> {
61 self.0.to_encoded_point(true).as_bytes().into()
62 }
63
64 fn to_jwk(&self) -> Jwk {
65 let jwk_str = self.0.to_jwk_string();
66 serde_json::from_str(&jwk_str).unwrap()
67 }
68}
69
70impl WithMulticodec for P256PublicKey {
71 fn codec(&self) -> Box<dyn Multicodec> {
72 Box::new(P256Codec)
73 }
74}
75
76pub(crate) struct P256KeyParser;
77
78impl KeyParser for P256KeyParser {
79 fn parse(&self, public_key: Vec<u8>) -> Box<dyn PublicKey> {
80 let point = p256::EncodedPoint::from_bytes(public_key).unwrap();
81 let key = p256::PublicKey::from_encoded_point(&point).unwrap();
82 Box::new(P256PublicKey(key))
83 }
84}
85
86impl WithMulticodec for P256KeyParser {
87 fn codec(&self) -> Box<dyn Multicodec> {
88 Box::new(P256Codec)
89 }
90}
91
92struct P256Codec;
93
94impl Multicodec for P256Codec {
95 fn code_u64(&self) -> u64 {
96 0x1200
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use ring::signature::{ECDSA_P256_SHA256_ASN1, VerificationAlgorithm};
103
104 use crate::parser::DidKeyParser;
105
106 use super::*;
107
108 #[test]
109 fn test_display() {
110 let pair = P256KeyPair::generate();
111 let did = pair.public().to_did();
112
113 let did_str = did.to_string();
114 println!("{}", did_str);
115 assert!(did_str.starts_with("did:key:zDn"));
116 }
117
118 #[test]
119 fn test_jwk() {
120 let pair = P256KeyPair::generate();
121 let _ = pair.public().to_jwk();
122 }
123
124 #[test]
125 fn test_parse() {
126 let pair = P256KeyPair::generate();
127 let did = pair.public().to_did();
128
129 let parser = DidKeyParser::default();
130 let _ = parser.parse(&did).unwrap();
131 }
132
133 #[test]
134 fn test_sign() {
135 let pair = P256KeyPair::generate();
136
137 let msg = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
138 let signature = pair.sign(&msg).unwrap();
139
140 assert!(
141 ECDSA_P256_SHA256_ASN1
142 .verify(
143 pair.public_bytes().to_vec().as_slice().into(),
144 msg.as_slice().into(),
145 signature.as_slice().into()
146 )
147 .is_ok()
148 );
149 }
150}