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