Skip to content

Commit e0ceeab

Browse files
authored
crypto/secp256k1: update to github.com/bitcoin-core/secp256k1 @ 9d560f9 (ethereum#3544)
- Use defined constants instead of hard-coding their integer value. - Allocate secp256k1 structs on the C stack instead of converting []byte - Remove dead code
1 parent 93077c9 commit e0ceeab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+8229
-1998
lines changed

crypto/crypto_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,6 @@ func BenchmarkSha3(b *testing.B) {
7272
fmt.Println(amount, ":", time.Since(start))
7373
}
7474

75-
func Test0Key(t *testing.T) {
76-
key := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
77-
_, err := secp256k1.GeneratePubKey(key)
78-
if err == nil {
79-
t.Errorf("expected error due to zero privkey")
80-
}
81-
}
82-
8375
func TestSign(t *testing.T) {
8476
key, _ := HexToECDSA(testPrivHex)
8577
addr := common.HexToAddress(testAddrHex)

crypto/secp256k1/curve.go

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ package secp256k1
3333

3434
import (
3535
"crypto/elliptic"
36-
"io"
3736
"math/big"
3837
"sync"
3938
"unsafe"
@@ -224,6 +223,7 @@ func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int,
224223
if len(scalar) > 32 {
225224
panic("can't handle scalars > 256 bits")
226225
}
226+
// NOTE: potential timing issue
227227
padded := make([]byte, 32)
228228
copy(padded[32-len(scalar):], scalar)
229229
scalar = padded
@@ -257,31 +257,6 @@ func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
257257
return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k)
258258
}
259259

260-
var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
261-
262-
//TODO: double check if it is okay
263-
// GenerateKey returns a public/private key pair. The private key is generated
264-
// using the given reader, which must return random data.
265-
func (BitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) {
266-
byteLen := (BitCurve.BitSize + 7) >> 3
267-
priv = make([]byte, byteLen)
268-
269-
for x == nil {
270-
_, err = io.ReadFull(rand, priv)
271-
if err != nil {
272-
return
273-
}
274-
// We have to mask off any excess bits in the case that the size of the
275-
// underlying field is not a whole number of bytes.
276-
priv[0] &= mask[BitCurve.BitSize%8]
277-
// This is because, in tests, rand will return all zeros and we don't
278-
// want to get the point at infinity and loop forever.
279-
priv[1] ^= 0x42
280-
x, y = BitCurve.ScalarBaseMult(priv)
281-
}
282-
return
283-
}
284-
285260
// Marshal converts a point into the form specified in section 4.3.6 of ANSI
286261
// X9.62.
287262
func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {

crypto/secp256k1/ext.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2015 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
// secp256k1_context_create_sign_verify creates a context for signing and signature verification.
18+
static secp256k1_context* secp256k1_context_create_sign_verify() {
19+
return secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
20+
}
21+
22+
// secp256k1_ecdsa_recover_pubkey recovers the public key of an encoded compact signature.
23+
//
24+
// Returns: 1: recovery was successful
25+
// 0: recovery was not successful
26+
// Args: ctx: pointer to a context object (cannot be NULL)
27+
// Out: pubkey_out: the serialized 65-byte public key of the signer (cannot be NULL)
28+
// In: sigdata: pointer to a 65-byte signature with the recovery id at the end (cannot be NULL)
29+
// msgdata: pointer to a 32-byte message (cannot be NULL)
30+
static int secp256k1_ecdsa_recover_pubkey(
31+
const secp256k1_context* ctx,
32+
unsigned char *pubkey_out,
33+
const unsigned char *sigdata,
34+
const unsigned char *msgdata
35+
) {
36+
secp256k1_ecdsa_recoverable_signature sig;
37+
secp256k1_pubkey pubkey;
38+
39+
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &sig, sigdata, (int)sigdata[64])) {
40+
return 0;
41+
}
42+
if (!secp256k1_ecdsa_recover(ctx, &pubkey, &sig, msgdata)) {
43+
return 0;
44+
}
45+
size_t outputlen = 65;
46+
return secp256k1_ec_pubkey_serialize(ctx, pubkey_out, &outputlen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
47+
}
48+
49+
// secp256k1_pubkey_scalar_mul multiplies a point by a scalar in constant time.
50+
//
51+
// Returns: 1: multiplication was successful
52+
// 0: scalar was invalid (zero or overflow)
53+
// Args: ctx: pointer to a context object (cannot be NULL)
54+
// Out: point: the multiplied point (usually secret)
55+
// In: point: pointer to a 64-byte public point,
56+
// encoded as two 256bit big-endian numbers.
57+
// scalar: a 32-byte scalar with which to multiply the point
58+
int secp256k1_pubkey_scalar_mul(const secp256k1_context* ctx, unsigned char *point, const unsigned char *scalar) {
59+
int ret = 0;
60+
int overflow = 0;
61+
secp256k1_fe feX, feY;
62+
secp256k1_gej res;
63+
secp256k1_ge ge;
64+
secp256k1_scalar s;
65+
ARG_CHECK(point != NULL);
66+
ARG_CHECK(scalar != NULL);
67+
(void)ctx;
68+
69+
secp256k1_fe_set_b32(&feX, point);
70+
secp256k1_fe_set_b32(&feY, point+32);
71+
secp256k1_ge_set_xy(&ge, &feX, &feY);
72+
secp256k1_scalar_set_b32(&s, scalar, &overflow);
73+
if (overflow || secp256k1_scalar_is_zero(&s)) {
74+
ret = 0;
75+
} else {
76+
secp256k1_ecmult_const(&res, &ge, &s);
77+
secp256k1_ge_set_gej(&ge, &res);
78+
/* Note: can't use secp256k1_pubkey_save here because it is not constant time. */
79+
secp256k1_fe_normalize(&ge.x);
80+
secp256k1_fe_normalize(&ge.y);
81+
secp256k1_fe_get_b32(point, &ge.x);
82+
secp256k1_fe_get_b32(point+32, &ge.y);
83+
ret = 1;
84+
}
85+
secp256k1_scalar_clear(&s);
86+
return ret;
87+
}

crypto/secp256k1/libsecp256k1/.gitignore

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ bench_schnorr_verify
66
bench_recover
77
bench_internal
88
tests
9+
exhaustive_tests
910
gen_context
1011
*.exe
1112
*.so
@@ -25,17 +26,24 @@ config.status
2526
libtool
2627
.deps/
2728
.dirstamp
28-
build-aux/
2929
*.lo
3030
*.o
3131
*~
3232
src/libsecp256k1-config.h
3333
src/libsecp256k1-config.h.in
3434
src/ecmult_static_context.h
35-
m4/libtool.m4
36-
m4/ltoptions.m4
37-
m4/ltsugar.m4
38-
m4/ltversion.m4
39-
m4/lt~obsolete.m4
35+
build-aux/config.guess
36+
build-aux/config.sub
37+
build-aux/depcomp
38+
build-aux/install-sh
39+
build-aux/ltmain.sh
40+
build-aux/m4/libtool.m4
41+
build-aux/m4/lt~obsolete.m4
42+
build-aux/m4/ltoptions.m4
43+
build-aux/m4/ltsugar.m4
44+
build-aux/m4/ltversion.m4
45+
build-aux/missing
46+
build-aux/compile
47+
build-aux/test-driver
4048
src/stamp-h1
4149
libsecp256k1.pc

crypto/secp256k1/libsecp256k1/.travis.yml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,30 @@ addons:
66
compiler:
77
- clang
88
- gcc
9+
cache:
10+
directories:
11+
- src/java/guava/
912
env:
1013
global:
11-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=NO RECOVERY=NO
14+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no
15+
- GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar
1216
matrix:
1317
- SCALAR=32bit RECOVERY=yes
14-
- SCALAR=32bit FIELD=32bit ECDH=yes
18+
- SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes
1519
- SCALAR=64bit
1620
- FIELD=64bit RECOVERY=yes
1721
- FIELD=64bit ENDOMORPHISM=yes
18-
- FIELD=64bit ENDOMORPHISM=yes ECDH=yes
22+
- FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes
1923
- FIELD=64bit ASM=x86_64
2024
- FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
21-
- FIELD=32bit SCHNORR=yes
2225
- FIELD=32bit ENDOMORPHISM=yes
2326
- BIGNUM=no
24-
- BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes
27+
- BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes
2528
- BIGNUM=no STATICPRECOMPUTATION=no
2629
- BUILD=distcheck
27-
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
30+
- EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC
31+
- EXTRAFLAGS=CFLAGS=-O0
32+
- BUILD=check-java ECDH=yes EXPERIMENTAL=yes
2833
matrix:
2934
fast_finish: true
3035
include:
@@ -54,9 +59,11 @@ matrix:
5459
packages:
5560
- gcc-multilib
5661
- libgmp-dev:i386
62+
before_install: mkdir -p `dirname $GUAVA_JAR`
63+
install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi
5764
before_script: ./autogen.sh
5865
script:
5966
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
6067
- if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
61-
- ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-schnorr=$SCHNORR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
68+
- ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
6269
os: linux

0 commit comments

Comments
 (0)