/*---------------------------------------------------------------------------*/ void ecc_add(point_t * P0, point_t * P1, point_t * P2) { NN_DIGIT Z0[NUMWORDS]; NN_DIGIT Z1[NUMWORDS]; NN_DIGIT Z2[NUMWORDS]; p_clear(P0); NN_AssignZero(Z0, NUMWORDS); NN_AssignZero(Z1, NUMWORDS); NN_AssignZero(Z2, NUMWORDS); Z1[0] = 0x01; Z2[0] = 0x01; #ifdef ADD_MIX c_add_mix(P0, Z0, P1, Z1, P2); #else ecc_add_proj(P0, Z0, P1, Z1, P2, Z2); #endif if(!Z_is_one(Z0)) { NN_ModInv(Z1, Z0, param.p, NUMWORDS); NN_ModMultOpt(Z0, Z1, Z1, param.p, param.omega, NUMWORDS); NN_ModMultOpt(P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS); NN_ModMultOpt(Z0, Z0, Z1, param.p, param.omega, NUMWORDS); NN_ModMultOpt(P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS); } }
/* * scalar point multiplication * P0 = n*basepoint * pointArray is array of basepoint, pointArray[0] = basepoint, pointArray[1] = 2*basepoint ... */ void ecc_win_mul(point_t * P0, NN_DIGIT * n, point_t * pointArray) { int16_t i, tmp; int8_t j; NN_DIGIT windex; NN_DIGIT Z0[NUMWORDS]; NN_DIGIT Z1[NUMWORDS]; #ifndef REPEAT_DOUBLE int8_t k; #endif p_clear(P0); /* Convert to Jprojective coordinate */ NN_AssignZero(Z0, NUMWORDS); NN_AssignZero(Z1, NUMWORDS); Z1[0] = 0x01; tmp = NN_Digits(n, NUMWORDS); for(i = tmp - 1; i >= 0; i--) { for(j = NN_DIGIT_BITS/W_BITS - 1; j >= 0; j--) { #ifndef REPEAT_DOUBLE for(k = 0; k < W_BITS; k++) { ecc_dbl_proj(P0, Z0, P0, Z0); } #else ecc_m_dbl_projective(P0, Z0, W_BITS); #endif windex = mask[j] & n[i]; if(windex) { windex = windex >> (j*W_BITS); #ifdef ADD_MIX c_add_mix(P0, Z0, P0, Z0, &(pointArray[windex-1])); #else ecc_add_proj(P0, Z0, P0, Z0, &(pointArray[windex-1]), Z1); #endif } } } /* Convert back to affine coordinate */ if(!Z_is_one(Z0)) { NN_ModInv(Z1, Z0, param.p, NUMWORDS); NN_ModMultOpt(Z0, Z1, Z1, param.p, param.omega, NUMWORDS); NN_ModMultOpt(P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS); NN_ModMultOpt(Z0, Z0, Z1, param.p, param.omega, NUMWORDS); NN_ModMultOpt(P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS); } }
/* * P0 = n * P1 */ void ecc_mul ( point_t* P0, point_t* P1, NN_DIGIT* n ) { int16_t i, tmp; NN_DIGIT Z0[NUMWORDS]; NN_DIGIT Z1[NUMWORDS]; /* clear point */ p_clear ( P0 ); /* convert to Jprojective coordinate */ NN_AssignZero ( Z0, NUMWORDS ); NN_AssignZero ( Z1, NUMWORDS ); Z1[0] = 0x01; tmp = NN_Bits ( n, NUMWORDS ); for ( i = tmp-1; i >= 0; i-- ) { ecc_dbl_proj ( P0, Z0, P0, Z0 ); if ( b_testbit ( n, i ) ) { #ifdef ADD_MIX c_add_mix ( P0, Z0, P0, Z0, P1 ); #else ecc_add_proj ( P0, Z0, P0, Z0, P1, Z1 ); #endif } } /* convert back to affine coordinate */ if ( !Z_is_one ( Z0 ) ) { NN_ModInv ( Z1, Z0, param.p, NUMWORDS ); NN_ModMultOpt ( Z0, Z1, Z1, param.p, param.omega, NUMWORDS ); NN_ModMultOpt ( P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS ); NN_ModMultOpt ( Z0, Z0, Z1, param.p, param.omega, NUMWORDS ); NN_ModMultOpt ( P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS ); } }