@@ -12,7 +12,10 @@ use serde::{Deserialize, Serialize};
1212use serde_json:: { json, Value } ;
1313use tokio:: net:: TcpStream ;
1414
15- use crate :: signer:: Signer ;
15+ use crate :: signer:: {
16+ p256_jwk:: { fix_p256_jwk_from_encoded_point, p256_encoded_point_from_public_key} ,
17+ Signer ,
18+ } ;
1619
1720/// Signer implementation for verified computing notary services.
1821#[ derive( Clone , Debug , Serialize , Deserialize ) ]
@@ -38,6 +41,18 @@ fn strip_urn_cid(cid: &str) -> &str {
3841}
3942
4043impl VCompNotarySigner {
44+ fn did_doc_from_public_key ( pub_key : & [ u8 ] ) -> Result < Document > {
45+ let key_pair = P256KeyPair :: from_public_key ( pub_key) ;
46+ let mut did_doc = key_pair. get_did_document ( did_key:: Config {
47+ use_jose_format : true ,
48+ serialize_secrets : true ,
49+ } ) ;
50+ let encoded_point = p256_encoded_point_from_public_key ( pub_key) ?;
51+ fix_p256_jwk_from_encoded_point ( & mut did_doc, & encoded_point, None ) ?;
52+
53+ Ok ( did_doc)
54+ }
55+
4156 /// Creates a new VCompNotarySigner by connecting to a verified computing notary service.
4257 ///
4358 /// # Arguments
@@ -69,12 +84,7 @@ impl VCompNotarySigner {
6984 let pub_key = hex:: decode ( pub_key) ?;
7085
7186 log:: trace!( "Importing a secp256r1 VComp Notary signer" ) ;
72- let key_pair = P256KeyPair :: from_public_key ( & pub_key) ;
73-
74- let did_doc = key_pair. get_did_document ( did_key:: Config {
75- use_jose_format : true ,
76- serialize_secrets : true ,
77- } ) ;
87+ let did_doc = Self :: did_doc_from_public_key ( & pub_key) ?;
7888
7989 let response = client
8090 . get ( format ! ( "{url}/get_dids" ) )
@@ -232,3 +242,47 @@ impl Signer for VCompNotarySigner {
232242 Ok ( Some ( self . did_doc . clone ( ) ) )
233243 }
234244}
245+
246+ #[ cfg( test) ]
247+ mod tests {
248+ use base64:: engine:: { general_purpose:: URL_SAFE_NO_PAD as BASE64_URL_NO_PAD , Engine } ;
249+ use did_key:: KeyFormat ;
250+ use p256:: ecdsa:: SigningKey ;
251+
252+ use super :: * ;
253+
254+ #[ test]
255+ fn compressed_vcomp_public_key_repairs_verification_method_jwk ( ) {
256+ let signing_key = SigningKey :: from_bytes ( ( & [ 7u8 ; 32 ] ) . into ( ) ) . unwrap ( ) ;
257+ let verifying_key = signing_key. verifying_key ( ) ;
258+ let compressed_pub_key = verifying_key. to_encoded_point ( true ) ;
259+ let uncompressed_pub_key = verifying_key. to_encoded_point ( false ) ;
260+
261+ let key_pair = P256KeyPair :: from_public_key ( compressed_pub_key. as_bytes ( ) ) ;
262+ let broken_did_doc = key_pair. get_did_document ( did_key:: Config {
263+ use_jose_format : true ,
264+ serialize_secrets : true ,
265+ } ) ;
266+
267+ let fixed_did_doc =
268+ VCompNotarySigner :: did_doc_from_public_key ( compressed_pub_key. as_bytes ( ) ) . unwrap ( ) ;
269+
270+ let expected_x = BASE64_URL_NO_PAD . encode ( uncompressed_pub_key. x ( ) . unwrap ( ) ) ;
271+ let expected_y = BASE64_URL_NO_PAD . encode ( uncompressed_pub_key. y ( ) . unwrap ( ) ) ;
272+ let compressed_b64 = BASE64_URL_NO_PAD . encode ( compressed_pub_key. as_bytes ( ) ) ;
273+
274+ let broken_jwk = match & broken_did_doc. verification_method [ 0 ] . public_key {
275+ Some ( KeyFormat :: JWK ( jwk) ) => jwk,
276+ _ => panic ! ( "expected JWK verification method" ) ,
277+ } ;
278+ assert_eq ! ( broken_jwk. x. as_deref( ) , Some ( compressed_b64. as_str( ) ) ) ;
279+ assert_eq ! ( broken_jwk. y, None ) ;
280+
281+ let fixed_jwk = match & fixed_did_doc. verification_method [ 0 ] . public_key {
282+ Some ( KeyFormat :: JWK ( jwk) ) => jwk,
283+ _ => panic ! ( "expected JWK verification method" ) ,
284+ } ;
285+ assert_eq ! ( fixed_jwk. x. as_deref( ) , Some ( expected_x. as_str( ) ) ) ;
286+ assert_eq ! ( fixed_jwk. y. as_deref( ) , Some ( expected_y. as_str( ) ) ) ;
287+ }
288+ }
0 commit comments