/* this*=c mod Modulus, where c is a small int */ public void IMul(int c) { // norm(); bool s = false; if (c < 0) { c = -c; s = true; } if (MODTYPE == PSEUDO_MERSENNE || MODTYPE == GENERALISED_MERSENNE) { DBIG d = x.PXMul(c); x.Copy(Mod(d)); XES = 2; } else { if (XES * c <= FEXCESS) { x.PMul(c); XES *= c; } else { // this is not good FP n = new FP(c); Mul(n); } } /* * if (c<=BIG.NEXCESS && XES*c<=FEXCESS) * { * x.imul(c); * XES*=c; * x.norm(); * } * else * { * DBIG d=x.pxmul(c); * x.copy(mod(d)); * XES=2; * } */ if (s) { Neg(); Norm(); } }
/* this=this^e */ /* Note this is simple square and multiply, so not side-channel safe */ public FP12 Pow(BIG e) { Norm(); e.Norm(); BIG e3 = new BIG(e); e3.PMul(3); e3.Norm(); FP12 w = new FP12(this); int nb = e3.NBits(); for (int i = nb - 2; i >= 1; i--) { w.USqr(); int bt = e3.Bit(i) - e.Bit(i); if (bt == 1) { w.mul(this); } if (bt == -1) { Conj(); w.mul(this); Conj(); } } w.Reduce(); return(w); /* * BIG z=new BIG(e); * FP12 r=new FP12(1); * * while (true) * { * int bt=z.parity(); * z.fshr(1); * if (bt==1) r.mul(w); * if (z.iszilch()) break; * w.usqr(); * } * r.reduce(); * return r; */ }
/* Optimal R-ate double pairing e(P,Q).e(R,S) */ public static FP12 Ate2(ECP2 P1, ECP Q1, ECP2 R1, ECP S1) { FP2 f; BIG x = new BIG(ROM.CURVE_Bnx); BIG n = new BIG(x); ECP2 K = new ECP2(); FP12 lv; int bt; ECP2 P = new ECP2(P1); ECP Q = new ECP(Q1); P.Affine(); Q.Affine(); ECP2 R = new ECP2(R1); ECP S = new ECP(S1); R.Affine(); S.Affine(); if (ECP.CURVE_PAIRING_TYPE == ECP.BN) { f = new FP2(new BIG(ROM.Fra), new BIG(ROM.Frb)); if (ECP.SEXTIC_TWIST == ECP.M_TYPE) { f.Inverse(); f.Norm(); } n.PMul(6); if (ECP.SIGN_OF_X == ECP.POSITIVEX) { n.Inc(2); } else { n.Dec(2); } } else { n.Copy(x); } n.Norm(); BIG n3 = new BIG(n); n3.PMul(3); n3.Norm(); FP Qx = new FP(Q.GetX()); FP Qy = new FP(Q.GetY()); FP Sx = new FP(S.GetX()); FP Sy = new FP(S.GetY()); ECP2 A = new ECP2(); ECP2 B = new ECP2(); FP12 r = new FP12(1); A.Copy(P); B.Copy(R); ECP2 MP = new ECP2(); MP.Copy(P); MP.Neg(); ECP2 MR = new ECP2(); MR.Copy(R); MR.Neg(); int nb = n3.NBits(); for (int i = nb - 2; i >= 1; i--) { r.Sqr(); lv = Line(A, A, Qx, Qy); r.SMul(lv, ECP.SEXTIC_TWIST); lv = Line(B, B, Sx, Sy); r.SMul(lv, ECP.SEXTIC_TWIST); bt = n3.Bit(i) - n.Bit(i); // bt=n.bit(i); if (bt == 1) { lv = Line(A, P, Qx, Qy); r.SMul(lv, ECP.SEXTIC_TWIST); lv = Line(B, R, Sx, Sy); r.SMul(lv, ECP.SEXTIC_TWIST); } if (bt == -1) { //P.neg(); lv = Line(A, MP, Qx, Qy); r.SMul(lv, ECP.SEXTIC_TWIST); //P.neg(); //R.neg(); lv = Line(B, MR, Sx, Sy); r.SMul(lv, ECP.SEXTIC_TWIST); //R.neg(); } } if (ECP.SIGN_OF_X == ECP.NEGATIVEX) { r.Conj(); } /* R-ate fixup required for BN curves */ if (ECP.CURVE_PAIRING_TYPE == ECP.BN) { if (ECP.SIGN_OF_X == ECP.NEGATIVEX) { // r.conj(); A.Neg(); B.Neg(); } K.Copy(P); K.Frob(f); lv = Line(A, K, Qx, Qy); r.SMul(lv, ECP.SEXTIC_TWIST); K.Frob(f); K.Neg(); lv = Line(A, K, Qx, Qy); r.SMul(lv, ECP.SEXTIC_TWIST); K.Copy(R); K.Frob(f); lv = Line(B, K, Sx, Sy); r.SMul(lv, ECP.SEXTIC_TWIST); K.Frob(f); K.Neg(); lv = Line(B, K, Sx, Sy); r.SMul(lv, ECP.SEXTIC_TWIST); } return(r); }
/// <summary> ///************** 64-bit specific *********************** </summary> /* reduce a DBIG to a BIG using the appropriate form of the modulus */ public static BIG Mod(DBIG d) { if (MODTYPE == PSEUDO_MERSENNE) { BIG b; long v, tw; BIG t = d.Split(MODBITS); b = new BIG(d); v = t.PMul(unchecked ((int)ROM.MConst)); t.Add(b); t.Norm(); tw = t.w[BIG.NLEN - 1]; t.w[BIG.NLEN - 1] &= FP.TMASK; t.w[0] += (ROM.MConst * ((tw >> TBITS) + (v << (BIG.BASEBITS - TBITS)))); t.Norm(); return(t); } if (FP.MODTYPE == MONTGOMERY_FRIENDLY) { BIG b; long[] cr = new long[2]; for (int i = 0; i < BIG.NLEN; i++) { cr = BIG.MulAdd(d.w[i], ROM.MConst - 1, d.w[i], d.w[BIG.NLEN + i - 1]); d.w[BIG.NLEN + i] += cr[0]; d.w[BIG.NLEN + i - 1] = cr[1]; } b = new BIG(0); for (int i = 0; i < BIG.NLEN; i++) { b.w[i] = d.w[BIG.NLEN + i]; } b.Norm(); return(b); } if (MODTYPE == GENERALISED_MERSENNE) { // GoldiLocks Only BIG b; BIG t = d.Split(MODBITS); b = new BIG(d); b.Add(t); DBIG dd = new DBIG(t); dd.Shl(MODBITS / 2); BIG tt = dd.Split(MODBITS); BIG lo = new BIG(dd); b.Add(tt); b.Add(lo); b.Norm(); tt.Shl(MODBITS / 2); b.Add(tt); long carry = b.w[BIG.NLEN - 1] >> TBITS; b.w[BIG.NLEN - 1] &= FP.TMASK; b.w[0] += carry; b.w[224 / BIG.BASEBITS] += carry << (224 % BIG.BASEBITS); b.Norm(); return(b); } if (MODTYPE == NOT_SPECIAL) { return(BIG.Monty(new BIG(ROM.Modulus), ROM.MConst, d)); } return(new BIG(0)); }