public override ECPoint TwicePlus(ECPoint b) { if (this.IsInfinity) return b; if (b.IsInfinity) return Twice(); ECCurve curve = this.Curve; ECFieldElement X1 = this.RawXCoord; if (X1.IsZero) { // A point with X == 0 is it's own additive inverse return b; } int coord = curve.CoordinateSystem; switch (coord) { case ECCurve.COORD_LAMBDA_PROJECTIVE: { // NOTE: twicePlus() only optimized for lambda-affine argument ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0]; if (X2.IsZero || !Z2.IsOne) { return Twice().Add(b); } ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0]; ECFieldElement L2 = b.RawYCoord; ECFieldElement X1Sq = X1.Square(); ECFieldElement L1Sq = L1.Square(); ECFieldElement Z1Sq = Z1.Square(); ECFieldElement L1Z1 = L1.Multiply(Z1); ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); ECFieldElement L2plus1 = L2.AddOne(); ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq); ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); ECFieldElement B = X2Z1Sq.Add(T).Square(); if (B.IsZero) { if (A.IsZero) { return b.Twice(); } return curve.Infinity; } if (A.IsZero) { return new F2mPoint(curve, A, curve.B.Sqrt(), IsCompressed); } ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2plus1, Z3); return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); } default: { return Twice().Add(b); } } }
/** * Tests <code>ECPoint.add()</code> and <code>ECPoint.subtract()</code> * for the given point and the given point at infinity. * * @param p * The point on which the tests are performed. * @param infinity * The point at infinity on the same curve as <code>p</code>. */ private void ImplTestAddSubtract(ECPoint p, ECPoint infinity) { AssertPointsEqual("Twice and Add inconsistent", p.Twice(), p.Add(p)); AssertPointsEqual("Twice p - p is not p", p, p.Twice().Subtract(p)); AssertPointsEqual("TwicePlus(p, -p) is not p", p, p.TwicePlus(p.Negate())); AssertPointsEqual("p - p is not infinity", infinity, p.Subtract(p)); AssertPointsEqual("p plus infinity is not p", p, p.Add(infinity)); AssertPointsEqual("infinity plus p is not p", p, infinity.Add(p)); AssertPointsEqual("infinity plus infinity is not infinity ", infinity, infinity.Add(infinity)); AssertPointsEqual("Twice infinity is not infinity ", infinity, infinity.Twice()); }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p * The point to multiply. * @param k * The multiplier. * @return The result of the point multiplication <code>kP</code>. */ private ECPoint Multiply(ECPoint p, BigInteger k) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { if (i != 0) { p = p.Twice(); } if (k.TestBit(i)) { q = q.Add(p); } } return q; }
/** * Tests <code>ECPoint.add()</code> and <code>ECPoint.subtract()</code> * for the given point and the given point at infinity. * * @param p * The point on which the tests are performed. * @param infinity * The point at infinity on the same curve as <code>p</code>. */ private void implTestAddSubtract(ECPoint p, ECPoint infinity) { Assert.AreEqual(p.Twice(), p.Add(p), "Twice and Add inconsistent"); Assert.AreEqual(p, p.Twice().Subtract(p), "Twice p - p is not p"); Assert.AreEqual(infinity, p.Subtract(p), "p - p is not infinity"); Assert.AreEqual(p, p.Add(infinity), "p plus infinity is not p"); Assert.AreEqual(p, infinity.Add(p), "infinity plus p is not p"); Assert.AreEqual(infinity, infinity.Add(infinity), "infinity plus infinity is not infinity "); }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations, and for very small scalars. * * @param p * The point to multiply. * @param k * The multiplier. * @return The result of the point multiplication <code>kP</code>. */ public static ECPoint ReferenceMultiply(ECPoint p, BigInteger k) { BigInteger x = k.Abs(); ECPoint q = p.Curve.Infinity; int t = x.BitLength; if (t > 0) { if (x.TestBit(0)) { q = p; } for (int i = 1; i < t; i++) { p = p.Twice(); if (x.TestBit(i)) { q = q.Add(p); } } } return k.SignValue < 0 ? q.Negate() : q; }
public override ECPoint TwicePlus(ECPoint b) { if (base.IsInfinity) { return(b); } if (b.IsInfinity) { return(this.Twice()); } ECCurve curve = this.Curve; ECFieldElement rawXCoord = base.RawXCoord; if (rawXCoord.IsZero) { return(b); } int coordinateSystem = curve.CoordinateSystem; int num = coordinateSystem; if (num != 6) { return(this.Twice().Add(b)); } ECFieldElement rawXCoord2 = b.RawXCoord; ECFieldElement eCFieldElement = b.RawZCoords[0]; if (rawXCoord2.IsZero || !eCFieldElement.IsOne) { return(this.Twice().Add(b)); } ECFieldElement rawYCoord = base.RawYCoord; ECFieldElement eCFieldElement2 = base.RawZCoords[0]; ECFieldElement rawYCoord2 = b.RawYCoord; ECFieldElement x = rawXCoord.Square(); ECFieldElement b2 = rawYCoord.Square(); ECFieldElement eCFieldElement3 = eCFieldElement2.Square(); ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2); ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3); ECFieldElement eCFieldElement4 = rawYCoord2.AddOne(); ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3); ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3); ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square(); if (eCFieldElement7.IsZero) { if (eCFieldElement5.IsZero) { return(b.Twice()); } return(curve.Infinity); } else { if (eCFieldElement5.IsZero) { return(new F2mPoint(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed)); } ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6); ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3); ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8); return(new F2mPoint(curve, x2, y, new ECFieldElement[] { eCFieldElement8 }, base.IsCompressed)); } }