]> Git Repo - secp256k1.git/blobdiff - src/tests.c
Add secp256k1_scalar_add_bit
[secp256k1.git] / src / tests.c
index 2f6585acd3191389993bacfce51562667f76fed8..e96444969c4762bc954bc412bdcfa36eb19ce8c9 100644 (file)
@@ -38,7 +38,7 @@ void random_field_element_test(secp256k1_fe_t *fe) {
         secp256k1_num_set_bin(&num, b32, 32);
         if (secp256k1_num_cmp(&num, &secp256k1_fe_consts->p) >= 0)
             continue;
-        secp256k1_fe_set_b32(fe, b32);
+        VERIFY_CHECK(secp256k1_fe_set_b32(fe, b32));
         break;
     } while(1);
 }
@@ -382,6 +382,25 @@ void scalar_test(void) {
         CHECK(secp256k1_scalar_eq(&r1, &r2));
     }
 
+    {
+        /* Test add_bit. */
+        int bit = secp256k1_rand32() % 256;
+        secp256k1_scalar_t b;
+        secp256k1_scalar_clear(&b);
+        secp256k1_scalar_add_bit(&b, 0);
+        CHECK(secp256k1_scalar_is_one(&b));
+        for (int i = 0; i < bit; i++) {
+            secp256k1_scalar_add(&b, &b, &b);
+        }
+        secp256k1_scalar_t r1 = s1, r2 = s1;
+        secp256k1_scalar_add(&r1, &r1, &b);
+        if (!(secp256k1_scalar_get_bits(&s1, 255, 1) == 1 && secp256k1_scalar_get_bits(&r1, 255, 1) == 0)) {
+            /* No overflow happened. */
+            secp256k1_scalar_add_bit(&r2, bit);
+            CHECK(secp256k1_scalar_eq(&r1, &r2));
+        }
+    }
+
     {
         /* Test commutativity of mul. */
         secp256k1_scalar_t r1, r2;
@@ -440,8 +459,12 @@ void run_scalar_tests(void) {
 
 void random_fe(secp256k1_fe_t *x) {
     unsigned char bin[32];
-    secp256k1_rand256(bin);
-    secp256k1_fe_set_b32(x, bin);
+    do {
+        secp256k1_rand256(bin);
+        if (secp256k1_fe_set_b32(x, bin)) {
+            return;
+        }
+    } while(1);
 }
 
 void random_fe_non_zero(secp256k1_fe_t *nz) {
@@ -697,8 +720,8 @@ void run_ge(void) {
 
 void run_ecmult_chain(void) {
     /* random starting point A (on the curve) */
-    secp256k1_fe_t ax; secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64);
-    secp256k1_fe_t ay; secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64);
+    secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64));
+    secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64));
     secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
     /* two random initial factors xn and gn */
     secp256k1_num_t xn;
@@ -759,7 +782,7 @@ void test_point_times_order(const secp256k1_gej_t *point) {
 }
 
 void run_point_times_order(void) {
-    secp256k1_fe_t x; secp256k1_fe_set_hex(&x, "02", 2);
+    secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2));
     for (int i=0; i<500; i++) {
         secp256k1_ge_t p;
         if (secp256k1_ge_set_xo(&p, &x, 1)) {
@@ -935,6 +958,59 @@ void run_ecdsa_end_to_end(void) {
     }
 }
 
+/* Tests several edge cases. */
+void test_ecdsa_edge_cases(void) {
+    const unsigned char msg32[32] = {
+        'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
+        'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
+        'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
+        's', 's', 'a', 'g', 'e', '.', '.', '.'
+    };
+    const unsigned char sig64[64] = {
+        /* Generated by signing the above message with nonce 'This is the nonce we will use...'
+         * and secret key 0 (which is not valid), resulting in recid 0. */
+        0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
+        0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
+        0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
+        0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
+        0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
+        0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
+        0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
+        0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
+    };
+    unsigned char pubkey[65];
+    int pubkeylen = 65;
+    CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 0));
+    CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 1));
+    CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 2));
+    CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 3));
+
+    /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
+    const unsigned char sigb64[64] = {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+    };
+    unsigned char pubkeyb[33];
+    int pubkeyblen = 33;
+    for (int recid = 0; recid < 4; recid++) {
+        unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
+        CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
+        CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
+        /* Damage signature. */
+        sigbder[7]++;
+        CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
+    }
+}
+
+void run_ecdsa_edge_cases(void) {
+    test_ecdsa_edge_cases();
+}
 
 #ifdef ENABLE_OPENSSL_TESTS
 EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
@@ -1037,6 +1113,7 @@ int main(int argc, char **argv) {
     /* ecdsa tests */
     run_ecdsa_sign_verify();
     run_ecdsa_end_to_end();
+    run_ecdsa_edge_cases();
 #ifdef ENABLE_OPENSSL_TESTS
     run_ecdsa_openssl();
 #endif
This page took 0.025301 seconds and 4 git commands to generate.