|
8 | 8 | anything but tests."""
|
9 | 9 | import csv
|
10 | 10 | import hashlib
|
| 11 | +import hmac |
11 | 12 | import os
|
12 | 13 | import random
|
13 | 14 | import sys
|
@@ -328,6 +329,16 @@ def generate_privkey():
|
328 | 329 | """Generate a valid random 32-byte private key."""
|
329 | 330 | return random.randrange(1, SECP256K1_ORDER).to_bytes(32, 'big')
|
330 | 331 |
|
| 332 | +def rfc6979_nonce(key): |
| 333 | + """Compute signing nonce using RFC6979.""" |
| 334 | + v = bytes([1] * 32) |
| 335 | + k = bytes([0] * 32) |
| 336 | + k = hmac.new(k, v + b"\x00" + key, 'sha256').digest() |
| 337 | + v = hmac.new(k, v, 'sha256').digest() |
| 338 | + k = hmac.new(k, v + b"\x01" + key, 'sha256').digest() |
| 339 | + v = hmac.new(k, v, 'sha256').digest() |
| 340 | + return hmac.new(k, v, 'sha256').digest() |
| 341 | + |
331 | 342 | class ECKey():
|
332 | 343 | """A secp256k1 private key"""
|
333 | 344 |
|
@@ -370,15 +381,18 @@ def get_pubkey(self):
|
370 | 381 | ret.compressed = self.compressed
|
371 | 382 | return ret
|
372 | 383 |
|
373 |
| - def sign_ecdsa(self, msg, low_s=True): |
| 384 | + def sign_ecdsa(self, msg, low_s=True, rfc6979=False): |
374 | 385 | """Construct a DER-encoded ECDSA signature with this key.
|
375 | 386 |
|
376 | 387 | See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the
|
377 | 388 | ECDSA signer algorithm."""
|
378 | 389 | assert(self.valid)
|
379 | 390 | z = int.from_bytes(msg, 'big')
|
380 |
| - # Note: no RFC6979, but a simple random nonce (some tests rely on distinct transactions for the same operation) |
381 |
| - k = random.randrange(1, SECP256K1_ORDER) |
| 391 | + # Note: no RFC6979 by default, but a simple random nonce (some tests rely on distinct transactions for the same operation) |
| 392 | + if rfc6979: |
| 393 | + k = int.from_bytes(rfc6979_nonce(self.secret.to_bytes(32, 'big') + msg), 'big') |
| 394 | + else: |
| 395 | + k = random.randrange(1, SECP256K1_ORDER) |
382 | 396 | R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, k)]))
|
383 | 397 | r = R[0] % SECP256K1_ORDER
|
384 | 398 | s = (pow(k, -1, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER
|
|
0 commit comments