⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecdsam.nc

📁 elliptic curve加密源代码
💻 NC
字号:
/**
 * All new code in this distribution is Copyright 2005 by North Carolina
 * State University. All rights reserved. Redistribution and use in
 * source and binary forms are permitted provided that this entire
 * copyright notice is duplicated in all such copies, and that any
 * documentation, announcements, and other materials related to such
 * distribution and use acknowledge that the software was developed at
 * North Carolina State University, Raleigh, NC. No charge may be made
 * for copies, derivations, or distributions of this material without the
 * express written consent of the copyright holder. Neither the name of
 * the University nor the name of the author may be used to endorse or
 * promote products derived from this material without specific prior
 * written permission.
 *
 * IN NO EVENT SHALL THE NORTH CAROLINA STATE UNIVERSITY BE LIABLE TO ANY
 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
 * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
 * EVEN IF THE NORTH CAROLINA STATE UNIVERSITY HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
 * "AS IS" BASIS, AND THE NORTH CAROLINA STATE UNIVERSITY HAS NO
 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
 * MODIFICATIONS. "
 *
 */

/**
 * module for ECDSA
 *
 * Author: An Liu
 * Date: 09/29/2006
 */
includes sha1;

//enable shamir trick
#define SHAMIR_TRICK

#ifdef SHAMIR_TRICK
//The size of sliding window, S_W_BITS <= 8
#define S_W_BITS 2

//basic mask used to generate mask array (you need to change this if
//you want to change window size)
//For example: if S_W_BITS is 2, BASIC_MASK must be 0x03;
//             if S_W_BITS is 4, BASIC_MASK must be 0x0f;
//	       if S_W_BITS is 8, BASIC_MASK must be 0xff;
#define S_BASIC_MASK 0x03

//number of windows in one digit, NUM_MASKS = NN_DIGIT_BITS/W_BITS
#define S_NUM_MASKS (NN_DIGIT_BITS/S_W_BITS)

//number of points for precomputed points, NN_POINTS = 2^W_BITS - 1
#define S_NUM_POINTS ((1 << (2*S_W_BITS)) - 1)

//
#define S_MAX ((1 << S_W_BITS) - 1)
#endif

module ECDSAM {
  provides interface ECDSA;
  uses {
    interface NN;
    interface ECC;
    interface Random;
    interface SHA1;
  }
}

implementation {

#ifdef SHAMIR_TRICK
  Point pqBaseArray[S_NUM_POINTS];
  NN_DIGIT s_mask[S_NUM_MASKS];
  Params* param;
#else
  //precomputed array of Q (used in verification) for sliding window method
  Point qBaseArray[NUM_POINTS];
#endif

  NN_DIGIT order[NUMWORDS];
  Point * baseP;

  //generate random natural number a[length]
  void gen_random(NN_DIGIT *a, uint8_t length)
  {
#ifdef TEST_VECTOR
#ifdef EIGHT_BIT_PROCESSOR
    a[20] = 0x0;
    a[19] = 0x7b;
    a[18] = 0x01;
    a[17] = 0x2d;
    a[16] = 0xb7;
    a[15] = 0x68;
    a[14] = 0x1a;
    a[13] = 0x3f;
    a[12] = 0x28;
    a[11] = 0xb9;
    a[10] = 0x18;
    a[9] = 0x5c;
    a[8] = 0x8b;
    a[7] = 0x2a;
    a[6] = 0xc5;
    a[5] = 0xd5;
    a[4] = 0x28;
    a[3] = 0xde;
    a[2] = 0xcd;
    a[1] = 0x52;
    a[0] = 0xda;
#else
#ifdef SIXTEEN_BIT_PROCESSOR
    a[10] = 0x0;
    a[9] = 0x7b01;
    a[8] = 0x2db7;
    a[7] = 0x681a;
    a[6] = 0x3f28;
    a[5] = 0xb918;
    a[4] = 0x5c8b;
    a[3] = 0x2ac5;
    a[2] = 0xd528;
    a[1] = 0xdecd;
    a[0] = 0x52da;
#else
#ifdef THIRTYTWOBIT_PROCESSOR
    a[5] = 0x00000000;
    a[4] = 0x7b012db7;
    a[3] = 0x681a3f28;
    a[2] = 0xb9185c8b;
    a[1] = 0x2ac5d528;
    a[0] = 0xdecd52da;
#endif  //end of 32-bit
#endif  //end of 16-bit
#endif  //end of 8-bit

#else //not test vector

#ifdef THIRTYTWO_BIT_PROCESSOR
    uint8_t ri;
	
    for (ri=0; ri<length; ri++)
      a[ri] = ((uint32_t)call Random.rand() << 16)^((uint32_t)call Random.rand());
#else
    uint8_t ri;
	
    for (ri=0; ri<length; ri++)
      a[ri] = (NN_DIGIT)call Random.rand();
#endif

#endif  //end of test vector
  } 

#ifdef SHAMIR_TRICK
  // Shamir trick init
  void shamir_init(Point * pKey, Point * pointArray)
  {
    uint16_t i;
    uint16_t j;

    baseP = call ECC.get_baseP();

    /* max = 2^w-1
     * [0] = Q
     * [1] = 2Q
     * ...
     * [max-1] = max*Q
     */
    call NN.Assign(pointArray[0].x, pKey->x, NUMWORDS);
    call NN.Assign(pointArray[0].y, pKey->y, NUMWORDS);
    
    for (i=1; i<S_MAX; i++){
      call ECC.add(&(pointArray[i]), &(pointArray[i-1]), pKey);
    }

    /*
     * [max] = P
     * [max+1] = P+Q
     * ...
     * [max+max] = P+max*Q
     * [max+max+1] = 2P
     * [max+max+2] = 2P+Q
     * ...
     * [max+2*max+1] = 2P+max*Q
     * ...
     */
    for (i = 0; i < S_MAX; i++){
      for (j = 0; j<S_MAX+1; j++){
	if (i == 0 && j==0){
	  call NN.Assign(pointArray[S_MAX].x, baseP->x, NUMWORDS);
	  call NN.Assign(pointArray[S_MAX].y, baseP->y, NUMWORDS);
	}else if (j==0){
	  call ECC.add(&(pointArray[S_MAX+(S_MAX+1)*i]), &(pointArray[S_MAX+(S_MAX+1)*(i-1)]), baseP);
	}else{
	  call ECC.add(&(pointArray[S_MAX+(S_MAX+1)*i+j]), &(pointArray[S_MAX+(S_MAX+1)*i]), &(pointArray[j-1]));
	}
      }
    }
    
    for (i = 0; i < S_NUM_MASKS; i++)
      s_mask[i] = S_BASIC_MASK << (S_W_BITS*i);    
  }

  // Shamir trick
  void shamir(Point * P0, NN_DIGIT * u1, NN_DIGIT * u2){
    int16_t i, tmp, tmp2;
    int8_t j, k;
    NN_DIGIT windex;
    NN_DIGIT Z0[NUMWORDS];
    NN_DIGIT Z1[NUMWORDS];

    // clear point
    call NN.AssignZero(P0->x, NUMWORDS);
    call NN.AssignZero(P0->y, NUMWORDS);
    
    //convert to Jprojective coordinate
    call NN.AssignZero(Z0, NUMWORDS);
    call NN.AssignZero(Z1, NUMWORDS);
    Z1[0] = 0x01;	
    
    tmp = call NN.Digits(u1, NUMWORDS);
    tmp2 = call NN.Digits(u2, NUMWORDS);
    if (tmp2 > tmp)
      tmp = tmp2;

    for (i = tmp - 1; i >= 0; i--)
    { 
      //call Leds.redToggle();
      for (j = NN_DIGIT_BITS/S_W_BITS - 1; j >= 0; j--)
      {
        //call Leds.yellowToggle();
	for (k = 0; k < S_W_BITS; k++)
    	  call ECC.dbl_proj(P0, Z0, P0, Z0);
	
	if (j != 0){
	  windex = ((s_mask[j] & u1[i]) >> ((j-1)*S_W_BITS)) | ((s_mask[j] & u2[i]) >> (j*S_W_BITS));
	}else{
	  windex = ((s_mask[j] & u1[i]) << S_W_BITS) | (s_mask[j] & u2[i]);
	}
        if (windex){
	  call ECC.add_proj(P0, Z0, P0, Z0, &(pqBaseArray[windex-1]), Z1);
	}
      }
      
    }

       
    //convert back to affine coordinate
    if (call NN.One(Z0, NUMWORDS) == FALSE)
    {
      call NN.ModInv(Z1, Z0, param->p, NUMWORDS);
      call NN.ModMultOpt(Z0, Z1, Z1, param->p, param->omega, NUMWORDS);
      call NN.ModMultOpt(P0->x, P0->x, Z0, param->p, param->omega, NUMWORDS);
      call NN.ModMultOpt(Z0, Z0, Z1, param->p, param->omega, NUMWORDS);
      call NN.ModMultOpt(P0->y, P0->y, Z0, param->p, param->omega, NUMWORDS);
    }

  }
#endif

  //init the ECDSA, pKey is public key used to verify the signature
  //we assume that the node has already know the public key when node is deployed 	
  command result_t ECDSA.init(Point * pKey)
  {
    call ECC.init();
#ifdef SHAMIR_TRICK
    param = call ECC.get_param();
    shamir_init(pKey, pqBaseArray);
#else
    //precompute the array of public key for sliding window method
    call ECC.win_precompute(pKey, qBaseArray);
#endif
    //we need to know param->r
    call ECC.get_order(order);

    return SUCCESS;
  }

	
  command void ECDSA.sign(uint8_t *msg, uint8_t len, NN_DIGIT *r, NN_DIGIT *s, NN_DIGIT *d)
  {

    bool done = FALSE;
    NN_DIGIT k[NUMWORDS];
    NN_DIGIT k_inv[NUMWORDS];
    NN_DIGIT tmp[NUMWORDS];
    NN_DIGIT digest[NUMWORDS];
    Point P;
    uint8_t sha1sum[20];
    NN_DIGIT sha1tmp[20/NN_DIGIT_LEN];
    SHA1Context ctx;
		
    while(!done){
      gen_random(k, NUMWORDS);
      call NN.Mod(k, k, NUMWORDS, order, NUMWORDS);

      if ((call NN.Zero(k, NUMWORDS)) == 1)
        continue;

      call ECC.win_mul_base(&P, k);
     
      call NN.Mod(r, P.x, NUMWORDS, order, NUMWORDS);	
      
      if ((call NN.Zero(r, NUMWORDS)) == 1)
	continue;
      call NN.ModInv(k_inv, k, order, NUMWORDS);
      //memset(sha1sum, 0, 20);
      call SHA1.reset(&ctx);
      call SHA1.update(&ctx, msg, len);
      call SHA1.digest(&ctx, sha1sum);

      call NN.Decode(sha1tmp, 20/NN_DIGIT_LEN, sha1sum, 20);
      call NN.Mod(digest, sha1tmp, 20/NN_DIGIT_LEN, order, NUMWORDS);
      call NN.ModMult(k, d, r, order, NUMWORDS);
      call NN.ModAdd(tmp, digest, k, order, NUMWORDS);
      call NN.ModMult(s, k_inv, tmp, order, NUMWORDS);
      if ((call NN.Zero(s, NUMWORDS)) != 1)			
	done = TRUE;
    }
		
  }
	
  command uint8_t ECDSA.verify(uint8_t *msg, uint8_t len, NN_DIGIT *r, NN_DIGIT *s, Point *Q)
  {
    uint8_t sha1sum[20];
    NN_DIGIT sha1tmp[20/NN_DIGIT_LEN];
    SHA1Context ctx;
    NN_DIGIT w[NUMWORDS];
    NN_DIGIT u1[NUMWORDS];
    NN_DIGIT u2[NUMWORDS];
    NN_DIGIT digest[NUMWORDS];
#ifndef SHAMIR_TRICK
    Point u1P, u2Q;
#endif
    Point final;

    // r and s shoud be in [1, p-1]
    if ((call NN.Cmp(r, order, NUMWORDS)) >= 0)
      return 3;
    if ((call NN.Zero(r, NUMWORDS)) == 1)
      return 4;
    if ((call NN.Cmp(s, order, NUMWORDS)) >= 0)
      return 5;
    if ((call NN.Zero(s, NUMWORDS)) == 1)
      return 6;
		
    //w = s^-1 mod p
    call NN.ModInv(w, s, order, NUMWORDS);
    //h(msg)
    memset(sha1sum, 0, 20);
    call SHA1.reset(&ctx);
    call SHA1.update(&ctx, msg, len);
    call SHA1.digest(&ctx, sha1sum);
    call NN.Decode(sha1tmp, 20/NN_DIGIT_LEN, sha1sum, 20);
    call NN.Mod(digest, sha1tmp, 20/NN_DIGIT_LEN, order, NUMWORDS);
    //u1 = h(msg)w mod p
    call NN.ModMult(u1, digest, w, order, NUMWORDS);
    //u2 = rw mod p
    call NN.ModMult(u2, r, w, order, NUMWORDS);

    //u1P+u2Q
#ifdef SHAMIR_TRICK
    shamir(&final, u1, u2);
#else
    call ECC.win_mul_base(&u1P, u1);
    call ECC.win_mul(&u2Q, u2, qBaseArray);
    call ECC.add(&final, &u1P, &u2Q);
#endif

    call NN.Mod(w, final.x, NUMWORDS, order, NUMWORDS);

    if ((call NN.Cmp(w, r, NUMWORDS)) == 0)
      return 1;
    else
      return 2;
  }



}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -