|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "mpi.h" |
|
6 #include "mplogic.h" |
|
7 #include "ecl.h" |
|
8 #include "ecp.h" |
|
9 #include "ecl-priv.h" |
|
10 |
|
11 #include <sys/types.h> |
|
12 #include <stdio.h> |
|
13 #include <time.h> |
|
14 #include <sys/time.h> |
|
15 #include <sys/resource.h> |
|
16 |
|
17 /* Returns 2^e as an integer. This is meant to be used for small powers of |
|
18 * two. */ |
|
19 int ec_twoTo(int e); |
|
20 |
|
21 /* Number of bits of scalar to test */ |
|
22 #define BITSIZE 160 |
|
23 |
|
24 /* Time k repetitions of operation op. */ |
|
25 #define M_TimeOperation(op, k) { \ |
|
26 double dStart, dNow, dUserTime; \ |
|
27 struct rusage ru; \ |
|
28 int i; \ |
|
29 getrusage(RUSAGE_SELF, &ru); \ |
|
30 dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \ |
|
31 for (i = 0; i < k; i++) { \ |
|
32 { op; } \ |
|
33 }; \ |
|
34 getrusage(RUSAGE_SELF, &ru); \ |
|
35 dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \ |
|
36 dUserTime = dNow-dStart; \ |
|
37 if (dUserTime) printf(" %-45s\n k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ |
|
38 } |
|
39 |
|
40 /* Tests wNAF computation. Non-adjacent-form is discussed in the paper: D. |
|
41 * Hankerson, J. Hernandez and A. Menezes, "Software implementation of |
|
42 * elliptic curve cryptography over binary fields", Proc. CHES 2000. */ |
|
43 |
|
44 mp_err |
|
45 main(void) |
|
46 { |
|
47 signed char naf[BITSIZE + 1]; |
|
48 ECGroup *group = NULL; |
|
49 mp_int k; |
|
50 mp_int *scalar; |
|
51 int i, count; |
|
52 int res; |
|
53 int w = 5; |
|
54 char s[1000]; |
|
55 |
|
56 /* Get a 160 bit scalar to compute wNAF from */ |
|
57 group = ECGroup_fromName(ECCurve_SECG_PRIME_160R1); |
|
58 scalar = &group->genx; |
|
59 |
|
60 /* Compute wNAF representation of scalar */ |
|
61 ec_compute_wNAF(naf, BITSIZE, scalar, w); |
|
62 |
|
63 /* Verify correctness of representation */ |
|
64 mp_init(&k); /* init k to 0 */ |
|
65 |
|
66 for (i = BITSIZE; i >= 0; i--) { |
|
67 mp_add(&k, &k, &k); |
|
68 /* digits in mp_???_d are unsigned */ |
|
69 if (naf[i] >= 0) { |
|
70 mp_add_d(&k, naf[i], &k); |
|
71 } else { |
|
72 mp_sub_d(&k, -naf[i], &k); |
|
73 } |
|
74 } |
|
75 |
|
76 if (mp_cmp(&k, scalar) != 0) { |
|
77 printf("Error: incorrect NAF value.\n"); |
|
78 MP_CHECKOK(mp_toradix(&k, s, 16)); |
|
79 printf("NAF value %s\n", s); |
|
80 MP_CHECKOK(mp_toradix(scalar, s, 16)); |
|
81 printf("original value %s\n", s); |
|
82 goto CLEANUP; |
|
83 } |
|
84 |
|
85 /* Verify digits of representation are valid */ |
|
86 for (i = 0; i <= BITSIZE; i++) { |
|
87 if (naf[i] % 2 == 0 && naf[i] != 0) { |
|
88 printf("Error: Even non-zero digit found.\n"); |
|
89 goto CLEANUP; |
|
90 } |
|
91 if (naf[i] < -(ec_twoTo(w - 1)) || naf[i] >= ec_twoTo(w - 1)) { |
|
92 printf("Error: Magnitude of naf digit too large.\n"); |
|
93 goto CLEANUP; |
|
94 } |
|
95 } |
|
96 |
|
97 /* Verify sparsity of representation */ |
|
98 count = w - 1; |
|
99 for (i = 0; i <= BITSIZE; i++) { |
|
100 if (naf[i] != 0) { |
|
101 if (count < w - 1) { |
|
102 printf("Error: Sparsity failed.\n"); |
|
103 goto CLEANUP; |
|
104 } |
|
105 count = 0; |
|
106 } else |
|
107 count++; |
|
108 } |
|
109 |
|
110 /* Check timing */ |
|
111 M_TimeOperation(ec_compute_wNAF(naf, BITSIZE, scalar, w), 10000); |
|
112 |
|
113 printf("Test passed.\n"); |
|
114 CLEANUP: |
|
115 ECGroup_free(group); |
|
116 return MP_OKAY; |
|
117 } |