Create a Schnorr signature (see BIP 340).
(key, msg, aux=None, flip_p=False, flip_r=False)
| 487 | return True |
| 488 | |
| 489 | def sign_schnorr(key, msg, aux=None, flip_p=False, flip_r=False): |
| 490 | """Create a Schnorr signature (see BIP 340).""" |
| 491 | |
| 492 | if aux is None: |
| 493 | aux = bytes(32) |
| 494 | |
| 495 | assert len(key) == 32 |
| 496 | # Variable length signature message support is required for checksigfromstack |
| 497 | assert len(aux) == 32 |
| 498 | |
| 499 | sec = int.from_bytes(key, 'big') |
| 500 | if sec == 0 or sec >= SECP256K1_ORDER: |
| 501 | return None |
| 502 | P = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, sec)])) |
| 503 | if SECP256K1.has_even_y(P) == flip_p: |
| 504 | sec = SECP256K1_ORDER - sec |
| 505 | t = (sec ^ int.from_bytes(TaggedHash("BIP0340/aux", aux), 'big')).to_bytes(32, 'big') |
| 506 | kp = int.from_bytes(TaggedHash("BIP0340/nonce", t + P[0].to_bytes(32, 'big') + msg), 'big') % SECP256K1_ORDER |
| 507 | assert kp != 0 |
| 508 | R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, kp)])) |
| 509 | k = kp if SECP256K1.has_even_y(R) != flip_r else SECP256K1_ORDER - kp |
| 510 | e = int.from_bytes(TaggedHash("BIP0340/challenge", R[0].to_bytes(32, 'big') + P[0].to_bytes(32, 'big') + msg), 'big') % SECP256K1_ORDER |
| 511 | return R[0].to_bytes(32, 'big') + ((k + e * sec) % SECP256K1_ORDER).to_bytes(32, 'big') |
| 512 | |
| 513 | class TestFrameworkKey(unittest.TestCase): |
| 514 | def test_schnorr(self): |