3
/* Generate compile time constant (but machine dependent) tables. */
5
/* nettle, low-level cryptographics library
7
* Copyright (C) 2013 Niels Möller
9
* The nettle library is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU Lesser General Public License as published by
11
* the Free Software Foundation; either version 2.1 of the License, or (at your
12
* option) any later version.
14
* The nettle library is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
* License for more details.
19
* You should have received a copy of the GNU Lesser General Public License
20
* along with the nettle library; see the file COPYING.LIB. If not, write to
21
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25
/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
34
/* Affine coordinates, for simplicity. Infinity point represented as x
42
/* Represents an elliptic curve of the form
44
y^2 = x^3 - 3x + b (mod p)
60
/* Table for pippenger's algorithm.
63
i 2^c + j_0 + j_1 2 + j_2 2^2 + ... + j_{c-1} 2^{c-1}
67
2^{ikc} ( j_0 + j_1 2^k + j_2 2^{2k} + ... + j_{c-1} 2^{(c-1)k}) g
70
struct ecc_point *table;
72
/* If non-NULL, holds 2g, 3g, 4g */
73
struct ecc_point *ref;
77
ecc_init (struct ecc_point *p)
84
ecc_clear (struct ecc_point *p)
91
ecc_zero_p (const struct ecc_point *p)
93
return mpz_sgn (p->x) == 0 && mpz_sgn (p->y) == 0;
97
ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q)
99
return mpz_cmp (p->x, q->x) == 0 && mpz_cmp (p->y, q->y) == 0;
103
ecc_set_zero (struct ecc_point *r)
105
mpz_set_ui (r->x, 0);
106
mpz_set_ui (r->y, 0);
110
ecc_set (struct ecc_point *r, const struct ecc_point *p)
112
mpz_set (r->x, p->x);
113
mpz_set (r->y, p->y);
117
ecc_dup (const struct ecc_curve *ecc,
118
struct ecc_point *r, const struct ecc_point *p)
133
mpz_mul_ui (m, p->y, 2);
134
mpz_invert (m, m, ecc->p);
136
/* t = 3 (x^2 - 1) * m */
137
mpz_mul (t, p->x, p->x);
138
mpz_mod (t, t, ecc->p);
139
mpz_sub_ui (t, t, 1);
140
mpz_mul_ui (t, t, 3);
145
/* mpz_submul_ui (x, p->x, 2); not available in mini-gmp */
146
mpz_mul_ui (m, p->x, 2);
148
mpz_mod (x, x, ecc->p);
150
/* y' = (x - x') * t - y */
151
mpz_sub (y, p->x, x);
153
mpz_sub (y, y, p->y);
154
mpz_mod (y, y, ecc->p);
167
ecc_add (const struct ecc_curve *ecc,
168
struct ecc_point *r, const struct ecc_point *p, const struct ecc_point *q)
173
else if (ecc_zero_p (q))
176
else if (mpz_cmp (p->x, q->x) == 0)
178
if (mpz_cmp (p->y, q->y) == 0)
191
/* t = (q_y - p_y) / (q_x - p_x) */
192
mpz_sub (t, q->x, p->x);
193
mpz_invert (t, t, ecc->p);
194
mpz_sub (s, q->y, p->y);
196
mpz_mod (t, t, ecc->p);
198
/* x' = t^2 - p_x - q_x */
200
mpz_sub (x, x, p->x);
201
mpz_sub (x, x, q->x);
202
mpz_mod (x, x, ecc->p);
204
/* y' = (x - x') * t - y */
205
mpz_sub (y, p->x, x);
207
mpz_sub (y, y, p->y);
208
mpz_mod (y, y, ecc->p);
221
ecc_mul_binary (const struct ecc_curve *ecc,
222
struct ecc_point *r, const mpz_t n, const struct ecc_point *p)
224
/* Avoid the mp_bitcnt_t type for compatibility with older GMP
229
assert (mpz_sgn (n) > 0);
233
/* Index of highest one bit */
234
for (k = mpz_sizeinbase (n, 2) - 1; k-- > 0; )
237
if (mpz_tstbit (n, k))
238
ecc_add (ecc, r, r, p);
242
static struct ecc_point *
245
struct ecc_point *p = malloc (n * sizeof(*p));
250
fprintf (stderr, "Virtual memory exhausted.\n");
253
for (i = 0; i < n; i++)
260
ecc_set_str (struct ecc_point *p,
261
const char *x, const char *y)
263
mpz_set_str (p->x, x, 16);
264
mpz_set_str (p->y, y, 16);
268
ecc_curve_init_str (struct ecc_curve *ecc,
269
const char *p, const char *b, const char *q,
270
const char *gx, const char *gy)
272
mpz_init_set_str (ecc->p, p, 16);
273
mpz_init_set_str (ecc->b, b, 16);
274
mpz_init_set_str (ecc->q, q, 16);
276
ecc_set_str (&ecc->g, gx, gy);
278
ecc->pippenger_k = 0;
279
ecc->pippenger_c = 0;
286
ecc_curve_init (struct ecc_curve *ecc, unsigned bit_size)
291
ecc_curve_init_str (ecc,
292
/* p = 2^{192} - 2^{64} - 1 */
293
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
296
"64210519e59c80e70fa7e9ab72243049"
299
"ffffffffffffffffffffffff99def836"
302
"188da80eb03090f67cbf20eb43a18800"
305
"07192b95ffc8da78631011ed6b24cdd5"
307
ecc->ref = ecc_alloc (3);
308
ecc_set_str (&ecc->ref[0], /* 2 g */
309
"dafebf5828783f2ad35534631588a3f629a70fb16982a888",
310
"dd6bda0d993da0fa46b27bbc141b868f59331afa5c7e93ab");
312
ecc_set_str (&ecc->ref[1], /* 3 g */
313
"76e32a2557599e6edcd283201fb2b9aadfd0d359cbb263da",
314
"782c37e372ba4520aa62e0fed121d49ef3b543660cfd05fd");
316
ecc_set_str (&ecc->ref[2], /* 4 g */
317
"35433907297cc378b0015703374729d7a4fe46647084e4ba",
318
"a2649984f2135c301ea3acb0776cd4f125389b311db3be32");
322
ecc_curve_init_str (ecc,
323
/* p = 2^{224} - 2^{96} + 1 */
324
"ffffffffffffffffffffffffffffffff"
325
"000000000000000000000001",
327
"b4050a850c04b3abf54132565044b0b7"
328
"d7bfd8ba270b39432355ffb4",
330
"ffffffffffffffffffffffffffff16a2"
331
"e0b8f03e13dd29455c5c2a3d",
333
"b70e0cbd6bb4bf7f321390b94a03c1d3"
334
"56c21122343280d6115c1d21",
336
"bd376388b5f723fb4c22dfe6cd4375a0"
337
"5a07476444d5819985007e34");
339
ecc->ref = ecc_alloc (3);
340
ecc_set_str (&ecc->ref[0], /* 2 g */
341
"706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6",
342
"1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb");
344
ecc_set_str (&ecc->ref[1], /* 3 g */
345
"df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04",
346
"a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925");
348
ecc_set_str (&ecc->ref[2], /* 4 g */
349
"ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301",
350
"482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9");
354
ecc_curve_init_str (ecc,
355
/* p = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1 */
356
"FFFFFFFF000000010000000000000000"
357
"00000000FFFFFFFFFFFFFFFFFFFFFFFF",
359
"5AC635D8AA3A93E7B3EBBD55769886BC"
360
"651D06B0CC53B0F63BCE3C3E27D2604B",
362
"FFFFFFFF00000000FFFFFFFFFFFFFFFF"
363
"BCE6FAADA7179E84F3B9CAC2FC632551",
365
"6B17D1F2E12C4247F8BCE6E563A440F2"
366
"77037D812DEB33A0F4A13945D898C296",
368
"4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
369
"2BCE33576B315ECECBB6406837BF51F5");
371
ecc->ref = ecc_alloc (3);
372
ecc_set_str (&ecc->ref[0], /* 2 g */
373
"7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978",
374
"7775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d1");
376
ecc_set_str (&ecc->ref[1], /* 3 g */
377
"5ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c",
378
"8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d5032");
380
ecc_set_str (&ecc->ref[2], /* 4 g */
381
"e2534a3532d08fbba02dde659ee62bd0031fe2db785596ef509302446b030852",
382
"e0f1575a4c633cc719dfee5fda862d764efc96c3f30ee0055c42c23f184ed8c6");
386
ecc_curve_init_str (ecc,
387
/* p = 2^{384} - 2^{128} - 2^{96} + 2^{32} - 1 */
388
"ffffffffffffffffffffffffffffffff"
389
"fffffffffffffffffffffffffffffffe"
390
"ffffffff0000000000000000ffffffff",
392
"b3312fa7e23ee7e4988e056be3f82d19"
393
"181d9c6efe8141120314088f5013875a"
394
"c656398d8a2ed19d2a85c8edd3ec2aef",
396
"ffffffffffffffffffffffffffffffff"
397
"ffffffffffffffffc7634d81f4372ddf"
398
"581a0db248b0a77aecec196accc52973",
400
"aa87ca22be8b05378eb1c71ef320ad74"
401
"6e1d3b628ba79b9859f741e082542a38"
402
"5502f25dbf55296c3a545e3872760ab7",
404
"3617de4a96262c6f5d9e98bf9292dc29"
405
"f8f41dbd289a147ce9da3113b5f0b8c0"
406
"0a60b1ce1d7e819d7a431d7c90ea0e5f");
408
ecc->ref = ecc_alloc (3);
409
ecc_set_str (&ecc->ref[0], /* 2 g */
410
"8d999057ba3d2d969260045c55b97f089025959a6f434d651d207d19fb96e9e4fe0e86ebe0e64f85b96a9c75295df61",
411
"8e80f1fa5b1b3cedb7bfe8dffd6dba74b275d875bc6cc43e904e505f256ab4255ffd43e94d39e22d61501e700a940e80");
413
ecc_set_str (&ecc->ref[1], /* 3 g */
414
"77a41d4606ffa1464793c7e5fdc7d98cb9d3910202dcd06bea4f240d3566da6b408bbae5026580d02d7e5c70500c831",
415
"c995f7ca0b0c42837d0bbe9602a9fc998520b41c85115aa5f7684c0edc111eacc24abd6be4b5d298b65f28600a2f1df1");
417
ecc_set_str (&ecc->ref[2], /* 4 g */
418
"138251cd52ac9298c1c8aad977321deb97e709bd0b4ca0aca55dc8ad51dcfc9d1589a1597e3a5120e1efd631c63e1835",
419
"cacae29869a62e1631e8a28181ab56616dc45d918abc09f3ab0e63cf792aa4dced7387be37bba569549f1c02b270ed67");
423
ecc_curve_init_str (ecc,
424
"1ff" /* p = 2^{521} - 1 */
425
"ffffffffffffffffffffffffffffffff"
426
"ffffffffffffffffffffffffffffffff"
427
"ffffffffffffffffffffffffffffffff"
428
"ffffffffffffffffffffffffffffffff",
431
"953eb9618e1c9a1f929a21a0b68540ee"
432
"a2da725b99b315f3b8b489918ef109e1"
433
"56193951ec7e937b1652c0bd3bb1bf07"
434
"3573df883d2c34f1ef451fd46b503f00",
437
"ffffffffffffffffffffffffffffffff"
438
"fffffffffffffffffffffffffffffffa"
439
"51868783bf2f966b7fcc0148f709a5d0"
440
"3bb5c9b8899c47aebb6fb71e91386409",
443
"858e06b70404e9cd9e3ecb662395b442"
444
"9c648139053fb521f828af606b4d3dba"
445
"a14b5e77efe75928fe1dc127a2ffa8de"
446
"3348b3c1856a429bf97e7e31c2e5bd66",
449
"39296a789a3bc0045c8a5fb42c7d1bd9"
450
"98f54449579b446817afbd17273e662c"
451
"97ee72995ef42640c550b9013fad0761"
452
"353c7086a272c24088be94769fd16650");
454
ecc->ref = ecc_alloc (3);
455
ecc_set_str (&ecc->ref[0], /* 2 g */
456
"433c219024277e7e682fcb288148c282747403279b1ccc06352c6e5505d769be97b3b204da6ef55507aa104a3a35c5af41cf2fa364d60fd967f43e3933ba6d783d",
457
"f4bb8cc7f86db26700a7f3eceeeed3f0b5c6b5107c4da97740ab21a29906c42dbbb3e377de9f251f6b93937fa99a3248f4eafcbe95edc0f4f71be356d661f41b02");
459
ecc_set_str (&ecc->ref[1], /* 3 g */
460
"1a73d352443de29195dd91d6a64b5959479b52a6e5b123d9ab9e5ad7a112d7a8dd1ad3f164a3a4832051da6bd16b59fe21baeb490862c32ea05a5919d2ede37ad7d",
461
"13e9b03b97dfa62ddd9979f86c6cab814f2f1557fa82a9d0317d2f8ab1fa355ceec2e2dd4cf8dc575b02d5aced1dec3c70cf105c9bc93a590425f588ca1ee86c0e5");
463
ecc_set_str (&ecc->ref[2], /* 4 g */
464
"35b5df64ae2ac204c354b483487c9070cdc61c891c5ff39afc06c5d55541d3ceac8659e24afe3d0750e8b88e9f078af066a1d5025b08e5a5e2fbc87412871902f3",
465
"82096f84261279d2b673e0178eb0b4abb65521aef6e6e32e1b5ae63fe2f19907f279f283e54ba385405224f750a95b85eebb7faef04699d1d9e21f47fc346e4d0d");
469
fprintf (stderr, "No known curve for size %d\n", bit_size);
472
ecc->bit_size = bit_size;
476
ecc_pippenger_precompute (struct ecc_curve *ecc, unsigned k, unsigned c)
478
unsigned p = (ecc->bit_size + k-1) / k;
479
unsigned M = (p + c-1)/c;
482
ecc->pippenger_k = k;
483
ecc->pippenger_c = c;
484
ecc->table_size = M << c;
485
ecc->table = ecc_alloc (ecc->table_size);
487
/* Compute the first 2^c entries */
488
ecc_set_zero (&ecc->table[0]);
489
ecc_set (&ecc->table[1], &ecc->g);
491
for (j = 2; j < (1U<<c); j <<= 1)
493
/* T[j] = 2^k T[j/2] */
494
ecc_dup (ecc, &ecc->table[j], &ecc->table[j/2]);
495
for (i = 1; i < k; i++)
496
ecc_dup (ecc, &ecc->table[j], &ecc->table[j]);
498
for (i = 1; i < j; i++)
499
ecc_add (ecc, &ecc->table[j + i], &ecc->table[j], &ecc->table[i]);
501
for (j = 1<<c; j < ecc->table_size; j++)
503
/* T[j] = 2^{kc} T[j-2^c] */
504
ecc_dup (ecc, &ecc->table[j], &ecc->table[j - (1<<c)]);
505
for (i = 1; i < k*c; i++)
506
ecc_dup (ecc, &ecc->table[j], &ecc->table[j]);
511
ecc_mul_pippenger (const struct ecc_curve *ecc,
512
struct ecc_point *r, const mpz_t n_input)
521
mpz_mod (n, n_input, ecc->q);
524
k = ecc->pippenger_k;
525
c = ecc->pippenger_c;
527
bit_rows = (ecc->bit_size + k - 1) / k;
529
for (i = k; i-- > 0; )
532
for (j = 0; j * c < bit_rows; j++)
537
/* Extract c bits of the exponent, stride k, starting at i + kcj, ending at
539
for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; )
542
bits = (bits << 1) | mpz_tstbit (n, bit_index);
545
ecc_add (ecc, r, r, &ecc->table[(j << c) | bits]);
551
#define ASSERT_EQUAL(p, q) do { \
552
if (!ecc_equal_p (p, q)) \
554
fprintf (stderr, "%s:%d: ASSERT_EQUAL (%s, %s) failed.\n", \
555
__FILE__, __LINE__, #p, #q); \
556
fprintf (stderr, "p = ("); \
557
mpz_out_str (stderr, 16, (p)->x); \
558
fprintf (stderr, ",\n "); \
559
mpz_out_str (stderr, 16, (p)->y); \
560
fprintf (stderr, ")\nq = ("); \
561
mpz_out_str (stderr, 16, (q)->x); \
562
fprintf (stderr, ",\n "); \
563
mpz_out_str (stderr, 16, (q)->y); \
564
fprintf (stderr, ")\n"); \
569
#define ASSERT_ZERO(p) do { \
570
if (!ecc_zero_p (p)) \
572
fprintf (stderr, "%s:%d: ASSERT_ZERO (%s) failed.\n", \
573
__FILE__, __LINE__, #p); \
574
fprintf (stderr, "p = ("); \
575
mpz_out_str (stderr, 16, (p)->x); \
576
fprintf (stderr, ",\n "); \
577
mpz_out_str (stderr, 16, (p)->y); \
578
fprintf (stderr, ")\n"); \
584
ecc_curve_check (const struct ecc_curve *ecc)
586
struct ecc_point p, q;
593
ecc_dup (ecc, &p, &ecc->g);
595
ASSERT_EQUAL (&p, &ecc->ref[0]);
598
fprintf (stderr, "g2 = ");
599
mpz_out_str (stderr, 16, p.x);
600
fprintf (stderr, "\n ");
601
mpz_out_str (stderr, 16, p.y);
602
fprintf (stderr, "\n");
604
ecc_add (ecc, &q, &p, &ecc->g);
606
ASSERT_EQUAL (&q, &ecc->ref[1]);
609
fprintf (stderr, "g3 = ");
610
mpz_out_str (stderr, 16, q.x);
611
fprintf (stderr, "\n ");
612
mpz_out_str (stderr, 16, q.y);
613
fprintf (stderr, "\n");
616
ecc_add (ecc, &q, &q, &ecc->g);
618
ASSERT_EQUAL (&q, &ecc->ref[2]);
621
fprintf (stderr, "g4 = ");
622
mpz_out_str (stderr, 16, q.x);
623
fprintf (stderr, "\n ");
624
mpz_out_str (stderr, 16, q.y);
625
fprintf (stderr, "\n");
628
ecc_dup (ecc, &q, &p);
630
ASSERT_EQUAL (&q, &ecc->ref[2]);
633
fprintf (stderr, "g4 = ");
634
mpz_out_str (stderr, 16, q.x);
635
fprintf (stderr, "\n ");
636
mpz_out_str (stderr, 16, q.y);
637
fprintf (stderr, "\n");
640
ecc_mul_binary (ecc, &p, ecc->q, &ecc->g);
643
ecc_mul_pippenger (ecc, &q, ecc->q);
652
output_digits (const mpz_t x,
653
unsigned size, unsigned bits_per_limb)
665
mpz_setbit (mask, bits_per_limb);
666
mpz_sub_ui (mask, mask, 1);
668
suffix = bits_per_limb > 32 ? "ULL" : "UL";
672
for (i = 0; i < size; i++)
677
mpz_and (limb, mask, t);
679
mpz_out_str (stdout, 16, limb);
680
printf ("%s,", suffix);
681
mpz_tdiv_q_2exp (t, t, bits_per_limb);
690
output_bignum (const char *name, const mpz_t x,
691
unsigned size, unsigned bits_per_limb)
693
printf ("static const mp_limb_t %s[%d] = {", name, size);
694
output_digits (x, size, bits_per_limb);
699
output_point (const char *name, const struct ecc_point *p,
700
unsigned size, unsigned bits_per_limb)
703
printf("static const mp_limb_t %s[%u] = {", name, 2*size);
705
output_digits (p->x, size, bits_per_limb);
706
output_digits (p->y, size, bits_per_limb);
713
output_point_redc (const char *name, const struct ecc_curve *ecc,
714
const struct ecc_point *p,
715
unsigned size, unsigned bits_per_limb)
721
printf("static const mp_limb_t %s[%u] = {", name, 2*size);
723
mpz_mul_2exp (t, p->x, size * bits_per_limb);
724
mpz_mod (t, t, ecc->p);
726
output_digits (t, size, bits_per_limb);
728
mpz_mul_2exp (t, p->y, size * bits_per_limb);
729
mpz_mod (t, t, ecc->p);
731
output_digits (t, size, bits_per_limb);
740
output_modulo (const char *name, const mpz_t x,
741
unsigned size, unsigned bits_per_limb)
748
mpz_setbit (mod, bits_per_limb * size);
749
mpz_mod (mod, mod, x);
751
bits = mpz_sizeinbase (mod, 2);
752
assert (bits <= size * bits_per_limb - 32);
754
output_bignum (name, mod, size, bits_per_limb);
761
output_curve (const struct ecc_curve *ecc, unsigned bits_per_limb)
763
unsigned limb_size = (ecc->bit_size + bits_per_limb - 1)/bits_per_limb;
771
printf ("/* For NULL. */\n#include <stddef.h>\n");
773
printf ("#define ECC_LIMB_SIZE %u\n", limb_size);
774
printf ("#define ECC_PIPPENGER_K %u\n", ecc->pippenger_k);
775
printf ("#define ECC_PIPPENGER_C %u\n", ecc->pippenger_c);
777
output_bignum ("ecc_p", ecc->p, limb_size, bits_per_limb);
778
output_bignum ("ecc_b", ecc->b, limb_size, bits_per_limb);
779
output_bignum ("ecc_q", ecc->q, limb_size, bits_per_limb);
780
output_point ("ecc_g", &ecc->g, limb_size, bits_per_limb);
781
output_point_redc ("ecc_redc_g", ecc, &ecc->g, limb_size, bits_per_limb);
783
bits = output_modulo ("ecc_Bmodp", ecc->p, limb_size, bits_per_limb);
784
printf ("#define ECC_BMODP_SIZE %u\n",
785
(bits + bits_per_limb - 1) / bits_per_limb);
786
bits = output_modulo ("ecc_Bmodq", ecc->q, limb_size, bits_per_limb);
787
printf ("#define ECC_BMODQ_SIZE %u\n",
788
(bits + bits_per_limb - 1) / bits_per_limb);
790
if (ecc->bit_size < limb_size * bits_per_limb)
795
mpz_setbit (t, ecc->bit_size);
796
mpz_sub (t, t, ecc->p);
797
output_bignum ("ecc_Bmodp_shifted", t, limb_size, bits_per_limb);
799
shift = limb_size * bits_per_limb - ecc->bit_size;
802
/* Check condition for reducing hi limbs. If s is the
803
normalization shift and n is the bit size (so that s + n
804
= limb_size * bite_per_limb), then we need
806
(2^n - 1) + (2^s - 1) (2^n - p) < 2p
812
To a allow a carry limb to be added in at the same time,
813
substitute s+1 for s.
815
/* FIXME: For ecdsa verify, we actually need the stricter
817
mpz_mul_2exp (t, t, shift + 1);
818
if (mpz_cmp (t, ecc->p) > 0)
820
fprintf (stderr, "Reduction condition failed for %u-bit curve.\n",
826
mpz_setbit (t, ecc->bit_size);
827
mpz_sub (t, t, ecc->q);
828
output_bignum ("ecc_Bmodq_shifted", t, limb_size, bits_per_limb);
832
printf ("#define ecc_Bmodp_shifted ecc_Bmodp\n");
833
printf ("#define ecc_Bmodq_shifted ecc_Bmodq\n");
836
mpz_add_ui (t, ecc->p, 1);
837
mpz_fdiv_q_2exp (t, t, 1);
838
output_bignum ("ecc_pp1h", t, limb_size, bits_per_limb);
840
mpz_add_ui (t, ecc->q, 1);
841
mpz_fdiv_q_2exp (t, t, 1);
842
output_bignum ("ecc_qp1h", t, limb_size, bits_per_limb);
844
/* Trailing zeros in p+1 correspond to trailing ones in p. */
845
redc_limbs = mpz_scan0 (ecc->p, 0) / bits_per_limb;
848
mpz_add_ui (t, ecc->p, 1);
849
mpz_fdiv_q_2exp (t, t, redc_limbs * bits_per_limb);
850
output_bignum ("ecc_redc_ppm1", t, limb_size - redc_limbs, bits_per_limb);
854
/* Trailing zeros in p-1 correspond to zeros just above the low
856
redc_limbs = mpz_scan1 (ecc->p, 1) / bits_per_limb;
859
printf ("#define ecc_redc_ppm1 (ecc_p + %d)\n",
861
redc_limbs = -redc_limbs;
864
printf ("#define ecc_redc_ppm1 NULL\n");
866
printf ("#define ECC_REDC_SIZE %d\n", redc_limbs);
868
printf ("#if USE_REDC\n");
869
printf ("#define ecc_unit ecc_Bmodp\n");
871
printf ("static const mp_limb_t ecc_table[%lu] = {",
872
(unsigned long) (2*ecc->table_size * limb_size));
873
for (i = 0; i < ecc->table_size; i++)
874
output_point_redc (NULL, ecc, &ecc->table[i], limb_size, bits_per_limb);
880
mpz_init_set_ui (t, 1);
881
output_bignum ("ecc_unit", t, limb_size, bits_per_limb);
883
printf ("static const mp_limb_t ecc_table[%lu] = {",
884
(unsigned long) (2*ecc->table_size * limb_size));
885
for (i = 0; i < ecc->table_size; i++)
886
output_point (NULL, &ecc->table[i], limb_size, bits_per_limb);
895
main (int argc, char **argv)
897
struct ecc_curve ecc;
901
fprintf (stderr, "Usage: %s CURVE-BITS K C [BITS-PER-LIMB]\n", argv[0]);
905
ecc_curve_init (&ecc, atoi(argv[1]));
907
ecc_pippenger_precompute (&ecc, atoi(argv[2]), atoi(argv[3]));
909
fprintf (stderr, "Table size: %lu entries\n",
910
(unsigned long) ecc.table_size);
912
ecc_curve_check (&ecc);
915
output_curve (&ecc, atoi(argv[4]));