main_impl.h (7325B)
1 /*********************************************************************** 2 * Copyright (c) 2013-2015 Pieter Wuille * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 ***********************************************************************/ 6 7 #ifndef SECP256K1_MODULE_RECOVERY_MAIN_H 8 #define SECP256K1_MODULE_RECOVERY_MAIN_H 9 10 #include "../../../include/secp256k1_recovery.h" 11 12 static void haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_scalar* r, haskellsecp256k1_v0_1_0_scalar* s, int* recid, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig) { 13 (void)ctx; 14 if (sizeof(haskellsecp256k1_v0_1_0_scalar) == 32) { 15 /* When the haskellsecp256k1_v0_1_0_scalar type is exactly 32 byte, use its 16 * representation inside haskellsecp256k1_v0_1_0_ecdsa_signature, as conversion is very fast. 17 * Note that haskellsecp256k1_v0_1_0_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 haskellsecp256k1_v0_1_0_scalar_set_b32(r, &sig->data[0], NULL); 22 haskellsecp256k1_v0_1_0_scalar_set_b32(s, &sig->data[32], NULL); 23 } 24 *recid = sig->data[64]; 25 } 26 27 static void haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig, const haskellsecp256k1_v0_1_0_scalar* r, const haskellsecp256k1_v0_1_0_scalar* s, int recid) { 28 if (sizeof(haskellsecp256k1_v0_1_0_scalar) == 32) { 29 memcpy(&sig->data[0], r, 32); 30 memcpy(&sig->data[32], s, 32); 31 } else { 32 haskellsecp256k1_v0_1_0_scalar_get_b32(&sig->data[0], r); 33 haskellsecp256k1_v0_1_0_scalar_get_b32(&sig->data[32], s); 34 } 35 sig->data[64] = recid; 36 } 37 38 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { 39 haskellsecp256k1_v0_1_0_scalar r, s; 40 int ret = 1; 41 int overflow = 0; 42 43 VERIFY_CHECK(ctx != NULL); 44 ARG_CHECK(sig != NULL); 45 ARG_CHECK(input64 != NULL); 46 ARG_CHECK(recid >= 0 && recid <= 3); 47 48 haskellsecp256k1_v0_1_0_scalar_set_b32(&r, &input64[0], &overflow); 49 ret &= !overflow; 50 haskellsecp256k1_v0_1_0_scalar_set_b32(&s, &input64[32], &overflow); 51 ret &= !overflow; 52 if (ret) { 53 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(sig, &r, &s, recid); 54 } else { 55 memset(sig, 0, sizeof(*sig)); 56 } 57 return ret; 58 } 59 60 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(const haskellsecp256k1_v0_1_0_context* ctx, unsigned char *output64, int *recid, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sig) { 61 haskellsecp256k1_v0_1_0_scalar r, s; 62 63 VERIFY_CHECK(ctx != NULL); 64 ARG_CHECK(output64 != NULL); 65 ARG_CHECK(sig != NULL); 66 ARG_CHECK(recid != NULL); 67 68 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); 69 haskellsecp256k1_v0_1_0_scalar_get_b32(&output64[0], &r); 70 haskellsecp256k1_v0_1_0_scalar_get_b32(&output64[32], &s); 71 return 1; 72 } 73 74 int haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_signature* sig, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature* sigin) { 75 haskellsecp256k1_v0_1_0_scalar r, s; 76 int recid; 77 78 VERIFY_CHECK(ctx != NULL); 79 ARG_CHECK(sig != NULL); 80 ARG_CHECK(sigin != NULL); 81 82 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); 83 haskellsecp256k1_v0_1_0_ecdsa_signature_save(sig, &r, &s); 84 return 1; 85 } 86 87 static int haskellsecp256k1_v0_1_0_ecdsa_sig_recover(const haskellsecp256k1_v0_1_0_scalar *sigr, const haskellsecp256k1_v0_1_0_scalar* sigs, haskellsecp256k1_v0_1_0_ge *pubkey, const haskellsecp256k1_v0_1_0_scalar *message, int recid) { 88 unsigned char brx[32]; 89 haskellsecp256k1_v0_1_0_fe fx; 90 haskellsecp256k1_v0_1_0_ge x; 91 haskellsecp256k1_v0_1_0_gej xj; 92 haskellsecp256k1_v0_1_0_scalar rn, u1, u2; 93 haskellsecp256k1_v0_1_0_gej qj; 94 int r; 95 96 if (haskellsecp256k1_v0_1_0_scalar_is_zero(sigr) || haskellsecp256k1_v0_1_0_scalar_is_zero(sigs)) { 97 return 0; 98 } 99 100 haskellsecp256k1_v0_1_0_scalar_get_b32(brx, sigr); 101 r = haskellsecp256k1_v0_1_0_fe_set_b32_limit(&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 (haskellsecp256k1_v0_1_0_fe_cmp_var(&fx, &haskellsecp256k1_v0_1_0_ecdsa_const_p_minus_order) >= 0) { 106 return 0; 107 } 108 haskellsecp256k1_v0_1_0_fe_add(&fx, &haskellsecp256k1_v0_1_0_ecdsa_const_order_as_fe); 109 } 110 if (!haskellsecp256k1_v0_1_0_ge_set_xo_var(&x, &fx, recid & 1)) { 111 return 0; 112 } 113 haskellsecp256k1_v0_1_0_gej_set_ge(&xj, &x); 114 haskellsecp256k1_v0_1_0_scalar_inverse_var(&rn, sigr); 115 haskellsecp256k1_v0_1_0_scalar_mul(&u1, &rn, message); 116 haskellsecp256k1_v0_1_0_scalar_negate(&u1, &u1); 117 haskellsecp256k1_v0_1_0_scalar_mul(&u2, &rn, sigs); 118 haskellsecp256k1_v0_1_0_ecmult(&qj, &xj, &u2, &u1); 119 haskellsecp256k1_v0_1_0_ge_set_gej_var(pubkey, &qj); 120 return !haskellsecp256k1_v0_1_0_gej_is_infinity(&qj); 121 } 122 123 int haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, haskellsecp256k1_v0_1_0_nonce_function noncefp, const void* noncedata) { 124 haskellsecp256k1_v0_1_0_scalar r, s; 125 int ret, recid; 126 VERIFY_CHECK(ctx != NULL); 127 ARG_CHECK(haskellsecp256k1_v0_1_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 128 ARG_CHECK(msghash32 != NULL); 129 ARG_CHECK(signature != NULL); 130 ARG_CHECK(seckey != NULL); 131 132 ret = haskellsecp256k1_v0_1_0_ecdsa_sign_inner(ctx, &r, &s, &recid, msghash32, seckey, noncefp, noncedata); 133 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_save(signature, &r, &s, recid); 134 return ret; 135 } 136 137 int haskellsecp256k1_v0_1_0_ecdsa_recover(const haskellsecp256k1_v0_1_0_context* ctx, haskellsecp256k1_v0_1_0_pubkey *pubkey, const haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) { 138 haskellsecp256k1_v0_1_0_ge q; 139 haskellsecp256k1_v0_1_0_scalar r, s; 140 haskellsecp256k1_v0_1_0_scalar m; 141 int recid; 142 VERIFY_CHECK(ctx != NULL); 143 ARG_CHECK(msghash32 != NULL); 144 ARG_CHECK(signature != NULL); 145 ARG_CHECK(pubkey != NULL); 146 147 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); 148 VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ 149 haskellsecp256k1_v0_1_0_scalar_set_b32(&m, msghash32, NULL); 150 if (haskellsecp256k1_v0_1_0_ecdsa_sig_recover(&r, &s, &q, &m, recid)) { 151 haskellsecp256k1_v0_1_0_pubkey_save(pubkey, &q); 152 return 1; 153 } else { 154 memset(pubkey, 0, sizeof(*pubkey)); 155 return 0; 156 } 157 } 158 159 #endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */