github.com/klaytn/klaytn@v1.12.1/crypto/secp256k1/ext.h (about)

     1  // Copyright 2018 The klaytn Authors
     2  // Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
     3  // Use of this source code is governed by a BSD-style license that can be found in
     4  // the LICENSE file.
     5  //
     6  // This file is derived from crypto/secp256k1/ext.h (2018/06/04).
     7  // See LICENSE in the top directory for the original copyright and license.
     8  
     9  // secp256k1_context_create_sign_verify creates a context for signing and signature verification.
    10  static secp256k1_context* secp256k1_context_create_sign_verify() {
    11  	return secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
    12  }
    13  
    14  // secp256k1_ext_ecdsa_recover recovers the public key of an encoded compact signature.
    15  //
    16  // Returns: 1: recovery was successful
    17  //          0: recovery was not successful
    18  // Args:    ctx:        pointer to a context object (cannot be NULL)
    19  //  Out:    pubkey_out: the serialized 65-byte public key of the signer (cannot be NULL)
    20  //  In:     sigdata:    pointer to a 65-byte signature with the recovery id at the end (cannot be NULL)
    21  //          msgdata:    pointer to a 32-byte message (cannot be NULL)
    22  static int secp256k1_ext_ecdsa_recover(
    23  	const secp256k1_context* ctx,
    24  	unsigned char *pubkey_out,
    25  	const unsigned char *sigdata,
    26  	const unsigned char *msgdata
    27  ) {
    28  	secp256k1_ecdsa_recoverable_signature sig;
    29  	secp256k1_pubkey pubkey;
    30  
    31  	if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &sig, sigdata, (int)sigdata[64])) {
    32  		return 0;
    33  	}
    34  	if (!secp256k1_ecdsa_recover(ctx, &pubkey, &sig, msgdata)) {
    35  		return 0;
    36  	}
    37  	size_t outputlen = 65;
    38  	return secp256k1_ec_pubkey_serialize(ctx, pubkey_out, &outputlen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
    39  }
    40  
    41  // secp256k1_ext_ecdsa_verify verifies an encoded compact signature.
    42  //
    43  // Returns: 1: signature is valid
    44  //          0: signature is invalid
    45  // Args:    ctx:        pointer to a context object (cannot be NULL)
    46  //  In:     sigdata:    pointer to a 64-byte signature (cannot be NULL)
    47  //          msgdata:    pointer to a 32-byte message (cannot be NULL)
    48  //          pubkeydata: pointer to public key data (cannot be NULL)
    49  //          pubkeylen:  length of pubkeydata
    50  static int secp256k1_ext_ecdsa_verify(
    51  	const secp256k1_context* ctx,
    52  	const unsigned char *sigdata,
    53  	const unsigned char *msgdata,
    54  	const unsigned char *pubkeydata,
    55  	size_t pubkeylen
    56  ) {
    57  	secp256k1_ecdsa_signature sig;
    58  	secp256k1_pubkey pubkey;
    59  
    60  	if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, sigdata)) {
    61  		return 0;
    62  	}
    63  	if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeydata, pubkeylen)) {
    64  		return 0;
    65  	}
    66  	return secp256k1_ecdsa_verify(ctx, &sig, msgdata, &pubkey);
    67  }
    68  
    69  // secp256k1_ext_reencode_pubkey decodes then encodes a public key. It can be used to
    70  // convert between public key formats. The input/output formats are chosen depending on the
    71  // length of the input/output buffers.
    72  //
    73  // Returns: 1: conversion successful
    74  //          0: conversion unsuccessful
    75  // Args:    ctx:        pointer to a context object (cannot be NULL)
    76  //  Out:    out:        output buffer that will contain the reencoded key (cannot be NULL)
    77  //  In:     outlen:     length of out (33 for compressed keys, 65 for uncompressed keys)
    78  //          pubkeydata: the input public key (cannot be NULL)
    79  //          pubkeylen:  length of pubkeydata
    80  static int secp256k1_ext_reencode_pubkey(
    81  	const secp256k1_context* ctx,
    82  	unsigned char *out,
    83  	size_t outlen,
    84  	const unsigned char *pubkeydata,
    85  	size_t pubkeylen
    86  ) {
    87  	secp256k1_pubkey pubkey;
    88  
    89  	if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeydata, pubkeylen)) {
    90  		return 0;
    91  	}
    92  	unsigned int flag = (outlen == 33) ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
    93  	return secp256k1_ec_pubkey_serialize(ctx, out, &outlen, &pubkey, flag);
    94  }
    95  
    96  // secp256k1_ext_scalar_mul multiplies a point by a scalar in constant time.
    97  //
    98  // Returns: 1: multiplication was successful
    99  //          0: scalar was invalid (zero or overflow)
   100  // Args:    ctx:      pointer to a context object (cannot be NULL)
   101  //  Out:    point:    the multiplied point (usually secret)
   102  //  In:     point:    pointer to a 64-byte public point,
   103  //                    encoded as two 256bit big-endian numbers.
   104  //          scalar:   a 32-byte scalar with which to multiply the point
   105  int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, unsigned char *point, const unsigned char *scalar) {
   106  	int ret = 0;
   107  	int overflow = 0;
   108  	secp256k1_fe feX, feY;
   109  	secp256k1_gej res;
   110  	secp256k1_ge ge;
   111  	secp256k1_scalar s;
   112  	ARG_CHECK(point != NULL);
   113  	ARG_CHECK(scalar != NULL);
   114  	(void)ctx;
   115  
   116  	secp256k1_fe_set_b32(&feX, point);
   117  	secp256k1_fe_set_b32(&feY, point+32);
   118  	secp256k1_ge_set_xy(&ge, &feX, &feY);
   119  	secp256k1_scalar_set_b32(&s, scalar, &overflow);
   120  	if (overflow || secp256k1_scalar_is_zero(&s)) {
   121  		ret = 0;
   122  	} else {
   123  		secp256k1_ecmult_const(&res, &ge, &s);
   124  		secp256k1_ge_set_gej(&ge, &res);
   125  		/* Note: can't use secp256k1_pubkey_save here because it is not constant time. */
   126  		secp256k1_fe_normalize(&ge.x);
   127  		secp256k1_fe_normalize(&ge.y);
   128  		secp256k1_fe_get_b32(point, &ge.x);
   129  		secp256k1_fe_get_b32(point+32, &ge.y);
   130  		ret = 1;
   131  	}
   132  	secp256k1_scalar_clear(&s);
   133  	return ret;
   134  }
   135  
   136  // eric.kim@groundx.xyz
   137  // The following functions are added to support Schnorr signature scheme:
   138  int secp256k1_ext_scalar_mul_bytes(const secp256k1_context* ctx, unsigned char *out, unsigned char *point, const unsigned char *scalar);
   139  int secp256k1_ext_scalar_base_mult(const secp256k1_context* ctx, unsigned char *out, const unsigned char *scalar);
   140  int secp256k1_ext_schnorr_verify(const secp256k1_context* ctx, unsigned char *P, unsigned char *R, const unsigned char *s, const unsigned char *e);
   141  int secp256k1_ext_sc_mul(unsigned char *out, unsigned char *s1, unsigned char *s2);
   142  int secp256k1_ext_sc_sub(unsigned char *out, unsigned char *s1, unsigned char *s2);
   143  int secp256k1_ext_sc_add(unsigned char *out, unsigned char *s1, unsigned char *s2);
   144  
   145  // secp256k1_ext_scalar_mul_bytes multiplies a point by a scalar in constant time.
   146  //
   147  // Returns: 1: multiplication was successful
   148  //          0: scalar was invalid (zero or overflow)
   149  // Args:    ctx:      pointer to a context object (cannot be NULL)
   150  //  Out:    out:      the 64-byte multiplied point, encoded as two 256bit big-endian numbers
   151  //  In:     point:    pointer to a 64-byte public point, encoded as two 256bit big-endian numbers
   152  //          scalar:   a 32-byte scalar with which to multiply the point
   153  int secp256k1_ext_scalar_mul_bytes(const secp256k1_context* ctx, unsigned char *out, unsigned char *point, const unsigned char *scalar) {
   154  	int ret = 0;
   155  	int overflow = 0;
   156  	secp256k1_fe feX, feY;
   157  	secp256k1_gej res;
   158  	secp256k1_ge ge;
   159  	secp256k1_scalar s;
   160  	ARG_CHECK(point != NULL);
   161  	ARG_CHECK(scalar != NULL);
   162  	(void)ctx;
   163  
   164  	secp256k1_fe_set_b32(&feX, point);
   165  	secp256k1_fe_set_b32(&feY, point+32);
   166  	secp256k1_ge_set_xy(&ge, &feX, &feY);
   167  	secp256k1_scalar_set_b32(&s, scalar, &overflow);
   168  	if (overflow || secp256k1_scalar_is_zero(&s)) {
   169  		ret = 0;
   170  	} else {
   171  		secp256k1_ecmult_const(&res, &ge, &s);
   172  		secp256k1_ge_set_gej(&ge, &res);
   173  		/* Note: can't use secp256k1_pubkey_save here because it is not constant time. */
   174  		secp256k1_fe_normalize(&ge.x);
   175  		secp256k1_fe_normalize(&ge.y);
   176  		secp256k1_fe_get_b32(out, &ge.x);
   177  		secp256k1_fe_get_b32(out+32, &ge.y);
   178  		ret = 1;
   179  	}
   180  	secp256k1_scalar_clear(&s);
   181  	return ret;
   182  }
   183  
   184  // secp256k1_ext_scalar_base_mult multiplies a scalar to the SECP256k1 curve
   185  // Out: res:    the 64-byte multiplied point, encoded as two 256-bit big-endian numbers
   186  // In:  scalar: a 32-byte scalar with which to multiply the point
   187  int secp256k1_ext_scalar_base_mult(const secp256k1_context* ctx, unsigned char *out, const unsigned char *scalar) {
   188      int overflow = 0;
   189      secp256k1_gej point;
   190      secp256k1_fe feX, feY;
   191      secp256k1_ge ge;
   192      secp256k1_scalar s;
   193  
   194      secp256k1_scalar_set_b32(&s, scalar, &overflow);
   195      if (overflow || secp256k1_scalar_is_zero(&s)) {
   196          return 0;
   197      }
   198  
   199      secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &point, &s);
   200      secp256k1_ge_set_gej(&ge, &point);
   201      /* Note: can't use secp256k1_pubkey_save here because it is not constant time. */
   202      secp256k1_fe_normalize(&ge.x);
   203      secp256k1_fe_normalize(&ge.y);
   204      secp256k1_fe_get_b32(out, &ge.x);
   205      secp256k1_fe_get_b32(out+32, &ge.y);
   206      secp256k1_scalar_clear(&s);
   207      return 1;
   208  }
   209  
   210  // secp256k1_ext_schnorr_verify verifies a Schnorr signature.
   211  // Args:    ctx:    pointer to a context object (cannot be NULL)
   212  //   In:    P:      a public key that is an elliptic curve point (64 bytes, big-endian)
   213  //          R:      a part of a signature that is an elliptic curve point (64 bytes, big-endian)
   214  //          s:      a part of a signature that is a scalar (32 bytes, big-endian)
   215  //          e:      a derived random for this signature (32 bytes, big-endian; e = SHA256(msg || P || R))
   216  int secp256k1_ext_schnorr_verify(const secp256k1_context* ctx, unsigned char *P, unsigned char *R,
   217                                      const unsigned char *s, const unsigned char *e) {
   218      int overflow = 0;
   219      secp256k1_fe feX, feY;
   220      secp256k1_gej V, ep, sg;
   221      secp256k1_ge ge;
   222      secp256k1_scalar sc;
   223      unsigned char tmp[64];
   224      (void)ctx;
   225  
   226      // compute e * P
   227      secp256k1_fe_set_b32(&feX, P);
   228      secp256k1_fe_set_b32(&feY, P+32);
   229      secp256k1_ge_set_xy(&ge, &feX, &feY);
   230      secp256k1_scalar_set_b32(&sc, e, &overflow);
   231      if (overflow || secp256k1_scalar_is_zero(&sc)) {
   232          return 0;
   233      }
   234      secp256k1_ecmult_const(&ep, &ge, &sc); // ep => e * P
   235      secp256k1_scalar_clear(&sc);
   236  
   237      // compute s * G
   238      secp256k1_scalar_set_b32(&sc, s, &overflow);
   239      if (overflow || secp256k1_scalar_is_zero(&sc)) {
   240          return 0;
   241      }
   242      secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &sg, &sc);
   243      secp256k1_ge_set_gej(&ge, &sg); // ge => s * G
   244      secp256k1_scalar_clear(&sc);
   245  
   246      // compute s * G + e * P
   247      secp256k1_gej_add_ge(&V, &ep, &ge); // V => s * G + e * P
   248  
   249      secp256k1_ge_set_gej(&ge, &V);
   250      secp256k1_fe_normalize(&ge.x);
   251      secp256k1_fe_normalize(&ge.y);
   252      secp256k1_fe_get_b32(tmp, &ge.x);
   253      secp256k1_fe_get_b32(tmp+32, &ge.y); // tmp1 => s * G + e * P
   254  
   255      return 0 == memcmp(tmp, R, 64);
   256  }
   257  
   258  // secp256k1_ext_sc_mul multiplies two 32-byte scalars and returns the outcome.
   259  // returns 0 in case of an overflow.
   260  int secp256k1_ext_sc_mul(unsigned char *out, unsigned char *s1, unsigned char *s2) {
   261      int overflow = 0;
   262      secp256k1_scalar r, a, b;
   263  
   264      secp256k1_scalar_set_b32(&a, s1, &overflow);
   265      if (overflow || secp256k1_scalar_is_zero(&a)) {
   266          return 0;
   267      }
   268      secp256k1_scalar_set_b32(&b, s2, &overflow);
   269      if (overflow || secp256k1_scalar_is_zero(&b)) {
   270          return 0;
   271      }
   272  
   273      secp256k1_scalar_mul(&r, &a, &b);
   274  
   275      secp256k1_scalar_clear(&a);
   276      secp256k1_scalar_clear(&b);
   277  
   278      secp256k1_scalar_get_b32(out, &r);
   279      return 1;
   280  }
   281  
   282  // secp256k1_ext_sc_sub subtracts s2 from s1 where both s1 and s2 are 32-byte scalars.
   283  // returns 0 in case of an overflow.
   284  int secp256k1_ext_sc_sub(unsigned char *out, unsigned char *s1, unsigned char *s2) {
   285      int overflow = 0;
   286      secp256k1_scalar r, n, a, b;
   287  
   288      secp256k1_scalar_set_b32(&a, s1, &overflow);
   289      if (overflow || secp256k1_scalar_is_zero(&a)) {
   290          return 0;
   291      }
   292      secp256k1_scalar_set_b32(&b, s2, &overflow);
   293      if (overflow || secp256k1_scalar_is_zero(&b)) {
   294          return 0;
   295      }
   296  
   297      secp256k1_scalar_negate(&n, &b);
   298      secp256k1_scalar_add(&r, &a, &n);
   299  
   300      secp256k1_scalar_clear(&a);
   301      secp256k1_scalar_clear(&b);
   302      secp256k1_scalar_clear(&n);
   303  
   304      secp256k1_scalar_get_b32(out, &r);
   305      return 1;
   306  }
   307  
   308  // secp256k1_ext_sc_add adds s1 and s2 where both s1 and s2 are 32-byte scalars.
   309  // returns 0 in case of an overflow.
   310  int secp256k1_ext_sc_add(unsigned char *out, unsigned char *s1, unsigned char *s2) {
   311      int overflow = 0;
   312      secp256k1_scalar r, a, b;
   313  
   314      secp256k1_scalar_set_b32(&a, s1, &overflow);
   315      if (overflow || secp256k1_scalar_is_zero(&a)) {
   316          return 0;
   317      }
   318      secp256k1_scalar_set_b32(&b, s2, &overflow);
   319      if (overflow || secp256k1_scalar_is_zero(&b)) {
   320          return 0;
   321      }
   322  
   323      secp256k1_scalar_add(&r, &a, &b);
   324  
   325      secp256k1_scalar_clear(&a);
   326      secp256k1_scalar_clear(&b);
   327  
   328      secp256k1_scalar_get_b32(out, &r);
   329      return 1;
   330  }
   331