bsv_wasm/ecdsa/
recover.rs

1use crate::get_hash_digest;
2use crate::BSVErrors;
3use crate::PrivateKey;
4use crate::PublicKey;
5use crate::Signature;
6use crate::SigningHash;
7use crate::ECDSA;
8use digest::FixedOutput;
9use elliptic_curve::bigint::Encoding;
10use elliptic_curve::bigint::U1024;
11#[cfg(target_arch = "wasm32")]
12use wasm_bindgen::prelude::*;
13#[cfg(target_arch = "wasm32")]
14use wasm_bindgen::throw_str;
15#[cfg(target_arch = "wasm32")]
16use wasm_bindgen::JsValue;
17
18impl ECDSA {
19    /**
20     * Recovers a Private Key from a signature with a known message digest and K value.
21     */
22
23    fn private_key_from_signature_k_impl(signature: &Signature, public_key: &PublicKey, ephemeral_key: &PrivateKey, preimage: &[u8], hash_algo: SigningHash) -> Result<PrivateKey, BSVErrors> {
24        let mut k_final = [0u8; 128];
25        ephemeral_key
26            .secret_key
27            .to_nonzero_scalar()
28            .to_bytes()
29            .iter()
30            .copied()
31            .enumerate()
32            .for_each(|(i, x)| k_final[i + 96] = x);
33        let k = U1024::from_be_slice(&k_final);
34
35        let m_final = get_hash_digest(hash_algo, preimage).finalize_fixed().to_vec();
36
37        let m = U1024::from_be_slice(&[
38            0x00u8,
39            0x00,
40            0x00,
41            0x00,
42            0x00,
43            0x00,
44            0x00,
45            0x00,
46            0x00,
47            0x00,
48            0x00,
49            0x00,
50            0x00,
51            0x00,
52            0x00,
53            0x00,
54            0x00,
55            0x00,
56            0x00,
57            0x00,
58            0x00,
59            0x00,
60            0x00,
61            0x00,
62            0x00,
63            0x00,
64            0x00,
65            0x00,
66            0x00,
67            0x00,
68            0x00,
69            0x00,
70            0x00,
71            0x00,
72            0x00,
73            0x00,
74            0x00,
75            0x00,
76            0x00,
77            0x00,
78            0x00,
79            0x00,
80            0x00,
81            0x00,
82            0x00,
83            0x00,
84            0x00,
85            0x00,
86            0x00,
87            0x00,
88            0x00,
89            0x00,
90            0x00,
91            0x00,
92            0x00,
93            0x00,
94            0x00,
95            0x00,
96            0x00,
97            0x00,
98            0x00,
99            0x00,
100            0x00,
101            0x00,
102            0x00,
103            0x00,
104            0x00,
105            0x00,
106            0x00,
107            0x00,
108            0x00,
109            0x00,
110            0x00,
111            0x00,
112            0x00,
113            0x00,
114            0x00,
115            0x00,
116            0x00,
117            0x00,
118            0x00,
119            0x00,
120            0x00,
121            0x00,
122            0x00,
123            0x00,
124            0x00,
125            0x00,
126            0x00,
127            0x00,
128            0x00,
129            0x00,
130            0x00,
131            0x00,
132            0x00,
133            0x00,
134            m_final[0],
135            m_final[1],
136            m_final[2],
137            m_final[3],
138            m_final[4],
139            m_final[5],
140            m_final[6],
141            m_final[7],
142            m_final[8],
143            m_final[9],
144            m_final[10],
145            m_final[11],
146            m_final[12],
147            m_final[13],
148            m_final[14],
149            m_final[15],
150            m_final[16],
151            m_final[17],
152            m_final[18],
153            m_final[19],
154            m_final[20],
155            m_final[21],
156            m_final[22],
157            m_final[23],
158            m_final[24],
159            m_final[25],
160            m_final[26],
161            m_final[27],
162            m_final[28],
163            m_final[29],
164            m_final[30],
165            m_final[31],
166        ]);
167
168        let s_final = signature.sig.s().to_bytes().to_vec();
169        let s = U1024::from_be_slice(&[
170            0x00u8,
171            0x00,
172            0x00,
173            0x00,
174            0x00,
175            0x00,
176            0x00,
177            0x00,
178            0x00,
179            0x00,
180            0x00,
181            0x00,
182            0x00,
183            0x00,
184            0x00,
185            0x00,
186            0x00,
187            0x00,
188            0x00,
189            0x00,
190            0x00,
191            0x00,
192            0x00,
193            0x00,
194            0x00,
195            0x00,
196            0x00,
197            0x00,
198            0x00,
199            0x00,
200            0x00,
201            0x00,
202            0x00,
203            0x00,
204            0x00,
205            0x00,
206            0x00,
207            0x00,
208            0x00,
209            0x00,
210            0x00,
211            0x00,
212            0x00,
213            0x00,
214            0x00,
215            0x00,
216            0x00,
217            0x00,
218            0x00,
219            0x00,
220            0x00,
221            0x00,
222            0x00,
223            0x00,
224            0x00,
225            0x00,
226            0x00,
227            0x00,
228            0x00,
229            0x00,
230            0x00,
231            0x00,
232            0x00,
233            0x00,
234            0x00,
235            0x00,
236            0x00,
237            0x00,
238            0x00,
239            0x00,
240            0x00,
241            0x00,
242            0x00,
243            0x00,
244            0x00,
245            0x00,
246            0x00,
247            0x00,
248            0x00,
249            0x00,
250            0x00,
251            0x00,
252            0x00,
253            0x00,
254            0x00,
255            0x00,
256            0x00,
257            0x00,
258            0x00,
259            0x00,
260            0x00,
261            0x00,
262            0x00,
263            0x00,
264            0x00,
265            0x00,
266            s_final[0],
267            s_final[1],
268            s_final[2],
269            s_final[3],
270            s_final[4],
271            s_final[5],
272            s_final[6],
273            s_final[7],
274            s_final[8],
275            s_final[9],
276            s_final[10],
277            s_final[11],
278            s_final[12],
279            s_final[13],
280            s_final[14],
281            s_final[15],
282            s_final[16],
283            s_final[17],
284            s_final[18],
285            s_final[19],
286            s_final[20],
287            s_final[21],
288            s_final[22],
289            s_final[23],
290            s_final[24],
291            s_final[25],
292            s_final[26],
293            s_final[27],
294            s_final[28],
295            s_final[29],
296            s_final[30],
297            s_final[31],
298        ]);
299
300        let inv_r = signature.sig.r().invert();
301        if inv_r.is_none().into() {
302            return Err(BSVErrors::CustomECDSAError("Invalid modInvR value".to_string()));
303        }
304        let rinv_final = inv_r.unwrap().to_bytes().to_vec();
305        let r_inverse = U1024::from_be_slice(&[
306            0x00u8,
307            0x00,
308            0x00,
309            0x00,
310            0x00,
311            0x00,
312            0x00,
313            0x00,
314            0x00,
315            0x00,
316            0x00,
317            0x00,
318            0x00,
319            0x00,
320            0x00,
321            0x00,
322            0x00,
323            0x00,
324            0x00,
325            0x00,
326            0x00,
327            0x00,
328            0x00,
329            0x00,
330            0x00,
331            0x00,
332            0x00,
333            0x00,
334            0x00,
335            0x00,
336            0x00,
337            0x00,
338            0x00,
339            0x00,
340            0x00,
341            0x00,
342            0x00,
343            0x00,
344            0x00,
345            0x00,
346            0x00,
347            0x00,
348            0x00,
349            0x00,
350            0x00,
351            0x00,
352            0x00,
353            0x00,
354            0x00,
355            0x00,
356            0x00,
357            0x00,
358            0x00,
359            0x00,
360            0x00,
361            0x00,
362            0x00,
363            0x00,
364            0x00,
365            0x00,
366            0x00,
367            0x00,
368            0x00,
369            0x00,
370            0x00,
371            0x00,
372            0x00,
373            0x00,
374            0x00,
375            0x00,
376            0x00,
377            0x00,
378            0x00,
379            0x00,
380            0x00,
381            0x00,
382            0x00,
383            0x00,
384            0x00,
385            0x00,
386            0x00,
387            0x00,
388            0x00,
389            0x00,
390            0x00,
391            0x00,
392            0x00,
393            0x00,
394            0x00,
395            0x00,
396            0x00,
397            0x00,
398            0x00,
399            0x00,
400            0x00,
401            0x00,
402            rinv_final[0],
403            rinv_final[1],
404            rinv_final[2],
405            rinv_final[3],
406            rinv_final[4],
407            rinv_final[5],
408            rinv_final[6],
409            rinv_final[7],
410            rinv_final[8],
411            rinv_final[9],
412            rinv_final[10],
413            rinv_final[11],
414            rinv_final[12],
415            rinv_final[13],
416            rinv_final[14],
417            rinv_final[15],
418            rinv_final[16],
419            rinv_final[17],
420            rinv_final[18],
421            rinv_final[19],
422            rinv_final[20],
423            rinv_final[21],
424            rinv_final[22],
425            rinv_final[23],
426            rinv_final[24],
427            rinv_final[25],
428            rinv_final[26],
429            rinv_final[27],
430            rinv_final[28],
431            rinv_final[29],
432            rinv_final[30],
433            rinv_final[31],
434        ]);
435
436        let n = U1024::from_be_slice(&[
437            0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440            0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C,
441            0xD0, 0x36, 0x41, 0x41,
442        ]);
443
444        // The formula to reverse a private key is P = r^-1(N) * ((k * s) -H(m)) % N
445        // however as Bitcoin signatures must use a low S value due to Bip 62, we
446        // must account for both high and low S values in our equation.
447        let k_s = r_inverse.wrapping_mul(&k.wrapping_mul(&s).wrapping_sub(&m)).wrapping_rem(&n);
448
449        let priv_p = PrivateKey::from_bytes_impl(&k_s.to_be_bytes()[96..])?;
450        let pub_p = PublicKey::from_private_key_impl(&priv_p).to_bytes_impl()?;
451        if pub_p == public_key.to_bytes_impl()? {
452            Ok(priv_p)
453        } else {
454            let k_low_s = r_inverse.wrapping_mul(&k.wrapping_mul(&n.wrapping_sub(&s)).wrapping_sub(&m)).wrapping_rem(&n);
455            let priv_low_p = PrivateKey::from_bytes_impl(&k_low_s.to_be_bytes()[96..])?;
456            let pub_low_p = PublicKey::from_private_key_impl(&priv_low_p).to_bytes_impl()?;
457            if pub_low_p == public_key.to_bytes_impl()? {
458                Ok(priv_low_p)
459            } else {
460                Err(BSVErrors::CustomECDSAError("Unable to recover private key.".to_string()))
461            }
462        }
463    }
464}
465
466#[cfg(target_arch = "wasm32")]
467#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecdsa"), wasm_bindgen)]
468impl ECDSA {
469    #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-ecdsa"), wasm_bindgen(js_name = privateKeyFromSignatureK))]
470    pub fn private_key_from_signature_k(signature: &Signature, public_key: &PublicKey, ephemeral_key: &PrivateKey, preimage: &[u8], hash_algo: SigningHash) -> Result<PrivateKey, JsValue> {
471        match ECDSA::private_key_from_signature_k_impl(signature, public_key, ephemeral_key, preimage, hash_algo) {
472            Ok(v) => Ok(v),
473            Err(e) => throw_str(&e.to_string()),
474        }
475    }
476}
477
478#[cfg(not(target_arch = "wasm32"))]
479impl ECDSA {
480    pub fn private_key_from_signature_k(signature: &Signature, public_key: &PublicKey, ephemeral_key: &PrivateKey, preimage: &[u8], hash_algo: SigningHash) -> Result<PrivateKey, BSVErrors> {
481        ECDSA::private_key_from_signature_k_impl(signature, public_key, ephemeral_key, preimage, hash_algo)
482    }
483}