github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_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_TESTS_ 8 #define _SECP256K1_MODULE_RECOVERY_TESTS_ 9 10 void test_ecdsa_recovery_end_to_end(void) { 11 unsigned char extra[32] = {0x00}; 12 unsigned char privkey[32]; 13 unsigned char message[32]; 14 secp256k1_ecdsa_signature signature[5]; 15 secp256k1_ecdsa_recoverable_signature rsignature[5]; 16 unsigned char sig[74]; 17 secp256k1_pubkey pubkey; 18 secp256k1_pubkey recpubkey; 19 int recid = 0; 20 21 /* Generate a random key and message. */ 22 { 23 secp256k1_scalar msg, key; 24 random_scalar_order_test(&msg); 25 random_scalar_order_test(&key); 26 secp256k1_scalar_get_b32(privkey, &key); 27 secp256k1_scalar_get_b32(message, &msg); 28 } 29 30 /* Construct and verify corresponding public key. */ 31 CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); 32 CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); 33 34 /* Serialize/parse compact and verify/recover. */ 35 extra[0] = 0; 36 CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1); 37 CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1); 38 CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1); 39 extra[31] = 1; 40 CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1); 41 extra[31] = 0; 42 extra[0] = 1; 43 CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1); 44 CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); 45 CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); 46 CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); 47 memset(&rsignature[4], 0, sizeof(rsignature[4])); 48 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); 49 CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); 50 CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); 51 /* Parse compact (with recovery id) and recover. */ 52 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); 53 CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1); 54 CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); 55 /* Serialize/destroy/parse signature and verify again. */ 56 CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); 57 sig[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); 58 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); 59 CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); 60 CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0); 61 /* Recover again */ 62 CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 || 63 memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); 64 } 65 66 /* Tests several edge cases. */ 67 void test_ecdsa_recovery_edge_cases(void) { 68 const unsigned char msg32[32] = { 69 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 70 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', 71 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', 72 's', 's', 'a', 'g', 'e', '.', '.', '.' 73 }; 74 const unsigned char sig64[64] = { 75 /* Generated by signing the above message with nonce 'This is the nonce we will use...' 76 * and secret key 0 (which is not valid), resulting in recid 0. */ 77 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, 78 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, 79 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, 80 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, 81 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, 82 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, 83 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, 84 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 85 }; 86 secp256k1_pubkey pubkey; 87 /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ 88 const unsigned char sigb64[64] = { 89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 97 }; 98 secp256k1_pubkey pubkeyb; 99 secp256k1_ecdsa_recoverable_signature rsig; 100 secp256k1_ecdsa_signature sig; 101 int recid; 102 103 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0)); 104 CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); 105 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1)); 106 CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); 107 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2)); 108 CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); 109 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3)); 110 CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); 111 112 for (recid = 0; recid < 4; recid++) { 113 int i; 114 int recid2; 115 /* (4,4) encoded in DER. */ 116 unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; 117 unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; 118 unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; 119 unsigned char sigbderalt1[39] = { 120 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, 125 }; 126 unsigned char sigbderalt2[39] = { 127 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, 128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 132 }; 133 unsigned char sigbderalt3[40] = { 134 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, 139 }; 140 unsigned char sigbderalt4[40] = { 141 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 146 }; 147 /* (order + r,4) encoded in DER. */ 148 unsigned char sigbderlong[40] = { 149 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, 150 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 151 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 152 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 153 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 154 }; 155 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1); 156 CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1); 157 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); 158 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); 159 for (recid2 = 0; recid2 < 4; recid2++) { 160 secp256k1_pubkey pubkey2b; 161 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1); 162 CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1); 163 /* Verifying with (order + r,4) should always fail. */ 164 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 0); 165 } 166 /* DER parsing tests. */ 167 /* Zero length r/s. */ 168 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); 169 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); 170 /* Leading zeros. */ 171 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 1); 172 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); 173 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 1); 174 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); 175 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); 176 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); 177 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); 178 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); 179 sigbderalt3[4] = 1; 180 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); 181 sigbderalt4[7] = 1; 182 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); 183 /* Damage signature. */ 184 sigbder[7]++; 185 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); 186 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); 187 sigbder[7]--; 188 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0); 189 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0); 190 for(i = 0; i < 8; i++) { 191 int c; 192 unsigned char orig = sigbder[i]; 193 /*Try every single-byte change.*/ 194 for (c = 0; c < 256; c++) { 195 if (c == orig ) { 196 continue; 197 } 198 sigbder[i] = c; 199 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); 200 } 201 sigbder[i] = orig; 202 } 203 } 204 205 /* Test r/s equal to zero */ 206 { 207 /* (1,1) encoded in DER. */ 208 unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; 209 unsigned char sigc64[64] = { 210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 218 }; 219 secp256k1_pubkey pubkeyc; 220 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); 221 CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1); 222 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); 223 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1); 224 sigcder[4] = 0; 225 sigc64[31] = 0; 226 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); 227 CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); 228 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); 229 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); 230 sigcder[4] = 1; 231 sigcder[7] = 0; 232 sigc64[31] = 1; 233 sigc64[63] = 0; 234 CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); 235 CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); 236 CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); 237 CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); 238 } 239 } 240 241 void run_recovery_tests(void) { 242 int i; 243 for (i = 0; i < 64*count; i++) { 244 test_ecdsa_recovery_end_to_end(); 245 } 246 test_ecdsa_recovery_edge_cases(); 247 } 248 249 #endif