/* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* AMCL Elliptic Curve Functions */ /* SU=m, SU is Stack Usage (Weierstrass Curves) */ //#define HAS_MAIN #include "ecp_FP256BN.h" /* test for P=O point-at-infinity */ int ECP_FP256BN_isinf(ECP_FP256BN *P) { if (P->inf) return 1; FP_FP256BN_reduce(&(P->x)); FP_FP256BN_reduce(&(P->z)); #if CURVETYPE_FP256BN==EDWARDS FP_FP256BN_reduce(&(P->y)); P->inf= (FP_FP256BN_iszilch(&(P->x)) && FP_FP256BN_equals(&(P->y),&(P->z))); #endif #if CURVETYPE_FP256BN==WEIERSTRASS FP_FP256BN_reduce(&(P->y)); P->inf= (FP_FP256BN_iszilch(&(P->x)) && FP_FP256BN_iszilch(&(P->z))); #endif #if CURVETYPE_FP256BN==MONTGOMERY P->inf= FP_FP256BN_iszilch(&(P->z)); #endif return P->inf; } /* Conditional swap of P and Q dependant on d */ static void ECP_FP256BN_cswap(ECP_FP256BN *P,ECP_FP256BN *Q,int d) { FP_FP256BN_cswap(&(P->x),&(Q->x),d); #if CURVETYPE_FP256BN!=MONTGOMERY FP_FP256BN_cswap(&(P->y),&(Q->y),d); #endif FP_FP256BN_cswap(&(P->z),&(Q->z),d); d=~(d-1); d=d&(P->inf^Q->inf); P->inf^=d; Q->inf^=d; } #if CURVETYPE_FP256BN!=MONTGOMERY /* Conditional move Q to P dependant on d */ static void ECP_FP256BN_cmove(ECP_FP256BN *P,ECP_FP256BN *Q,int d) { FP_FP256BN_cmove(&(P->x),&(Q->x),d); #if CURVETYPE_FP256BN!=MONTGOMERY FP_FP256BN_cmove(&(P->y),&(Q->y),d); #endif FP_FP256BN_cmove(&(P->z),&(Q->z),d); d=~(d-1); P->inf^=(P->inf^Q->inf)&d; } /* return 1 if b==c, no branching */ static int teq(sign32 b,sign32 c) { sign32 x=b^c; x-=1; // if x=0, x now -1 return (int)((x>>31)&1); } #endif // CURVETYPE_FP256BN!=MONTGOMERY #if CURVETYPE_FP256BN!=MONTGOMERY /* Constant time select from pre-computed table */ static void ECP_FP256BN_select(ECP_FP256BN *P,ECP_FP256BN W[],sign32 b) { ECP_FP256BN MP; sign32 m=b>>31; sign32 babs=(b^m)-m; babs=(babs-1)/2; ECP_FP256BN_cmove(P,&W[0],teq(babs,0)); // conditional move ECP_FP256BN_cmove(P,&W[1],teq(babs,1)); ECP_FP256BN_cmove(P,&W[2],teq(babs,2)); ECP_FP256BN_cmove(P,&W[3],teq(babs,3)); ECP_FP256BN_cmove(P,&W[4],teq(babs,4)); ECP_FP256BN_cmove(P,&W[5],teq(babs,5)); ECP_FP256BN_cmove(P,&W[6],teq(babs,6)); ECP_FP256BN_cmove(P,&W[7],teq(babs,7)); ECP_FP256BN_copy(&MP,P); ECP_FP256BN_neg(&MP); // minus P ECP_FP256BN_cmove(P,&MP,(int)(m&1)); } #endif /* Test P == Q */ /* SU=168 */ int ECP_FP256BN_equals(ECP_FP256BN *P,ECP_FP256BN *Q) { FP_FP256BN a,b; if (ECP_FP256BN_isinf(P) && ECP_FP256BN_isinf(Q)) return 1; if (ECP_FP256BN_isinf(P) || ECP_FP256BN_isinf(Q)) return 0; FP_FP256BN_mul(&a,&(P->x),&(Q->z)); FP_FP256BN_mul(&b,&(Q->x),&(P->z)); if (!FP_FP256BN_equals(&a,&b)) return 0; #if CURVETYPE_FP256BN!=MONTGOMERY FP_FP256BN_mul(&a,&(P->y),&(Q->z)); FP_FP256BN_mul(&b,&(Q->y),&(P->z)); if (!FP_FP256BN_equals(&a,&b)) return 0; #endif return 1; } /* Set P=Q */ /* SU=16 */ void ECP_FP256BN_copy(ECP_FP256BN *P,ECP_FP256BN *Q) { P->inf=Q->inf; FP_FP256BN_copy(&(P->x),&(Q->x)); #if CURVETYPE_FP256BN!=MONTGOMERY FP_FP256BN_copy(&(P->y),&(Q->y)); #endif FP_FP256BN_copy(&(P->z),&(Q->z)); } /* Set P=-Q */ #if CURVETYPE_FP256BN!=MONTGOMERY /* SU=8 */ void ECP_FP256BN_neg(ECP_FP256BN *P) { // if (ECP_FP256BN_isinf(P)) return; #if CURVETYPE_FP256BN==WEIERSTRASS FP_FP256BN_neg(&(P->y),&(P->y)); FP_FP256BN_norm(&(P->y)); #else FP_FP256BN_neg(&(P->x),&(P->x)); FP_FP256BN_norm(&(P->x)); #endif } #endif /* Set P=O */ void ECP_FP256BN_inf(ECP_FP256BN *P) { FP_FP256BN_zero(&(P->x)); #if CURVETYPE_FP256BN!=MONTGOMERY FP_FP256BN_one(&(P->y)); #endif #if CURVETYPE_FP256BN!=EDWARDS FP_FP256BN_zero(&(P->z)); #else FP_FP256BN_one(&(P->z)); #endif P->inf=1; } /* Calculate right Hand Side of curve equation y^2=RHS */ /* SU=56 */ void ECP_FP256BN_rhs(FP_FP256BN *v,FP_FP256BN *x) { #if CURVETYPE_FP256BN==WEIERSTRASS /* x^3+Ax+B */ FP_FP256BN t; FP_FP256BN_sqr(&t,x); FP_FP256BN_mul(&t,&t,x); if (CURVE_A_FP256BN==-3) { FP_FP256BN_neg(v,x); FP_FP256BN_norm(v); FP_FP256BN_imul(v,v,-CURVE_A_FP256BN); FP_FP256BN_norm(v); FP_FP256BN_add(v,&t,v); } else FP_FP256BN_copy(v,&t); FP_FP256BN_rcopy(&t,CURVE_B_FP256BN); FP_FP256BN_add(v,&t,v); FP_FP256BN_reduce(v); #endif #if CURVETYPE_FP256BN==EDWARDS /* (Ax^2-1)/(Bx^2-1) */ BIG_256_56 m,b,c; FP_FP256BN t,one; BIG_256_56_rcopy(m,Modulus_FP256BN); FP_FP256BN_sqr(v,x); FP_FP256BN_one(&one); FP_FP256BN_rcopy(&t,CURVE_B_FP256BN); FP_FP256BN_mul(&t,v,&t); FP_FP256BN_sub(&t,&t,&one); if (CURVE_A_FP256BN==1) FP_FP256BN_sub(v,v,&one); if (CURVE_A_FP256BN==-1) { FP_FP256BN_add(v,v,&one); FP_FP256BN_norm(v); FP_FP256BN_neg(v,v); } FP_FP256BN_redc(b,v); FP_FP256BN_redc(c,&t); BIG_256_56_moddiv(b,b,c,m); FP_FP256BN_nres(v,b); #endif #if CURVETYPE_FP256BN==MONTGOMERY /* x^3+Ax^2+x */ FP_FP256BN x2,x3; FP_FP256BN_sqr(&x2,x); FP_FP256BN_mul(&x3,&x2,x); FP_FP256BN_copy(v,x); FP_FP256BN_imul(&x2,&x2,CURVE_A_FP256BN); FP_FP256BN_add(v,v,&x2); FP_FP256BN_add(v,v,&x3); FP_FP256BN_reduce(v); #endif } /* Set P=(x,y) */ #if CURVETYPE_FP256BN==MONTGOMERY /* Set P=(x,{y}) */ int ECP_FP256BN_set(ECP_FP256BN *P,BIG_256_56 x) { BIG_256_56 m,b; FP_FP256BN rhs; BIG_256_56_rcopy(m,Modulus_FP256BN); FP_FP256BN_nres(&rhs,x); ECP_FP256BN_rhs(&rhs,&rhs); FP_FP256BN_redc(b,&rhs); if (BIG_256_56_jacobi(b,m)!=1) { ECP_FP256BN_inf(P); return 0; } P->inf=0; FP_FP256BN_nres(&(P->x),x); FP_FP256BN_one(&(P->z)); return 1; } /* Extract x coordinate as BIG */ int ECP_FP256BN_get(BIG_256_56 x,ECP_FP256BN *P) { if (ECP_FP256BN_isinf(P)) return -1; ECP_FP256BN_affine(P); FP_FP256BN_redc(x,&(P->x)); return 0; } #else /* Extract (x,y) and return sign of y. If x and y are the same return only x */ /* SU=16 */ int ECP_FP256BN_get(BIG_256_56 x,BIG_256_56 y,ECP_FP256BN *P) { int s; if (ECP_FP256BN_isinf(P)) return -1; ECP_FP256BN_affine(P); FP_FP256BN_redc(y,&(P->y)); s=BIG_256_56_parity(y); FP_FP256BN_redc(x,&(P->x)); return s; } /* Set P=(x,{y}) */ /* SU=96 */ int ECP_FP256BN_set(ECP_FP256BN *P,BIG_256_56 x,BIG_256_56 y) { FP_FP256BN rhs,y2; FP_FP256BN_nres(&y2,y); FP_FP256BN_sqr(&y2,&y2); FP_FP256BN_reduce(&y2); FP_FP256BN_nres(&rhs,x); ECP_FP256BN_rhs(&rhs,&rhs); if (!FP_FP256BN_equals(&y2,&rhs)) { ECP_FP256BN_inf(P); return 0; } P->inf=0; FP_FP256BN_nres(&(P->x),x); FP_FP256BN_nres(&(P->y),y); FP_FP256BN_one(&(P->z)); return 1; } /* Set P=(x,y), where y is calculated from x with sign s */ /* SU=136 */ int ECP_FP256BN_setx(ECP_FP256BN *P,BIG_256_56 x,int s) { FP_FP256BN rhs; BIG_256_56 t,m; BIG_256_56_rcopy(m,Modulus_FP256BN); FP_FP256BN_nres(&rhs,x); ECP_FP256BN_rhs(&rhs,&rhs); FP_FP256BN_redc(t,&rhs); if (BIG_256_56_jacobi(t,m)!=1) { ECP_FP256BN_inf(P); return 0; } P->inf=0; FP_FP256BN_nres(&(P->x),x); FP_FP256BN_sqrt(&(P->y),&rhs); //printf("SR= "); FP_FP256BN_output(&(P->y)); printf("\n"); FP_FP256BN_redc(t,&(P->y)); //printf("t= "); BIG_256_56_output(t); printf("\n"); if (BIG_256_56_parity(t)!=s) FP_FP256BN_neg(&(P->y),&(P->y)); FP_FP256BN_reduce(&(P->y)); FP_FP256BN_one(&(P->z)); return 1; } /* map BIG to point on curve of correct order */ /* The BIG should be the output of some hash function */ void ECP_FP256BN_mapit(ECP_FP256BN *P,octet *W) { BIG_256_56 q,x; BIG_256_56_fromBytes(x,W->val); BIG_256_56_rcopy(q,Modulus_FP256BN); BIG_256_56_mod(x,q); int k=0; while (!ECP_FP256BN_setx(P,x,0)) { BIG_256_56_inc(x,1); k++; BIG_256_56_norm(x); } #if PAIRING_FRIENDLY_FP256BN == BLS BIG_256_56 c; BIG_256_56_rcopy(c,CURVE_Cof_FP256BN); ECP_FP256BN_mul(P,c); #endif } #endif /* Convert P to Affine, from (x,y,z) to (x,y) */ /* SU=160 */ void ECP_FP256BN_affine(ECP_FP256BN *P) { FP_FP256BN one,iz; BIG_256_56 m,b; if (ECP_FP256BN_isinf(P)) return; FP_FP256BN_one(&one); if (FP_FP256BN_equals(&(P->z),&one)) return; BIG_256_56_rcopy(m,Modulus_FP256BN); FP_FP256BN_redc(b,&(P->z)); BIG_256_56_invmodp(b,b,m); FP_FP256BN_nres(&iz,b); FP_FP256BN_mul(&(P->x),&(P->x),&iz); #if CURVETYPE_FP256BN==EDWARDS || CURVETYPE_FP256BN==WEIERSTRASS FP_FP256BN_mul(&(P->y),&(P->y),&iz); FP_FP256BN_reduce(&(P->y)); #endif FP_FP256BN_reduce(&(P->x)); FP_FP256BN_copy(&(P->z),&one); } /* SU=120 */ void ECP_FP256BN_outputxyz(ECP_FP256BN *P) { BIG_256_56 x,z; if (ECP_FP256BN_isinf(P)) { printf("Infinity\n"); return; } FP_FP256BN_reduce(&(P->x)); FP_FP256BN_redc(x,&(P->x)); FP_FP256BN_reduce(&(P->z)); FP_FP256BN_redc(z,&(P->z)); #if CURVETYPE_FP256BN!=MONTGOMERY BIG_256_56 y; FP_FP256BN_reduce(&(P->y)); FP_FP256BN_redc(y,&(P->y)); printf("("); BIG_256_56_output(x); printf(","); BIG_256_56_output(y); printf(","); BIG_256_56_output(z); printf(")\n"); #else printf("("); BIG_256_56_output(x); printf(","); BIG_256_56_output(z); printf(")\n"); #endif } /* SU=16 */ /* Output point P */ void ECP_FP256BN_output(ECP_FP256BN *P) { BIG_256_56 x; if (ECP_FP256BN_isinf(P)) { printf("Infinity\n"); return; } ECP_FP256BN_affine(P); #if CURVETYPE_FP256BN!=MONTGOMERY BIG_256_56 y; FP_FP256BN_redc(x,&(P->x)); FP_FP256BN_redc(y,&(P->y)); printf("("); BIG_256_56_output(x); printf(","); BIG_256_56_output(y); printf(")\n"); #else FP_FP256BN_redc(x,&(P->x)); printf("("); BIG_256_56_output(x); printf(")\n"); #endif } /* SU=16 */ /* Output point P */ void ECP_FP256BN_rawoutput(ECP_FP256BN *P) { BIG_256_56 x,z; // if (ECP_FP256BN_isinf(P)) // { // printf("Infinity\n"); // return; // } // ECP_FP256BN_affine(P); #if CURVETYPE_FP256BN!=MONTGOMERY BIG_256_56 y; FP_FP256BN_redc(x,&(P->x)); FP_FP256BN_redc(y,&(P->y)); FP_FP256BN_redc(z,&(P->z)); printf("("); BIG_256_56_output(x); printf(","); BIG_256_56_output(y); printf(","); BIG_256_56_output(z); printf(")\n"); #else FP_FP256BN_redc(x,&(P->x)); FP_FP256BN_redc(z,&(P->z)); printf("("); BIG_256_56_output(x); printf(","); BIG_256_56_output(z); printf(")\n"); #endif } /* SU=88 */ /* Convert P to octet string */ void ECP_FP256BN_toOctet(octet *W,ECP_FP256BN *P) { #if CURVETYPE_FP256BN==MONTGOMERY BIG_256_56 x; ECP_FP256BN_get(x,P); W->len=MODBYTES_256_56+1; W->val[0]=6; BIG_256_56_toBytes(&(W->val[1]),x); #else BIG_256_56 x,y; ECP_FP256BN_get(x,y,P); W->len=2*MODBYTES_256_56+1; W->val[0]=4; BIG_256_56_toBytes(&(W->val[1]),x); BIG_256_56_toBytes(&(W->val[MODBYTES_256_56+1]),y); #endif } /* SU=88 */ /* Restore P from octet string */ int ECP_FP256BN_fromOctet(ECP_FP256BN *P,octet *W) { #if CURVETYPE_FP256BN==MONTGOMERY BIG_256_56 x; BIG_256_56_fromBytes(x,&(W->val[1])); if (ECP_FP256BN_set(P,x)) return 1; return 0; #else BIG_256_56 x,y; BIG_256_56_fromBytes(x,&(W->val[1])); BIG_256_56_fromBytes(y,&(W->val[MODBYTES_256_56+1])); if (ECP_FP256BN_set(P,x,y)) return 1; return 0; #endif } /* Set P=2P */ /* SU=272 */ void ECP_FP256BN_dbl(ECP_FP256BN *P) { #if CURVETYPE_FP256BN==WEIERSTRASS FP_FP256BN t0,t1,t2,t3,x3,y3,z3,b; if (ECP_FP256BN_isinf(P)) return; if (CURVE_A_FP256BN==0) { //FP_FP256BN_copy(&t0,&(P->y)); //FP t0=new FP(y); FP_FP256BN_sqr(&t0,&(P->y)); //t0.sqr(); //FP_FP256BN_copy(&t1,&(P->y)); //FP t1=new FP(y); FP_FP256BN_mul(&t1,&(P->y),&(P->z)); //t1.mul(z); //FP_FP256BN_copy(&t2,&(P->z)); //FP t2=new FP(z); FP_FP256BN_sqr(&t2,&(P->z)); //t2.sqr(); //FP_FP256BN_copy(&(P->z),&t0); //z.copy(t0); FP_FP256BN_add(&(P->z),&t0,&t0); //z.add(t0); FP_FP256BN_norm(&(P->z)); //z.norm(); FP_FP256BN_add(&(P->z),&(P->z),&(P->z)); //z.add(z); FP_FP256BN_add(&(P->z),&(P->z),&(P->z)); //z.add(z); FP_FP256BN_norm(&(P->z)); //z.norm(); FP_FP256BN_imul(&t2,&t2,3*CURVE_B_I_FP256BN); //t2.imul(3*ROM.CURVE_B_I); //FP_FP256BN_copy(&x3,&t2); //FP x3=new FP(t2); FP_FP256BN_mul(&x3,&t2,&(P->z)); //x3.mul(z); //FP_FP256BN_copy(&y3,&t0); //FP y3=new FP(t0); FP_FP256BN_add(&y3,&t0,&t2); //y3.add(t2); FP_FP256BN_norm(&y3); //y3.norm(); FP_FP256BN_mul(&(P->z),&(P->z),&t1); //z.mul(t1); //FP_FP256BN_copy(&t1,&t2); //t1.copy(t2); FP_FP256BN_add(&t1,&t2,&t2); //t1.add(t2); FP_FP256BN_add(&t2,&t2,&t1); //t2.add(t1); FP_FP256BN_sub(&t0,&t0,&t2); //t0.sub(t2); FP_FP256BN_norm(&t0); //t0.norm(); FP_FP256BN_mul(&y3,&y3,&t0); //y3.mul(t0); FP_FP256BN_add(&y3,&y3,&x3); //y3.add(x3); //FP_FP256BN_copy(&t1,&(P->x)); //t1.copy(x); *** optimization possible FP_FP256BN_mul(&t1,&(P->x),&(P->y)); //t1.mul(y); //FP_FP256BN_copy(&(P->x),&t0); //x.copy(t0); FP_FP256BN_norm(&t0); //x.norm(); FP_FP256BN_mul(&(P->x),&t0,&t1); //x.mul(t1); FP_FP256BN_add(&(P->x),&(P->x),&(P->x)); //x.add(x); FP_FP256BN_norm(&(P->x)); //x.norm(); FP_FP256BN_copy(&(P->y),&y3); //y.copy(y3); FP_FP256BN_norm(&(P->y)); //y.norm(); } else // its -3 { //FP_FP256BN_copy(&t0,&(P->x)); //FP t0=new FP(x); //FP_FP256BN_copy(&t1,&(P->y)); //FP t1=new FP(y); //FP_FP256BN_copy(&t2,&(P->z)); //FP t2=new FP(z); //FP_FP256BN_copy(&t3,&(P->x)); //FP t3=new FP(x); //FP_FP256BN_copy(&z3,&(P->z)); //FP z3=new FP(z); if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_rcopy(&b,CURVE_B_FP256BN); //b.copy(new FP(new BIG(ROM.CURVE_B))); FP_FP256BN_sqr(&t0,&(P->x)); //t0.sqr(); //1 x^2 FP_FP256BN_sqr(&t1,&(P->y)); //t1.sqr(); //2 y^2 FP_FP256BN_sqr(&t2,&(P->z)); //t2.sqr(); //3 FP_FP256BN_mul(&t3,&(P->x),&(P->y)); //t3.mul(y); //4 FP_FP256BN_add(&t3,&t3,&t3); //t3.add(t3); FP_FP256BN_norm(&t3); //t3.norm();//5 FP_FP256BN_mul(&z3,&(P->z),&(P->x)); //z3.mul(x); //6 FP_FP256BN_add(&z3,&z3,&z3); //z3.add(z3); FP_FP256BN_norm(&z3); //z3.norm();//7 //FP_FP256BN_copy(&y3,&t2); //y3.copy(t2); if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_mul(&y3,&t2,&b); //y3.mul(b); //8 else FP_FP256BN_imul(&y3,&t2,CURVE_B_I_FP256BN); //y3.imul(ROM.CURVE_B_I); FP_FP256BN_sub(&y3,&y3,&z3); //y3.sub(z3); //y3.norm(); //9 *** //FP_FP256BN_copy(&x3,&y3); //x3.copy(y3); FP_FP256BN_add(&x3,&y3,&y3); //x3.add(y3); FP_FP256BN_norm(&x3); //x3.norm();//10 FP_FP256BN_add(&y3,&y3,&x3); //y3.add(x3); //y3.norm();//11 //FP_FP256BN_copy(&x3,&t1); //x3.copy(t1); FP_FP256BN_sub(&x3,&t1,&y3); //x3.sub(y3); FP_FP256BN_norm(&x3); //x3.norm();//12 FP_FP256BN_add(&y3,&y3,&t1); //y3.add(t1); FP_FP256BN_norm(&y3); //y3.norm();//13 FP_FP256BN_mul(&y3,&y3,&x3); //y3.mul(x3); //14 FP_FP256BN_mul(&x3,&x3,&t3); //x3.mul(t3); //15 //FP_FP256BN_copy(&t3,&t2); //t3.copy(t2); FP_FP256BN_add(&t3,&t2,&t2); //t3.add(t2); //16 FP_FP256BN_add(&t2,&t2,&t3); //t2.add(t3); //17 if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_mul(&z3,&z3,&b); //z3.mul(b); //18 else FP_FP256BN_imul(&z3,&z3,CURVE_B_I_FP256BN); //z3.imul(ROM.CURVE_B_I); FP_FP256BN_sub(&z3,&z3,&t2); //z3.sub(t2); //z3.norm();//19 FP_FP256BN_sub(&z3,&z3,&t0); //z3.sub(t0); FP_FP256BN_norm(&z3); //z3.norm();//20 *** //FP_FP256BN_copy(&t3,&z3); //t3.copy(z3); FP_FP256BN_add(&t3,&z3,&z3); //t3.add(z3); //t3.norm();//21 FP_FP256BN_add(&z3,&z3,&t3); //z3.add(t3); FP_FP256BN_norm(&z3); //z3.norm(); //22 //FP_FP256BN_copy(&t3,&t0); //t3.copy(t0); FP_FP256BN_add(&t3,&t0,&t0); //t3.add(t0); //t3.norm(); //23 FP_FP256BN_add(&t0,&t0,&t3); //t0.add(t3); //t0.norm();//24 FP_FP256BN_sub(&t0,&t0,&t2); //t0.sub(t2); FP_FP256BN_norm(&t0); //t0.norm();//25 FP_FP256BN_mul(&t0,&t0,&z3); //t0.mul(z3);//26 FP_FP256BN_add(&y3,&y3,&t0); //y3.add(t0); //y3.norm();//27 //FP_FP256BN_copy(&t0,&(P->y)); //t0.copy(y); FP_FP256BN_mul(&t0,&(P->y),&(P->z)); //t0.mul(z);//28 FP_FP256BN_add(&t0,&t0,&t0); //t0.add(t0); FP_FP256BN_norm(&t0); //t0.norm(); //29 FP_FP256BN_mul(&z3,&z3,&t0); //z3.mul(t0);//30 FP_FP256BN_sub(&(P->x),&x3,&z3); //x3.sub(z3); //x3.norm();//31 FP_FP256BN_add(&t0,&t0,&t0); //t0.add(t0); FP_FP256BN_norm(&t0); //t0.norm();//32 FP_FP256BN_add(&t1,&t1,&t1); //t1.add(t1); FP_FP256BN_norm(&t1); //t1.norm();//33 //FP_FP256BN_copy(&z3,&t0); //z3.copy(t0); FP_FP256BN_mul(&(P->z),&t0,&t1); //z3.mul(t1);//34 //FP_FP256BN_copy(&(P->x),&x3); //x.copy(x3); FP_FP256BN_norm(&(P->x)); //x.norm(); FP_FP256BN_copy(&(P->y),&y3); //y.copy(y3); FP_FP256BN_norm(&(P->y)); //y.norm(); //FP_FP256BN_copy(&(P->z),&z3); //z.copy(z3); FP_FP256BN_norm(&(P->z)); //z.norm(); } #endif #if CURVETYPE_FP256BN==EDWARDS /* Not using square for multiplication swap, as (1) it needs more adds, and (2) it triggers more reductions */ FP_FP256BN C,D,H,J; if (ECP_FP256BN_isinf(P)) return; //FP_FP256BN_copy(&C,&(P->x)); //FP C=new FP(x); FP_FP256BN_sqr(&C,&(P->x)); //C.sqr(); //FP_FP256BN_copy(&D,&(P->y)); //FP D=new FP(y); //FP_FP256BN_copy(&H,&(P->z)); //FP H=new FP(z); FP_FP256BN_mul(&(P->x),&(P->x),&(P->y)); //x.mul(y); FP_FP256BN_add(&(P->x),&(P->x),&(P->x)); //x.add(x); FP_FP256BN_norm(&(P->x)); //x.norm(); FP_FP256BN_sqr(&D,&(P->y)); //D.sqr(); if (CURVE_A_FP256BN==-1) //if (ROM.CURVE_A==-1) FP_FP256BN_neg(&C,&C); // C.neg(); //FP_FP256BN_copy(&(P->y),&C); //y.copy(C); FP_FP256BN_add(&(P->y),&C,&D); //y.add(D); FP_FP256BN_norm(&(P->y)); //y.norm(); FP_FP256BN_sqr(&H,&(P->z)); //H.sqr(); FP_FP256BN_add(&H,&H,&H); //H.add(H); //FP_FP256BN_copy(&(P->z),&(P->y)); //z.copy(y); //FP_FP256BN_copy(&J,&(P->y)); //J.copy(y); FP_FP256BN_sub(&J,&(P->y),&H); //J.sub(H); FP_FP256BN_norm(&J); //J.norm(); FP_FP256BN_mul(&(P->x),&(P->x),&J); //x.mul(J); FP_FP256BN_sub(&C,&C,&D); //C.sub(D); FP_FP256BN_norm(&C); //C.norm(); FP_FP256BN_mul(&(P->z),&(P->y),&J); //z.mul(J); FP_FP256BN_mul(&(P->y),&(P->y),&C); //y.mul(C); #endif #if CURVETYPE_FP256BN==MONTGOMERY FP_FP256BN A,B,AA,BB,C; if (ECP_FP256BN_isinf(P)) return; //FP_FP256BN_copy(&A,&(P->x)); //FP A=new FP(x); //FP_FP256BN_copy(&B,&(P->x)); //FP B=new FP(x); FP_FP256BN_add(&A,&(P->x),&(P->z)); //A.add(z); FP_FP256BN_norm(&A); //A.norm(); //FP_FP256BN_copy(&AA,&A); //AA.copy(A); FP_FP256BN_sqr(&AA,&A); //AA.sqr(); FP_FP256BN_sub(&B,&(P->x),&(P->z)); //B.sub(z); FP_FP256BN_norm(&B); //B.norm(); //FP_FP256BN_copy(&BB,&B); //BB.copy(B); FP_FP256BN_sqr(&BB,&B); //BB.sqr(); //FP_FP256BN_copy(&C,&AA); //C.copy(AA); FP_FP256BN_sub(&C,&AA,&BB); //C.sub(BB); FP_FP256BN_norm(&C); //C.norm(); //FP_FP256BN_copy(&(P->x),&AA); //x.copy(AA); FP_FP256BN_mul(&(P->x),&AA,&BB); //x.mul(BB); //FP_FP256BN_copy(&A,&C); //A.copy(C); FP_FP256BN_imul(&A,&C,(CURVE_A_FP256BN+2)/4); //A.imul((ROM.CURVE_A+2)/4); FP_FP256BN_add(&BB,&BB,&A); //BB.add(A); FP_FP256BN_norm(&BB); //BB.norm(); //FP_FP256BN_copy(&(P->z),&BB); //z.copy(BB); FP_FP256BN_mul(&(P->z),&BB,&C); //z.mul(C); #endif } #if CURVETYPE_FP256BN==MONTGOMERY /* Set P+=Q. W is difference between P and Q and is affine */ void ECP_FP256BN_add(ECP_FP256BN *P,ECP_FP256BN *Q,ECP_FP256BN *W) { FP_FP256BN A,B,C,D,DA,CB; //FP_FP256BN_copy(&A,&(P->x)); //FP A=new FP(x); //FP_FP256BN_copy(&B,&(P->x)); //FP B=new FP(x); //FP_FP256BN_copy(&C,&(Q->x)); //FP C=new FP(Q.x); //FP_FP256BN_copy(&D,&(Q->x)); //FP D=new FP(Q.x); FP_FP256BN_add(&A,&(P->x),&(P->z)); //A.add(z); FP_FP256BN_sub(&B,&(P->x),&(P->z)); //B.sub(z); FP_FP256BN_add(&C,&(Q->x),&(Q->z)); //C.add(Q.z); FP_FP256BN_sub(&D,&(Q->x),&(Q->z)); //D.sub(Q.z); FP_FP256BN_norm(&A); //A.norm(); FP_FP256BN_norm(&D); //D.norm(); //FP_FP256BN_copy(&DA,&D); //DA.copy(D); FP_FP256BN_mul(&DA,&D,&A); //DA.mul(A); FP_FP256BN_norm(&C); //C.norm(); FP_FP256BN_norm(&B); //B.norm(); //FP_FP256BN_copy(&CB,&C); //CB.copy(C); FP_FP256BN_mul(&CB,&C,&B); //CB.mul(B); //FP_FP256BN_copy(&A,&DA); //A.copy(DA); FP_FP256BN_add(&A,&DA,&CB); //A.add(CB); FP_FP256BN_norm(&A); //A.norm(); FP_FP256BN_sqr(&(P->x),&A); //A.sqr(); //FP_FP256BN_copy(&B,&DA); //B.copy(DA); FP_FP256BN_sub(&B,&DA,&CB); //B.sub(CB); FP_FP256BN_norm(&B); //B.norm(); FP_FP256BN_sqr(&B,&B); //B.sqr(); //FP_FP256BN_copy(&(P->x),&A); //x.copy(A); //FP_FP256BN_copy(&(P->z),&(W->x));//z.copy(W.x); FP_FP256BN_mul(&(P->z),&(W->x),&B); //z.mul(B); } #else /* Set P+=Q */ /* SU=248 */ void ECP_FP256BN_add(ECP_FP256BN *P,ECP_FP256BN *Q) { #if CURVETYPE_FP256BN==WEIERSTRASS int b3; FP_FP256BN t0,t1,t2,t3,t4,x3,y3,z3,b; if (ECP_FP256BN_isinf(Q)) return; if (ECP_FP256BN_isinf(P)) { ECP_FP256BN_copy(P,Q); return; } if (CURVE_A_FP256BN==0) { b3=3*CURVE_B_I_FP256BN; //int b=3*ROM.CURVE_B_I; //FP_FP256BN_copy(&t0,&(P->x)); //FP t0=new FP(x); FP_FP256BN_mul(&t0,&(P->x),&(Q->x)); //t0.mul(Q.x); //FP_FP256BN_copy(&t1,&(P->y)); //FP t1=new FP(y); FP_FP256BN_mul(&t1,&(P->y),&(Q->y)); //t1.mul(Q.y); //FP_FP256BN_copy(&t2,&(P->z)); //FP t2=new FP(z); FP_FP256BN_mul(&t2,&(P->z),&(Q->z)); //t2.mul(Q.z); //FP_FP256BN_copy(&t3,&(P->x)); //FP t3=new FP(x); FP_FP256BN_add(&t3,&(P->x),&(P->y)); //t3.add(y); FP_FP256BN_norm(&t3); //t3.norm(); //FP_FP256BN_copy(&t4,&(Q->x)); //FP t4=new FP(Q.x); FP_FP256BN_add(&t4,&(Q->x),&(Q->y)); //t4.add(Q.y); FP_FP256BN_norm(&t4); //t4.norm(); FP_FP256BN_mul(&t3,&t3,&t4); //t3.mul(t4); //FP_FP256BN_copy(&t4,&t0); //t4.copy(t0); FP_FP256BN_add(&t4,&t0,&t1); //t4.add(t1); FP_FP256BN_sub(&t3,&t3,&t4); //t3.sub(t4); FP_FP256BN_norm(&t3); //t3.norm(); //FP_FP256BN_copy(&t4,&(P->y)); //t4.copy(y); FP_FP256BN_add(&t4,&(P->y),&(P->z)); //t4.add(z); FP_FP256BN_norm(&t4); //t4.norm(); //FP_FP256BN_copy(&x3,&(Q->y)); //FP x3=new FP(Q.y); FP_FP256BN_add(&x3,&(Q->y),&(Q->z)); //x3.add(Q.z); FP_FP256BN_norm(&x3); //x3.norm(); FP_FP256BN_mul(&t4,&t4,&x3); //t4.mul(x3); //FP_FP256BN_copy(&x3,&t1); //x3.copy(t1); FP_FP256BN_add(&x3,&t1,&t2); //x3.add(t2); FP_FP256BN_sub(&t4,&t4,&x3); //t4.sub(x3); FP_FP256BN_norm(&t4); //t4.norm(); //FP_FP256BN_copy(&x3,&(P->x)); //x3.copy(x); FP_FP256BN_add(&x3,&(P->x),&(P->z)); //x3.add(z); FP_FP256BN_norm(&x3); //x3.norm(); //FP_FP256BN_copy(&y3,&(Q->x)); //FP y3=new FP(Q.x); FP_FP256BN_add(&y3,&(Q->x),&(Q->z)); //y3.add(Q.z); FP_FP256BN_norm(&y3); //y3.norm(); FP_FP256BN_mul(&x3,&x3,&y3); //x3.mul(y3); //FP_FP256BN_copy(&y3,&t0); //y3.copy(t0); FP_FP256BN_add(&y3,&t0,&t2); //y3.add(t2); FP_FP256BN_sub(&y3,&x3,&y3); //y3.rsub(x3); FP_FP256BN_norm(&y3); //y3.norm(); //FP_FP256BN_copy(&x3,&t0); //x3.copy(t0); FP_FP256BN_add(&x3,&t0,&t0); //x3.add(t0); FP_FP256BN_add(&t0,&t0,&x3); //t0.add(x3); FP_FP256BN_norm(&t0); //t0.norm(); FP_FP256BN_imul(&t2,&t2,b3); //t2.imul(b); //FP_FP256BN_copy(&z3,&t1); //FP z3=new FP(t1); FP_FP256BN_add(&z3,&t1,&t2); //z3.add(t2); FP_FP256BN_norm(&z3); //z3.norm(); FP_FP256BN_sub(&t1,&t1,&t2); //t1.sub(t2); FP_FP256BN_norm(&t1); //t1.norm(); FP_FP256BN_imul(&y3,&y3,b3); //y3.imul(b); //FP_FP256BN_copy(&x3,&y3); //x3.copy(y3); FP_FP256BN_mul(&x3,&y3,&t4); //x3.mul(t4); //FP_FP256BN_copy(&t2,&t3); //t2.copy(t3); FP_FP256BN_mul(&t2,&t3,&t1); //t2.mul(t1); FP_FP256BN_sub(&(P->x),&t2,&x3); //x3.rsub(t2); FP_FP256BN_mul(&y3,&y3,&t0); //y3.mul(t0); FP_FP256BN_mul(&t1,&t1,&z3); //t1.mul(z3); FP_FP256BN_add(&(P->y),&y3,&t1); //y3.add(t1); FP_FP256BN_mul(&t0,&t0,&t3); //t0.mul(t3); FP_FP256BN_mul(&z3,&z3,&t4); //z3.mul(t4); FP_FP256BN_add(&(P->z),&z3,&t0); //z3.add(t0); //FP_FP256BN_copy(&(P->x),&x3); //x.copy(x3); FP_FP256BN_norm(&(P->x)); //x.norm(); //FP_FP256BN_copy(&(P->y),&y3); //y.copy(y3); FP_FP256BN_norm(&(P->y)); //y.norm(); //FP_FP256BN_copy(&(P->z),&z3); //z.copy(z3); FP_FP256BN_norm(&(P->z)); //z.norm(); } else { //FP_FP256BN_copy(&t0,&(P->x)); //FP t0=new FP(x); //FP_FP256BN_copy(&t1,&(P->y)); //FP t1=new FP(y); //FP_FP256BN_copy(&t2,&(P->z)); //FP t2=new FP(z); //FP_FP256BN_copy(&t3,&(P->x)); //FP t3=new FP(x); //FP_FP256BN_copy(&t4,&(Q->x)); //FP t4=new FP(Q.x); //FP_FP256BN_copy(&y3,&(Q->x)); //FP y3=new FP(Q.x); //FP_FP256BN_copy(&x3,&(Q->y)); //FP x3=new FP(Q.y); if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_rcopy(&b,CURVE_B_FP256BN); //b.copy(new FP(new BIG(ROM.CURVE_B))); FP_FP256BN_mul(&t0,&(P->x),&(Q->x)); //t0.mul(Q.x); //1 FP_FP256BN_mul(&t1,&(P->y),&(Q->y)); //t1.mul(Q.y); //2 FP_FP256BN_mul(&t2,&(P->z),&(Q->z)); //t2.mul(Q.z); //3 FP_FP256BN_add(&t3,&(P->x),&(P->y)); //t3.add(y); FP_FP256BN_norm(&t3); //t3.norm(); //4 FP_FP256BN_add(&t4,&(Q->x),&(Q->y)); //t4.add(Q.y); FP_FP256BN_norm(&t4); //t4.norm();//5 FP_FP256BN_mul(&t3,&t3,&t4); //t3.mul(t4);//6 //FP_FP256BN_copy(&t4,&t0); //t4.copy(t0); FP_FP256BN_add(&t4,&t0,&t1); //t4.add(t1); //t4.norm(); //7 FP_FP256BN_sub(&t3,&t3,&t4); //t3.sub(t4); FP_FP256BN_norm(&t3); //t3.norm(); //8 //FP_FP256BN_copy(&t4,&(P->y)); //t4.copy(y); FP_FP256BN_add(&t4,&(P->y),&(P->z)); //t4.add(z); FP_FP256BN_norm(&t4); //t4.norm();//9 FP_FP256BN_add(&x3,&(Q->y),&(Q->z)); //x3.add(Q.z); FP_FP256BN_norm(&x3); //x3.norm();//10 FP_FP256BN_mul(&t4,&t4,&x3); //t4.mul(x3); //11 //FP_FP256BN_copy(&x3,&t1); //x3.copy(t1); FP_FP256BN_add(&x3,&t1,&t2); //x3.add(t2); //x3.norm();//12 FP_FP256BN_sub(&t4,&t4,&x3); //t4.sub(x3); FP_FP256BN_norm(&t4); //t4.norm();//13 //FP_FP256BN_copy(&x3,&(P->x)); //x3.copy(x); FP_FP256BN_add(&x3,&(P->x),&(P->z)); //x3.add(z); FP_FP256BN_norm(&x3); //x3.norm(); //14 FP_FP256BN_add(&y3,&(Q->x),&(Q->z)); //y3.add(Q.z); FP_FP256BN_norm(&y3); //y3.norm();//15 FP_FP256BN_mul(&x3,&x3,&y3); //x3.mul(y3); //16 //FP_FP256BN_copy(&y3,&t0); //y3.copy(t0); FP_FP256BN_add(&y3,&t0,&t2); //y3.add(t2); //y3.norm();//17 FP_FP256BN_sub(&y3,&x3,&y3); //y3.rsub(x3); FP_FP256BN_norm(&y3); //y3.norm(); //18 //FP_FP256BN_copy(&z3,&t2); //z3.copy(t2); if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_mul(&z3,&t2,&b); //z3.mul(b); //18 else FP_FP256BN_imul(&z3,&t2,CURVE_B_I_FP256BN); //z3.imul(ROM.CURVE_B_I); //FP_FP256BN_copy(&x3,&y3); //x3.copy(y3); FP_FP256BN_sub(&x3,&y3,&z3); //x3.sub(z3); FP_FP256BN_norm(&x3); //x3.norm(); //20 //FP_FP256BN_copy(&z3,&x3); //z3.copy(x3); FP_FP256BN_add(&z3,&x3,&x3); //z3.add(x3); //z3.norm(); //21 FP_FP256BN_add(&x3,&x3,&z3); //x3.add(z3); //x3.norm(); //22 //FP_FP256BN_copy(&z3,&t1); //z3.copy(t1); FP_FP256BN_sub(&z3,&t1,&x3); //z3.sub(x3); FP_FP256BN_norm(&z3); //z3.norm(); //23 FP_FP256BN_add(&x3,&x3,&t1); //x3.add(t1); FP_FP256BN_norm(&x3); //x3.norm(); //24 if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) FP_FP256BN_mul(&y3,&y3,&b); //y3.mul(b); //18 else FP_FP256BN_imul(&y3,&y3,CURVE_B_I_FP256BN); //y3.imul(ROM.CURVE_B_I); //FP_FP256BN_copy(&t1,&t2); //t1.copy(t2); FP_FP256BN_add(&t1,&t2,&t2); //t1.add(t2); //t1.norm();//26 FP_FP256BN_add(&t2,&t2,&t1); //t2.add(t1); //t2.norm();//27 FP_FP256BN_sub(&y3,&y3,&t2); //y3.sub(t2); //y3.norm(); //28 FP_FP256BN_sub(&y3,&y3,&t0); //y3.sub(t0); FP_FP256BN_norm(&y3); //y3.norm(); //29 //FP_FP256BN_copy(&t1,&y3); //t1.copy(y3); FP_FP256BN_add(&t1,&y3,&y3); //t1.add(y3); //t1.norm();//30 FP_FP256BN_add(&y3,&y3,&t1); //y3.add(t1); FP_FP256BN_norm(&y3); //y3.norm(); //31 //FP_FP256BN_copy(&t1,&t0); //t1.copy(t0); FP_FP256BN_add(&t1,&t0,&t0); //t1.add(t0); //t1.norm(); //32 FP_FP256BN_add(&t0,&t0,&t1); //t0.add(t1); //t0.norm();//33 FP_FP256BN_sub(&t0,&t0,&t2); //t0.sub(t2); FP_FP256BN_norm(&t0); //t0.norm();//34 //FP_FP256BN_copy(&t1,&t4); //t1.copy(t4); FP_FP256BN_mul(&t1,&t4,&y3); //t1.mul(y3);//35 //FP_FP256BN_copy(&t2,&t0); //t2.copy(t0); FP_FP256BN_mul(&t2,&t0,&y3); //t2.mul(y3);//36 //FP_FP256BN_copy(&y3,&x3); //y3.copy(x3); FP_FP256BN_mul(&y3,&x3,&z3); //y3.mul(z3);//37 FP_FP256BN_add(&(P->y),&y3,&t2); //y3.add(t2); //y3.norm();//38 FP_FP256BN_mul(&x3,&x3,&t3); //x3.mul(t3);//39 FP_FP256BN_sub(&(P->x),&x3,&t1); //x3.sub(t1);//40 FP_FP256BN_mul(&z3,&z3,&t4); //z3.mul(t4);//41 //FP_FP256BN_copy(&t1,&t3); //t1.copy(t3); FP_FP256BN_mul(&t1,&t3,&t0); //t1.mul(t0);//42 FP_FP256BN_add(&(P->z),&z3,&t1); //z3.add(t1); //FP_FP256BN_copy(&(P->x),&x3); //x.copy(x3); FP_FP256BN_norm(&(P->x)); //x.norm(); //FP_FP256BN_copy(&(P->y),&y3); //y.copy(y3); FP_FP256BN_norm(&(P->y)); //y.norm(); //FP_FP256BN_copy(&(P->z),&z3); //z.copy(z3); FP_FP256BN_norm(&(P->z)); //z.norm(); } #else FP_FP256BN A,B,C,D,E,F,G,b; if (ECP_FP256BN_isinf(Q)) return; if (ECP_FP256BN_isinf(P)) { ECP_FP256BN_copy(P,Q); return; } //FP_FP256BN_copy(&A,&(P->z)); //FP A=new FP(z); //FP_FP256BN_copy(&C,&(P->x)); //FP C=new FP(x); //FP_FP256BN_copy(&D,&(P->y)); //FP D=new FP(y); FP_FP256BN_mul(&A,&(P->z),&(Q->z)); //A.mul(Q.z); //FP_FP256BN_copy(&B,&A); //B.copy(A); FP_FP256BN_sqr(&B,&A); //B.sqr(); FP_FP256BN_mul(&C,&(P->x),&(Q->x)); //C.mul(Q.x); FP_FP256BN_mul(&D,&(P->y),&(Q->y)); //D.mul(Q.y); //FP_FP256BN_copy(&E,&C); //E.copy(C); FP_FP256BN_mul(&E,&C,&D); //E.mul(D); if (CURVE_B_I_FP256BN==0) //if (ROM.CURVE_B_I==0) { FP_FP256BN_rcopy(&b,CURVE_B_FP256BN); //FP b=new FP(new BIG(ROM.CURVE_B)); FP_FP256BN_mul(&E,&E,&b); //E.mul(b); } else FP_FP256BN_imul(&E,&E,CURVE_B_I_FP256BN); //E.imul(ROM.CURVE_B_I); //FP_FP256BN_copy(&F,&B); //F.copy(B); FP_FP256BN_sub(&F,&B,&E); //F.sub(E); //FP_FP256BN_copy(&G,&B); //G.copy(B); FP_FP256BN_add(&G,&B,&E); //G.add(E); if (CURVE_A_FP256BN==1) //if (ROM.CURVE_A==1) { //FP_FP256BN_copy(&E,&D); //E.copy(D); FP_FP256BN_sub(&E,&D,&C); //E.sub(C); } FP_FP256BN_add(&C,&C,&D); //C.add(D); //FP_FP256BN_copy(&B,&(P->x)); //B.copy(x); FP_FP256BN_add(&B,&(P->x),&(P->y)); //B.add(y); //FP_FP256BN_copy(&D,&(Q->x)); //D.copy(Q.x); FP_FP256BN_add(&D,&(Q->x),&(Q->y)); //D.add(Q.y); FP_FP256BN_norm(&B); //B.norm(); FP_FP256BN_norm(&D); //D.norm(); FP_FP256BN_mul(&B,&B,&D); //B.mul(D); FP_FP256BN_sub(&B,&B,&C); //B.sub(C); FP_FP256BN_norm(&B); //B.norm(); FP_FP256BN_norm(&F); //F.norm(); FP_FP256BN_mul(&B,&B,&F); //B.mul(F); //FP_FP256BN_copy(&(P->x),&A); //x.copy(A); FP_FP256BN_mul(&(P->x),&A,&B); //x.mul(B); FP_FP256BN_norm(&G); //G.norm(); if (CURVE_A_FP256BN==1) //if (ROM.CURVE_A==1) { FP_FP256BN_norm(&E); //E.norm(); //FP_FP256BN_copy(&C,&E); //C.copy(E); FP_FP256BN_mul(&C,&E,&G); //C.mul(G); } if (CURVE_A_FP256BN==-1) //if (ROM.CURVE_A==-1) { FP_FP256BN_norm(&C); //C.norm(); FP_FP256BN_mul(&C,&C,&G); //C.mul(G); } //FP_FP256BN_copy(&(P->y),&A); //y.copy(A); FP_FP256BN_mul(&(P->y),&A,&C); //y.mul(C); //FP_FP256BN_copy(&(P->z),&F); //z.copy(F); FP_FP256BN_mul(&(P->z),&F,&G); //z.mul(G); #endif } /* Set P-=Q */ /* SU=16 */ void ECP_FP256BN_sub(ECP_FP256BN *P,ECP_FP256BN *Q) { ECP_FP256BN_neg(Q); ECP_FP256BN_add(P,Q); ECP_FP256BN_neg(Q); } #endif #if CURVETYPE_FP256BN!=MONTGOMERY /* constant time multiply by small integer of length bts - use ladder */ void ECP_FP256BN_pinmul(ECP_FP256BN *P,int e,int bts) { int i,b; ECP_FP256BN R0,R1; ECP_FP256BN_affine(P); ECP_FP256BN_inf(&R0); ECP_FP256BN_copy(&R1,P); for (i=bts-1; i>=0; i--) { b=(e>>i)&1; ECP_FP256BN_copy(P,&R1); ECP_FP256BN_add(P,&R0); ECP_FP256BN_cswap(&R0,&R1,b); ECP_FP256BN_copy(&R1,P); ECP_FP256BN_dbl(&R0); ECP_FP256BN_cswap(&R0,&R1,b); } ECP_FP256BN_copy(P,&R0); ECP_FP256BN_affine(P); } #endif /* Set P=r*P */ /* SU=424 */ void ECP_FP256BN_mul(ECP_FP256BN *P,BIG_256_56 e) { #if CURVETYPE_FP256BN==MONTGOMERY /* Montgomery ladder */ int nb,i,b; ECP_FP256BN R0,R1,D; if (ECP_FP256BN_isinf(P)) return; if (BIG_256_56_iszilch(e)) { ECP_FP256BN_inf(P); return; } ECP_FP256BN_affine(P); ECP_FP256BN_copy(&R0,P); ECP_FP256BN_copy(&R1,P); ECP_FP256BN_dbl(&R1); ECP_FP256BN_copy(&D,P); ECP_FP256BN_affine(&D); nb=BIG_256_56_nbits(e); for (i=nb-2; i>=0; i--) { b=BIG_256_56_bit(e,i); ECP_FP256BN_copy(P,&R1); ECP_FP256BN_add(P,&R0,&D); ECP_FP256BN_cswap(&R0,&R1,b); ECP_FP256BN_copy(&R1,P); ECP_FP256BN_dbl(&R0); ECP_FP256BN_cswap(&R0,&R1,b); } ECP_FP256BN_copy(P,&R0); #else /* fixed size windows */ int i,nb,s,ns; BIG_256_56 mt,t; ECP_FP256BN Q,W[8],C; sign8 w[1+(NLEN_256_56*BASEBITS_256_56+3)/4]; if (ECP_FP256BN_isinf(P)) return; if (BIG_256_56_iszilch(e)) { ECP_FP256BN_inf(P); return; } ECP_FP256BN_affine(P); /* precompute table */ ECP_FP256BN_copy(&Q,P); ECP_FP256BN_dbl(&Q); ECP_FP256BN_copy(&W[0],P); for (i=1; i<8; i++) { ECP_FP256BN_copy(&W[i],&W[i-1]); ECP_FP256BN_add(&W[i],&Q); } //printf("W[1]= ");ECP_output(&W[1]); printf("\n"); /* make exponent odd - add 2P if even, P if odd */ BIG_256_56_copy(t,e); s=BIG_256_56_parity(t); BIG_256_56_inc(t,1); BIG_256_56_norm(t); ns=BIG_256_56_parity(t); BIG_256_56_copy(mt,t); BIG_256_56_inc(mt,1); BIG_256_56_norm(mt); BIG_256_56_cmove(t,mt,s); ECP_FP256BN_cmove(&Q,P,ns); ECP_FP256BN_copy(&C,&Q); nb=1+(BIG_256_56_nbits(t)+3)/4; /* convert exponent to signed 4-bit window */ for (i=0; i=0; i--) { ECP_FP256BN_select(&Q,W,w[i]); ECP_FP256BN_dbl(P); ECP_FP256BN_dbl(P); ECP_FP256BN_dbl(P); ECP_FP256BN_dbl(P); ECP_FP256BN_add(P,&Q); } ECP_FP256BN_sub(P,&C); /* apply correction */ #endif ECP_FP256BN_affine(P); } #if CURVETYPE_FP256BN!=MONTGOMERY /* Set P=eP+fQ double multiplication */ /* constant time - as useful for GLV method in pairings */ /* SU=456 */ void ECP_FP256BN_mul2(ECP_FP256BN *P,ECP_FP256BN *Q,BIG_256_56 e,BIG_256_56 f) { BIG_256_56 te,tf,mt; ECP_FP256BN S,T,W[8],C; sign8 w[1+(NLEN_256_56*BASEBITS_256_56+1)/2]; int i,a,b,s,ns,nb; ECP_FP256BN_affine(P); ECP_FP256BN_affine(Q); BIG_256_56_copy(te,e); BIG_256_56_copy(tf,f); /* precompute table */ ECP_FP256BN_copy(&W[1],P); ECP_FP256BN_sub(&W[1],Q); /* P+Q */ ECP_FP256BN_copy(&W[2],P); ECP_FP256BN_add(&W[2],Q); /* P-Q */ ECP_FP256BN_copy(&S,Q); ECP_FP256BN_dbl(&S); /* S=2Q */ ECP_FP256BN_copy(&W[0],&W[1]); ECP_FP256BN_sub(&W[0],&S); ECP_FP256BN_copy(&W[3],&W[2]); ECP_FP256BN_add(&W[3],&S); ECP_FP256BN_copy(&T,P); ECP_FP256BN_dbl(&T); /* T=2P */ ECP_FP256BN_copy(&W[5],&W[1]); ECP_FP256BN_add(&W[5],&T); ECP_FP256BN_copy(&W[6],&W[2]); ECP_FP256BN_add(&W[6],&T); ECP_FP256BN_copy(&W[4],&W[5]); ECP_FP256BN_sub(&W[4],&S); ECP_FP256BN_copy(&W[7],&W[6]); ECP_FP256BN_add(&W[7],&S); /* if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction */ s=BIG_256_56_parity(te); BIG_256_56_inc(te,1); BIG_256_56_norm(te); ns=BIG_256_56_parity(te); BIG_256_56_copy(mt,te); BIG_256_56_inc(mt,1); BIG_256_56_norm(mt); BIG_256_56_cmove(te,mt,s); ECP_FP256BN_cmove(&T,P,ns); ECP_FP256BN_copy(&C,&T); s=BIG_256_56_parity(tf); BIG_256_56_inc(tf,1); BIG_256_56_norm(tf); ns=BIG_256_56_parity(tf); BIG_256_56_copy(mt,tf); BIG_256_56_inc(mt,1); BIG_256_56_norm(mt); BIG_256_56_cmove(tf,mt,s); ECP_FP256BN_cmove(&S,Q,ns); ECP_FP256BN_add(&C,&S); BIG_256_56_add(mt,te,tf); BIG_256_56_norm(mt); nb=1+(BIG_256_56_nbits(mt)+1)/2; /* convert exponent to signed 2-bit window */ for (i=0; i=0; i--) { ECP_FP256BN_select(&T,W,w[i]); ECP_FP256BN_dbl(P); ECP_FP256BN_dbl(P); ECP_FP256BN_add(P,&T); } ECP_FP256BN_sub(P,&C); /* apply correction */ ECP_FP256BN_affine(P); } #endif #ifdef HAS_MAIN int main() { int i; ECP_FP256BN G,P; csprng RNG; BIG_256_56 r,s,x,y,b,m,w,q; BIG_256_56_rcopy(x,CURVE_Gx); #if CURVETYPE_FP256BN!=MONTGOMERY BIG_256_56_rcopy(y,CURVE_Gy); #endif BIG_256_56_rcopy(m,Modulus_FP256BN); printf("x= "); BIG_256_56_output(x); printf("\n"); #if CURVETYPE_FP256BN!=MONTGOMERY printf("y= "); BIG_256_56_output(y); printf("\n"); #endif RNG_seed(&RNG,3,"abc"); #if CURVETYPE_FP256BN!=MONTGOMERY ECP_FP256BN_set(&G,x,y); #else ECP_FP256BN_set(&G,x); #endif if (ECP_FP256BN_isinf(&G)) printf("Failed to set - point not on curve\n"); else printf("set success\n"); ECP_FP256BN_output(&G); BIG_256_56_rcopy(r,CURVE_Order); //BIG_dec(r,7); printf("r= "); BIG_256_56_output(r); printf("\n"); ECP_FP256BN_copy(&P,&G); ECP_FP256BN_mul(&P,r); ECP_FP256BN_output(&P); //exit(0); BIG_256_56_randomnum(w,&RNG); BIG_256_56_mod(w,r); ECP_FP256BN_copy(&P,&G); ECP_FP256BN_mul(&P,w); ECP_FP256BN_output(&P); return 0; } #endif