3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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_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
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
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
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
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 };
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 };
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 };
88 bigint_t nist_curve_p192_p = {
89 .length_W = 192 / BIGINT_WORD_SIZE,
90 .wordv = nist_curve_p192_p_w,
95 bigint_t nist_curve_p192_n = {
96 .length_W = 192 / BIGINT_WORD_SIZE,
97 .wordv = nist_curve_p192_n_w,
101 bigint_t nist_curve_p192_b = {
102 .length_W = 192 / BIGINT_WORD_SIZE,
103 .wordv = nist_curve_p192_b_w,
107 ecc_combi_point_t nist_curve_p192_basepoint = {
110 .length_W = 192 / BIGINT_WORD_SIZE,
111 .wordv = nist_curve_p192_gx_w,
115 .length_W = 192 / BIGINT_WORD_SIZE,
116 .wordv = nist_curve_p192_gy_w,
121 .wordv = nist_curve_p192_z1_w,
126 .wordv = nist_curve_p192_z2_w,
131 .wordv = nist_curve_p192_z3_w,
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
146 * A = ( A5 || A4 || A3 || A2 || A1 || A0 ) ; An is 64-bit
147 * A mod p = B = T + S1 + S2 + S3 mod p
149 * T = ( A2 || A1 || A0 )
150 * S1 = ( 0 || A3 || A3 )
151 * S2 = ( A4 || A4 || 0 )
152 * S3 = ( A5 || A5 || A5 )
156 int bigint_reduce_p192(bigint_t *a){
158 bigint_word_t s_w[3 * 64 / BIGINT_WORD_SIZE];
162 if(a->info & BIGINT_NEG_MASK){
163 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
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);
172 o_length = a->length_W;
174 if(o_length < 192 / BIGINT_WORD_SIZE){
178 if(o_length > 192 * 2 / BIGINT_WORD_SIZE){
179 bigint_reduce(a, &nist_curve_p192_p);
182 if(o_length > 192 / BIGINT_WORD_SIZE){
184 s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
187 printf_P(PSTR("DBG: Line: %d\n"), __LINE__);
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);
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);
201 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
205 * Set A3 to zero so we can use a as T
207 memset(a->wordv + 3 * 64 / BIGINT_WORD_SIZE, 0, sizeof(bigint_word_t));
208 a->length_W = 3 * 64 / BIGINT_WORD_SIZE;
212 * Add s (alias S1) to a (alias T)
215 printf_P(PSTR("T: "));
219 printf_P(PSTR("s1: "));
220 bigint_print_hex(&s);
222 bigint_add_u(a, a, &s);
225 if(o_length > 4 * 64 / BIGINT_WORD_SIZE){
226 s.length_W = 2 * 64 / BIGINT_WORD_SIZE;
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);
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);
240 memcpy(s.wordv + 64 / BIGINT_WORD_SIZE, s.wordv, 64 / 8);
244 * Add s (alias S2) to a (alias T + S1)
246 printf_P(PSTR("s2: "));
247 bigint_print_hex(&s);
249 bigint_add_scale_u(a, &s, 8);
252 if(o_length > 5 * 64 / BIGINT_WORD_SIZE){
254 * copy A5 three times in s
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);
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);
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;
272 * Add s (alias S2) to a (alias T + S1)
274 printf_P(PSTR("s3: "));
275 bigint_print_hex(&s);
278 bigint_add_u(a, a, &s);
283 printf_P(PSTR("pre-result: "));
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);
290 printf_P(PSTR("result: "));