summaryrefslogtreecommitdiff
path: root/testsuite/gostdsa-keygen-test.c
blob: 67459182e0b4bfe07e42a55f0274c4837b1779a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "testutils.h"
#include "gostdsa.h"
#include "knuth-lfib.h"

/* Check if y^2 = x^3 - 3x + b */
static int
ecc_valid_p (struct ecc_point *pub)
{
  mpz_t t, x, y;
  mpz_t lhs, rhs;
  int res;
  mp_size_t size;

  size = pub->ecc->p.size;

  /* First check range */
  if (mpn_cmp (pub->p, pub->ecc->p.m, size) >= 0
      || mpn_cmp (pub->p + size, pub->ecc->p.m, size) >= 0)
    return 0;

  mpz_init (lhs);
  mpz_init (rhs);

  mpz_roinit_n (x, pub->p, size);
  mpz_roinit_n (y, pub->p + size, size);

  mpz_mul (lhs, y, y);

  if (pub->ecc->p.bit_size == 255)
    {
      /* Check that
	 121666 (1 + x^2 - y^2) = 121665 x^2 y^2 */
      mpz_t x2;
      mpz_init (x2);
      mpz_mul (x2, x, x); /* x^2 */
      mpz_mul (rhs, x2, lhs); /* x^2 y^2 */
      mpz_sub (lhs, x2, lhs); /* x^2 - y^2 */
      mpz_add_ui (lhs, lhs, 1); /* 1 + x^2 - y^2 */
      mpz_mul_ui (lhs, lhs, 121666);
      mpz_mul_ui (rhs, rhs, 121665);

      mpz_clear (x2);
    }
  else if (pub->ecc->p.bit_size == 448)
    {
      /* Check that
	 x^2 + y^2 = 1 - 39081 x^2 y^2 */
      mpz_t x2, d;
      mpz_init (x2);
      mpz_init_set_ui (d, 39081);
      mpz_mul (x2, x, x); /* x^2 */
      mpz_mul (d, d, x2); /* 39081 x^2 */
      mpz_set_ui (rhs, 1);
      mpz_submul (rhs, d, lhs); /* 1 - 39081 x^2 y^2 */
      mpz_add (lhs, x2, lhs);	/* x^2 + y^2 */

      mpz_clear (d);
      mpz_clear (x2);
    }
  else
    {
      /* Check y^2 = x^3 - 3 x + b */
      mpz_mul (rhs, x, x);
      mpz_sub_ui (rhs, rhs, 3);
      mpz_mul (rhs, rhs, x);
      mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));
    }
  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p.m, size));

  mpz_clear (lhs);
  mpz_clear (rhs);

  return res;
}

void
test_main (void)
{
  unsigned i;
  struct knuth_lfib_ctx rctx;
  struct dsa_signature signature;

  struct tstring *digest;

  knuth_lfib_init (&rctx, 4711);
  dsa_signature_init (&signature);

  digest = SHEX (/* sha256("abc") */
		 "BA7816BF 8F01CFEA 414140DE 5DAE2223"
		 "B00361A3 96177A9C B410FF61 F20015AD");

  for (i = 0; ecc_curves[i]; i++)
    {
      const struct ecc_curve *ecc = ecc_curves[i];
      struct ecc_point pub;
      struct ecc_scalar key;

      if (ecc->p.bit_size == 255 || ecc->p.bit_size == 448)
	/* Exclude curve25519 and curve448, not supported with GOSTDSA. */
	continue;

      if (verbose)
	fprintf (stderr, "Curve %d\n", ecc->p.bit_size);

      ecc_point_init (&pub, ecc);
      ecc_scalar_init (&key, ecc);

      ecdsa_generate_keypair (&pub, &key,
			      &rctx,
			      (nettle_random_func *) knuth_lfib_random);

      if (verbose)
	{
	  fprintf (stderr, "Public key:\nx = ");
	  write_mpn (stderr, 16, pub.p, ecc->p.size);
	  fprintf (stderr, "\ny = ");
	  write_mpn (stderr, 16, pub.p + ecc->p.size, ecc->p.size);
	  fprintf (stderr, "\nPrivate key: ");
	  write_mpn (stderr, 16, key.p, ecc->p.size);
	  fprintf (stderr, "\n");
	}
      if (!ecc_valid_p (&pub))
	die ("gostdsa_generate_keypair produced an invalid point.\n");

      gostdsa_sign (&key,
		   &rctx, (nettle_random_func *) knuth_lfib_random,
		   digest->length, digest->data,
		   &signature);

      if (!gostdsa_verify (&pub, digest->length, digest->data,
			   &signature))
	die ("gostdsa_verify failed.\n");

      digest->data[3] ^= 17;
      if (gostdsa_verify (&pub, digest->length, digest->data,
			  &signature))
	die ("gostdsa_verify returned success with invalid digest.\n");
      digest->data[3] ^= 17;

      mpz_combit (signature.r, 117);
      if (gostdsa_verify (&pub, digest->length, digest->data,
			  &signature))
	die ("gostdsa_verify returned success with invalid signature.r.\n");

      mpz_combit (signature.r, 117);
      mpz_combit (signature.s, 93);
      if (gostdsa_verify (&pub, digest->length, digest->data,
			  &signature))
	die ("gostdsa_verify returned success with invalid signature.s.\n");

      ecc_point_clear (&pub);
      ecc_scalar_clear (&key);
    }
  dsa_signature_clear (&signature);
}