diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-01-13 04:29:11 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-13 04:29:11 +0800 |
commit | e0ceeab0d111ada7d847c83992d2ff3128bfb959 (patch) | |
tree | be9fcaa85d61ba461a3ee2293206f5f73c7e5451 /crypto/secp256k1/ext.h | |
parent | 93077c98e43610122ad0933b20a44f04a8f4b6b2 (diff) | |
download | dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar.gz dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar.bz2 dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar.lz dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar.xz dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.tar.zst dexon-e0ceeab0d111ada7d847c83992d2ff3128bfb959.zip |
crypto/secp256k1: update to github.com/bitcoin-core/secp256k1 @ 9d560f9 (#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
Diffstat (limited to 'crypto/secp256k1/ext.h')
-rw-r--r-- | crypto/secp256k1/ext.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/crypto/secp256k1/ext.h b/crypto/secp256k1/ext.h new file mode 100644 index 000000000..ee759fde6 --- /dev/null +++ b/crypto/secp256k1/ext.h @@ -0,0 +1,87 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// secp256k1_context_create_sign_verify creates a context for signing and signature verification. +static secp256k1_context* secp256k1_context_create_sign_verify() { + return secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); +} + +// secp256k1_ecdsa_recover_pubkey recovers the public key of an encoded compact signature. +// +// Returns: 1: recovery was successful +// 0: recovery was not successful +// Args: ctx: pointer to a context object (cannot be NULL) +// Out: pubkey_out: the serialized 65-byte public key of the signer (cannot be NULL) +// In: sigdata: pointer to a 65-byte signature with the recovery id at the end (cannot be NULL) +// msgdata: pointer to a 32-byte message (cannot be NULL) +static int secp256k1_ecdsa_recover_pubkey( + const secp256k1_context* ctx, + unsigned char *pubkey_out, + const unsigned char *sigdata, + const unsigned char *msgdata +) { + secp256k1_ecdsa_recoverable_signature sig; + secp256k1_pubkey pubkey; + + if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &sig, sigdata, (int)sigdata[64])) { + return 0; + } + if (!secp256k1_ecdsa_recover(ctx, &pubkey, &sig, msgdata)) { + return 0; + } + size_t outputlen = 65; + return secp256k1_ec_pubkey_serialize(ctx, pubkey_out, &outputlen, &pubkey, SECP256K1_EC_UNCOMPRESSED); +} + +// secp256k1_pubkey_scalar_mul multiplies a point by a scalar in constant time. +// +// Returns: 1: multiplication was successful +// 0: scalar was invalid (zero or overflow) +// Args: ctx: pointer to a context object (cannot be NULL) +// Out: point: the multiplied point (usually secret) +// In: point: pointer to a 64-byte public point, +// encoded as two 256bit big-endian numbers. +// scalar: a 32-byte scalar with which to multiply the point +int secp256k1_pubkey_scalar_mul(const secp256k1_context* ctx, unsigned char *point, const unsigned char *scalar) { + int ret = 0; + int overflow = 0; + secp256k1_fe feX, feY; + secp256k1_gej res; + secp256k1_ge ge; + secp256k1_scalar s; + ARG_CHECK(point != NULL); + ARG_CHECK(scalar != NULL); + (void)ctx; + + secp256k1_fe_set_b32(&feX, point); + secp256k1_fe_set_b32(&feY, point+32); + secp256k1_ge_set_xy(&ge, &feX, &feY); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + if (overflow || secp256k1_scalar_is_zero(&s)) { + ret = 0; + } else { + secp256k1_ecmult_const(&res, &ge, &s); + secp256k1_ge_set_gej(&ge, &res); + /* Note: can't use secp256k1_pubkey_save here because it is not constant time. */ + secp256k1_fe_normalize(&ge.x); + secp256k1_fe_normalize(&ge.y); + secp256k1_fe_get_b32(point, &ge.x); + secp256k1_fe_get_b32(point+32, &ge.y); + ret = 1; + } + secp256k1_scalar_clear(&s); + return ret; +} |