public BN128 <T> Mul(BigInteger s) { if (s.CompareTo(BigInteger.Zero) == 0) // P * 0 = 0 { return(Zero()); } if (IsZero()) { return(this); // 0 * s = 0 } BN128 <T> res = Zero(); for (int i = s.BitLength - 1; i >= 0; i--) { res = res.Dbl(); if (s.TestBit(i)) { res = res.Add(this); } } return(res); }
/** * Runs affine transformation and encodes point at infinity as (0; 0; 0) */ public BN128 <T> ToEthNotation() { BN128 <T> affine = ToAffine(); // affine zero is (0; 1; 0), convert to Ethereum zero: (0; 0; 0) if (affine.IsZero()) { return(Zero()); } else { return(affine); } }
public BN128 <T> Add(BN128 <T> o) { if (this.IsZero()) { return(o); // 0 + P = P } if (o.IsZero()) { return(this); // P + 0 = P } T x1 = this.x, y1 = this.y, z1 = this.z; T x2 = o.x, y2 = o.y, z2 = o.z; // ported code is started from here // next calculations are done in Jacobian coordinates T z1z1 = z1.Squared(); T z2z2 = z2.Squared(); T u1 = x1.Mul(z2z2); T u2 = x2.Mul(z1z1); T z1Cubed = z1.Mul(z1z1); T z2Cubed = z2.Mul(z2z2); T s1 = y1.Mul(z2Cubed); // s1 = y1 * Z2^3 T s2 = y2.Mul(z1Cubed); // s2 = y2 * Z1^3 if (u1.Equals(u2) && s1.Equals(s2)) { return(Dbl()); // P + P = 2P } T h = u2.Sub(u1); // h = u2 - u1 T i = h.Dbl().Squared(); // i = (2 * h)^2 T j = h.Mul(i); // j = h * i T r = s2.Sub(s1).Dbl(); // r = 2 * (s2 - s1) T v = u1.Mul(i); // v = u1 * i T zz = z1.Add(z2).Squared() .Sub(z1.Squared()).Sub(z2.Squared()); T x3 = r.Squared().Sub(j).Sub(v.Dbl()); // x3 = r^2 - j - 2 * v T y3 = v.Sub(x3).Mul(r).Sub(s1.Mul(j).Dbl()); // y3 = r * (v - x3) - 2 * (s1 * j) T z3 = zz.Mul(h); // z3 = ((z1+z2)^2 - z1^2 - z2^2) * h = zz * h return(Instance(x3, y3, z3)); }
/** * Transforms given Jacobian to affine coordinates and then creates a point */ public virtual BN128 <T> ToAffine() { if (IsZero()) { BN128 <T> zero = Zero(); return(Instance(zero.x, One(), zero.z)); // (0; 1; 0) } T zInv = z.Inverse(); T zInv2 = zInv.Squared(); T zInv3 = zInv2.Mul(zInv); T ax = x.Mul(zInv2); T ay = y.Mul(zInv3); return(Instance(ax, ay, One())); }
/** * Checks whether provided data are coordinates of a point belonging to subgroup, if check has * been passed it returns a point, otherwise returns null */ public static BN128G2 Create(byte[] a, byte[] b, byte[] c, byte[] d) { BN128 <Fp2> p = BN128Fp2.Create(a, b, c, d); // fails if point is invalid if (p == null) { return(null); } // check whether point is a subgroup member if (!IsGroupMember(p)) { return(null); } return(new BN128G2(p)); }
public override bool Equals(object o) { if (this == o) { return(true); } if (!(o is BN128 <T>)) { return(false); } BN128 <T> bn128 = o as BN128 <T>; if (x != null ? !x.Equals(bn128.x) : bn128.x != null) { return(false); } if (y != null ? !y.Equals(bn128.y) : bn128.y != null) { return(false); } return(!(z != null ? !z.Equals(bn128.z) : bn128.z != null)); }
private static bool IsGroupMember(BN128 <Fp2> p) { BN128 <Fp2> left = p.Mul(FR_NEG_ONE).Add(p); return(left.IsZero()); // should satisfy condition: -1 * p + p == 0, where -1 belongs to F_r }
public BN128G2(BN128 <Fp2> p) : base(p.x, p.y, p.z) { }