1
- use candid:: { CandidType , Principal } ;
2
- use serde:: { Deserialize , Serialize } ;
1
+ use candid:: CandidType ;
2
+ use ic_cdk:: api:: management_canister:: ecdsa:: {
3
+ ecdsa_public_key, sign_with_ecdsa, EcdsaCurve , EcdsaKeyId , EcdsaPublicKeyArgument ,
4
+ SignWithEcdsaArgument ,
5
+ } ;
3
6
use ic_cdk:: { query, update} ;
7
+ use serde:: Serialize ;
4
8
use std:: convert:: TryFrom ;
5
- use std:: str:: FromStr ;
6
9
7
10
#[ derive( CandidType , Serialize , Debug ) ]
8
11
struct PublicKeyReply {
@@ -19,82 +22,38 @@ struct SignatureVerificationReply {
19
22
pub is_signature_valid : bool ,
20
23
}
21
24
22
- type CanisterId = Principal ;
23
-
24
- #[ derive( CandidType , Serialize , Debug ) ]
25
- struct ECDSAPublicKey {
26
- pub canister_id : Option < CanisterId > ,
27
- pub derivation_path : Vec < Vec < u8 > > ,
28
- pub key_id : EcdsaKeyId ,
29
- }
30
-
31
- #[ derive( CandidType , Deserialize , Debug ) ]
32
- struct ECDSAPublicKeyReply {
33
- pub public_key : Vec < u8 > ,
34
- pub chain_code : Vec < u8 > ,
35
- }
36
-
37
- #[ derive( CandidType , Serialize , Debug ) ]
38
- struct SignWithECDSA {
39
- pub message_hash : Vec < u8 > ,
40
- pub derivation_path : Vec < Vec < u8 > > ,
41
- pub key_id : EcdsaKeyId ,
42
- }
43
-
44
- #[ derive( CandidType , Deserialize , Debug ) ]
45
- struct SignWithECDSAReply {
46
- pub signature : Vec < u8 > ,
47
- }
48
-
49
- #[ derive( CandidType , Serialize , Debug , Clone ) ]
50
- struct EcdsaKeyId {
51
- pub curve : EcdsaCurve ,
52
- pub name : String ,
53
- }
54
-
55
- #[ derive( CandidType , Serialize , Debug , Clone ) ]
56
- pub enum EcdsaCurve {
57
- #[ serde( rename = "secp256k1" ) ]
58
- Secp256k1 ,
59
- }
60
25
61
26
#[ update]
62
27
async fn public_key ( ) -> Result < PublicKeyReply , String > {
63
- let request = ECDSAPublicKey {
28
+ let request = EcdsaPublicKeyArgument {
64
29
canister_id : None ,
65
30
derivation_path : vec ! [ ] ,
66
31
key_id : EcdsaKeyIds :: TestKeyLocalDevelopment . to_key_id ( ) ,
67
32
} ;
68
33
69
- let ( res, ) : ( ECDSAPublicKeyReply , ) =
70
- ic_cdk:: call ( mgmt_canister_id ( ) , "ecdsa_public_key" , ( request, ) )
71
- . await
72
- . map_err ( |e| format ! ( "ecdsa_public_key failed {}" , e. 1 ) ) ?;
34
+ let ( response, ) = ecdsa_public_key ( request)
35
+ . await
36
+ . map_err ( |e| format ! ( "ecdsa_public_key failed {}" , e. 1 ) ) ?;
73
37
74
38
Ok ( PublicKeyReply {
75
- public_key_hex : hex:: encode ( & res . public_key ) ,
39
+ public_key_hex : hex:: encode ( response . public_key ) ,
76
40
} )
77
41
}
78
42
79
43
#[ update]
80
44
async fn sign ( message : String ) -> Result < SignatureReply , String > {
81
- let request = SignWithECDSA {
45
+ let request = SignWithEcdsaArgument {
82
46
message_hash : sha256 ( & message) . to_vec ( ) ,
83
47
derivation_path : vec ! [ ] ,
84
48
key_id : EcdsaKeyIds :: TestKeyLocalDevelopment . to_key_id ( ) ,
85
49
} ;
86
50
87
- let ( response, ) : ( SignWithECDSAReply , ) = ic_cdk:: api:: call:: call_with_payment (
88
- mgmt_canister_id ( ) ,
89
- "sign_with_ecdsa" ,
90
- ( request, ) ,
91
- 25_000_000_000 ,
92
- )
93
- . await
94
- . map_err ( |e| format ! ( "sign_with_ecdsa failed {}" , e. 1 ) ) ?;
51
+ let ( response, ) = sign_with_ecdsa ( request)
52
+ . await
53
+ . map_err ( |e| format ! ( "sign_with_ecdsa failed {}" , e. 1 ) ) ?;
95
54
96
55
Ok ( SignatureReply {
97
- signature_hex : hex:: encode ( & response. signature ) ,
56
+ signature_hex : hex:: encode ( response. signature ) ,
98
57
} )
99
58
}
100
59
@@ -104,25 +63,19 @@ async fn verify(
104
63
message : String ,
105
64
public_key_hex : String ,
106
65
) -> Result < SignatureVerificationReply , String > {
107
- let signature_bytes = hex:: decode ( & signature_hex) . expect ( "failed to hex-decode signature" ) ;
108
- let pubkey_bytes = hex:: decode ( & public_key_hex) . expect ( "failed to hex-decode public key" ) ;
66
+ let signature_bytes = hex:: decode ( signature_hex) . expect ( "failed to hex-decode signature" ) ;
67
+ let pubkey_bytes = hex:: decode ( public_key_hex) . expect ( "failed to hex-decode public key" ) ;
109
68
let message_bytes = message. as_bytes ( ) ;
110
69
111
70
use k256:: ecdsa:: signature:: Verifier ;
112
71
let signature = k256:: ecdsa:: Signature :: try_from ( signature_bytes. as_slice ( ) )
113
72
. expect ( "failed to deserialize signature" ) ;
114
- let is_signature_valid= k256:: ecdsa:: VerifyingKey :: from_sec1_bytes ( & pubkey_bytes)
73
+ let is_signature_valid = k256:: ecdsa:: VerifyingKey :: from_sec1_bytes ( & pubkey_bytes)
115
74
. expect ( "failed to deserialize sec1 encoding into public key" )
116
75
. verify ( message_bytes, & signature)
117
76
. is_ok ( ) ;
118
77
119
- Ok ( SignatureVerificationReply {
120
- is_signature_valid
121
- } )
122
- }
123
-
124
- fn mgmt_canister_id ( ) -> CanisterId {
125
- CanisterId :: from_str ( & "aaaaa-aa" ) . unwrap ( )
78
+ Ok ( SignatureVerificationReply { is_signature_valid } )
126
79
}
127
80
128
81
fn sha256 ( input : & String ) -> [ u8 ; 32 ] {
0 commit comments