/** * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 * D.1.6) The other solution is <code>z + 1</code>. * * @param beta * The value to solve the qradratic equation for. * @return the solution for <code>z<sup>2</sup> + z = beta</code> or * <code>null</code> if no solution exists. */ private ECFieldElement solveQuadradicEquation(ECFieldElement beta) { if (beta.x.SignValue == 0) { return(new F2mFieldElement( this.m, this.k1, this.k2, this.k3, BigInteger.Zero)); } ECFieldElement z = null; ECFieldElement gamma = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.Zero); while (gamma.ToBigInteger().SignValue == 0) { ECFieldElement t = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, new BigInteger(m, new Random())); z = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.Zero); ECFieldElement w = beta; for (int i = 1; i <= m - 1; i++) { ECFieldElement w2 = w.Square(); z = z.Square().Add(w2.Multiply(t)); w = w2.Add(beta); } if (w.x.SignValue != 0) { return(null); } gamma = z.Square().Add(z); } return(z); }
/* (non-Javadoc) * @see Org.BouncyCastle.Math.EC.ECPoint#add(Org.BouncyCastle.Math.EC.ECPoint) */ public override ECPoint Add( ECPoint b) { // Check, if points are on the same curve if (!curve.Equals(b.Curve)) { throw new ArgumentException("Only points on the same curve can be added"); } if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } F2mFieldElement.CheckFieldElements(this.x, b.X); F2mFieldElement x2 = (F2mFieldElement)b.X; F2mFieldElement y2 = (F2mFieldElement)b.Y; // Check if b = this or b = -this if (this.x.Equals(x2)) { // this = b, i.e. this must be doubled if (this.y.Equals(y2)) { return(this.Twice()); } // this = -b, i.e. the result is the point at infinity return(this.curve.Infinity); } F2mFieldElement lambda = (F2mFieldElement)(this.y.Add(y2)).Divide(this.x.Add(x2)); F2mFieldElement x3 = (F2mFieldElement)lambda.Square().Add(lambda).Add(this.x).Add(x2).Add(this.curve.A); F2mFieldElement y3 = (F2mFieldElement)lambda.Multiply(this.x.Add(x3)).Add(x3).Add(this.y); return(new F2mPoint(curve, x3, y3, withCompression)); }
public override ECPoint Twice() { if (this.IsInfinity) { return(this); } if (this.x.ToBigInteger().SignValue == 0) { return(this.curve.Infinity); } F2mFieldElement lambda = (F2mFieldElement)this.x.Add(this.y.Divide(this.x)); F2mFieldElement x2 = (F2mFieldElement)lambda.Square().Add(lambda).Add(this.curve.A); ECFieldElement ONE = this.curve.FromBigInteger(BigInteger.One); F2mFieldElement y2 = (F2mFieldElement)this.x.Square().Add( x2.Multiply(lambda.Add(ONE))); return(new F2mPoint(this.curve, x2, y2, withCompression)); }
/** * Adds another <code>ECPoints.F2m</code> to <code>this</code> without * checking if both points are on the same curve. Used by multiplication * algorithms, because there all points are a multiple of the same point * and hence the checks can be omitted. * @param b The other <code>ECPoints.F2m</code> to add to * <code>this</code>. * @return <code>this + b</code> */ internal F2mPoint AddSimple(F2mPoint b) { if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } F2mFieldElement x2 = (F2mFieldElement)b.X; F2mFieldElement y2 = (F2mFieldElement)b.Y; // Check if b == this or b == -this if (this.x.Equals(x2)) { // this == b, i.e. this must be doubled if (this.y.Equals(y2)) { return((F2mPoint)this.Twice()); } // this = -other, i.e. the result is the point at infinity return((F2mPoint)this.curve.Infinity); } ECFieldElement xSum = this.x.Add(x2); F2mFieldElement lambda = (F2mFieldElement)(this.y.Add(y2)).Divide(xSum); F2mFieldElement x3 = (F2mFieldElement)lambda.Square().Add(lambda).Add(xSum).Add(this.curve.A); F2mFieldElement y3 = (F2mFieldElement)lambda.Multiply(this.x.Add(x3)).Add(x3).Add(this.y); return(new F2mPoint(curve, x3, y3, withCompression)); }
/* (non-Javadoc) * @see Org.BouncyCastle.Math.EC.ECPoint#twice() */ public override ECPoint Twice() { // Twice identity element (point at infinity) is identity if (this.IsInfinity) { return(this); } // if x1 == 0, then (x1, y1) == (x1, x1 + y1) // and hence this = -this and thus 2(x1, y1) == infinity if (this.x.ToBigInteger().SignValue == 0) { return(this.curve.Infinity); } F2mFieldElement lambda = (F2mFieldElement)this.x.Add(this.y.Divide(this.x)); F2mFieldElement x3 = (F2mFieldElement)lambda.Square().Add(lambda).Add(this.curve.A); F2mFieldElement y3 = (F2mFieldElement)this.x.Square().Add(lambda.Multiply(x3)).Add(x3); return(new F2mPoint(this.curve, x3, y3, withCompression)); }
/** * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). * * @param xEnc * The encoding of field element xp. * @param ypBit * ~yp, an indication bit for the decompression of yp. * @return the decompressed point. */ private ECPoint decompressPoint( byte[] xEnc, int ypBit) { ECFieldElement xp = new F2mFieldElement( this.m, this.k1, this.k2, this.k3, new BigInteger(1, xEnc)); ECFieldElement yp = null; if (xp.x.SignValue == 0) { yp = (F2mFieldElement)b; for (int i = 0; i < m - 1; i++) { yp = yp.Square(); } } else { ECFieldElement beta = xp.Add(a).Add( b.Multiply(xp.Square().Invert())); ECFieldElement z = solveQuadradicEquation(beta); if (z == null) { throw new ArithmeticException("Invalid point compression"); } int zBit = 0; if (z.x.TestBit(0)) { zBit = 1; } if (zBit != ypBit) { z = z.Add(new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.One)); } yp = xp.Multiply(z); } return(new F2mPoint(this, xp, yp)); }
internal F2mPoint AddSimple(F2mPoint b) { if (this.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } F2mFieldElement x2 = (F2mFieldElement)b.X; F2mFieldElement y2 = (F2mFieldElement)b.Y; if (this.x.Equals(x2)) { if (this.y.Equals(y2)) { return((F2mPoint)this.Twice()); } return((F2mPoint)this.curve.Infinity); } ECFieldElement xSum = this.x.Add(x2); F2mFieldElement lambda = (F2mFieldElement)(this.y.Add(y2)).Divide(xSum); F2mFieldElement x3 = (F2mFieldElement)lambda.Square().Add(lambda).Add(xSum).Add(this.curve.A); F2mFieldElement y3 = (F2mFieldElement)lambda.Multiply(this.x.Add(x3)).Add(x3).Add(this.y); return(new F2mPoint(curve, x3, y3, withCompression)); }
/** * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 * D.1.6) The other solution is <code>z + 1</code>. * * @param beta * The value to solve the qradratic equation for. * @return the solution for <code>z<sup>2</sup> + z = beta</code> or * <code>null</code> if no solution exists. */ private ECFieldElement solveQuadradicEquation(ECFieldElement beta) { if (beta.x.SignValue == 0) { return new F2mFieldElement( this.m, this.k1, this.k2, this.k3, BigInteger.Zero); } ECFieldElement z = null; ECFieldElement gamma = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.Zero); while (gamma.ToBigInteger().SignValue == 0) { ECFieldElement t = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, new BigInteger(m, new Random())); z = new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.Zero); ECFieldElement w = beta; for (int i = 1; i <= m - 1; i++) { ECFieldElement w2 = w.Square(); z = z.Square().Add(w2.Multiply(t)); w = w2.Add(beta); } if (w.x.SignValue != 0) { return null; } gamma = z.Square().Add(z); } return z; }
/** * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2). * * @param xEnc * The encoding of field element xp. * @param ypBit * ~yp, an indication bit for the decompression of yp. * @return the decompressed point. */ private ECPoint decompressPoint( byte[] xEnc, int ypBit) { ECFieldElement xp = new F2mFieldElement( this.m, this.k1, this.k2, this.k3, new BigInteger(1, xEnc)); ECFieldElement yp = null; if (xp.x.SignValue == 0) { yp = (F2mFieldElement)b; for (int i = 0; i < m - 1; i++) { yp = yp.Square(); } } else { ECFieldElement beta = xp.Add(a).Add( b.Multiply(xp.Square().Invert())); ECFieldElement z = solveQuadradicEquation(beta); if (z == null) { throw new ArithmeticException("Invalid point compression"); } int zBit = 0; if (z.x.TestBit(0)) { zBit = 1; } if (zBit != ypBit) { z = z.Add(new F2mFieldElement(this.m, this.k1, this.k2, this.k3, BigInteger.One)); } yp = xp.Multiply(z); } return new F2mPoint(this, xp, yp); }