protected static ECFieldElement[] GetInitialZCoords(ECCurve curve) { // Cope with null curve, most commonly used by implicitlyCa int coord = null == curve ? ECCurve.COORD_AFFINE : curve.CoordinateSystem; switch (coord) { case ECCurve.COORD_AFFINE: case ECCurve.COORD_LAMBDA_AFFINE: return EMPTY_ZS; default: break; } ECFieldElement one = curve.FromBigInteger(BigInteger.One); switch (coord) { case ECCurve.COORD_HOMOGENEOUS: case ECCurve.COORD_JACOBIAN: case ECCurve.COORD_LAMBDA_PROJECTIVE: return new ECFieldElement[] { one }; case ECCurve.COORD_JACOBIAN_CHUDNOVSKY: return new ECFieldElement[] { one, one, one }; case ECCurve.COORD_JACOBIAN_MODIFIED: return new ECFieldElement[] { one, curve.A }; default: throw new ArgumentException("unknown coordinate system"); } }
/// <summary> /// Hashes a seed t into a point T on the curve. Returns null if t is unsuitable. /// </summary> /// <param name="curve">The elliptic curve in Weierstrass form</param> /// <param name="t">The seed</param> /// <returns>A random point T uniquely determined by seed t, otherwise null</returns> public static ECPoint?HashToWeierstrassCurve(ECCurve curve, byte[] t) { ECFieldElement x, ax, x3, y, y2; BigInteger P = curve.Field.Characteristic; SHA256? sha256 = SHA256.Create(); BigInteger hash = new BigInteger(sha256.ComputeHash(t)); // Check that the hash is within valid range if (hash.CompareTo(BigInteger.One) < 0 || hash.CompareTo(P) >= 0) { return(null); } // A valid point (x,y) must satisfy: y^2 = x^3 + Ax + B mod P // Convert hash from BigInt to FieldElement x modulo P x = curve.FromBigInteger(hash); // x ax = x.Multiply(curve.A); // Ax x3 = x.Square().Multiply(x); // x^3 = x^2 * x y2 = x3.Add(ax).Add(curve.B); // y^2 = x^3 + Ax + B y = y2.Sqrt(); // y = sqrt(x^3 + Ax + B) // y == null if square root mod P does not exist if (y == null) { return(null); } ECPoint T = curve.CreatePoint(x.ToBigInteger(), y.ToBigInteger()); // Use the built-in point validator, which also checks for membership // in weak subgroups if (!T.IsValid()) { return(null); } return(T); }
private void ImplSqrtTest(ECCurve c) { if (ECAlgorithms.IsFpCurve(c)) { BigInteger p = c.Field.Characteristic; BigInteger pMinusOne = p.Subtract(BigInteger.One); BigInteger legendreExponent = p.ShiftRight(1); int count = 0; while (count < 10) { BigInteger nonSquare = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusOne, secRand); if (!nonSquare.ModPow(legendreExponent, p).Equals(BigInteger.One)) { ECFieldElement root = c.FromBigInteger(nonSquare).Sqrt(); Assert.IsNull(root); ++count; } } } }
private void ImplSqrtTest(ECCurve c) { if (ECAlgorithms.IsFpCurve(c)) { BigInteger p = c.Field.Characteristic; BigInteger pMinusOne = p.Subtract(BigInteger.One); BigInteger legendreExponent = p.ShiftRight(1); int count = 0; while (count < 10) { BigInteger nonSquare = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusOne, secRand); if (!nonSquare.ModPow(legendreExponent, p).Equals(BigInteger.One)) { ECFieldElement root = c.FromBigInteger(nonSquare).Sqrt(); Assert.IsNull(root); ++count; } } } else if (ECAlgorithms.IsF2mCurve(c)) { int m = c.FieldSize; BigInteger x = new BigInteger(m, secRand); ECFieldElement fe = c.FromBigInteger(x); for (int i = 0; i < 100; ++i) { ECFieldElement sq = fe.Square(); ECFieldElement check = sq.Sqrt(); Assert.AreEqual(fe, check); fe = sq; } } }
public override ECPoint Add(ECPoint b) { if (base.IsInfinity) { return(b); } if (b.IsInfinity) { return(this); } ECCurve curve = this.Curve; int coordinateSystem = curve.CoordinateSystem; ECFieldElement rawXCoord = base.RawXCoord; ECFieldElement rawXCoord2 = b.RawXCoord; int num = coordinateSystem; switch (num) { case 0: { ECFieldElement rawYCoord = base.RawYCoord; ECFieldElement rawYCoord2 = b.RawYCoord; ECFieldElement eCFieldElement = rawXCoord.Add(rawXCoord2); ECFieldElement eCFieldElement2 = rawYCoord.Add(rawYCoord2); if (!eCFieldElement.IsZero) { ECFieldElement eCFieldElement3 = eCFieldElement2.Divide(eCFieldElement); ECFieldElement eCFieldElement4 = eCFieldElement3.Square().Add(eCFieldElement3).Add(eCFieldElement).Add(curve.A); ECFieldElement y = eCFieldElement3.Multiply(rawXCoord.Add(eCFieldElement4)).Add(eCFieldElement4).Add(rawYCoord); return(new F2mPoint(curve, eCFieldElement4, y, base.IsCompressed)); } if (eCFieldElement2.IsZero) { return(this.Twice()); } return(curve.Infinity); } case 1: { ECFieldElement rawYCoord3 = base.RawYCoord; ECFieldElement eCFieldElement5 = base.RawZCoords[0]; ECFieldElement rawYCoord4 = b.RawYCoord; ECFieldElement eCFieldElement6 = b.RawZCoords[0]; bool isOne = eCFieldElement5.IsOne; ECFieldElement eCFieldElement7 = rawYCoord4; ECFieldElement eCFieldElement8 = rawXCoord2; if (!isOne) { eCFieldElement7 = eCFieldElement7.Multiply(eCFieldElement5); eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement5); } bool isOne2 = eCFieldElement6.IsOne; ECFieldElement eCFieldElement9 = rawYCoord3; ECFieldElement eCFieldElement10 = rawXCoord; if (!isOne2) { eCFieldElement9 = eCFieldElement9.Multiply(eCFieldElement6); eCFieldElement10 = eCFieldElement10.Multiply(eCFieldElement6); } ECFieldElement eCFieldElement11 = eCFieldElement7.Add(eCFieldElement9); ECFieldElement eCFieldElement12 = eCFieldElement8.Add(eCFieldElement10); if (!eCFieldElement12.IsZero) { ECFieldElement eCFieldElement13 = eCFieldElement12.Square(); ECFieldElement eCFieldElement14 = eCFieldElement13.Multiply(eCFieldElement12); ECFieldElement b2 = isOne ? eCFieldElement6 : (isOne2 ? eCFieldElement5 : eCFieldElement5.Multiply(eCFieldElement6)); ECFieldElement eCFieldElement15 = eCFieldElement11.Add(eCFieldElement12); ECFieldElement eCFieldElement16 = eCFieldElement15.MultiplyPlusProduct(eCFieldElement11, eCFieldElement13, curve.A).Multiply(b2).Add(eCFieldElement14); ECFieldElement x = eCFieldElement12.Multiply(eCFieldElement16); ECFieldElement b3 = isOne2 ? eCFieldElement13 : eCFieldElement13.Multiply(eCFieldElement6); ECFieldElement y2 = eCFieldElement11.MultiplyPlusProduct(rawXCoord, eCFieldElement12, rawYCoord3).MultiplyPlusProduct(b3, eCFieldElement15, eCFieldElement16); ECFieldElement eCFieldElement17 = eCFieldElement14.Multiply(b2); return(new F2mPoint(curve, x, y2, new ECFieldElement[] { eCFieldElement17 }, base.IsCompressed)); } if (eCFieldElement11.IsZero) { return(this.Twice()); } return(curve.Infinity); } default: if (num != 6) { throw new InvalidOperationException("unsupported coordinate system"); } if (rawXCoord.IsZero) { if (rawXCoord2.IsZero) { return(curve.Infinity); } return(b.Add(this)); } else { ECFieldElement rawYCoord5 = base.RawYCoord; ECFieldElement eCFieldElement18 = base.RawZCoords[0]; ECFieldElement rawYCoord6 = b.RawYCoord; ECFieldElement eCFieldElement19 = b.RawZCoords[0]; bool isOne3 = eCFieldElement18.IsOne; ECFieldElement eCFieldElement20 = rawXCoord2; ECFieldElement eCFieldElement21 = rawYCoord6; if (!isOne3) { eCFieldElement20 = eCFieldElement20.Multiply(eCFieldElement18); eCFieldElement21 = eCFieldElement21.Multiply(eCFieldElement18); } bool isOne4 = eCFieldElement19.IsOne; ECFieldElement eCFieldElement22 = rawXCoord; ECFieldElement eCFieldElement23 = rawYCoord5; if (!isOne4) { eCFieldElement22 = eCFieldElement22.Multiply(eCFieldElement19); eCFieldElement23 = eCFieldElement23.Multiply(eCFieldElement19); } ECFieldElement eCFieldElement24 = eCFieldElement23.Add(eCFieldElement21); ECFieldElement eCFieldElement25 = eCFieldElement22.Add(eCFieldElement20); if (!eCFieldElement25.IsZero) { ECFieldElement eCFieldElement27; ECFieldElement y3; ECFieldElement eCFieldElement29; if (rawXCoord2.IsZero) { ECPoint eCPoint = this.Normalize(); rawXCoord = eCPoint.RawXCoord; ECFieldElement yCoord = eCPoint.YCoord; ECFieldElement b4 = rawYCoord6; ECFieldElement eCFieldElement26 = yCoord.Add(b4).Divide(rawXCoord); eCFieldElement27 = eCFieldElement26.Square().Add(eCFieldElement26).Add(rawXCoord).Add(curve.A); if (eCFieldElement27.IsZero) { return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement eCFieldElement28 = eCFieldElement26.Multiply(rawXCoord.Add(eCFieldElement27)).Add(eCFieldElement27).Add(yCoord); y3 = eCFieldElement28.Divide(eCFieldElement27).Add(eCFieldElement27); eCFieldElement29 = curve.FromBigInteger(BigInteger.One); } else { eCFieldElement25 = eCFieldElement25.Square(); ECFieldElement eCFieldElement30 = eCFieldElement24.Multiply(eCFieldElement22); ECFieldElement eCFieldElement31 = eCFieldElement24.Multiply(eCFieldElement20); eCFieldElement27 = eCFieldElement30.Multiply(eCFieldElement31); if (eCFieldElement27.IsZero) { return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement eCFieldElement32 = eCFieldElement24.Multiply(eCFieldElement25); if (!isOne4) { eCFieldElement32 = eCFieldElement32.Multiply(eCFieldElement19); } y3 = eCFieldElement31.Add(eCFieldElement25).SquarePlusProduct(eCFieldElement32, rawYCoord5.Add(eCFieldElement18)); eCFieldElement29 = eCFieldElement32; if (!isOne3) { eCFieldElement29 = eCFieldElement29.Multiply(eCFieldElement18); } } return(new F2mPoint(curve, eCFieldElement27, y3, new ECFieldElement[] { eCFieldElement29 }, base.IsCompressed)); } if (eCFieldElement24.IsZero) { return(this.Twice()); } return(curve.Infinity); } break; } }