github.com/tuotoo/go-ethereum@v1.7.4-0.20171121184211-049797d40a24/crypto/secp256k1/ext.h (about)

     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  }