@@ -15,13 +15,28 @@ impl AsRef<[u8]> for PersonalMessage<'_> {
15
15
}
16
16
}
17
17
18
+ #[ derive( Clone ) ]
19
+ pub struct SignMessageOptions {
20
+ /// The auxiliary randomness exists only to mitigate specific kinds of power analysis
21
+ /// side-channel attacks. Providing it definitely improves security, but omitting it
22
+ /// should not be considered dangerous, as most legacy signature schemes don't provide
23
+ /// mitigations against such attacks. To read more about the relevant discussions that
24
+ /// arose in adding this randomness please see: https://github.com/sipa/bips/issues/195
25
+ pub no_aux_rand : bool ,
26
+ }
27
+
18
28
/// Sign a message with the given private key
19
- pub fn sign_message ( msg : & PersonalMessage , privkey : & [ u8 ; 32 ] ) -> Result < Vec < u8 > , Error > {
29
+ pub fn sign_message ( msg : & PersonalMessage , privkey : & [ u8 ; 32 ] , options : & SignMessageOptions ) -> Result < Vec < u8 > , Error > {
20
30
let hash = calc_personal_message_hash ( msg) ;
21
31
22
32
let msg = secp256k1:: Message :: from_digest_slice ( hash. as_bytes ( ) . as_slice ( ) ) ?;
23
33
let schnorr_key = secp256k1:: Keypair :: from_seckey_slice ( secp256k1:: SECP256K1 , privkey) ?;
24
- let sig: [ u8 ; 64 ] = * schnorr_key. sign_schnorr ( msg) . as_ref ( ) ;
34
+
35
+ let sig: [ u8 ; 64 ] = if options. no_aux_rand {
36
+ * secp256k1:: SECP256K1 . sign_schnorr_no_aux_rand ( & msg, & schnorr_key) . as_ref ( )
37
+ } else {
38
+ * schnorr_key. sign_schnorr ( msg) . as_ref ( )
39
+ } ;
25
40
26
41
Ok ( sig. to_vec ( ) )
27
42
}
@@ -74,7 +89,26 @@ mod tests {
74
89
] )
75
90
. unwrap ( ) ;
76
91
77
- verify_message ( & pm, & sign_message ( & pm, & privkey) . expect ( "sign_message failed" ) , & pubkey) . expect ( "verify_message failed" ) ;
92
+ let sign_with_aux_rand = SignMessageOptions { no_aux_rand : false } ;
93
+ let sign_with_no_aux_rand = SignMessageOptions { no_aux_rand : true } ;
94
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
95
+ . expect ( "verify_message failed" ) ;
96
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_no_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
97
+ . expect ( "verify_message failed" ) ;
98
+ }
99
+
100
+ #[ test]
101
+ fn test_basic_sign_without_rand_twice_should_get_same_signature ( ) {
102
+ let pm = PersonalMessage ( "Hello Kaspa!" ) ;
103
+ let privkey: [ u8 ; 32 ] = [
104
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
105
+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x03 ,
106
+ ] ;
107
+
108
+ let sign_with_no_aux_rand = SignMessageOptions { no_aux_rand : true } ;
109
+ let signature = sign_message ( & pm, & privkey, & sign_with_no_aux_rand) . expect ( "sign_message failed" ) ;
110
+ let signature_twice = sign_message ( & pm, & privkey, & sign_with_no_aux_rand) . expect ( "sign_message failed" ) ;
111
+ assert_eq ! ( signature, signature_twice) ;
78
112
}
79
113
80
114
#[ test]
@@ -90,7 +124,12 @@ mod tests {
90
124
] )
91
125
. unwrap ( ) ;
92
126
93
- verify_message ( & pm, & sign_message ( & pm, & privkey) . expect ( "sign_message failed" ) , & pubkey) . expect ( "verify_message failed" ) ;
127
+ let sign_with_aux_rand = SignMessageOptions { no_aux_rand : false } ;
128
+ let sign_with_no_aux_rand = SignMessageOptions { no_aux_rand : true } ;
129
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
130
+ . expect ( "verify_message failed" ) ;
131
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_no_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
132
+ . expect ( "verify_message failed" ) ;
94
133
}
95
134
96
135
#[ test]
@@ -110,7 +149,12 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
110
149
] )
111
150
. unwrap ( ) ;
112
151
113
- verify_message ( & pm, & sign_message ( & pm, & privkey) . expect ( "sign_message failed" ) , & pubkey) . expect ( "verify_message failed" ) ;
152
+ let sign_with_aux_rand = SignMessageOptions { no_aux_rand : false } ;
153
+ let sign_with_no_aux_rand = SignMessageOptions { no_aux_rand : true } ;
154
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
155
+ . expect ( "verify_message failed" ) ;
156
+ verify_message ( & pm, & sign_message ( & pm, & privkey, & sign_with_no_aux_rand) . expect ( "sign_message failed" ) , & pubkey)
157
+ . expect ( "verify_message failed" ) ;
114
158
}
115
159
116
160
#[ test]
0 commit comments