@@ -14,6 +14,7 @@ pub struct Signer {
14
14
key_id : String ,
15
15
client : InnerClient ,
16
16
public_key : rust_eigenda_signers:: PublicKey ,
17
+ k256_verifying_key : VerifyingKey ,
17
18
}
18
19
19
20
impl Signer {
@@ -42,6 +43,7 @@ impl Signer {
42
43
key_id,
43
44
client,
44
45
public_key : secp_pub_key,
46
+ k256_verifying_key : k256_pub_key,
45
47
} )
46
48
}
47
49
@@ -119,6 +121,16 @@ impl Signer {
119
121
120
122
Ok ( encoded_point. as_bytes ( ) . to_vec ( ) )
121
123
}
124
+
125
+ fn k256_recovery_id (
126
+ & self ,
127
+ signature : & k256:: ecdsa:: Signature ,
128
+ message_hash : & [ u8 ; 32 ] ,
129
+ ) -> anyhow:: Result < u8 > {
130
+ signature
131
+ . get_recovery_id ( message_hash, & self . k256_verifying_key )
132
+ . context ( "Failed to determine recovery ID" )
133
+ }
122
134
}
123
135
124
136
#[ derive( Error , Debug ) ]
@@ -153,8 +165,13 @@ impl eigenda::Sign for crate::eigen::kms::Signer {
153
165
154
166
let k256_sig_normalized = k256_sig. normalize_s ( ) . unwrap_or ( k256_sig) ;
155
167
168
+ let k256_recid = self
169
+ . k256_recovery_id ( & k256_sig_normalized, digest_bytes)
170
+ . context ( "Failed to determine recovery ID" ) ?;
171
+
156
172
let mut sig: [ u8 ; 65 ] = [ 0 ; 65 ] ;
157
- sig. copy_from_slice ( k256_sig_normalized. to_bytes ( ) . as_ref ( ) ) ;
173
+ sig[ 0 ] = k256_recid;
174
+ sig[ ..64 ] . copy_from_slice ( k256_sig_normalized. to_bytes ( ) . as_ref ( ) ) ;
158
175
159
176
let standard_recoverable_sig = rust_eigenda_signers:: RecoverableSignature :: from_bytes ( & sig)
160
177
. context ( "Failed to create recoverable signature" ) ?;
@@ -166,3 +183,34 @@ impl eigenda::Sign for crate::eigen::kms::Signer {
166
183
self . public_key . into ( )
167
184
}
168
185
}
186
+
187
+ trait RecIdExt {
188
+ fn get_recovery_id (
189
+ & self ,
190
+ message_hash : & [ u8 ; 32 ] ,
191
+ expected_pubkey : & VerifyingKey ,
192
+ ) -> anyhow:: Result < u8 > ;
193
+ }
194
+
195
+ impl RecIdExt for k256:: ecdsa:: Signature {
196
+ fn get_recovery_id (
197
+ & self ,
198
+ message_hash : & [ u8 ; 32 ] ,
199
+ expected_pubkey : & VerifyingKey ,
200
+ ) -> anyhow:: Result < u8 > {
201
+ ( 0 ..2 )
202
+ . find_map ( |id| {
203
+ let recovery_id = k256:: ecdsa:: RecoveryId :: from_byte ( id)
204
+ . with_context ( || format ! ( "Bad RecoveryId byte {}" , id) )
205
+ . ok ( ) ?;
206
+
207
+ let recovered_key =
208
+ VerifyingKey :: recover_from_prehash ( message_hash, self , recovery_id) . ok ( ) ?;
209
+
210
+ ( & recovered_key == expected_pubkey) . then_some ( id)
211
+ } )
212
+ . ok_or_else ( || {
213
+ anyhow:: anyhow!( "Could not recover correct public key from k256 signature" )
214
+ } )
215
+ }
216
+ }
0 commit comments