xdid_method_key/keys/
p256.rs

1use 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}