Skip to content

Commit dbda25c

Browse files
committed
Squashed 'src/secp256k1/' changes from efe85c70a2..6ddf3e958e
6ddf3e958e [DEMO-ONLY] add bip352 test vectors running suite using python and ctypes 0b5293f4f2 test: add simple BIP-352 test with mixed plain/taproot inputs 26bdb5f195 silentpayments: implement output spending privkey creation (for receiver) d6c9856bde silentpayments: add routine for tx output scanning (for receiver) 8460be58cc silentpayments: implement output pubkey creation (for sender) dbcccbb7cc silentpayments: add routine for creating labelled spend pubkeys (for addresses) 2a00e12e58 silentpayments: add label tweak calculation routine b0e37968b0 silentpayments: add shared secret creation routine (a*B == A*b) 842e5bf427 silentpayments: add tweaked pubkey creation routine (for light clients / sp index) 98f5ba4aa6 silentpayments: add public tweak data creation routine 81d13038d5 silentpayments: add private tweak data creation routine 6e3ed2d5df doc: add module description for secp256k1-silentpayments a9a5fe8e28 build: add skeleton for new silentpayments (BIP352) module 2483627299 Merge bitcoin-core/secp256k1#1483: cmake: Recommend native CMake commands in README 5ad3aa3dcd Merge bitcoin-core/secp256k1#1484: tests: Drop redundant _scalar_check_overflow calls 51df2d9ab3 tests: Drop redundant _scalar_check_overflow calls 3777e3f36a cmake: Recommend native CMake commands in README e4af41c61b Merge bitcoin-core/secp256k1#1249: cmake: Add `SECP256K1_LATE_CFLAGS` configure option 3bf4d68fc0 Merge bitcoin-core/secp256k1#1482: build: Clean up handling of module dependencies e6822678ea build: Error if required module explicitly off 89ec583ccf build: Clean up handling of module dependencies 44378867a0 Merge bitcoin-core/secp256k1#1468: v0.4.1 release aftermath a9db9f2d75 Merge bitcoin-core/secp256k1#1480: Get rid of untested sizeof(secp256k1_ge_storage) == 64 code path 74b7c3b53e Merge bitcoin-core/secp256k1#1476: include: make docs more consistent b37fdb28ce check-abi: Minor UI improvements ad5f589a94 check-abi: Default to HEAD for new version 9fb7e2f156 release process: Style and formatting nits ba5d72d626 assumptions: Use new STATIC_ASSERT macro e53c2d9ffc Require that sizeof(secp256k1_ge_storage) == 64 d0ba2abbff util: Add STATIC_ASSERT macro da7bc1b803 include: in doc, remove article in front of "pointer" aa3dd5280b include: make doc about ctx more consistent e3f690015a include: remove obvious "cannot be NULL" doc d373bf6d08 Merge bitcoin-core/secp256k1#1474: tests: restore scalar_mul test 79e094517c Merge bitcoin-core/secp256k1#1473: Fix typos 3dbfb48946 tests: restore scalar_mul test d77170a88d Fix typos e7053d065b release process: Add email step 429d21dc79 release process: Run sanity checks on release PR 42f8c51402 cmake: Add `SECP256K1_LATE_CFLAGS` configure option git-subtree-dir: src/secp256k1 git-subtree-split: 6ddf3e958e60f01ef1e9c85d9f957d91cf0abba7
1 parent 29fde02 commit dbda25c

30 files changed

+4111
-215
lines changed

CMakeLists.txt

+35-10
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,45 @@ endif()
5151

5252
option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
5353

54+
## Modules
55+
56+
# We declare all options before processing them, to make sure we can express
57+
# dependendencies while processing.
5458
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
55-
if(SECP256K1_ENABLE_MODULE_ECDH)
56-
add_compile_definitions(ENABLE_MODULE_ECDH=1)
59+
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
60+
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
61+
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
62+
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
63+
option(SECP256K1_ENABLE_MODULE_SILENTPAYMENTS "Enable Silent Payments module." OFF)
64+
65+
# Processing must be done in a topological sorting of the dependency graph
66+
# (dependent module first).
67+
if(SECP256K1_ENABLE_MODULE_SILENTPAYMENTS)
68+
add_compile_definitions(ENABLE_MODULE_SILENTPAYMENTS=1)
5769
endif()
5870

59-
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
60-
if(SECP256K1_ENABLE_MODULE_RECOVERY)
61-
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
71+
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
72+
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
6273
endif()
6374

64-
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
65-
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
6675
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
76+
if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS)
77+
message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.")
78+
endif()
6779
set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON)
6880
add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1)
6981
endif()
82+
7083
if(SECP256K1_ENABLE_MODULE_EXTRAKEYS)
7184
add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1)
7285
endif()
7386

74-
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
75-
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
76-
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
87+
if(SECP256K1_ENABLE_MODULE_RECOVERY)
88+
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
89+
endif()
90+
91+
if(SECP256K1_ENABLE_MODULE_ECDH)
92+
add_compile_definitions(ENABLE_MODULE_ECDH=1)
7793
endif()
7894

7995
option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
@@ -254,9 +270,14 @@ if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUST
254270
enable_testing()
255271
endif()
256272

273+
set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.")
274+
include(AllTargetsCompileOptions)
275+
257276
add_subdirectory(src)
277+
all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}")
258278
if(SECP256K1_BUILD_EXAMPLES)
259279
add_subdirectory(examples)
280+
all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}")
260281
endif()
261282

262283
message("\n")
@@ -276,6 +297,7 @@ message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOV
276297
message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
277298
message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
278299
message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
300+
message(" Silent Payments ..................... ${SECP256K1_ENABLE_MODULE_SILENTPAYMENTS}")
279301
message("Parameters:")
280302
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
281303
message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}")
@@ -330,6 +352,9 @@ else()
330352
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
331353
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
332354
endif()
355+
if(SECP256K1_LATE_CFLAGS)
356+
message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}")
357+
endif()
333358
message("\n")
334359
if(SECP256K1_EXPERIMENTAL)
335360
message(

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Co
4444

4545
In addition, libsecp256k1 tries to maintain the following coding conventions:
4646

47-
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Morever, it should be possible to use the library without any heap allocations.
47+
* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
4848
* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
4949
* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
5050
* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.

Makefile.am

+4
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,7 @@ endif
271271
if ENABLE_MODULE_ELLSWIFT
272272
include src/modules/ellswift/Makefile.am.include
273273
endif
274+
275+
if ENABLE_MODULE_SILENTPAYMENTS
276+
include src/modules/silentpayments/Makefile.am.include
277+
endif

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ To maintain a pristine source tree, CMake encourages to perform an out-of-source
7979

8080
$ mkdir build && cd build
8181
$ cmake ..
82-
$ make
83-
$ make check # run the test suite
84-
$ sudo make install # optional
82+
$ cmake --build .
83+
$ ctest # run the test suite
84+
$ sudo cmake --build . --target install # optional
8585

8686
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags.
8787

bip352-testsuite/bech32m.py

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Copyright (c) 2017, 2020 Pieter Wuille
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
21+
"""Reference implementation for Bech32/Bech32m and segwit addresses."""
22+
23+
24+
from enum import Enum
25+
26+
class Encoding(Enum):
27+
"""Enumeration type to list the various supported encodings."""
28+
BECH32 = 1
29+
BECH32M = 2
30+
31+
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
32+
BECH32M_CONST = 0x2bc830a3
33+
34+
def bech32_polymod(values):
35+
"""Internal function that computes the Bech32 checksum."""
36+
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
37+
chk = 1
38+
for value in values:
39+
top = chk >> 25
40+
chk = (chk & 0x1ffffff) << 5 ^ value
41+
for i in range(5):
42+
chk ^= generator[i] if ((top >> i) & 1) else 0
43+
return chk
44+
45+
46+
def bech32_hrp_expand(hrp):
47+
"""Expand the HRP into values for checksum computation."""
48+
return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp]
49+
50+
51+
def bech32_verify_checksum(hrp, data):
52+
"""Verify a checksum given HRP and converted data characters."""
53+
const = bech32_polymod(bech32_hrp_expand(hrp) + data)
54+
if const == 1:
55+
return Encoding.BECH32
56+
if const == BECH32M_CONST:
57+
return Encoding.BECH32M
58+
return None
59+
60+
def bech32_create_checksum(hrp, data, spec):
61+
"""Compute the checksum values given HRP and data."""
62+
values = bech32_hrp_expand(hrp) + data
63+
const = BECH32M_CONST if spec == Encoding.BECH32M else 1
64+
polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const
65+
return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
66+
67+
68+
def bech32_encode(hrp, data, spec):
69+
"""Compute a Bech32 string given HRP and data values."""
70+
combined = data + bech32_create_checksum(hrp, data, spec)
71+
return hrp + '1' + ''.join([CHARSET[d] for d in combined])
72+
73+
def bech32_decode(bech):
74+
"""Validate a Bech32/Bech32m string, and determine HRP and data."""
75+
if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or
76+
(bech.lower() != bech and bech.upper() != bech)):
77+
return (None, None, None)
78+
bech = bech.lower()
79+
pos = bech.rfind('1')
80+
81+
# remove the requirement that bech32m be less than 90 chars
82+
if pos < 1 or pos + 7 > len(bech):
83+
return (None, None, None)
84+
if not all(x in CHARSET for x in bech[pos+1:]):
85+
return (None, None, None)
86+
hrp = bech[:pos]
87+
data = [CHARSET.find(x) for x in bech[pos+1:]]
88+
spec = bech32_verify_checksum(hrp, data)
89+
if spec is None:
90+
return (None, None, None)
91+
return (hrp, data[:-6], spec)
92+
93+
def convertbits(data, frombits, tobits, pad=True):
94+
"""General power-of-2 base conversion."""
95+
acc = 0
96+
bits = 0
97+
ret = []
98+
maxv = (1 << tobits) - 1
99+
max_acc = (1 << (frombits + tobits - 1)) - 1
100+
for value in data:
101+
if value < 0 or (value >> frombits):
102+
return None
103+
acc = ((acc << frombits) | value) & max_acc
104+
bits += frombits
105+
while bits >= tobits:
106+
bits -= tobits
107+
ret.append((acc >> bits) & maxv)
108+
if pad:
109+
if bits:
110+
ret.append((acc << (tobits - bits)) & maxv)
111+
elif bits >= frombits or ((acc << (tobits - bits)) & maxv):
112+
return None
113+
return ret
114+
115+
116+
def decode(hrp, addr):
117+
"""Decode a segwit address."""
118+
hrpgot, data, spec = bech32_decode(addr)
119+
if hrpgot != hrp:
120+
return (None, None)
121+
decoded = convertbits(data[1:], 5, 8, False)
122+
if decoded is None or len(decoded) < 2:
123+
return (None, None)
124+
if data[0] > 16:
125+
return (None, None)
126+
return (data[0], decoded)
127+
128+
129+
def encode(hrp, witver, witprog):
130+
"""Encode a segwit address."""
131+
spec = Encoding.BECH32 if witver == 0 else Encoding.BECH32M
132+
ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5), spec)
133+
if decode(hrp, ret) == (None, None):
134+
return None
135+
return ret

0 commit comments

Comments
 (0)