/* return this^e mod Modulus * public FP pow(BIG e) * { * int bt; * FP r=new FP(1); * e.norm(); * x.norm(); * FP m=new FP(this); * while (true) * { * bt=e.parity(); * e.fshr(1); * if (bt==1) r.mul(m); * if (e.iszilch()) break; * m.sqr(); * } * r.x.mod(p); * return r; * } */ /* return sqrt(this) mod Modulus */ public FP Sqrt() { Reduce(); BIG b = new BIG(ROM.Modulus); if (MOD8 == 5) { b.Dec(5); b.Norm(); b.Shr(3); FP i = new FP(this); i.x.Shl(1); FP v = i.Pow(b); i.Mul(v); i.Mul(v); i.x.Dec(1); FP r = new FP(this); r.Mul(v); r.Mul(i); r.Reduce(); return(r); } else { b.Inc(1); b.Norm(); b.Shr(2); return(Pow(b)); } }
/* r=x^n using XTR method on traces of FP12s */ public FP4 Xtr_Pow(BIG n) { FP4 a = new FP4(3); FP4 b = new FP4(this); FP4 c = new FP4(b); c.Xtr_D(); FP4 t = new FP4(0); FP4 r = new FP4(0); n.Norm(); int par = n.Parity(); BIG v = new BIG(n); v.FShr(1); if (par == 0) { v.Dec(1); v.Norm(); } int nb = v.NBits(); for (int i = nb - 1; i >= 0; i--) { if (v.Bit(i) != 1) { t.Copy(b); Conj(); c.Conj(); b.Xtr_A(a, this, c); Conj(); c.Copy(t); c.Xtr_D(); a.Xtr_D(); } else { t.Copy(a); t.Conj(); a.Copy(b); a.Xtr_D(); b.Xtr_A(c, this, t); c.Xtr_D(); } } if (par == 0) { r.Copy(c); } else { r.Copy(b); } r.Reduce(); return(r); }
/* this=1/this mod Modulus */ public void Inverse() { /* * BIG r=redc(); * r.invmodp(p); * x.copy(r); * nres(); */ BIG m2 = new BIG(ROM.Modulus); m2.Dec(2); m2.Norm(); Copy(Pow(m2)); }
public FP Pow(BIG e) { sbyte[] w = new sbyte[1 + (BIG.NLEN * BIG.BASEBITS + 3) / 4]; FP[] tb = new FP[16]; BIG t = new BIG(e); t.Norm(); int nb = 1 + (t.NBits() + 3) / 4; for (int i = 0; i < nb; i++) { int lsbs = t.LastBits(4); t.Dec(lsbs); t.Norm(); w[i] = (sbyte)lsbs; t.FShr(4); } tb[0] = new FP(1); tb[1] = new FP(this); for (int i = 2; i < 16; i++) { tb[i] = new FP(tb[i - 1]); tb[i].Mul(this); } FP r = new FP(tb[w[nb - 1]]); for (int i = nb - 2; i >= 0; i--) { r.Sqr(); r.Sqr(); r.Sqr(); r.Sqr(); r.Mul(tb[w[i]]); } 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); }