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