Skip to content

Commit a591d98

Browse files
committed
Squashed 'src/secp256k1/' changes from 1897b8e..22f60a6
22f60a6 Merge pull request bitcoin-core#245 61c1b1e Merge pull request bitcoin-core#190 d227579 Add scalar blinding and a secp256k1_context_randomize() call. c146b4a Add bench_internal to gitignore. 9c4fb23 Add a secp256k1_fe_cmov unit test. 426fa52 Merge pull request bitcoin-core#243 d505a89 Merge pull request bitcoin-core#244 2d2707a travis: test i686 builds with gmp cf7f702 travis: update to new build infrastructure bb0ea50 Replace set/add with cmov in secp256k1_gej_add_ge. f3d3519 Merge pull request bitcoin-core#241 5c2a4fa Fix memory leak in context unit test 14aacdc Merge pull request bitcoin-core#239 93226a5 secp256k1.c: Add missing DEBUG_CHECKs for sufficiently capable contexts 6099220 Merge pull request bitcoin-core#237 6066bb6 Fix typo: avg -> max 9688030 Merge pull request bitcoin-core#236 d899b5b Expose ability to deep-copy a context 3608c7f Merge pull request bitcoin-core#208 a9b6595 [API BREAK] Introduce explicit contexts a0d3b89 Merge pull request bitcoin-core#233 9e8d89b Merge pull request bitcoin-core#234 65e70e7 Merge pull request bitcoin-core#235 5098f62 Improve documentation formatting consistency 4450e24 Add a comment about the avoidance of secret data in array indexes. 6534ee1 initialize variable d5b53aa Merge pull request bitcoin-core#232 c01df1a Avoid some implicit type conversions to make C++ compilers happy. bfe96ba Merge pull request bitcoin-core#231 33270bf Add a couple comments pointing to particular sections of RFC6979. 41603aa Merge pull request bitcoin-core#230 2632019 Brace all the if/for/while. git-subtree-dir: src/secp256k1 git-subtree-split: 22f60a62801a8a49ecd049e7a563f69a41affd8d
1 parent 9d09322 commit a591d98

26 files changed

+1154
-468
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ bench_inv
22
bench_sign
33
bench_verify
44
bench_recover
5+
bench_internal
56
tests
67
*.exe
78
*.so

.travis.yml

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
language: c
2+
sudo: false
3+
addons:
4+
apt:
5+
packages: libgmp-dev
26
compiler:
37
- clang
48
- gcc
5-
install:
6-
- sudo apt-get install -qq libssl-dev
7-
- if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
8-
- if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi
99
env:
1010
global:
11-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
11+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST=
1212
matrix:
1313
- SCALAR=32bit
1414
- SCALAR=64bit
@@ -22,8 +22,35 @@ env:
2222
- BIGNUM=no ENDOMORPHISM=yes
2323
- BUILD=distcheck
2424
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
25-
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib"
26-
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes
25+
matrix:
26+
fast_finish: true
27+
include:
28+
- compiler: clang
29+
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
30+
addons:
31+
apt:
32+
packages:
33+
- gcc-multilib
34+
- libgmp-dev:i386
35+
- compiler: clang
36+
env: HOST=i686-linux-gnu
37+
addons:
38+
apt:
39+
packages:
40+
- gcc-multilib
41+
- compiler: gcc
42+
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
43+
addons:
44+
apt:
45+
packages:
46+
- gcc-multilib
47+
- compiler: gcc
48+
env: HOST=i686-linux-gnu
49+
addons:
50+
apt:
51+
packages:
52+
- gcc-multilib
53+
- libgmp-dev:i386
2754
before_script: ./autogen.sh
2855
script:
2956
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi

include/secp256k1.h

Lines changed: 101 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -40,42 +40,60 @@ extern "C" {
4040
# define SECP256K1_ARG_NONNULL(_x)
4141
# endif
4242

43+
/** Opaque data structure that holds context information (precomputed tables etc.).
44+
* Only functions that take a pointer to a non-const context require exclusive
45+
* access to it. Multiple functions that take a pointer to a const context may
46+
* run simultaneously.
47+
*/
48+
typedef struct secp256k1_context_struct secp256k1_context_t;
49+
50+
/** Flags to pass to secp256k1_context_create. */
51+
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
52+
# define SECP256K1_CONTEXT_SIGN (1 << 1)
4353

44-
/** Flags to pass to secp256k1_start. */
45-
# define SECP256K1_START_VERIFY (1 << 0)
46-
# define SECP256K1_START_SIGN (1 << 1)
54+
/** Create a secp256k1 context object.
55+
* Returns: a newly created context object.
56+
* In: flags: which parts of the context to initialize.
57+
*/
58+
secp256k1_context_t* secp256k1_context_create(
59+
int flags
60+
) SECP256K1_WARN_UNUSED_RESULT;
4761

48-
/** Initialize the library. This may take some time (10-100 ms).
49-
* You need to call this before calling any other function.
50-
* It cannot run in parallel with any other functions, but once
51-
* secp256k1_start() returns, all other functions are thread-safe.
62+
/** Copies a secp256k1 context object.
63+
* Returns: a newly created context object.
64+
* In: ctx: an existing context to copy
5265
*/
53-
void secp256k1_start(unsigned int flags);
66+
secp256k1_context_t* secp256k1_context_clone(
67+
const secp256k1_context_t* ctx
68+
) SECP256K1_WARN_UNUSED_RESULT;
5469

55-
/** Free all memory associated with this library. After this, no
56-
* functions can be called anymore, except secp256k1_start()
70+
/** Destroy a secp256k1 context object.
71+
* The context pointer may not be used afterwards.
5772
*/
58-
void secp256k1_stop(void);
73+
void secp256k1_context_destroy(
74+
secp256k1_context_t* ctx
75+
) SECP256K1_ARG_NONNULL(1);
5976

6077
/** Verify an ECDSA signature.
6178
* Returns: 1: correct signature
6279
* 0: incorrect signature
6380
* -1: invalid public key
6481
* -2: invalid signature
65-
* In: msg32: the 32-byte message hash being verified (cannot be NULL)
82+
* In: ctx: a secp256k1 context object, initialized for verification.
83+
* msg32: the 32-byte message hash being verified (cannot be NULL)
6684
* sig: the signature being verified (cannot be NULL)
6785
* siglen: the length of the signature
6886
* pubkey: the public key to verify with (cannot be NULL)
6987
* pubkeylen: the length of pubkey
70-
* Requires starting using SECP256K1_START_VERIFY.
7188
*/
7289
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
90+
const secp256k1_context_t* ctx,
7391
const unsigned char *msg32,
7492
const unsigned char *sig,
7593
int siglen,
7694
const unsigned char *pubkey,
7795
int pubkeylen
78-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
96+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
7997

8098
/** A pointer to a function to deterministically generate a nonce.
8199
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
@@ -111,15 +129,14 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
111129
* Returns: 1: signature created
112130
* 0: the nonce generation function failed, the private key was invalid, or there is not
113131
* enough space in the signature (as indicated by siglen).
114-
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
132+
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
133+
* msg32: the 32-byte message hash being signed (cannot be NULL)
115134
* seckey: pointer to a 32-byte secret key (cannot be NULL)
116135
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
117136
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
118137
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
119138
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
120-
* to contain the actual signature length (<=72). If 0 is returned, this will be
121-
* set to zero.
122-
* Requires starting using SECP256K1_START_SIGN.
139+
* to contain the actual signature length (<=72).
123140
*
124141
* The sig always has an s value in the lower half of the range (From 0x1
125142
* to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
@@ -148,145 +165,180 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
148165
* be taken when this property is required for an application.
149166
*/
150167
int secp256k1_ecdsa_sign(
168+
const secp256k1_context_t* ctx,
151169
const unsigned char *msg32,
152170
unsigned char *sig,
153171
int *siglen,
154172
const unsigned char *seckey,
155173
secp256k1_nonce_function_t noncefp,
156174
const void *ndata
157-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
175+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
158176

159177
/** Create a compact ECDSA signature (64 byte + recovery id).
160178
* Returns: 1: signature created
161179
* 0: the nonce generation function failed, or the secret key was invalid.
162-
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
180+
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
181+
* msg32: the 32-byte message hash being signed (cannot be NULL)
163182
* seckey: pointer to a 32-byte secret key (cannot be NULL)
164183
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
165184
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
166185
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
167186
* In case 0 is returned, the returned signature length will be zero.
168187
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
169-
* Requires starting using SECP256K1_START_SIGN.
170188
*/
171189
int secp256k1_ecdsa_sign_compact(
190+
const secp256k1_context_t* ctx,
172191
const unsigned char *msg32,
173192
unsigned char *sig64,
174193
const unsigned char *seckey,
175194
secp256k1_nonce_function_t noncefp,
176195
const void *ndata,
177196
int *recid
178-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
197+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
179198

180199
/** Recover an ECDSA public key from a compact signature.
181200
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
182201
* 0: otherwise.
183-
* In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
202+
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
203+
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
184204
* sig64: signature as 64 byte array (cannot be NULL)
185205
* compressed: whether to recover a compressed or uncompressed pubkey
186206
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
187207
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL)
188208
* pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL)
189-
* Requires starting using SECP256K1_START_VERIFY.
190209
*/
191210
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
211+
const secp256k1_context_t* ctx,
192212
const unsigned char *msg32,
193213
const unsigned char *sig64,
194214
unsigned char *pubkey,
195215
int *pubkeylen,
196216
int compressed,
197217
int recid
198-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
218+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
199219

200220
/** Verify an ECDSA secret key.
201221
* Returns: 1: secret key is valid
202222
* 0: secret key is invalid
203-
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
223+
* In: ctx: pointer to a context object (cannot be NULL)
224+
* seckey: pointer to a 32-byte secret key (cannot be NULL)
204225
*/
205-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const unsigned char *seckey) SECP256K1_ARG_NONNULL(1);
226+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
227+
const secp256k1_context_t* ctx,
228+
const unsigned char *seckey
229+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
206230

207231
/** Just validate a public key.
208-
* Returns: 1: valid public key
209-
* 0: invalid public key
210-
* In: pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
232+
* Returns: 1: public key is valid
233+
* 0: public key is invalid
234+
* In: ctx: pointer to a context object (cannot be NULL)
235+
* pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
211236
* pubkeylen: length of pubkey
212237
*/
213-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) SECP256K1_ARG_NONNULL(1);
238+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
239+
const secp256k1_context_t* ctx,
240+
const unsigned char *pubkey,
241+
int pubkeylen
242+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
214243

215244
/** Compute the public key for a secret key.
216-
* In: compressed: whether the computed public key should be compressed
245+
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
246+
* compressed: whether the computed public key should be compressed
217247
* seckey: pointer to a 32-byte private key (cannot be NULL)
218248
* Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
219249
* area to store the public key (cannot be NULL)
220250
* pubkeylen: pointer to int that will be updated to contains the pubkey's
221251
* length (cannot be NULL)
222252
* Returns: 1: secret was valid, public key stores
223-
* 0: secret was invalid, try again.
224-
* Requires starting using SECP256K1_START_SIGN.
253+
* 0: secret was invalid, try again
225254
*/
226255
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
256+
const secp256k1_context_t* ctx,
227257
unsigned char *pubkey,
228258
int *pubkeylen,
229259
const unsigned char *seckey,
230260
int compressed
231-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
261+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
232262

233263
/** Decompress a public key.
264+
* In: ctx: pointer to a context object (cannot be NULL)
234265
* In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key.
235-
It must contain a 33-byte or 65-byte public key already (cannot be NULL)
266+
* It must contain a 33-byte or 65-byte public key already (cannot be NULL)
236267
* pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL)
237-
It will be updated to reflect the new size.
238-
* Returns: 0 if the passed public key was invalid, 1 otherwise. If 1 is returned, the
239-
pubkey is replaced with its decompressed version.
268+
* It will be updated to reflect the new size.
269+
* Returns: 0: pubkey was invalid
270+
* 1: pubkey was valid, and was replaced with its decompressed version
240271
*/
241272
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
273+
const secp256k1_context_t* ctx,
242274
unsigned char *pubkey,
243275
int *pubkeylen
244-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
276+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
245277

246-
/** Export a private key in DER format. */
278+
/** Export a private key in DER format.
279+
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
280+
*/
247281
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
282+
const secp256k1_context_t* ctx,
248283
const unsigned char *seckey,
249284
unsigned char *privkey,
250285
int *privkeylen,
251286
int compressed
252-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
287+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
253288

254289
/** Import a private key in DER format. */
255290
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
291+
const secp256k1_context_t* ctx,
256292
unsigned char *seckey,
257293
const unsigned char *privkey,
258294
int privkeylen
259-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
295+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
260296

261297
/** Tweak a private key by adding tweak to it. */
262298
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
299+
const secp256k1_context_t* ctx,
263300
unsigned char *seckey,
264301
const unsigned char *tweak
265-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
302+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
266303

267304
/** Tweak a public key by adding tweak times the generator to it.
268-
* Requires starting with SECP256K1_START_VERIFY.
305+
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
269306
*/
270307
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
308+
const secp256k1_context_t* ctx,
271309
unsigned char *pubkey,
272310
int pubkeylen,
273311
const unsigned char *tweak
274-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
312+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
275313

276314
/** Tweak a private key by multiplying it with tweak. */
277315
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
316+
const secp256k1_context_t* ctx,
278317
unsigned char *seckey,
279318
const unsigned char *tweak
280-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
319+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
281320

282321
/** Tweak a public key by multiplying it with tweak.
283-
* Requires starting with SECP256K1_START_VERIFY.
322+
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
284323
*/
285324
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
325+
const secp256k1_context_t* ctx,
286326
unsigned char *pubkey,
287327
int pubkeylen,
288328
const unsigned char *tweak
289-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
329+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
330+
331+
/** Updates the context randomization.
332+
* Returns: 1: randomization successfully updated
333+
* 0: error
334+
* In: ctx: pointer to a context object (cannot be NULL)
335+
* seed32: pointer to a 32-byte random seed (NULL resets to initial state)
336+
*/
337+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
338+
secp256k1_context_t* ctx,
339+
const unsigned char *seed32
340+
) SECP256K1_ARG_NONNULL(1);
341+
290342

291343
# ifdef __cplusplus
292344
}

src/bench.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v
4848
print_number(min * 1000000.0 / iter);
4949
printf("us / avg ");
5050
print_number((sum / count) * 1000000.0 / iter);
51-
printf("us / avg ");
51+
printf("us / max ");
5252
print_number(max * 1000000.0 / iter);
5353
printf("us\n");
5454
}

0 commit comments

Comments
 (0)