github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/crypto/secp256k1/libsecp256k1/src/modules/schnorr/tests_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_TESTS 8 #define SECP256K1_MODULE_SCHNORR_TESTS 9 10 #include "include/secp256k1_schnorr.h" 11 12 void test_schnorr_end_to_end(void) { 13 unsigned char privkey[32]; 14 unsigned char message[32]; 15 unsigned char schnorr_signature[64]; 16 secp256k1_pubkey pubkey, recpubkey; 17 18 /* Generate a random key and message. */ 19 { 20 secp256k1_scalar key; 21 random_scalar_order_test(&key); 22 secp256k1_scalar_get_b32(privkey, &key); 23 secp256k1_rand256_test(message); 24 } 25 26 /* Construct and verify corresponding public key. */ 27 CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); 28 CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); 29 30 /* Schnorr sign. */ 31 CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1); 32 CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1); 33 CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1); 34 CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); 35 /* Destroy signature and verify again. */ 36 schnorr_signature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); 37 CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0); 38 CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 || 39 memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); 40 } 41 42 /** Horribly broken hash function. Do not use for anything but tests. */ 43 void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { 44 int i; 45 for (i = 0; i < 32; i++) { 46 h32[i] = r32[i] ^ msg32[i]; 47 } 48 } 49 50 void test_schnorr_sign_verify(void) { 51 unsigned char msg32[32]; 52 unsigned char sig64[3][64]; 53 secp256k1_gej pubkeyj[3]; 54 secp256k1_ge pubkey[3]; 55 secp256k1_scalar nonce[3], key[3]; 56 int i = 0; 57 int k; 58 59 secp256k1_rand256_test(msg32); 60 61 for (k = 0; k < 3; k++) { 62 random_scalar_order_test(&key[k]); 63 64 do { 65 random_scalar_order_test(&nonce[k]); 66 if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) { 67 break; 68 } 69 } while(1); 70 71 secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]); 72 secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]); 73 CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32)); 74 75 for (i = 0; i < 4; i++) { 76 int pos = secp256k1_rand32() % 64; 77 int mod = 1 + (secp256k1_rand32() % 255); 78 sig64[k][pos] ^= mod; 79 CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0); 80 sig64[k][pos] ^= mod; 81 } 82 } 83 } 84 85 void test_schnorr_threshold(void) { 86 unsigned char msg[32]; 87 unsigned char sec[5][32]; 88 secp256k1_pubkey pub[5]; 89 unsigned char nonce[5][32]; 90 secp256k1_pubkey pubnonce[5]; 91 unsigned char sig[5][64]; 92 const unsigned char* sigs[5]; 93 unsigned char allsig[64]; 94 const secp256k1_pubkey* pubs[5]; 95 secp256k1_pubkey allpub; 96 int n, i; 97 int damage; 98 int ret = 0; 99 100 damage = (secp256k1_rand32() % 2) ? (1 + (secp256k1_rand32() % 4)) : 0; 101 secp256k1_rand256_test(msg); 102 n = 2 + (secp256k1_rand32() % 4); 103 for (i = 0; i < n; i++) { 104 do { 105 secp256k1_rand256_test(sec[i]); 106 } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); 107 CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); 108 CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); 109 pubs[i] = &pub[i]; 110 } 111 if (damage == 1) { 112 nonce[secp256k1_rand32() % n][secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255); 113 } else if (damage == 2) { 114 sec[secp256k1_rand32() % n][secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255); 115 } 116 for (i = 0; i < n; i++) { 117 secp256k1_pubkey allpubnonce; 118 const secp256k1_pubkey *pubnonces[4]; 119 int j; 120 for (j = 0; j < i; j++) { 121 pubnonces[j] = &pubnonce[j]; 122 } 123 for (j = i + 1; j < n; j++) { 124 pubnonces[j - 1] = &pubnonce[j]; 125 } 126 CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); 127 ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; 128 sigs[i] = sig[i]; 129 } 130 if (damage == 3) { 131 sig[secp256k1_rand32() % n][secp256k1_rand32() % 64] ^= 1 + (secp256k1_rand32() % 255); 132 } 133 ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; 134 if ((ret & 1) == 0) { 135 ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; 136 } 137 if (damage == 4) { 138 allsig[secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255); 139 } 140 if ((ret & 7) == 0) { 141 ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; 142 } 143 CHECK((ret == 0) == (damage == 0)); 144 } 145 146 void test_schnorr_recovery(void) { 147 unsigned char msg32[32]; 148 unsigned char sig64[64]; 149 secp256k1_ge Q; 150 151 secp256k1_rand256_test(msg32); 152 secp256k1_rand256_test(sig64); 153 secp256k1_rand256_test(sig64 + 32); 154 if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) { 155 CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1); 156 } 157 } 158 159 void run_schnorr_tests(void) { 160 int i; 161 for (i = 0; i < 32*count; i++) { 162 test_schnorr_end_to_end(); 163 } 164 for (i = 0; i < 32 * count; i++) { 165 test_schnorr_sign_verify(); 166 } 167 for (i = 0; i < 16 * count; i++) { 168 test_schnorr_recovery(); 169 } 170 for (i = 0; i < 10 * count; i++) { 171 test_schnorr_threshold(); 172 } 173 } 174 175 #endif