3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2012 Daniel Otte (daniel.otte@rub.de)
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.
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.
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/>.
27 #include "nist_p192.h"
30 #include <avr/pgmspace.h>
31 #include "bigint_io.h"
34 #define bigint_print_hex(a)
39 * p = 6277101735386680763835789423207666416083908700390324961279
40 * = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF
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
49 uint8_t nist_curve_p192_b_w[] = {
50 0xb1, 0xb9, 0x46, 0xc1, 0xec, 0xde, 0xb8, 0xfe,
51 0x49, 0x30, 0x24, 0x72, 0xab, 0xe9, 0xa7, 0x0f,
52 0xe7, 0x80, 0x9c, 0xe5, 0x19, 0x05, 0x21, 0x64
55 uint8_t nist_curve_p192_gx_w[] = {
56 0x12, 0x10, 0xff, 0x82, 0xfd, 0x0a, 0xff, 0xf4,
57 0x00, 0x88, 0xa1, 0x43, 0xeb, 0x20, 0xbf, 0x7c,
58 0xf6, 0x90, 0x30, 0xb0, 0x0e, 0xa8, 0x8d, 0x18
61 uint8_t nist_curve_p192_gy_w[] = {
62 0x11, 0x48, 0x79, 0x1e, 0xa1, 0x77, 0xf9, 0x73,
63 0xd5, 0xcd, 0x24, 0x6b, 0xed, 0x11, 0x10, 0x63,
64 0x78, 0xda, 0xc8, 0xff, 0x95, 0x2b, 0x19, 0x07
67 uint8_t nist_curve_p192_z1_w[192 / BIGINT_WORD_SIZE] = {
68 1, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0 };
72 uint8_t nist_curve_p192_z2_w[192 / BIGINT_WORD_SIZE] = {
73 1, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0 };
77 uint8_t nist_curve_p192_z3_w[192 / BIGINT_WORD_SIZE] = {
78 1, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0 };
82 bigint_t nist_curve_p192_p = {
83 .length_W = 192 / BIGINT_WORD_SIZE,
84 .wordv = nist_curve_p192_p_w,
88 bigint_t nist_curve_p192_b = {
89 .length_W = 192 / BIGINT_WORD_SIZE,
90 .wordv = nist_curve_p192_b_w,
94 ecc_combi_point_t nist_curve_p192_basepoint = {
97 .length_W = 192 / BIGINT_WORD_SIZE,
98 .wordv = nist_curve_p192_gx_w,
102 .length_W = 192 / BIGINT_WORD_SIZE,
103 .wordv = nist_curve_p192_gy_w,
108 .wordv = nist_curve_p192_z1_w,
113 .wordv = nist_curve_p192_z2_w,
118 .wordv = nist_curve_p192_z3_w,
124 ecc_curve_sp_t nist_curve_p192 = {
125 .b = &nist_curve_p192_b,
126 .p = &nist_curve_p192_p,
127 .reduce_p = bigint_reduce_p192
132 * A = ( A5 || A4 || A3 || A2 || A1 || A0 ) ; An if 64-bit
133 * A mod p = B = T + S1 + S2 + S3 mod p
135 * T = ( A2 || A1 || A0 )
137 * S2 = ( A4 || A4 || 0 )
138 * S3 = ( A5 || A5 || A5 )
142 int bigint_reduce_p192(bigint_t *a){
144 bigint_word_t s_w[3 * 64 / BIGINT_WORD_SIZE];
148 if(a->info & BIGINT_NEG_MASK){
149 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
151 a->info &= ~BIGINT_NEG_MASK;
152 bigint_reduce_p192(a);
153 a->info |= BIGINT_NEG_MASK;
154 bigint_add_s(a, a, &nist_curve_p192_p);
158 o_length = a->length_W;
160 if(o_length < 192 / BIGINT_WORD_SIZE){
164 if(o_length > 192 * 2 / BIGINT_WORD_SIZE){
165 bigint_reduce(a, &nist_curve_p192_p);
168 if(o_length > 192 / BIGINT_WORD_SIZE){
170 s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
173 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
177 if(o_length >= 4 * 64 / BIGINT_WORD_SIZE){
178 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
179 memcpy(s.wordv, a->wordv + 3 * 64 / BIGINT_WORD_SIZE, 64 / 8);
181 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
182 memset(s.wordv, 0, 8);
183 memcpy(s.wordv, a->wordv + 3 * 64 / BIGINT_WORD_SIZE,
184 o_length * BIGINT_WORD_SIZE / 8 - 3 * 64 / 8);
187 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
191 * Set A3 to zero so we can use a as T
193 memset(a->wordv + 3 * 64 / BIGINT_WORD_SIZE, 0, sizeof(bigint_word_t));
194 a->length_W = 3 * 64 / BIGINT_WORD_SIZE;
198 * Add s (alias S1) to a (alias T)
201 printf_P(PSTR("T: "));
205 printf_P(PSTR("s1: "));
206 bigint_print_hex(&s);
208 bigint_add_u(a, a, &s);
211 if(o_length > 4 * 64 / BIGINT_WORD_SIZE){
212 s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
216 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
217 if(o_length >= 5 * 64 / BIGINT_WORD_SIZE){
218 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
219 memcpy(s.wordv, a->wordv + 4 * 64 / BIGINT_WORD_SIZE, 64 / 8);
221 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
222 memset(s.wordv, 0, 8);
223 memcpy(s.wordv, a->wordv + 4 * 64 / BIGINT_WORD_SIZE,
224 o_length * BIGINT_WORD_SIZE / 8 - 4 * 64 / 8);
226 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
230 * Add s (alias S2) to a (alias T + S1)
232 printf_P(PSTR("s2: "));
233 bigint_print_hex(&s);
235 bigint_add_scale_u(a, &s, 8);
238 if(o_length > 5 * 64 / BIGINT_WORD_SIZE){
240 * copy A5 three times in s
242 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
243 if(o_length == 6 * 64 / BIGINT_WORD_SIZE){
244 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
245 memcpy(s.wordv, a->wordv + 5 * 64 / BIGINT_WORD_SIZE, 64 / 8);
247 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
248 memset(s.wordv, 0, 8);
249 memcpy(s.wordv, a->wordv + 5 * 64 / BIGINT_WORD_SIZE,
250 o_length * BIGINT_WORD_SIZE / 8 - 5 * 64 / 8);
252 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
253 memcpy(s.wordv + 2 * 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
254 s.length_W = 3 * 64 / BIGINT_WORD_SIZE;
258 * Add s (alias S2) to a (alias T + S1)
260 printf_P(PSTR("s3: "));
261 bigint_print_hex(&s);
264 bigint_add_u(a, a, &s);
269 printf_P(PSTR("pre-result: "));
272 while(bigint_cmp_u(a, &nist_curve_p192_p) >= 0){
273 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
274 bigint_sub_u(a, a, &nist_curve_p192_p);
276 printf_P(PSTR("result: "));