github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/crypto/secp256k1/libsecp256k1/src/modules/schnorr/main_impl.h (about) 1 /********************************************************************** 2 * Copyright (c) 2014-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_SCHNORR_MAIN 8 #define SECP256K1_MODULE_SCHNORR_MAIN 9 10 #include "include/secp256k1_schnorr.h" 11 #include "modules/schnorr/schnorr_impl.h" 12 13 static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { 14 secp256k1_sha256_t sha; 15 secp256k1_sha256_initialize(&sha); 16 secp256k1_sha256_write(&sha, r32, 32); 17 secp256k1_sha256_write(&sha, msg32, 32); 18 secp256k1_sha256_finalize(&sha, h32); 19 } 20 21 static const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; 22 23 int secp256k1_schnorr_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { 24 secp256k1_scalar sec, non; 25 int ret = 0; 26 int overflow = 0; 27 unsigned int count = 0; 28 VERIFY_CHECK(ctx != NULL); 29 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 30 ARG_CHECK(msg32 != NULL); 31 ARG_CHECK(sig64 != NULL); 32 ARG_CHECK(seckey != NULL); 33 if (noncefp == NULL) { 34 noncefp = secp256k1_nonce_function_default; 35 } 36 37 secp256k1_scalar_set_b32(&sec, seckey, NULL); 38 while (1) { 39 unsigned char nonce32[32]; 40 ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count); 41 if (!ret) { 42 break; 43 } 44 secp256k1_scalar_set_b32(&non, nonce32, &overflow); 45 memset(nonce32, 0, 32); 46 if (!secp256k1_scalar_is_zero(&non) && !overflow) { 47 if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, NULL, secp256k1_schnorr_msghash_sha256, msg32)) { 48 break; 49 } 50 } 51 count++; 52 } 53 if (!ret) { 54 memset(sig64, 0, 64); 55 } 56 secp256k1_scalar_clear(&non); 57 secp256k1_scalar_clear(&sec); 58 return ret; 59 } 60 61 int secp256k1_schnorr_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { 62 secp256k1_ge q; 63 VERIFY_CHECK(ctx != NULL); 64 ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); 65 ARG_CHECK(msg32 != NULL); 66 ARG_CHECK(sig64 != NULL); 67 ARG_CHECK(pubkey != NULL); 68 69 secp256k1_pubkey_load(ctx, &q, pubkey); 70 return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32); 71 } 72 73 int secp256k1_schnorr_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *sig64, const unsigned char *msg32) { 74 secp256k1_ge q; 75 76 VERIFY_CHECK(ctx != NULL); 77 ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); 78 ARG_CHECK(msg32 != NULL); 79 ARG_CHECK(sig64 != NULL); 80 ARG_CHECK(pubkey != NULL); 81 82 if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32)) { 83 secp256k1_pubkey_save(pubkey, &q); 84 return 1; 85 } else { 86 memset(pubkey, 0, sizeof(*pubkey)); 87 return 0; 88 } 89 } 90 91 int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function noncefp, const void* noncedata) { 92 int count = 0; 93 int ret = 1; 94 secp256k1_gej Qj; 95 secp256k1_ge Q; 96 secp256k1_scalar sec; 97 98 VERIFY_CHECK(ctx != NULL); 99 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 100 ARG_CHECK(msg32 != NULL); 101 ARG_CHECK(sec32 != NULL); 102 ARG_CHECK(pubnonce != NULL); 103 ARG_CHECK(privnonce32 != NULL); 104 105 if (noncefp == NULL) { 106 noncefp = secp256k1_nonce_function_default; 107 } 108 109 do { 110 int overflow; 111 ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++); 112 if (!ret) { 113 break; 114 } 115 secp256k1_scalar_set_b32(&sec, privnonce32, &overflow); 116 if (overflow || secp256k1_scalar_is_zero(&sec)) { 117 continue; 118 } 119 secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sec); 120 secp256k1_ge_set_gej(&Q, &Qj); 121 122 secp256k1_pubkey_save(pubnonce, &Q); 123 break; 124 } while(1); 125 126 secp256k1_scalar_clear(&sec); 127 if (!ret) { 128 memset(pubnonce, 0, sizeof(*pubnonce)); 129 } 130 return ret; 131 } 132 133 int secp256k1_schnorr_partial_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey *pubnonce_others, const unsigned char *secnonce32) { 134 int overflow = 0; 135 secp256k1_scalar sec, non; 136 secp256k1_ge pubnon; 137 VERIFY_CHECK(ctx != NULL); 138 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); 139 ARG_CHECK(msg32 != NULL); 140 ARG_CHECK(sig64 != NULL); 141 ARG_CHECK(sec32 != NULL); 142 ARG_CHECK(secnonce32 != NULL); 143 ARG_CHECK(pubnonce_others != NULL); 144 145 secp256k1_scalar_set_b32(&sec, sec32, &overflow); 146 if (overflow || secp256k1_scalar_is_zero(&sec)) { 147 return -1; 148 } 149 secp256k1_scalar_set_b32(&non, secnonce32, &overflow); 150 if (overflow || secp256k1_scalar_is_zero(&non)) { 151 return -1; 152 } 153 secp256k1_pubkey_load(ctx, &pubnon, pubnonce_others); 154 return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32); 155 } 156 157 int secp256k1_schnorr_partial_combine(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, int n) { 158 ARG_CHECK(sig64 != NULL); 159 ARG_CHECK(n >= 1); 160 ARG_CHECK(sig64sin != NULL); 161 return secp256k1_schnorr_sig_combine(sig64, n, sig64sin); 162 } 163 164 #endif