Skip to content

Commit b946f8a

Browse files
committed
crypto: add NUMS_H const
1 parent 2cedb42 commit b946f8a

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed

src/pubkey.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <secp256k1_schnorrsig.h>
1414
#include <span.h>
1515
#include <uint256.h>
16+
#include <util/strencodings.h>
1617

1718
#include <algorithm>
1819
#include <cassert>
@@ -181,6 +182,17 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
181182
return 1;
182183
}
183184

185+
/** Nothing Up My Sleeve (NUMS) point
186+
*
187+
* NUMS_H is a point with an unknown discrete logarithm, constructed by taking the sha256 of 'g'
188+
* (uncompressed encoding), which happens to be a point on the curve.
189+
*
190+
* For an example script for calculating H, refer to the unit tests in
191+
* ./test/functional/test_framework/crypto/secp256k1.py
192+
*/
193+
static const std::vector<unsigned char> NUMS_H_DATA{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
194+
const XOnlyPubKey XOnlyPubKey::NUMS_H{NUMS_H_DATA};
195+
184196
XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> bytes)
185197
{
186198
assert(bytes.size() == 32);

src/pubkey.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ class XOnlyPubKey
233233
uint256 m_keydata;
234234

235235
public:
236+
/** Nothing Up My Sleeve point H
237+
* Used as an internal key for provably disabling the key path spend
238+
* see BIP341 for more details */
239+
static const XOnlyPubKey NUMS_H;
240+
236241
/** Construct an empty x-only pubkey. */
237242
XOnlyPubKey() = default;
238243

test/functional/feature_framework_unit_tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"crypto.muhash",
2626
"crypto.poly1305",
2727
"crypto.ripemd160",
28+
"crypto.secp256k1",
2829
"script",
2930
"segwit_addr",
3031
"wallet_util",

test/functional/test_framework/crypto/secp256k1.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* G: the secp256k1 generator point
1616
"""
1717

18+
import unittest
19+
from hashlib import sha256
1820

1921
class FE:
2022
"""Objects of this class represent elements of the field GF(2**256 - 2**32 - 977).
@@ -344,3 +346,9 @@ def mul(self, a):
344346

345347
# Precomputed table with multiples of G for fast multiplication
346348
FAST_G = FastGEMul(G)
349+
350+
class TestFrameworkSecp256k1(unittest.TestCase):
351+
def test_H(self):
352+
H = sha256(G.to_bytes_uncompressed()).digest()
353+
assert GE.lift_x(FE.from_bytes(H)) is not None
354+
self.assertEqual(H.hex(), "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")

0 commit comments

Comments
 (0)