github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/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 67 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); 68 secp256k1_scalar_get_b32(&output64[0], &r); 69 secp256k1_scalar_get_b32(&output64[32], &s); 70 return 1; 71 } 72 73 int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { 74 secp256k1_scalar r, s; 75 int recid; 76 77 (void)ctx; 78 ARG_CHECK(sig != NULL); 79 ARG_CHECK(sigin != NULL); 80 81 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); 82 secp256k1_ecdsa_signature_save(sig, &r, &s); 83 return 1; 84 } 85 86 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) { 87 secp256k1_scalar r, s; 88 secp256k1_scalar sec, non, msg; 89 int recid; 90 int ret = 0; 91 int overflow = 0; 92 VERIFY_CHECK(ctx != NULL); 93 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 94 ARG_CHECK(msg32 != NULL); 95 ARG_CHECK(signature != NULL); 96 ARG_CHECK(seckey != NULL); 97 if (noncefp == NULL) { 98 noncefp = secp256k1_nonce_function_default; 99 } 100 101 secp256k1_scalar_set_b32(&sec, seckey, &overflow); 102 /* Fail if the secret key is invalid. */ 103 if (!overflow && !secp256k1_scalar_is_zero(&sec)) { 104 unsigned int count = 0; 105 secp256k1_scalar_set_b32(&msg, msg32, NULL); 106 while (1) { 107 unsigned char nonce32[32]; 108 ret = noncefp(nonce32, seckey, msg32, NULL, (void*)noncedata, count); 109 if (!ret) { 110 break; 111 } 112 secp256k1_scalar_set_b32(&non, nonce32, &overflow); 113 memset(nonce32, 0, 32); 114 if (!secp256k1_scalar_is_zero(&non) && !overflow) { 115 if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { 116 break; 117 } 118 } 119 count++; 120 } 121 secp256k1_scalar_clear(&msg); 122 secp256k1_scalar_clear(&non); 123 secp256k1_scalar_clear(&sec); 124 } 125 if (ret) { 126 secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); 127 } else { 128 memset(signature, 0, sizeof(*signature)); 129 } 130 return ret; 131 } 132 133 int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { 134 secp256k1_ge q; 135 secp256k1_scalar r, s; 136 secp256k1_scalar m; 137 int recid; 138 VERIFY_CHECK(ctx != NULL); 139 ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); 140 ARG_CHECK(msg32 != NULL); 141 ARG_CHECK(signature != NULL); 142 ARG_CHECK(pubkey != NULL); 143 144 secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); 145 ARG_CHECK(recid >= 0 && recid < 4); 146 secp256k1_scalar_set_b32(&m, msg32, NULL); 147 if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { 148 secp256k1_pubkey_save(pubkey, &q); 149 return 1; 150 } else { 151 memset(pubkey, 0, sizeof(*pubkey)); 152 return 0; 153 } 154 } 155 156 #endif