a96c09effeef6c7a679513b2e71fcc1ae6a230e3
[platform/upstream/nettle.git] / testsuite / ecdsa-keygen-test.c
1 #include "testutils.h"
2 #include "knuth-lfib.h"
3
4 /* Check if y^2 = x^3 - 3x + b */
5 static int
6 ecc_valid_p (struct ecc_point *pub)
7 {
8   mpz_t t, x, y;
9   mpz_t lhs, rhs;
10   int res;
11   mp_size_t size;
12
13   size = pub->ecc->p.size;
14
15   /* First check range */
16   if (mpn_cmp (pub->p, pub->ecc->p.m, size) >= 0
17       || mpn_cmp (pub->p + size, pub->ecc->p.m, size) >= 0)
18     return 0;
19
20   mpz_init (lhs);
21   mpz_init (rhs);
22
23   mpz_roinit_n (x, pub->p, size);
24   mpz_roinit_n (y, pub->p + size, size);
25
26   mpz_mul (lhs, y, y);
27   
28   if (pub->ecc->p.bit_size == 255)
29     {
30       /* Check that
31          121666 (1 + x^2 - y^2) = 121665 x^2 y^2 */
32       mpz_t x2;
33       mpz_init (x2);
34       mpz_mul (x2, x, x); /* x^2 */
35       mpz_mul (rhs, x2, lhs); /* x^2 y^2 */
36       mpz_sub (lhs, x2, lhs); /* x^2 - y^2 */
37       mpz_add_ui (lhs, lhs, 1); /* 1 + x^2 - y^2 */
38       mpz_mul_ui (lhs, lhs, 121666);
39       mpz_mul_ui (rhs, rhs, 121665);
40
41       mpz_clear (x2);
42     }
43   else
44     {
45       /* Check y^2 = x^3 - 3 x + b */
46       mpz_mul (rhs, x, x);
47       mpz_sub_ui (rhs, rhs, 3);
48       mpz_mul (rhs, rhs, x);
49       mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));
50     }
51   res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p.m, size));
52   
53   mpz_clear (lhs);
54   mpz_clear (rhs);
55
56   return res;
57 }
58
59 void
60 test_main (void)
61 {
62   unsigned i;
63   struct knuth_lfib_ctx rctx;
64   struct dsa_signature signature;
65
66   struct tstring *digest;
67
68   knuth_lfib_init (&rctx, 4711);
69   dsa_signature_init (&signature);
70
71   digest = SHEX (/* sha256("abc") */
72                  "BA7816BF 8F01CFEA 414140DE 5DAE2223"
73                  "B00361A3 96177A9C B410FF61 F20015AD");
74
75   for (i = 0; ecc_curves[i]; i++)
76     {
77       const struct ecc_curve *ecc = ecc_curves[i];
78       struct ecc_point pub;
79       struct ecc_scalar key;
80
81       if (verbose)
82         fprintf (stderr, "Curve %d\n", ecc->p.bit_size);
83
84       ecc_point_init (&pub, ecc);
85       ecc_scalar_init (&key, ecc);
86
87       ecdsa_generate_keypair (&pub, &key,
88                               &rctx,
89                               (nettle_random_func *) knuth_lfib_random);
90
91       if (verbose)
92         {
93           fprintf (stderr, "Public key:\nx = ");
94           write_mpn (stderr, 16, pub.p, ecc->p.size);
95           fprintf (stderr, "\ny = ");
96           write_mpn (stderr, 16, pub.p + ecc->p.size, ecc->p.size);
97           fprintf (stderr, "\nPrivate key: ");
98           write_mpn (stderr, 16, key.p, ecc->p.size);
99           fprintf (stderr, "\n");
100         }
101       if (!ecc_valid_p (&pub))
102         die ("ecdsa_generate_keypair produced an invalid point.\n");
103
104       ecdsa_sign (&key,
105                   &rctx, (nettle_random_func *) knuth_lfib_random,
106                   digest->length, digest->data,
107                   &signature);
108
109       if (!ecdsa_verify (&pub, digest->length, digest->data,
110                           &signature))
111         die ("ecdsa_verify failed.\n");
112
113       digest->data[3] ^= 17;
114       if (ecdsa_verify (&pub, digest->length, digest->data,
115                          &signature))
116         die ("ecdsa_verify  returned success with invalid digest.\n");
117       digest->data[3] ^= 17;
118
119       mpz_combit (signature.r, 117);
120       if (ecdsa_verify (&pub, digest->length, digest->data,
121                          &signature))
122         die ("ecdsa_verify  returned success with invalid signature.r.\n");
123
124       mpz_combit (signature.r, 117);
125       mpz_combit (signature.s, 93);
126       if (ecdsa_verify (&pub, digest->length, digest->data,
127                          &signature))
128         die ("ecdsa_verify  returned success with invalid signature.s.\n");
129
130       ecc_point_clear (&pub);
131       ecc_scalar_clear (&key);
132     }
133   dsa_signature_clear (&signature);
134 }