public FieldElement Compute(Point P, Point Q) { FieldElement f = new Complex((Fp)this.field, BigInt.ONE); JacobPoint V = this.ec.AToJ(P); BigInt n = this.order.Subtract(BigInt.ONE); Point nP = ec.Negate(P); //byte[] ba =n.toByteArray(); sbyte[] r = Naf(this.order, (byte)2); //Point T; //BigInt [] lamda= new BigInt[1];; FieldElement u; for (int i = r.Length - 2; i >= 0; i--) { u = EncDbl(V, Q); //f=f.square().multiply(u); f = this.gt.Multiply(this.gt.Square(f), u); if (r[i] == 1) { u = EncAdd(V, P, Q); f = this.gt.Multiply(f, u); } if (r[i] == -1) //this is probably going to fail! { u = EncAdd(V, nP, Q); f = this.gt.Multiply(f, u); } } f = ((Complex)f).Conjugate().Divide((Complex)f); return(this.gt.Pow(f, this.finalExponent)); }
//add two point, save result in the first argument public void JAddMut(JacobPoint P, Point Q) { if (P.IsInfinity()) { P.X = (BigInt)Q.X; P.Y = (BigInt)Q.Y; P.Z = (BigInt)this.field.GetOne(); return; } if (Q.IsInfinity()) { return; } FieldElement x1 = P.X; FieldElement y1 = P.Y; FieldElement z1 = P.Z; FieldElement x = Q.X; FieldElement y = Q.Y; //t1=z1^2 FieldElement t1 = this.field.Square(z1); //t2=z1t1 FieldElement t2 = this.field.Multiply(z1, t1); //t3=xt1 FieldElement t3 = this.field.Multiply(x, t1); //t4=Yt2 FieldElement t4 = this.field.Multiply(y, t2); //t5=t3-x1 FieldElement t5 = this.field.Subtract(t3, x1); //t6=t4-y1 FieldElement t6 = this.field.Subtract(t4, y1); //t7=t5^2 FieldElement t7 = this.field.Square(t5); //t8=t5t7 FieldElement t8 = this.field.Multiply(t5, t7); //t9=x1t7 FieldElement t9 = this.field.Multiply(x1, t7); //x3=t6^2-(t8+2t9) FieldElement x3 = this.field.Square(t6); x3 = this.field.Subtract(x3, this.field.Add(t8, this.field.Add(t9, t9))); //y3=t6(t9-x3)-y1t8 FieldElement y3 = this.field.Multiply(t6, this.field.Subtract(t9, x3)); y3 = this.field.Subtract(y3, this.field.Multiply(y1, t8)); //z3=z1t5 FieldElement z3 = this.field.Multiply(z1, t5); P.X = (BigInt)x3; P.Y = (BigInt)y3; P.Z = (BigInt)z3; return; }
public Complex EncAdd(JacobPoint A, Point P, Point Q) { BigInt x1 = A.X; BigInt y1 = A.Y; BigInt z1 = A.Z; FieldElement x = P.X; FieldElement y = P.Y; //t1=z1^2 FieldElement t1 = this.field.Square(z1); //t2=z1t1 FieldElement t2 = this.field.Multiply(z1, t1); //t3=xt1 FieldElement t3 = this.field.Multiply(x, t1); //t4=Yt2 FieldElement t4 = this.field.Multiply(y, t2); //t5=t3-x1 FieldElement t5 = this.field.Subtract(t3, x1); //t6=t4-y1 FieldElement t6 = this.field.Subtract(t4, y1); //t7=t5^2 FieldElement t7 = this.field.Square(t5); //t8=t5t7 FieldElement t8 = this.field.Multiply(t5, t7); //t9=x1t7 FieldElement t9 = this.field.Multiply(x1, t7); //x3=t6^2-(t8+2t9) FieldElement x3 = this.field.Square(t6); x3 = this.field.Subtract(x3, this.field.Add(t8, this.field.Add(t9, t9))); //y3=t6(t9-x3)-y1t8 FieldElement y3 = this.field.Multiply(t6, this.field.Subtract(t9, x3)); y3 = this.field.Subtract(y3, this.field.Multiply(y1, t8)); //z3=z1t5 FieldElement z3 = this.field.Multiply(z1, t5); A.X = (BigInt)x3; A.Y = (BigInt)y3; A.Z = (BigInt)z3; //z3yqi -(z3Y-t6(xq+x)) FieldElement imag = this.field.Multiply(z3, Q.Y); FieldElement real = this.field.Add(Q.X, x); real = this.field.Multiply(real, t6); real = this.field.Subtract(real, this.field.Multiply(z3, y)); return(new Complex((Fp)this.field, (BigInt)real, (BigInt)imag)); }
public override bool Equals(Object obj) { //this could fail if (this == obj) { return(true); } if (obj == null) { return(false); } //if ( != obj.getClass()) // return false; JacobPoint other = (JacobPoint)obj; if (x == null) { if (other.x != null) { return(false); } } else if (!x.Equals(other.x)) { return(false); } if (y == null) { if (other.y != null) { return(false); } } else if (!y.Equals(other.y)) { return(false); } if (z == null) { if (other.z != null) { return(false); } } else if (!z.Equals(other.z)) { return(false); } return(true); }
// convert Jacobian to Affine public Point JToA(JacobPoint P) { if (P.IsInfinity()) { return(Point.INFINITY); } FieldElement bi = P.Z; FieldElement zInverse = this.field.Inverse(P.Z); FieldElement square = this.field.Square(zInverse); //x =X/Z^2 FieldElement x = this.field.Multiply(P.X, square); //y=Y/Z^3 FieldElement y = this.field.Multiply(P.Y, this.field.Multiply(square, zInverse)); return(new Point(x, y)); }
//multiplication using Jacobian coordinates public JacobPoint JMultiplyMut(Point p, BigInt k) { if (!(this.field.IsValidElement(p.X)) || !(this.field.IsValidElement(p.Y))) { throw new ArgumentException("The input point must be taken over the field."); } if (p.IsInfinity()) { return(this.AToJ(p)); } if (k.Equals(BigInt.ZERO)) { return(JacobPoint.INFINITY); } if (k.Equals(BigInt.ONE)) { return(this.AToJ(p)); } if (k.Signum() == -1) { k = k.Abs(); p = this.Negate(p); } //byte [] ba =k.toByteArray(); int degree = k.BitLength() - 2; JacobPoint result = this.AToJ(p); for (int i = degree; i >= 0; i--) { this.JDblMut(result); if (k.TestBit(i)) ///AQUI TE QUEDASTE IMPLEMENTAR TESTBIT { this.JAddMut(result, p); } } return(result); }
//used by tate pairing, point doubling in Jacobian coordinates, and return the value of f public Complex EncDbl(JacobPoint P, Point Q) { //if(P.isInfinity()) // return; BigInt x = P.X; BigInt y = P.Y; BigInt z = P.Z; //t1=y^2 FieldElement t1 = this.field.Square(y); //t2=4xt1 FieldElement t2 = this.field.Multiply(x, t1); //t2=this.field.multiply(t2, 4); t2 = this.field.Add(t2, t2); t2 = this.field.Add(t2, t2); //t3=8t1^2 FieldElement t3 = this.field.Square(t1); //t3 = this.field.multiply(t3, 8); t3 = this.field.Add(t3, t3); t3 = this.field.Add(t3, t3); t3 = this.field.Add(t3, t3); //t4=z^2 FieldElement t4 = this.field.Square(z); FieldElement t5; //if a==-3 if (this.ec.Opt) { t5 = this.field.Multiply(this.field.Subtract(x, t4), this.field.Add(x, t4)); t5 = this.field.Add(t5, this.field.Add(t5, t5)); } else { //t5=3x^2+aZ^4 t5 = this.field.Square(x); t5 = this.field.Add(t5, this.field.Add(t5, t5)); t5 = this.field.Add(t5, this.field.Multiply(this.ec.A4, this.field.Square(t4))); // FieldElement temp =this.field.square(this.field.square(z)); // temp=this.field.multiply(this.ec.getA4(), temp); // // t5=this.field.add(t5,temp); } //x3=t5^2-2t2 FieldElement x3 = this.field.Square(t5); x3 = this.field.Subtract(x3, this.field.Add(t2, t2)); //y3=t5(t2-x3)-t3 FieldElement y3 = this.field.Multiply(t5, this.field.Subtract(t2, x3)); y3 = this.field.Subtract(y3, t3); //z3=2y1z1 FieldElement z3 = this.field.Multiply(y, z); z3 = this.field.Add(z3, z3); P.X = (BigInt)x3; P.Y = (BigInt)y3; P.Z = (BigInt)z3; //Z3t4yQi-(2t1-t5(t4Xq+x1)) FieldElement real = this.field.Multiply(t4, Q.X); real = this.field.Add(real, x); real = this.field.Multiply(t5, real); real = this.field.Subtract(real, t1); real = this.field.Subtract(real, t1); FieldElement imag = this.field.Multiply(z3, t4); imag = this.field.Multiply(imag, Q.Y); return(new Complex((Fp)this.field, (BigInt)real, (BigInt)imag)); }
//point doubling in Jacobian coordinates, result is saving in the input point public void JDblMut(JacobPoint P) { if (P.IsInfinity()) { return; } BigInt x = P.X; BigInt y = P.Y; BigInt z = P.Z; //t1=y^2 FieldElement t1 = this.field.Square(y); //t2=4xt1 FieldElement t2 = this.field.Multiply(x, t1); //t2=this.field.multiply(t2, 4); t2 = this.field.Add(t2, t2); t2 = this.field.Add(t2, t2); //t3=8t1^2 FieldElement t3 = this.field.Square(t1); //t3 = this.field.multiply(t3, 8); t3 = this.field.Add(t3, t3); t3 = this.field.Add(t3, t3); t3 = this.field.Add(t3, t3); //t4=z^2 FieldElement t4 = this.field.Square(z); FieldElement t5; //if a==-3 if (opt) { t5 = this.field.Multiply(this.field.Subtract(x, t4), this.field.Add(x, t4)); t5 = this.field.Add(t5, this.field.Add(t5, t5)); } else { //t5=3x^2+aZ^4 =3x^2+at4^2 t5 = this.field.Square(x); t5 = this.field.Add(t5, this.field.Add(t5, t5)); t5 = this.field.Add(t5, this.field.Multiply(this.A4, this.field.Square(t4))); } //x3=t5^2-2t2 FieldElement x3 = this.field.Square(t5); x3 = this.field.Subtract(x3, this.field.Add(t2, t2)); //y3=t5(t2-x3)-t3 FieldElement y3 = this.field.Multiply(t5, this.field.Subtract(t2, x3)); y3 = this.field.Subtract(y3, t3); //z3=2y1z1 FieldElement z3 = this.field.Multiply(y, z); z3 = this.field.Add(z3, z3); P.X = (BigInt)x3; P.Y = (BigInt)y3; P.Z = (BigInt)z3; return; }
private JacobPoint Negate(JacobPoint p) { return(new JacobPoint(p.X, (BigInt)this.field.Negate(p.Y), p.Z)); }