Wiselib
wiselib.testing/algorithms/crypto/eccfp.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines