tests_impl.h (19708B)
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_TESTS_H 8 #define SECP256K1_MODULE_RECOVERY_TESTS_H 9 10 static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { 11 (void) msg32; 12 (void) key32; 13 (void) algo16; 14 (void) data; 15 16 /* On the first run, return 0 to force a second run */ 17 if (counter == 0) { 18 memset(nonce32, 0, 32); 19 return 1; 20 } 21 /* On the second run, return an overflow to force a third run */ 22 if (counter == 1) { 23 memset(nonce32, 0xff, 32); 24 return 1; 25 } 26 /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */ 27 memset(nonce32, 1, 32); 28 return haskellsecp256k1_v0_1_0_testrand_bits(1); 29 } 30 31 static void test_ecdsa_recovery_api(void) { 32 /* Setup contexts that just count errors */ 33 haskellsecp256k1_v0_1_0_pubkey pubkey; 34 haskellsecp256k1_v0_1_0_pubkey recpubkey; 35 haskellsecp256k1_v0_1_0_ecdsa_signature normal_sig; 36 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature recsig; 37 unsigned char privkey[32] = { 1 }; 38 unsigned char message[32] = { 2 }; 39 int recid = 0; 40 unsigned char sig[74]; 41 unsigned char zero_privkey[32] = { 0 }; 42 unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 46 47 /* Construct and verify corresponding public key. */ 48 CHECK(haskellsecp256k1_v0_1_0_ec_seckey_verify(CTX, privkey) == 1); 49 CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pubkey, privkey) == 1); 50 51 /* Check bad contexts and NULLs for signing */ 52 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); 53 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, NULL, message, privkey, NULL, NULL)); 54 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, NULL, privkey, NULL, NULL)); 55 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, NULL, NULL, NULL)); 56 CHECK_ILLEGAL(STATIC_CTX, haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(STATIC_CTX, &recsig, message, privkey, NULL, NULL)); 57 /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */ 58 haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, recovery_test_nonce_function, NULL); 59 /* These will all fail, but not in ARG_CHECK way */ 60 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, zero_privkey, NULL, NULL) == 0); 61 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, over_privkey, NULL, NULL) == 0); 62 /* This one will succeed. */ 63 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); 64 65 /* Check signing with a goofy nonce function */ 66 67 /* Check bad contexts and NULLs for recovery */ 68 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &recpubkey, &recsig, message) == 1); 69 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, NULL, &recsig, message)); 70 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &recpubkey, NULL, message)); 71 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &recpubkey, &recsig, NULL)); 72 73 /* Check NULLs for conversion */ 74 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign(CTX, &normal_sig, message, privkey, NULL, NULL) == 1); 75 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, NULL, &recsig)); 76 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, &normal_sig, NULL)); 77 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, &normal_sig, &recsig) == 1); 78 79 /* Check NULLs for de/serialization */ 80 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1); 81 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, NULL, &recid, &recsig)); 82 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, sig, NULL, &recsig)); 83 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, NULL)); 84 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &recsig) == 1); 85 86 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, NULL, sig, recid)); 87 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, NULL, recid)); 88 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, -1)); 89 CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, 5)); 90 /* overflow in signature will not result in calling illegal_callback */ 91 memcpy(sig, over_privkey, 32); 92 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, recid) == 0); 93 } 94 95 static void test_ecdsa_recovery_end_to_end(void) { 96 unsigned char extra[32] = {0x00}; 97 unsigned char privkey[32]; 98 unsigned char message[32]; 99 haskellsecp256k1_v0_1_0_ecdsa_signature signature[5]; 100 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature rsignature[5]; 101 unsigned char sig[74]; 102 haskellsecp256k1_v0_1_0_pubkey pubkey; 103 haskellsecp256k1_v0_1_0_pubkey recpubkey; 104 int recid = 0; 105 106 /* Generate a random key and message. */ 107 { 108 haskellsecp256k1_v0_1_0_scalar msg, key; 109 random_scalar_order_test(&msg); 110 random_scalar_order_test(&key); 111 haskellsecp256k1_v0_1_0_scalar_get_b32(privkey, &key); 112 haskellsecp256k1_v0_1_0_scalar_get_b32(message, &msg); 113 } 114 115 /* Construct and verify corresponding public key. */ 116 CHECK(haskellsecp256k1_v0_1_0_ec_seckey_verify(CTX, privkey) == 1); 117 CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pubkey, privkey) == 1); 118 119 /* Serialize/parse compact and verify/recover. */ 120 extra[0] = 0; 121 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &rsignature[0], message, privkey, NULL, NULL) == 1); 122 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign(CTX, &signature[0], message, privkey, NULL, NULL) == 1); 123 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &rsignature[4], message, privkey, NULL, NULL) == 1); 124 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &rsignature[1], message, privkey, NULL, extra) == 1); 125 extra[31] = 1; 126 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &rsignature[2], message, privkey, NULL, extra) == 1); 127 extra[31] = 0; 128 extra[0] = 1; 129 CHECK(haskellsecp256k1_v0_1_0_ecdsa_sign_recoverable(CTX, &rsignature[3], message, privkey, NULL, extra) == 1); 130 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1); 131 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); 132 CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&signature[4], &signature[0], 64) == 0); 133 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1); 134 memset(&rsignature[4], 0, sizeof(rsignature[4])); 135 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); 136 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); 137 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1); 138 /* Parse compact (with recovery id) and recover. */ 139 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); 140 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 1); 141 CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0); 142 /* Serialize/destroy/parse signature and verify again. */ 143 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1); 144 sig[haskellsecp256k1_v0_1_0_testrand_bits(6)] += 1 + haskellsecp256k1_v0_1_0_testrand_int(255); 145 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1); 146 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1); 147 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 0); 148 /* Recover again */ 149 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 0 || 150 haskellsecp256k1_v0_1_0_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) != 0); 151 } 152 153 /* Tests several edge cases. */ 154 static void test_ecdsa_recovery_edge_cases(void) { 155 const unsigned char msg32[32] = { 156 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 157 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', 158 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', 159 's', 's', 'a', 'g', 'e', '.', '.', '.' 160 }; 161 const unsigned char sig64[64] = { 162 /* Generated by signing the above message with nonce 'This is the nonce we will use...' 163 * and secret key 0 (which is not valid), resulting in recid 1. */ 164 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, 165 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, 166 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, 167 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, 168 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, 169 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, 170 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, 171 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 172 }; 173 haskellsecp256k1_v0_1_0_pubkey pubkey; 174 /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ 175 const unsigned char sigb64[64] = { 176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 184 }; 185 haskellsecp256k1_v0_1_0_pubkey pubkeyb; 186 haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature rsig; 187 haskellsecp256k1_v0_1_0_ecdsa_signature sig; 188 int recid; 189 190 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 0)); 191 CHECK(!haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); 192 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 1)); 193 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); 194 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 2)); 195 CHECK(!haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); 196 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 3)); 197 CHECK(!haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkey, &rsig, msg32)); 198 199 for (recid = 0; recid < 4; recid++) { 200 int i; 201 int recid2; 202 /* (4,4) encoded in DER. */ 203 unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; 204 unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; 205 unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; 206 unsigned char sigbderalt1[39] = { 207 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, 212 }; 213 unsigned char sigbderalt2[39] = { 214 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 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, 0x00, 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 219 }; 220 unsigned char sigbderalt3[40] = { 221 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, 226 }; 227 unsigned char sigbderalt4[40] = { 228 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, 229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 233 }; 234 /* (order + r,4) encoded in DER. */ 235 unsigned char sigbderlong[40] = { 236 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, 237 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 238 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 239 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 240 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 241 }; 242 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid) == 1); 243 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 1); 244 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1); 245 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 1); 246 for (recid2 = 0; recid2 < 4; recid2++) { 247 haskellsecp256k1_v0_1_0_pubkey pubkey2b; 248 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid2) == 1); 249 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkey2b, &rsig, msg32) == 1); 250 /* Verifying with (order + r,4) should always fail. */ 251 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderlong, sizeof(sigbderlong)) == 1); 252 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); 253 } 254 /* DER parsing tests. */ 255 /* Zero length r/s. */ 256 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); 257 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); 258 /* Leading zeros. */ 259 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); 260 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); 261 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); 262 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); 263 sigbderalt3[4] = 1; 264 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); 265 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); 266 sigbderalt4[7] = 1; 267 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); 268 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); 269 /* Damage signature. */ 270 sigbder[7]++; 271 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1); 272 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); 273 sigbder[7]--; 274 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbder, 6) == 0); 275 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder) - 1) == 0); 276 for(i = 0; i < 8; i++) { 277 int c; 278 unsigned char orig = sigbder[i]; 279 /*Try every single-byte change.*/ 280 for (c = 0; c < 256; c++) { 281 if (c == orig ) { 282 continue; 283 } 284 sigbder[i] = c; 285 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 0 || haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0); 286 } 287 sigbder[i] = orig; 288 } 289 } 290 291 /* Test r/s equal to zero */ 292 { 293 /* (1,1) encoded in DER. */ 294 unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; 295 unsigned char sigc64[64] = { 296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 304 }; 305 haskellsecp256k1_v0_1_0_pubkey pubkeyc; 306 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); 307 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkeyc, &rsig, msg32) == 1); 308 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); 309 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 1); 310 sigcder[4] = 0; 311 sigc64[31] = 0; 312 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); 313 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0); 314 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); 315 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0); 316 sigcder[4] = 1; 317 sigcder[7] = 0; 318 sigc64[31] = 1; 319 sigc64[63] = 0; 320 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1); 321 CHECK(haskellsecp256k1_v0_1_0_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0); 322 CHECK(haskellsecp256k1_v0_1_0_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1); 323 CHECK(haskellsecp256k1_v0_1_0_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0); 324 } 325 } 326 327 static void run_recovery_tests(void) { 328 int i; 329 for (i = 0; i < COUNT; i++) { 330 test_ecdsa_recovery_api(); 331 } 332 for (i = 0; i < 64*COUNT; i++) { 333 test_ecdsa_recovery_end_to_end(); 334 } 335 test_ecdsa_recovery_edge_cases(); 336 } 337 338 #endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */