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