github.com/googgoog/go-ethereum@v1.9.7/crypto/secp256k1/libsecp256k1/src/modules/recovery/main_impl.h (about) 1 /********************************************************************** 2 * Copyright (c) 2013-2015 Pieter Wuille * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 **********************************************************************/ 6 7 #ifndef _SECP256K1_MODULE_RECOVERY_MAIN_ 8 #define _SECP256K1_MODULE_RECOVERY_MAIN_ 9 10 #include "include/secp256k1_recovery.h" 11 12 static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { 13 (void)ctx; 14 if (sizeof(secp256k1_scalar) == 32) { 15 /* When the secp256k1_scalar type is exactly 32 byte, use its 16 * representation inside secp256k1_ecdsa_signature, as conversion is very fast. 17 * Note that secp256k1_ecdsa_signature_save must use the same representation. */ 18 memcpy(r, &sig->data[0], 32); 19 memcpy(s, &sig->data[32], 32); 20 } else { 21 secp256k1_scalar_set_b32(r, &sig->data[0], NULL); 22 secp256k1_scalar_set_b32(s, &sig->data[32], NULL); 23 } 24 *recid = sig->data[64]; 25 } 26 27 static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { 28 if (sizeof(secp256k1_scalar) == 32) { 29 memcpy(&sig->data[0], r, 32); 30 memcpy(&sig->data[32], s, 32); 31 } else { 32 secp256k1_scalar_get_b32(&sig->data[0], r); 33 secp256k1_scalar_get_b32(&sig->data[32], s); 34 } 35 sig->data[64] = recid; 36 } 37 38 int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { 39 secp256k1_scalar r, s; 40 int ret = 1; 41 int overflow = 0; 42 43 (void)ctx; 44 ARG_CHECK(sig != NULL); 45 ARG_CHECK(input64 != NULL); 46 ARG_CHECK(recid >= 0 && recid <= 3); 47 48 secp256k1_scalar_set_b32(&r, &input64[0], &overflow); 49 ret &= !overflow; 50 secp256k1_scalar_set_b32(&s, &input64[32], &overflow); 51 ret &= !overflow; 52 if (ret) { 53 secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); 54 } else { 55 memset(sig, 0, sizeof(*sig)); 56 } 57 return ret; 58 } 59 60 int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { 61 secp256k1_scalar r, s; 62 63 (void)ctx; 64 ARG_CHECK(output64 != NULL); 65 ARG_CHECK(sig != NULL); 66 ARG_CHECK(recid != NULL); 67 68 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); 69 secp256k1_scalar_get_b32(&output64[0], &r); 70 secp256k1_scalar_get_b32(&output64[32], &s); 71 return 1; 72 } 73 74 int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { 75 secp256k1_scalar r, s; 76 int recid; 77 78 (void)ctx; 79 ARG_CHECK(sig != NULL); 80 ARG_CHECK(sigin != NULL); 81 82 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); 83 secp256k1_ecdsa_signature_save(sig, &r, &s); 84 return 1; 85 } 86 87 static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { 88 unsigned char brx[32]; 89 secp256k1_fe fx; 90 secp256k1_ge x; 91 secp256k1_gej xj; 92 secp256k1_scalar rn, u1, u2; 93 secp256k1_gej qj; 94 int r; 95 96 if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { 97 return 0; 98 } 99 100 secp256k1_scalar_get_b32(brx, sigr); 101 r = secp256k1_fe_set_b32(&fx, brx); 102 (void)r; 103 VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ 104 if (recid & 2) { 105 if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { 106 return 0; 107 } 108 secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); 109 } 110 if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { 111 return 0; 112 } 113 secp256k1_gej_set_ge(&xj, &x); 114 secp256k1_scalar_inverse_var(&rn, sigr); 115 secp256k1_scalar_mul(&u1, &rn, message); 116 secp256k1_scalar_negate(&u1, &u1); 117 secp256k1_scalar_mul(&u2, &rn, sigs); 118 secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); 119 secp256k1_ge_set_gej_var(pubkey, &qj); 120 return !secp256k1_gej_is_infinity(&qj); 121 } 122 123 int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { 124 secp256k1_scalar r, s; 125 secp256k1_scalar sec, non, msg; 126 int recid; 127 int ret = 0; 128 int overflow = 0; 129 VERIFY_CHECK(ctx != NULL); 130 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 131 ARG_CHECK(msg32 != NULL); 132 ARG_CHECK(signature != NULL); 133 ARG_CHECK(seckey != NULL); 134 if (noncefp == NULL) { 135 noncefp = secp256k1_nonce_function_default; 136 } 137 138 secp256k1_scalar_set_b32(&sec, seckey, &overflow); 139 /* Fail if the secret key is invalid. */ 140 if (!overflow && !secp256k1_scalar_is_zero(&sec)) { 141 unsigned char nonce32[32]; 142 unsigned int count = 0; 143 secp256k1_scalar_set_b32(&msg, msg32, NULL); 144 while (1) { 145 ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); 146 if (!ret) { 147 break; 148 } 149 secp256k1_scalar_set_b32(&non, nonce32, &overflow); 150 if (!secp256k1_scalar_is_zero(&non) && !overflow) { 151 if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { 152 break; 153 } 154 } 155 count++; 156 } 157 memset(nonce32, 0, 32); 158 secp256k1_scalar_clear(&msg); 159 secp256k1_scalar_clear(&non); 160 secp256k1_scalar_clear(&sec); 161 } 162 if (ret) { 163 secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); 164 } else { 165 memset(signature, 0, sizeof(*signature)); 166 } 167 return ret; 168 } 169 170 int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { 171 secp256k1_ge q; 172 secp256k1_scalar r, s; 173 secp256k1_scalar m; 174 int recid; 175 VERIFY_CHECK(ctx != NULL); 176 ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); 177 ARG_CHECK(msg32 != NULL); 178 ARG_CHECK(signature != NULL); 179 ARG_CHECK(pubkey != NULL); 180 181 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); 182 VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ 183 secp256k1_scalar_set_b32(&m, msg32, NULL); 184 if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { 185 secp256k1_pubkey_save(pubkey, &q); 186 return 1; 187 } else { 188 memset(pubkey, 0, sizeof(*pubkey)); 189 return 0; 190 } 191 } 192 193 #endif