Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 00020 #ifndef __ALGORITHMS_CRYPTO_ECCFP_H_ 00021 #define __ALGORITHMS_CRYPTO_ECCFP_H_ 00022 00023 #include "algorithms/crypto/pmp.h" 00024 00025 namespace wiselib 00026 { 00027 00028 //struct that contains the parameters for ECC operations 00029 Params param; 00039 class ECCFP 00040 { 00041 public: 00042 00043 /* ------------- Point functions ------------ */ 00044 00045 // set P0's x and y to zero 00046 void p_clear(Point * P0) 00047 { 00048 pmp.AssignZero(P0->x, NUMWORDS); 00049 pmp.AssignZero(P0->y, NUMWORDS); 00050 } 00051 00052 // set P0 = P1 00053 void p_copy(Point * P0, Point * P1) 00054 { 00055 pmp.Assign(P0->x, P1->x, NUMWORDS); 00056 pmp.Assign(P0->y, P1->y, NUMWORDS); 00057 } 00058 00059 // test whether x and y of P0 is all zero 00060 bool p_iszero(Point * P0) 00061 { 00062 bool result = FALSE; 00063 00064 if (pmp.Zero(P0->x, NUMWORDS)) 00065 if (pmp.Zero(P0->y, NUMWORDS)) 00066 result = TRUE; 00067 return result; 00068 } 00069 00070 // test whether points P1 and P2 are equal 00071 bool p_equal(Point * P1, Point * P2) 00072 { 00073 if (pmp.Equal(P1->x, P2->x, NUMWORDS)) 00074 if (pmp.Equal(P1->y, P2->y, NUMWORDS)) 00075 return TRUE; 00076 return FALSE; 00077 } 00078 00079 // test whether Z is one 00080 bool Z_is_one(NN_DIGIT *Z) 00081 { 00082 uint8_t i; 00083 00084 for (i = 1; i < NUMWORDS; i++) 00085 if (Z[i]) 00086 return FALSE; 00087 if (Z[0] == 1) 00088 return TRUE; 00089 00090 return FALSE; 00091 } 00092 00093 //convert a point to octet 00094 int8_t point2octet(uint8_t *octet, NN_UINT octet_len, Point *P, bool compress) 00095 { 00096 if (compress){ 00097 if(octet_len < KEYDIGITS*NN_DIGIT_LEN+1){ 00098 //too small octet 00099 return -1; 00100 }else{ 00101 //compressed point representation 00102 if((1 & P->y[0]) == 0){ 00103 octet[0] = 0x02; 00104 }else{ 00105 octet[0] = 0x03; 00106 } 00107 pmp.Encode(octet+1, KEYDIGITS*NN_DIGIT_LEN, P->x, KEYDIGITS); 00108 return KEYDIGITS*NN_DIGIT_LEN+1; 00109 } 00110 } 00111 else 00112 {//non compressed 00113 if(octet_len < 2*KEYDIGITS*NN_DIGIT_LEN+1) 00114 { 00115 return -1; 00116 } 00117 else 00118 { 00119 octet[0] = 0x04; 00120 pmp.Encode(octet+1, KEYDIGITS*NN_DIGIT_LEN, P->x, KEYDIGITS); 00121 pmp.Encode(octet+1+KEYDIGITS*NN_DIGIT_LEN, KEYDIGITS*NN_DIGIT_LEN, P->y, KEYDIGITS); 00122 return 2*KEYDIGITS*NN_DIGIT_LEN+1; 00123 } 00124 } 00125 } 00126 00127 //convert an octet to point 00128 int8_t octet2point(Point *P, uint8_t *octet, int8_t octet_len) 00129 { 00130 NN_DIGIT alpha[NUMWORDS], tmp[NUMWORDS]; 00131 00132 if (octet[0] == 0){//infinity 00133 pmp.AssignZero(P->x, NUMWORDS); 00134 pmp.AssignZero(P->y, NUMWORDS); 00135 }else if (octet[0] == 4){//non compressed 00136 pmp.Decode(P->x, NUMWORDS, octet+1, KEYDIGITS*NN_DIGIT_LEN); 00137 pmp.Decode(P->y, NUMWORDS, octet+1+KEYDIGITS*NN_DIGIT_LEN, KEYDIGITS*NN_DIGIT_LEN); 00138 return 2*KEYDIGITS*NN_DIGIT_LEN+1; 00139 }else if (octet[0] == 2 || octet[0] == 3){//compressed form 00140 pmp.Decode(P->x, NUMWORDS, octet+1, KEYDIGITS*NN_DIGIT_LEN); 00141 //compute y 00142 pmp.ModSqrOpt(alpha, P->x, param.p, param.omega, NUMWORDS); 00143 pmp.ModMultOpt(alpha, alpha, P->x, param.p, param.omega, NUMWORDS); 00144 pmp.ModMultOpt(tmp, param.E.a, P->x, param.p, param.omega, NUMWORDS); 00145 pmp.ModAdd(tmp, tmp, alpha, param.p, NUMWORDS); 00146 pmp.ModAdd(tmp, tmp, param.E.b, param.p, NUMWORDS); 00147 pmp.ModSqrRootOpt(P->y, tmp, param.p, NUMWORDS, param.omega); 00148 if(octet[0] == 3){ 00149 pmp.ModSub(P->y, param.p, P->y, param.p, NUMWORDS); 00150 } 00151 return KEYDIGITS*NN_DIGIT_LEN+1; 00152 } 00153 return -1; 00154 } 00155 00156 //check if point is on elliptic curve 00157 int8_t check_point(Point *P) 00158 { 00159 NN_DIGIT tmp1[NUMWORDS], tmp2[NUMWORDS]; 00160 00161 if (pmp.Zero(P->x, NUMWORDS)) 00162 return -1; 00163 if (pmp.Cmp(P->x, param.p, NUMWORDS) >= 0) 00164 return -1; 00165 if (pmp.Zero(P->y, NUMWORDS)) 00166 return -1; 00167 if (pmp.Cmp(P->y, param.p, NUMWORDS) >= 0) 00168 return -1; 00169 00170 memset(tmp1, 0, NUMWORDS*NN_DIGIT_LEN); 00171 memset(tmp2, 0, NUMWORDS*NN_DIGIT_LEN); 00172 pmp.ModSqrOpt(tmp2, P->x, param.p, param.omega, NUMWORDS); 00173 pmp.ModMultOpt(tmp2, tmp2, P->x, param.p, param.omega, NUMWORDS); 00174 pmp.ModMultOpt(tmp1, P->x, param.E.a, param.p, param.omega, NUMWORDS); 00175 pmp.ModAdd(tmp2, tmp1, tmp2, param.p, NUMWORDS); 00176 pmp.ModAdd(tmp2, tmp2, param.E.b, param.p, NUMWORDS); 00177 pmp.ModSqrOpt(tmp1, P->y, param.p, param.omega, NUMWORDS); 00178 if(pmp.Cmp(tmp1, tmp2, NUMWORDS) != 0) 00179 return -2; 00180 00181 return 1; 00182 } 00183 00184 /* ------------------------ Elliptic Curve functions ----------------- */ 00185 00186 //P0 = 2*P1, P0 and P1 can be same point 00187 void c_dbl_affine(Point *P0, Point *P1) 00188 { 00189 NN_DIGIT t1[NUMWORDS], t2[NUMWORDS], slope[NUMWORDS]; 00190 00191 if(pmp.Zero(P1->y, NUMWORDS)) 00192 return; 00193 pmp.ModSqrOpt(t1, P1->x, param.p, param.omega, NUMWORDS); //x1^2 00194 pmp.LShift(t2, t1, 1, NUMWORDS); 00195 if(pmp.Cmp(t2, param.p, NUMWORDS) >= 0) 00196 pmp.Sub(t2, t2, param.p, NUMWORDS); //2*x1^2 00197 pmp.ModAdd(t2, t2, t1, param.p, NUMWORDS); //3*x1^2 00198 pmp.ModAdd(t1, t2, param.E.a, param.p, NUMWORDS); //t1 = 3*x1^2+a 00199 pmp.LShift(t2, P1->y, 1, NUMWORDS); 00200 if(pmp.Cmp(t2, param.p, NUMWORDS) >= 0) 00201 pmp.Sub(t2, t2, param.p, NUMWORDS); //t2 = 2*y1 00202 pmp.ModDiv(slope, t1, t2, param.p, NUMWORDS); //(3x1^2+a)/(2y1) 00203 pmp.ModSqrOpt(t1, slope, param.p, param.omega, NUMWORDS); //[(3x1^2+a)/(2y1)]^2 00204 pmp.LShift(t2, P1->x, 1, NUMWORDS); 00205 if(pmp.Cmp(t2, param.p, NUMWORDS) >= 0) 00206 pmp.Sub(t2, t2, param.p, NUMWORDS); //2*x1 00207 pmp.ModSub(t1, t1, t2, param.p, NUMWORDS); //t1 = P0.x = [(3x1^2+a)/(2y1)]^2 - 2x1 00208 pmp.ModSub(t2, P1->x, t1, param.p, NUMWORDS); //x1-P0.x 00209 pmp.ModMultOpt(t2, slope, t2, param.p, param.omega, NUMWORDS); //[(3x1^2+a)/(2y1)](x1-P0.x) 00210 pmp.ModSub(P0->y, t2, P1->y, param.p, NUMWORDS); //[(3x1^2+a)/(2y1)](x1-P0.x)-y1 00211 pmp.Assign(P0->x, t1, NUMWORDS); 00212 } 00213 00214 //addition on elliptic curve 00215 //P0 = P1 + P2, P0 and P1 can be same point 00216 void c_add_affine(Point *P0, Point *P1, Point *P2) 00217 { 00218 NN_DIGIT t1[NUMWORDS], t2[NUMWORDS], slope[NUMWORDS]; 00219 00220 if (p_equal(P1, P2)){ 00221 c_dbl_affine(P0, P1); 00222 return; 00223 } 00224 if (p_iszero(P1)){ 00225 p_copy(P0, P2); 00226 return; 00227 }else if(p_iszero(P2)){ 00228 p_copy(P0, P1); 00229 return; 00230 } 00231 pmp.ModSub(t1, P2->y, P1->y, param.p, NUMWORDS); //y2-y1 00232 pmp.ModSub(t2, P2->x, P1->x, param.p, NUMWORDS); //x2-x1 00233 pmp.ModDiv(slope, t1, t2, param.p, NUMWORDS); //(y2-y1)/(x2-x1) 00234 pmp.ModSqrOpt(t1, slope, param.p, param.omega, NUMWORDS); //[(y2-y1)/(x2-x1)]^2 00235 pmp.ModSub(t2, t1, P1->x, param.p, NUMWORDS); 00236 pmp.ModSub(t1, t2, P2->x, param.p, NUMWORDS); //P0.x = [(y2-y1)/(x2-x1)]^2 - x1 - x2 00237 pmp.ModSub(t2, P1->x, t1, param.p, NUMWORDS); //x1-P0.x 00238 pmp.ModMultOpt(t2, t2, slope, param.p, param.omega, NUMWORDS); //(x1-P0.x)(y2-y1)/(x2-x1) 00239 pmp.ModSub(P0->y, t2, P1->y, param.p, NUMWORDS); //P0.y=(x1-P0.x)(y2-y1)/(x2-x1)-y1 00240 pmp.Assign(P0->x, t1, NUMWORDS); 00241 } 00242 00243 //scalar multiplication on elliptic curve 00244 //P0= n * P1 00245 void c_mul(Point * P0, Point * P1, NN_DIGIT * n) 00246 { 00247 int16 i, tmp; 00248 00249 // clear point 00250 p_clear(P0); 00251 tmp = pmp.Bits(n, NUMWORDS); 00252 00253 for (i = tmp-1; i >= 0; i--){ 00254 c_dbl_affine(P0, P0); 00255 if (pmp.b_testbit(n, i)){ 00256 c_add_affine(P0, P0, P1); 00257 } 00258 } 00259 } 00260 00261 //generate a private key using a random seed 00262 void gen_private_key(NN_DIGIT *PrivateKey, uint8_t b) 00263 { 00264 NN_UINT order_digit_len, order_bit_len; 00265 bool done = FALSE; 00266 uint8_t ri; 00267 NN_DIGIT digit_mask; 00268 00269 order_bit_len = pmp.Bits(param.r, NUMWORDS); 00270 order_digit_len = pmp.Digits(param.r, NUMWORDS); 00271 uint16_t d=5167; 00272 00273 while(!done) 00274 { 00275 00276 for (ri=0; ri<order_digit_len; ri++) 00277 { 00278 d = (d*ri) + (234 - b); 00279 PrivateKey[ri] = ((NN_DIGIT)d << 16)^((NN_DIGIT)d+1); 00280 } 00281 00282 for (ri=order_digit_len; ri<NUMWORDS; ri++) 00283 { 00284 PrivateKey[ri] = 0; 00285 } 00286 00287 if (order_bit_len % NN_DIGIT_BITS != 0) 00288 { 00289 digit_mask = MAX_NN_DIGIT >> (NN_DIGIT_BITS - order_bit_len % NN_DIGIT_BITS); 00290 PrivateKey[order_digit_len - 1] = PrivateKey[order_digit_len - 1] & digit_mask; 00291 } 00292 pmp.ModSmall(PrivateKey, param.r, NUMWORDS); 00293 00294 if (pmp.Zero(PrivateKey, NUMWORDS) != 1) 00295 done = TRUE; 00296 } 00297 } 00298 00299 //generate public key by multiplying private key with base point G 00300 // PublicKey = PrivateKey * params.G 00301 void gen_public_key(Point *PublicKey, NN_DIGIT *PrivateKey) 00302 { 00303 c_mul(PublicKey, &(param.G), PrivateKey); 00304 } 00305 00306 //initialize an 128-bit elliptic curve over F_{p} 00307 void init128() 00308 { 00309 00310 #ifdef EIGHT_BIT_PROCESSOR 00311 //init parameters 00312 //prime 00313 param.p[16] = 0x00; 00314 param.p[15] = 0xFF; 00315 param.p[14] = 0xFF; 00316 param.p[13] = 0xFF; 00317 param.p[12] = 0xFD; 00318 param.p[11] = 0xFF; 00319 param.p[10] = 0xFF; 00320 param.p[9] = 0xFF; 00321 param.p[8] = 0xFF; 00322 param.p[7] = 0xFF; 00323 param.p[6] = 0xFF; 00324 param.p[5] = 0xFF; 00325 param.p[4] = 0xFF; 00326 param.p[3] = 0xFF; 00327 param.p[2] = 0xFF; 00328 param.p[1] = 0xFF; 00329 param.p[0] = 0xFF; 00330 00331 memset(param.omega, 0, NUMWORDS*NN_DIGIT_LEN); 00332 param.omega[0] = 0x01; 00333 param.omega[12] = 0x02; 00334 //cure that will be used 00335 //a 00336 param.E.a[16] = 0x00; 00337 param.E.a[15] = 0xFF; 00338 param.E.a[14] = 0xFF; 00339 param.E.a[13] = 0xFF; 00340 param.E.a[12] = 0xFD; 00341 param.E.a[11] = 0xFF; 00342 param.E.a[10] = 0xFF; 00343 param.E.a[9] = 0xFF; 00344 param.E.a[8] = 0xFF; 00345 param.E.a[7] = 0xFF; 00346 param.E.a[6] = 0xFF; 00347 param.E.a[5] = 0xFF; 00348 param.E.a[4] = 0xFF; 00349 param.E.a[3] = 0xFF; 00350 param.E.a[2] = 0xFF; 00351 param.E.a[1] = 0xFF; 00352 param.E.a[0] = 0xFC; 00353 00354 param.E.a_minus3 = TRUE; 00355 param.E.a_zero = FALSE; 00356 00357 //b 00358 param.E.b[16] = 0x00; 00359 param.E.b[15] = 0xE8; 00360 param.E.b[14] = 0x75; 00361 param.E.b[13] = 0x79; 00362 param.E.b[12] = 0xC1; 00363 param.E.b[11] = 0x10; 00364 param.E.b[10] = 0x79; 00365 param.E.b[9] = 0xF4; 00366 param.E.b[8] = 0x3D; 00367 param.E.b[7] = 0xD8; 00368 param.E.b[6] = 0x24; 00369 param.E.b[5] = 0x99; 00370 param.E.b[4] = 0x3C; 00371 param.E.b[3] = 0x2C; 00372 param.E.b[2] = 0xEE; 00373 param.E.b[1] = 0x5E; 00374 param.E.b[0] = 0xD3; 00375 00376 //base point 00377 param.G.x[16] = 0x00; 00378 param.G.x[15] = 0x16; 00379 param.G.x[14] = 0x1F; 00380 param.G.x[13] = 0xF7; 00381 param.G.x[12] = 0x52; 00382 param.G.x[11] = 0x8B; 00383 param.G.x[10] = 0x89; 00384 param.G.x[9] = 0x9B; 00385 param.G.x[8] = 0x2D; 00386 param.G.x[7] = 0x0C; 00387 param.G.x[6] = 0x28; 00388 param.G.x[5] = 0x60; 00389 param.G.x[4] = 0x7C; 00390 param.G.x[3] = 0xA5; 00391 param.G.x[2] = 0x2C; 00392 param.G.x[1] = 0x5B; 00393 param.G.x[0] = 0x86; 00394 00395 param.G.y[16] = 0x00; 00396 param.G.y[15] = 0xCF; 00397 param.G.y[14] = 0x5A; 00398 param.G.y[13] = 0xC8; 00399 param.G.y[12] = 0x39; 00400 param.G.y[11] = 0x5B; 00401 param.G.y[10] = 0xAF; 00402 param.G.y[9] = 0xEB; 00403 param.G.y[8] = 0x13; 00404 param.G.y[7] = 0xC0; 00405 param.G.y[6] = 0x2D; 00406 param.G.y[5] = 0xA2; 00407 param.G.y[4] = 0x92; 00408 param.G.y[3] = 0xDD; 00409 param.G.y[2] = 0xED; 00410 param.G.y[1] = 0x7A; 00411 param.G.y[0] = 0x83; 00412 00413 //prime divide the number of points 00414 param.r[16] = 0x00; 00415 param.r[15] = 0xFF; 00416 param.r[14] = 0xFF; 00417 param.r[13] = 0xFF; 00418 param.r[12] = 0xFE; 00419 param.r[11] = 0x0; 00420 param.r[10] = 0x0; 00421 param.r[9] = 0x0; 00422 param.r[8] = 0x0; 00423 param.r[7] = 0x75; 00424 param.r[6] = 0xA3; 00425 param.r[5] = 0x0D; 00426 param.r[4] = 0x1B; 00427 param.r[3] = 0x90; 00428 param.r[2] = 0x38; 00429 param.r[1] = 0xA1; 00430 param.r[0] = 0x15; 00431 00432 #endif 00433 00434 #ifdef SIXTEEN_BIT_PROCESSOR 00435 //init parameters 00436 //prime 00437 param.p[8] = 0x0000; 00438 param.p[7] = 0xFFFF; 00439 param.p[6] = 0xFFFD; 00440 param.p[5] = 0xFFFF; 00441 param.p[4] = 0xFFFF; 00442 param.p[3] = 0xFFFF; 00443 param.p[2] = 0xFFFF; 00444 param.p[1] = 0xFFFF; 00445 param.p[0] = 0xFFFF; 00446 00447 memset(param.omega, 0, NUMWORDS*NN_DIGIT_LEN); 00448 param.omega[0] = 0x0001; 00449 param.omega[6] = 0x0002; 00450 //cure that will be used 00451 //a 00452 param.E.a[8] = 0x0000; 00453 param.E.a[7] = 0xFFFF; 00454 param.E.a[6] = 0xFFFD; 00455 param.E.a[5] = 0xFFFF; 00456 param.E.a[4] = 0xFFFF; 00457 param.E.a[3] = 0xFFFF; 00458 param.E.a[2] = 0xFFFF; 00459 param.E.a[1] = 0xFFFF; 00460 param.E.a[0] = 0xFFFC; 00461 00462 param.E.a_minus3 = TRUE; 00463 param.E.a_zero = FALSE; 00464 00465 //b 00466 param.E.b[8] = 0x0000; 00467 param.E.b[7] = 0xE875; 00468 param.E.b[6] = 0x79C1; 00469 param.E.b[5] = 0x1079; 00470 param.E.b[4] = 0xF43D; 00471 param.E.b[3] = 0xD824; 00472 param.E.b[2] = 0x993C; 00473 param.E.b[1] = 0x2CEE; 00474 param.E.b[0] = 0x5ED3; 00475 00476 //base point 00477 param.G.x[8] = 0x0000; 00478 param.G.x[7] = 0x161F; 00479 param.G.x[6] = 0xF752; 00480 param.G.x[5] = 0x8B89; 00481 param.G.x[4] = 0x9B2D; 00482 param.G.x[3] = 0x0C28; 00483 param.G.x[2] = 0x607C; 00484 param.G.x[1] = 0xA52C; 00485 param.G.x[0] = 0x5B86; 00486 00487 param.G.y[8] = 0x0000; 00488 param.G.y[7] = 0xCF5A; 00489 param.G.y[6] = 0xC839; 00490 param.G.y[5] = 0x5BAF; 00491 param.G.y[4] = 0xEB13; 00492 param.G.y[3] = 0xC02D; 00493 param.G.y[2] = 0xA292; 00494 param.G.y[1] = 0xDDED; 00495 param.G.y[0] = 0x7A83; 00496 00497 //prime divide the number of points 00498 param.r[8] = 0x0000; 00499 param.r[7] = 0xFFFF; 00500 param.r[6] = 0xFFFE; 00501 param.r[5] = 0x0000; 00502 param.r[4] = 0x0000; 00503 param.r[3] = 0x75A3; 00504 param.r[2] = 0x0D1B; 00505 param.r[1] = 0x9038; 00506 param.r[0] = 0xA115; 00507 #endif 00508 00509 #ifdef THIRTYTWO_BIT_PROCESSOR 00510 //init parameters 00511 //prime 00512 param.p[4] = 0x00000000; 00513 param.p[3] = 0xFFFFFFFD; 00514 param.p[2] = 0xFFFFFFFF; 00515 param.p[1] = 0xFFFFFFFF; 00516 param.p[0] = 0xFFFFFFFF; 00517 00518 memset(param.omega, 0, NUMWORDS*NN_DIGIT_LEN); 00519 param.omega[0] = 0x00000001; 00520 param.omega[3] = 0x00000002; 00521 //cure that will be used 00522 //a 00523 param.E.a[4] = 0x00000000; 00524 param.E.a[3] = 0xFFFFFFFD; 00525 param.E.a[2] = 0xFFFFFFFF; 00526 param.E.a[1] = 0xFFFFFFFF; 00527 param.E.a[0] = 0xFFFFFFFC; 00528 00529 param.E.a_minus3 = TRUE; 00530 param.E.a_zero = FALSE; 00531 00532 //b 00533 param.E.b[4] = 0x00000000; 00534 param.E.b[3] = 0xE87579C1; 00535 param.E.b[2] = 0x1079F43D; 00536 param.E.b[1] = 0xD824993C; 00537 param.E.b[0] = 0x2CEE5ED3; 00538 00539 //base point 00540 param.G.x[4] = 0x00000000; 00541 param.G.x[3] = 0x161FF752; 00542 param.G.x[2] = 0x8B899B2D; 00543 param.G.x[1] = 0x0C28607C; 00544 param.G.x[0] = 0xA52C5B86; 00545 00546 param.G.y[4] = 0x00000000; 00547 param.G.y[3] = 0xCF5AC839; 00548 param.G.y[2] = 0x5BAFEB13; 00549 param.G.y[1] = 0xC02DA292; 00550 param.G.y[0] = 0xDDED7A83; 00551 00552 //prime divide the number of points 00553 param.r[4] = 0x00000000; 00554 param.r[3] = 0xFFFFFFFE; 00555 param.r[2] = 0x00000000; 00556 param.r[1] = 0x75A30D1B; 00557 param.r[0] = 0x9038A115; 00558 #endif 00559 } 00560 00561 //initialize an 160-bit elliptic curve over F_{p} 00562 void init160() 00563 { 00564 00565 #ifdef EIGHT_BIT_PROCESSOR 00566 //init parameters 00567 //prime 00568 param.p[20] = 0x00; 00569 param.p[19] = 0xFF; 00570 param.p[18] = 0xFF; 00571 param.p[17] = 0xFF; 00572 param.p[16] = 0xFF; 00573 param.p[15] = 0xFF; 00574 param.p[14] = 0xFF; 00575 param.p[13] = 0xFF; 00576 param.p[12] = 0xFF; 00577 param.p[11] = 0xFF; 00578 param.p[10] = 0xFF; 00579 param.p[9] = 0xFF; 00580 param.p[8] = 0xFF; 00581 param.p[7] = 0xFF; 00582 param.p[6] = 0xFF; 00583 param.p[5] = 0xFF; 00584 param.p[4] = 0xFF; 00585 param.p[3] = 0x7F; 00586 param.p[2] = 0xFF; 00587 param.p[1] = 0xFF; 00588 param.p[0] = 0xFF; 00589 00590 memset(param.omega, 0, NUMWORDS); 00591 param.omega[0] = 0x01; 00592 param.omega[3] = 0x80; 00593 00594 //cure that will be used 00595 //a 00596 param.E.a[20] = 0x00; 00597 param.E.a[19] = 0xFF; 00598 param.E.a[18] = 0xFF; 00599 param.E.a[17] = 0xFF; 00600 param.E.a[16] = 0xFF; 00601 param.E.a[15] = 0xFF; 00602 param.E.a[14] = 0xFF; 00603 param.E.a[13] = 0xFF; 00604 param.E.a[12] = 0xFF; 00605 param.E.a[11] = 0xFF; 00606 param.E.a[10] = 0xFF; 00607 param.E.a[9] = 0xFF; 00608 param.E.a[8] = 0xFF; 00609 param.E.a[7] = 0xFF; 00610 param.E.a[6] = 0xFF; 00611 param.E.a[5] = 0xFF; 00612 param.E.a[4] = 0xFF; 00613 param.E.a[3] = 0x7F; 00614 param.E.a[2] = 0xFF; 00615 param.E.a[1] = 0xFF; 00616 param.E.a[0] = 0xFC; 00617 00618 param.E.a_minus3 = TRUE; 00619 param.E.a_zero = FALSE; 00620 00621 //b 00622 param.E.b[20] = 0x00; 00623 param.E.b[19] = 0x1C; 00624 param.E.b[18] = 0x97; 00625 param.E.b[17] = 0xBE; 00626 param.E.b[16] = 0xFC; 00627 param.E.b[15] = 0x54; 00628 param.E.b[14] = 0xBD; 00629 param.E.b[13] = 0x7A; 00630 param.E.b[12] = 0x8B; 00631 param.E.b[11] = 0x65; 00632 param.E.b[10] = 0xAC; 00633 param.E.b[9] = 0xF8; 00634 param.E.b[8] = 0x9F; 00635 param.E.b[7] = 0x81; 00636 param.E.b[6] = 0xD4; 00637 param.E.b[5] = 0xD4; 00638 param.E.b[4] = 0xAD; 00639 param.E.b[3] = 0xC5; 00640 param.E.b[2] = 0x65; 00641 param.E.b[1] = 0xFA; 00642 param.E.b[0] = 0x45; 00643 00644 //base point 00645 param.G.x[20] = 0x00; 00646 param.G.x[19] = 0x4A; 00647 param.G.x[18] = 0x96; 00648 param.G.x[17] = 0xB5; 00649 param.G.x[16] = 0x68; 00650 param.G.x[15] = 0x8E; 00651 param.G.x[14] = 0xF5; 00652 param.G.x[13] = 0x73; 00653 param.G.x[12] = 0x28; 00654 param.G.x[11] = 0x46; 00655 param.G.x[10] = 0x64; 00656 param.G.x[9] = 0x69; 00657 param.G.x[8] = 0x89; 00658 param.G.x[7] = 0x68; 00659 param.G.x[6] = 0xC3; 00660 param.G.x[5] = 0x8B; 00661 param.G.x[4] = 0xB9; 00662 param.G.x[3] = 0x13; 00663 param.G.x[2] = 0xCB; 00664 param.G.x[1] = 0xFC; 00665 param.G.x[0] = 0x82; 00666 00667 param.G.y[20] = 0x00; 00668 param.G.y[19] = 0x23; 00669 param.G.y[18] = 0xA6; 00670 param.G.y[17] = 0x28; 00671 param.G.y[16] = 0x55; 00672 param.G.y[15] = 0x31; 00673 param.G.y[14] = 0x68; 00674 param.G.y[13] = 0x94; 00675 param.G.y[12] = 0x7D; 00676 param.G.y[11] = 0x59; 00677 param.G.y[10] = 0xDC; 00678 param.G.y[9] = 0xC9; 00679 param.G.y[8] = 0x12; 00680 param.G.y[7] = 0x04; 00681 param.G.y[6] = 0x23; 00682 param.G.y[5] = 0x51; 00683 param.G.y[4] = 0x37; 00684 param.G.y[3] = 0x7A; 00685 param.G.y[2] = 0xC5; 00686 param.G.y[1] = 0xFB; 00687 param.G.y[0] = 0x32; 00688 00689 //prime divide the number of points 00690 param.r[20] = 0x01; 00691 param.r[19] = 0x0; 00692 param.r[18] = 0x0; 00693 param.r[17] = 0x0; 00694 param.r[16] = 0x0; 00695 param.r[15] = 0x0; 00696 param.r[14] = 0x0; 00697 param.r[13] = 0x0; 00698 param.r[12] = 0x0; 00699 param.r[11] = 0x0; 00700 param.r[10] = 0x01; 00701 param.r[9] = 0xF4; 00702 param.r[8] = 0xC8; 00703 param.r[7] = 0xF9; 00704 param.r[6] = 0x27; 00705 param.r[5] = 0xAE; 00706 param.r[4] = 0xD3; 00707 param.r[3] = 0xCA; 00708 param.r[2] = 0x75; 00709 param.r[1] = 0x22; 00710 param.r[0] = 0x57; 00711 00712 #endif 00713 00714 #ifdef SIXTEEN_BIT_PROCESSOR 00715 00716 //init parameters 00717 //prime 00718 param.p[9] = 0xFFFF; 00719 param.p[8] = 0xFFFF; 00720 param.p[7] = 0xFFFF; 00721 param.p[6] = 0xFFFF; 00722 param.p[5] = 0xFFFF; 00723 param.p[4] = 0xFFFF; 00724 param.p[3] = 0xFFFF; 00725 param.p[2] = 0xFFFF; 00726 param.p[1] = 0x7FFF; 00727 param.p[0] = 0xFFFF; 00728 00729 param.omega[0] = 0x0001; 00730 param.omega[1] = 0x8000; 00731 00732 //cure that will be used 00733 //a 00734 param.E.a[9] = 0xFFFF; 00735 param.E.a[8] = 0xFFFF; 00736 param.E.a[7] = 0xFFFF; 00737 param.E.a[6] = 0xFFFF; 00738 param.E.a[5] = 0xFFFF; 00739 param.E.a[4] = 0xFFFF; 00740 param.E.a[3] = 0xFFFF; 00741 param.E.a[2] = 0xFFFF; 00742 param.E.a[1] = 0x7FFF; 00743 param.E.a[0] = 0xFFFC; 00744 00745 param.E.a_minus3 = TRUE; 00746 param.E.a_zero = FALSE; 00747 00748 //b 00749 param.E.b[9] = 0x1C97; 00750 param.E.b[8] = 0xBEFC; 00751 param.E.b[7] = 0x54BD; 00752 param.E.b[6] = 0x7A8B; 00753 param.E.b[5] = 0x65AC; 00754 param.E.b[4] = 0xF89F; 00755 param.E.b[3] = 0x81D4; 00756 param.E.b[2] = 0xD4AD; 00757 param.E.b[1] = 0xC565; 00758 param.E.b[0] = 0xFA45; 00759 00760 //base point 00761 param.G.x[9] = 0x4A96; 00762 param.G.x[8] = 0xB568; 00763 param.G.x[7] = 0x8EF5; 00764 param.G.x[6] = 0x7328; 00765 param.G.x[5] = 0x4664; 00766 param.G.x[4] = 0x6989; 00767 param.G.x[3] = 0x68C3; 00768 param.G.x[2] = 0x8BB9; 00769 param.G.x[1] = 0x13CB; 00770 param.G.x[0] = 0xFC82; 00771 00772 param.G.y[9] = 0x23A6; 00773 param.G.y[8] = 0x2855; 00774 param.G.y[7] = 0x3168; 00775 param.G.y[6] = 0x947D; 00776 param.G.y[5] = 0x59DC; 00777 param.G.y[4] = 0xC912; 00778 param.G.y[3] = 0x0423; 00779 param.G.y[2] = 0x5137; 00780 param.G.y[1] = 0x7AC5; 00781 param.G.y[0] = 0xFB32; 00782 00783 //prime divide the number of points 00784 param.r[10] = 0x0001; 00785 param.r[9] = 0x0000; 00786 param.r[8] = 0x0000; 00787 param.r[7] = 0x0000; 00788 param.r[6] = 0x0000; 00789 param.r[5] = 0x0001; 00790 param.r[4] = 0xF4C8; 00791 param.r[3] = 0xF927; 00792 param.r[2] = 0xAED3; 00793 param.r[1] = 0xCA75; 00794 param.r[0] = 0x2257; 00795 #endif 00796 00797 #ifdef THIRTYTWO_BIT_PROCESSOR 00798 //init param.meters 00799 //prime 00800 param.p[5] = 0x00000000; 00801 param.p[4] = 0xFFFFFFFF; 00802 param.p[3] = 0xFFFFFFFF; 00803 param.p[2] = 0xFFFFFFFF; 00804 param.p[1] = 0xFFFFFFFF; 00805 param.p[0] = 0x7FFFFFFF; 00806 memset(param.omega, 0, NUMWORDS); 00807 param.omega[0] = 0x80000001; 00808 00809 //cure that will be used 00810 //a 00811 param.E.a[5] = 0x00000000; 00812 param.E.a[4] = 0xFFFFFFFF; 00813 param.E.a[3] = 0xFFFFFFFF; 00814 param.E.a[2] = 0xFFFFFFFF; 00815 param.E.a[1] = 0xFFFFFFFF; 00816 param.E.a[0] = 0x7FFFFFFC; 00817 00818 param.E.a_minus3 = TRUE; 00819 param.E.a_zero = FALSE; 00820 00821 //b 00822 param.E.b[5] = 0x00000000; 00823 param.E.b[4] = 0x1C97BEFC; 00824 param.E.b[3] = 0x54BD7A8B; 00825 param.E.b[2] = 0x65ACF89F; 00826 param.E.b[1] = 0x81D4D4AD; 00827 param.E.b[0] = 0xC565FA45; 00828 00829 //base point 00830 param.G.x[5] = 0x00000000; 00831 param.G.x[4] = 0x4A96B568; 00832 param.G.x[3] = 0x8EF57328; 00833 param.G.x[2] = 0x46646989; 00834 param.G.x[1] = 0x68C38BB9; 00835 param.G.x[0] = 0x13CBFC82; 00836 00837 param.G.y[5] = 0x00000000; 00838 param.G.y[4] = 0x23A62855; 00839 param.G.y[3] = 0x3168947D; 00840 param.G.y[2] = 0x59DCC912; 00841 param.G.y[1] = 0x04235137; 00842 param.G.y[0] = 0x7AC5FB32; 00843 00844 //prime divide the number of points 00845 param.r[5] = 0x00000001; 00846 param.r[4] = 0x00000000; 00847 param.r[3] = 0x00000000; 00848 param.r[2] = 0x0001F4C8; 00849 param.r[1] = 0xF927AED3; 00850 param.r[0] = 0xCA752257; 00851 #endif 00852 } 00853 00854 //initialize an 192-bit elliptic curve over F_{p} 00855 void init192() 00856 { 00857 00858 #ifdef EIGHT_BIT_PROCESSOR 00859 //init parameters 00860 //prime 00861 param.p[24] = 0x00; 00862 param.p[23] = 0xFF; 00863 param.p[22] = 0xFF; 00864 param.p[21] = 0xFF; 00865 param.p[20] = 0xFF; 00866 param.p[19] = 0xFF; 00867 param.p[18] = 0xFF; 00868 param.p[17] = 0xFF; 00869 param.p[16] = 0xFF; 00870 param.p[15] = 0xFF; 00871 param.p[14] = 0xFF; 00872 param.p[13] = 0xFF; 00873 param.p[12] = 0xFF; 00874 param.p[11] = 0xFF; 00875 param.p[10] = 0xFF; 00876 param.p[9] = 0xFF; 00877 param.p[8] = 0xFF; 00878 param.p[7] = 0xFF; 00879 param.p[6] = 0xFF; 00880 param.p[5] = 0xFF; 00881 param.p[4] = 0xFE; 00882 param.p[3] = 0xFF; 00883 param.p[2] = 0xFF; 00884 param.p[1] = 0xEE; 00885 param.p[0] = 0x37; 00886 00887 param.omega[0] = 0xC9; 00888 param.omega[1] = 0x11; 00889 param.omega[4] = 0x01; 00890 00891 //cure that will be used 00892 //a 00893 memset(param.E.a, 0, 25); 00894 00895 param.E.a_minus3 = FALSE; 00896 param.E.a_zero = TRUE; 00897 00898 //b 00899 memset(param.E.b, 0, 25); 00900 param.E.b[0] = 0x03; 00901 00902 //base point 00903 param.G.x[24] = 0x0; 00904 param.G.x[23] = 0xDB; 00905 param.G.x[22] = 0x4F; 00906 param.G.x[21] = 0xF1; 00907 param.G.x[20] = 0x0E; 00908 param.G.x[19] = 0xC0; 00909 param.G.x[18] = 0x57; 00910 param.G.x[17] = 0xE9; 00911 param.G.x[16] = 0xAE; 00912 param.G.x[15] = 0x26; 00913 param.G.x[14] = 0xB0; 00914 param.G.x[13] = 0x7D; 00915 param.G.x[12] = 0x02; 00916 param.G.x[11] = 0x80; 00917 param.G.x[10] = 0xB7; 00918 param.G.x[9] = 0xF4; 00919 param.G.x[8] = 0x34; 00920 param.G.x[7] = 0x1D; 00921 param.G.x[6] = 0xA5; 00922 param.G.x[5] = 0xD1; 00923 param.G.x[4] = 0xB1; 00924 param.G.x[3] = 0xEA; 00925 param.G.x[2] = 0xE0; 00926 param.G.x[1] = 0x6C; 00927 param.G.x[0] = 0x7D; 00928 00929 param.G.y[24] = 0x0; 00930 param.G.y[23] = 0x9B; 00931 param.G.y[22] = 0x2F; 00932 param.G.y[21] = 0x2F; 00933 param.G.y[20] = 0x6D; 00934 param.G.y[19] = 0x9C; 00935 param.G.y[18] = 0x56; 00936 param.G.y[17] = 0x28; 00937 param.G.y[16] = 0xA7; 00938 param.G.y[15] = 0x84; 00939 param.G.y[14] = 0x41; 00940 param.G.y[13] = 0x63; 00941 param.G.y[12] = 0xD0; 00942 param.G.y[11] = 0x15; 00943 param.G.y[10] = 0xBE; 00944 param.G.y[9] = 0x86; 00945 param.G.y[8] = 0x34; 00946 param.G.y[7] = 0x40; 00947 param.G.y[6] = 0x82; 00948 param.G.y[5] = 0xAA; 00949 param.G.y[4] = 0x88; 00950 param.G.y[3] = 0xD9; 00951 param.G.y[2] = 0x5E; 00952 param.G.y[1] = 0x2F; 00953 param.G.y[0] = 0x9D; 00954 00955 //prime divide the number of points 00956 param.r[24] = 0x00; 00957 param.r[23] = 0xFF; 00958 param.r[22] = 0xFF; 00959 param.r[21] = 0xFF; 00960 param.r[20] = 0xFF; 00961 param.r[19] = 0xFF; 00962 param.r[18] = 0xFF; 00963 param.r[17] = 0xFF; 00964 param.r[16] = 0xFF; 00965 param.r[15] = 0xFF; 00966 param.r[14] = 0xFF; 00967 param.r[13] = 0xFF; 00968 param.r[12] = 0xFE; 00969 param.r[11] = 0x26; 00970 param.r[10] = 0xF2; 00971 param.r[9] = 0xFC; 00972 param.r[8] = 0x17; 00973 param.r[7] = 0x0F; 00974 param.r[6] = 0x69; 00975 param.r[5] = 0x46; 00976 param.r[4] = 0x6A; 00977 param.r[3] = 0x74; 00978 param.r[2] = 0xDE; 00979 param.r[1] = 0xFD; 00980 param.r[0] = 0x8D; 00981 00982 #endif 00983 00984 #ifdef SIXTEEN_BIT_PROCESSOR 00985 //init parameters 00986 //prime 00987 memset(param.p, 0, NUMWORDS*NN_DIGIT_LEN); 00988 param.p[11] = 0xFFFF; 00989 param.p[10] = 0xFFFF; 00990 param.p[9] = 0xFFFF; 00991 param.p[8] = 0xFFFF; 00992 param.p[7] = 0xFFFF; 00993 param.p[6] = 0xFFFF; 00994 param.p[5] = 0xFFFF; 00995 param.p[4] = 0xFFFF; 00996 param.p[3] = 0xFFFF; 00997 param.p[2] = 0xFFFE; 00998 param.p[1] = 0xFFFF; 00999 param.p[0] = 0xEE37; 01000 01001 memset(param.omega, 0, NUMWORDS*NN_DIGIT_LEN); 01002 param.omega[0] = 0x11C9; 01003 param.omega[2] = 0x0001; 01004 //cure that will be used 01005 //a 01006 memset(param.E.a, 0, NUMWORDS*NN_DIGIT_LEN); 01007 param.E.a_minus3 = FALSE; 01008 param.E.a_zero = TRUE; 01009 01010 //b 01011 memset(param.E.b, 0, NUMWORDS*NN_DIGIT_LEN); 01012 param.E.b[0] = 0x0003; 01013 01014 //base point 01015 memset(param.G.x, 0, NUMWORDS*NN_DIGIT_LEN); 01016 param.G.x[11] = 0xDB4F; 01017 param.G.x[10] = 0xF10E; 01018 param.G.x[9] = 0xC057; 01019 param.G.x[8] = 0xE9AE; 01020 param.G.x[7] = 0x26B0; 01021 param.G.x[6] = 0x7D02; 01022 param.G.x[5] = 0x80B7; 01023 param.G.x[4] = 0xF434; 01024 param.G.x[3] = 0x1DA5; 01025 param.G.x[2] = 0xD1B1; 01026 param.G.x[1] = 0xEAE0; 01027 param.G.x[0] = 0x6C7D; 01028 01029 memset(param.G.y, 0, NUMWORDS*NN_DIGIT_LEN); 01030 param.G.y[11] = 0x9B2F; 01031 param.G.y[10] = 0x2F6D; 01032 param.G.y[9] = 0x9C56; 01033 param.G.y[8] = 0x28A7; 01034 param.G.y[7] = 0x8441; 01035 param.G.y[6] = 0x63D0; 01036 param.G.y[5] = 0x15BE; 01037 param.G.y[4] = 0x8634; 01038 param.G.y[3] = 0x4082; 01039 param.G.y[2] = 0xAA88; 01040 param.G.y[1] = 0xD95E; 01041 param.G.y[0] = 0x2F9D; 01042 01043 //prime divide the number of points 01044 memset(param.r, 0, NUMWORDS*NN_DIGIT_LEN); 01045 param.r[11] = 0xFFFF; 01046 param.r[10] = 0xFFFF; 01047 param.r[9] = 0xFFFF; 01048 param.r[8] = 0xFFFF; 01049 param.r[7] = 0xFFFF; 01050 param.r[6] = 0xFFFE; 01051 param.r[5] = 0x26F2; 01052 param.r[4] = 0xFC17; 01053 param.r[3] = 0x0F69; 01054 param.r[2] = 0x466A; 01055 param.r[1] = 0x74DE; 01056 param.r[0] = 0xFD8D; 01057 #endif 01058 01059 #ifdef THIRTYTWO_BIT_PROCESSOR 01060 //init parameters 01061 //prime 01062 memset(param.p, 0, NUMWORDS*NN_DIGIT_LEN); 01063 param.p[5] = 0xFFFFFFFF; 01064 param.p[4] = 0xFFFFFFFF; 01065 param.p[3] = 0xFFFFFFFF; 01066 param.p[2] = 0xFFFFFFFF; 01067 param.p[1] = 0xFFFFFFFE; 01068 param.p[0] = 0xFFFFEE37; 01069 01070 memset(param.omega, 0, NUMWORDS*NN_DIGIT_LEN); 01071 param.omega[0] = 0x000011C9; 01072 param.omega[1] = 0x00000001; 01073 //cure that will be used 01074 //a 01075 memset(param.E.a, 0, NUMWORDS*NN_DIGIT_LEN); 01076 param.E.a_minus3 = FALSE; 01077 param.E.a_zero = TRUE; 01078 01079 //b 01080 memset(param.E.b, 0, NUMWORDS*NN_DIGIT_LEN); 01081 param.E.b[0] = 0x00000003; 01082 01083 //base point 01084 memset(param.G.x, 0, NUMWORDS*NN_DIGIT_LEN); 01085 param.G.x[5] = 0xDB4FF10E; 01086 param.G.x[4] = 0xC057E9AE; 01087 param.G.x[3] = 0x26B07D02; 01088 param.G.x[2] = 0x80B7F434; 01089 param.G.x[1] = 0x1DA5D1B1; 01090 param.G.x[0] = 0xEAE06C7D; 01091 01092 memset(param.G.y, 0, NUMWORDS*NN_DIGIT_LEN); 01093 param.G.y[5] = 0x9B2F2F6D; 01094 param.G.y[4] = 0x9C5628A7; 01095 param.G.y[3] = 0x844163D0; 01096 param.G.y[2] = 0x15BE8634; 01097 param.G.y[1] = 0x4082AA88; 01098 param.G.y[0] = 0xD95E2F9D; 01099 01100 //prime divide the number of points 01101 memset(param.r, 0, NUMWORDS*NN_DIGIT_LEN); 01102 param.r[5] =0xFFFFFFFF; 01103 param.r[4] = 0xFFFFFFFF; 01104 param.r[3] = 0xFFFFFFFE; 01105 param.r[2] = 0x26F2FC17; 01106 param.r[1] = 0x0F69466A; 01107 param.r[0] = 0x74DEFD8D; 01108 #endif 01109 } 01110 01111 private: 01112 PMP pmp; 01113 }; 01114 01115 } //end of namespace wiselib 01116 01117 #endif //end