]> git.cryptolib.org Git - avr-crypto-lib.git/blob - ecdsa/nist_p192.c
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / ecdsa / nist_p192.c
1 /* p192.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <inttypes.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24
25 #include "bigint.h"
26 #include "ecc.h"
27 #include "nist_p192.h"
28
29 #include <stdio.h>
30 #include <avr/pgmspace.h>
31 #include "bigint_io.h"
32
33 #define printf_P(...)
34 #define bigint_print_hex(a)
35 #undef putchar
36 #define putchar(a)
37
38 /*
39  * p = 6277101735386680763835789423207666416083908700390324961279
40  *   = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF
41  */
42
43 uint8_t nist_curve_p192_p_w[] = {
44     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45     0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
46     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
47 };
48
49 uint8_t nist_curve_p192_n_w[] = {
50     0x31, 0x28, 0xd2, 0xb4, 0xb1, 0xc9, 0x6b, 0x14,
51     0x36, 0xf8, 0xde, 0x99, 0xff, 0xff, 0xff, 0xff,
52     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
53 };
54
55 uint8_t nist_curve_p192_b_w[] = {
56     0xb1, 0xb9, 0x46, 0xc1, 0xec, 0xde, 0xb8, 0xfe,
57     0x49, 0x30, 0x24, 0x72, 0xab, 0xe9, 0xa7, 0x0f,
58     0xe7, 0x80, 0x9c, 0xe5, 0x19, 0x05, 0x21, 0x64
59 };
60
61 uint8_t nist_curve_p192_gx_w[] = {
62     0x12, 0x10, 0xff, 0x82, 0xfd, 0x0a, 0xff, 0xf4,
63     0x00, 0x88, 0xa1, 0x43, 0xeb, 0x20, 0xbf, 0x7c,
64     0xf6, 0x90, 0x30, 0xb0, 0x0e, 0xa8, 0x8d, 0x18
65 };
66
67 uint8_t nist_curve_p192_gy_w[] = {
68     0x11, 0x48, 0x79, 0x1e, 0xa1, 0x77, 0xf9, 0x73,
69     0xd5, 0xcd, 0x24, 0x6b, 0xed, 0x11, 0x10, 0x63,
70     0x78, 0xda, 0xc8, 0xff, 0x95, 0x2b, 0x19, 0x07
71 };
72
73 uint8_t nist_curve_p192_z1_w[192 / BIGINT_WORD_SIZE] = {
74     1, 0, 0, 0, 0, 0, 0, 0,
75     0, 0, 0, 0, 0, 0, 0, 0,
76     0, 0, 0, 0, 0, 0, 0, 0 };
77
78 uint8_t nist_curve_p192_z2_w[192 / BIGINT_WORD_SIZE] = {
79     1, 0, 0, 0, 0, 0, 0, 0,
80     0, 0, 0, 0, 0, 0, 0, 0,
81     0, 0, 0, 0, 0, 0, 0, 0 };
82
83 uint8_t nist_curve_p192_z3_w[192 / BIGINT_WORD_SIZE] = {
84     1, 0, 0, 0, 0, 0, 0, 0,
85     0, 0, 0, 0, 0, 0, 0, 0,
86     0, 0, 0, 0, 0, 0, 0, 0 };
87
88 bigint_t nist_curve_p192_p = {
89     .length_W = 192 / BIGINT_WORD_SIZE,
90     .wordv = nist_curve_p192_p_w,
91     .info = 7
92 };
93
94
95 bigint_t nist_curve_p192_n = {
96     .length_W = 192 / BIGINT_WORD_SIZE,
97     .wordv = nist_curve_p192_n_w,
98     .info = 7
99 };
100
101 bigint_t nist_curve_p192_b = {
102     .length_W = 192 / BIGINT_WORD_SIZE,
103     .wordv = nist_curve_p192_b_w,
104     .info = 6
105 };
106
107 ecc_combi_point_t nist_curve_p192_basepoint = {
108     .chudnovsky = {
109         .x = {
110             .length_W = 192 / BIGINT_WORD_SIZE,
111             .wordv = nist_curve_p192_gx_w,
112             .info = 4
113         },
114         .y = {
115             .length_W = 192 / BIGINT_WORD_SIZE,
116             .wordv = nist_curve_p192_gy_w,
117             .info = 2
118         },
119         .z1 = {
120             .length_W = 1,
121             .wordv = nist_curve_p192_z1_w,
122             .info = 0
123         },
124         .z2 = {
125             .length_W = 1,
126             .wordv = nist_curve_p192_z2_w,
127             .info = 0
128         },
129         .z3 = {
130             .length_W = 1,
131             .wordv = nist_curve_p192_z3_w,
132             .info = 0
133         }
134     }
135 };
136
137 ecc_curve_sp_t nist_curve_p192 = {
138     .b = &nist_curve_p192_b,
139     .p = &nist_curve_p192_p,
140     .n = &nist_curve_p192_n,
141     .reduce_p = bigint_reduce_p192
142 };
143
144
145 /*
146  * A = ( A5 || A4 || A3 || A2 || A1 || A0 ) ; An is 64-bit
147  * A mod p = B = T + S1 + S2 + S3 mod p
148  *
149  * T  = ( A2 || A1 || A0 )
150  * S1 = (  0 || A3 || A3 )
151  * S2 = ( A4 || A4 ||  0 )
152  * S3 = ( A5 || A5 || A5 )
153  *
154  */
155
156 int bigint_reduce_p192(bigint_t *a){
157
158     bigint_word_t s_w[3 * 64 / BIGINT_WORD_SIZE];
159     bigint_t s;
160     uint16_t o_length;
161
162     if(a->info & BIGINT_NEG_MASK){
163         printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
164         /* negative value */
165         a->info &= ~BIGINT_NEG_MASK;
166         bigint_reduce_p192(a);
167         a->info |= BIGINT_NEG_MASK;
168         bigint_add_s(a, a, &nist_curve_p192_p);
169         return 0;
170     }
171
172     o_length = a->length_W;
173
174     if(o_length < 192 / BIGINT_WORD_SIZE){
175         return 0;
176     }
177
178     if(o_length > 192 * 2 / BIGINT_WORD_SIZE){
179         bigint_reduce(a, &nist_curve_p192_p);
180     }
181
182     if(o_length > 192 / BIGINT_WORD_SIZE){
183         s.wordv = s_w;
184         s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
185         s.info = 0;
186
187         printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
188         /*
189          * copy A3 twice in s
190          */
191         if(o_length >= 4 * 64 / BIGINT_WORD_SIZE){
192             printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
193             memcpy(s.wordv, a->wordv + 3 * 64 / BIGINT_WORD_SIZE, 64 / 8);
194         }else{
195             printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
196             memset(s.wordv, 0, 8);
197             memcpy(s.wordv, a->wordv + 3 * 64 / BIGINT_WORD_SIZE,
198                     o_length * BIGINT_WORD_SIZE / 8 - 3 * 64 / 8);
199         }
200
201         memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
202         bigint_adjust(&s);
203
204         /*
205          * Set A3 to zero so we can use a as T
206          */
207         memset(a->wordv + 3 * 64 / BIGINT_WORD_SIZE, 0, sizeof(bigint_word_t));
208         a->length_W = 3 * 64 / BIGINT_WORD_SIZE;
209         bigint_adjust(a);
210
211         /*
212          * Add s (alias S1) to a (alias T)
213          */
214
215         printf_P(PSTR("T: "));
216         bigint_print_hex(a);
217         putchar('\n');
218
219         printf_P(PSTR("s1: "));
220         bigint_print_hex(&s);
221         putchar('\n');
222         bigint_add_u(a, a, &s);
223
224
225         if(o_length > 4 * 64 / BIGINT_WORD_SIZE){
226             s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
227             /*
228              * copy A4 twice in s
229              */
230             printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
231             if(o_length >= 5 * 64 / BIGINT_WORD_SIZE){
232                 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
233                 memcpy(s.wordv, a->wordv + 4 * 64 / BIGINT_WORD_SIZE, 64 / 8);
234             }else{
235                 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
236                 memset(s.wordv, 0, 8);
237                 memcpy(s.wordv, a->wordv + 4 * 64 / BIGINT_WORD_SIZE,
238                         o_length * BIGINT_WORD_SIZE / 8 - 4 * 64 / 8);
239             }
240             memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
241             bigint_adjust(&s);
242
243             /*
244              * Add s (alias S2) to a (alias T + S1)
245              */
246             printf_P(PSTR("s2: "));
247             bigint_print_hex(&s);
248             putchar('\n');
249             bigint_add_scale_u(a, &s, 8);
250
251
252             if(o_length > 5 * 64 / BIGINT_WORD_SIZE){
253                 /*
254                  * copy A5 three times in s
255                  */
256                 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
257                 if(o_length == 6 * 64 / BIGINT_WORD_SIZE){
258                     printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
259                     memcpy(s.wordv, a->wordv + 5 * 64 / BIGINT_WORD_SIZE, 64 / 8);
260                 } else {
261                     printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
262                     memset(s.wordv, 0, 8);
263                     memcpy(s.wordv, a->wordv + 5 * 64 / BIGINT_WORD_SIZE,
264                             o_length * BIGINT_WORD_SIZE / 8 - 5 * 64 / 8);
265                 }
266                 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
267                 memcpy(s.wordv + 2 * 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
268                 s.length_W = 3 * 64 / BIGINT_WORD_SIZE;
269                 bigint_adjust(&s);
270
271                 /*
272                  * Add s (alias S2) to a (alias T + S1)
273                  */
274                 printf_P(PSTR("s3: "));
275                 bigint_print_hex(&s);
276                 putchar('\n');
277
278                 bigint_add_u(a, a, &s);
279             }
280         }
281
282     }
283     printf_P(PSTR("pre-result: "));
284     bigint_print_hex(a);
285     putchar('\n');
286     while(bigint_cmp_u(a, &nist_curve_p192_p) >= 0){
287         printf_P(PSTR("DBG: Line: %d\n"),  __LINE__);
288         bigint_sub_u(a, a, &nist_curve_p192_p);
289     }
290     printf_P(PSTR("result: "));
291     bigint_print_hex(a);
292     putchar('\n');
293
294     return 0;
295 }
296
297