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 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 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}