diff options
Diffstat (limited to 'crypto/src/math/ec')
-rw-r--r-- | crypto/src/math/ec/custom/djb/Curve25519.cs | 171 | ||||
-rw-r--r-- | crypto/src/math/ec/custom/djb/Curve25519Field.cs | 292 | ||||
-rw-r--r-- | crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs | 233 | ||||
-rw-r--r-- | crypto/src/math/ec/custom/djb/Curve25519Point.cs | 287 |
4 files changed, 0 insertions, 983 deletions
diff --git a/crypto/src/math/ec/custom/djb/Curve25519.cs b/crypto/src/math/ec/custom/djb/Curve25519.cs deleted file mode 100644 index 380be7252..000000000 --- a/crypto/src/math/ec/custom/djb/Curve25519.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; - -using Org.BouncyCastle.Math.Raw; -using Org.BouncyCastle.Security; -using Org.BouncyCastle.Utilities.Encoders; - -namespace Org.BouncyCastle.Math.EC.Custom.Djb -{ - internal class Curve25519 - : AbstractFpCurve - { - public static readonly BigInteger q = Curve25519FieldElement.Q; - - private static readonly BigInteger C_a = new BigInteger(1, Hex.DecodeStrict("2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144")); - private static readonly BigInteger C_b = new BigInteger(1, Hex.DecodeStrict("7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864")); - - private const int CURVE25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; - private const int CURVE25519_FE_INTS = 8; - private static readonly ECFieldElement[] CURVE25519_AFFINE_ZS = new ECFieldElement[] { - new Curve25519FieldElement(BigInteger.One), new Curve25519FieldElement(C_a) }; - protected readonly Curve25519Point m_infinity; - - public Curve25519() - : base(q) - { - this.m_infinity = new Curve25519Point(this, null, null); - - this.m_a = FromBigInteger(C_a); - this.m_b = FromBigInteger(C_b); - this.m_order = new BigInteger(1, Hex.DecodeStrict("1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED")); - this.m_cofactor = BigInteger.ValueOf(8); - this.m_coord = CURVE25519_DEFAULT_COORDS; - } - - protected override ECCurve CloneCurve() - { - return new Curve25519(); - } - - public override bool SupportsCoordinateSystem(int coord) - { - switch (coord) - { - case COORD_JACOBIAN_MODIFIED: - return true; - default: - return false; - } - } - - public virtual BigInteger Q - { - get { return q; } - } - - public override ECPoint Infinity - { - get { return m_infinity; } - } - - public override int FieldSize - { - get { return q.BitLength; } - } - - public override ECFieldElement FromBigInteger(BigInteger x) - { - return new Curve25519FieldElement(x); - } - - protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y) - { - return new Curve25519Point(this, x, y); - } - - protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs) - { - return new Curve25519Point(this, x, y, zs); - } - - public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) - { - uint[] table = new uint[len * CURVE25519_FE_INTS * 2]; - { - int pos = 0; - for (int i = 0; i < len; ++i) - { - ECPoint p = points[off + i]; - Nat256.Copy(((Curve25519FieldElement)p.RawXCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS; - Nat256.Copy(((Curve25519FieldElement)p.RawYCoord).x, 0, table, pos); pos += CURVE25519_FE_INTS; - } - } - - return new Curve25519LookupTable(this, table, len); - } - - public override ECFieldElement RandomFieldElement(SecureRandom r) - { - uint[] x = Nat256.Create(); - Curve25519Field.Random(r, x); - return new Curve25519FieldElement(x); - } - - public override ECFieldElement RandomFieldElementMult(SecureRandom r) - { - uint[] x = Nat256.Create(); - Curve25519Field.RandomMult(r, x); - return new Curve25519FieldElement(x); - } - - private class Curve25519LookupTable - : AbstractECLookupTable - { - private readonly Curve25519 m_outer; - private readonly uint[] m_table; - private readonly int m_size; - - internal Curve25519LookupTable(Curve25519 outer, uint[] table, int size) - { - this.m_outer = outer; - this.m_table = table; - this.m_size = size; - } - - public override int Size - { - get { return m_size; } - } - - public override ECPoint Lookup(int index) - { - uint[] x = Nat256.Create(), y = Nat256.Create(); - int pos = 0; - - for (int i = 0; i < m_size; ++i) - { - uint MASK = (uint)(((i ^ index) - 1) >> 31); - - for (int j = 0; j < CURVE25519_FE_INTS; ++j) - { - x[j] ^= m_table[pos + j] & MASK; - y[j] ^= m_table[pos + CURVE25519_FE_INTS + j] & MASK; - } - - pos += (CURVE25519_FE_INTS * 2); - } - - return CreatePoint(x, y); - } - - public override ECPoint LookupVar(int index) - { - uint[] x = Nat256.Create(), y = Nat256.Create(); - int pos = index * CURVE25519_FE_INTS * 2; - - for (int j = 0; j < CURVE25519_FE_INTS; ++j) - { - x[j] = m_table[pos + j]; - y[j] = m_table[pos + CURVE25519_FE_INTS + j]; - } - - return CreatePoint(x, y); - } - - private ECPoint CreatePoint(uint[] x, uint[] y) - { - return m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), CURVE25519_AFFINE_ZS); - } - } - } -} diff --git a/crypto/src/math/ec/custom/djb/Curve25519Field.cs b/crypto/src/math/ec/custom/djb/Curve25519Field.cs deleted file mode 100644 index 31416249d..000000000 --- a/crypto/src/math/ec/custom/djb/Curve25519Field.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System; -using System.Diagnostics; - -using Org.BouncyCastle.Crypto.Utilities; -using Org.BouncyCastle.Math.Raw; -using Org.BouncyCastle.Security; - -namespace Org.BouncyCastle.Math.EC.Custom.Djb -{ - internal class Curve25519Field - { - // 2^255 - 19 - internal static readonly uint[] P = new uint[]{ 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }; - private const uint P7 = 0x7FFFFFFF; - private static readonly uint[] PExt = new uint[]{ 0x00000169, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0x3FFFFFFF }; - private const uint PInv = 0x13; - - public static void Add(uint[] x, uint[] y, uint[] z) - { - Nat256.Add(x, y, z); - if (Nat256.Gte(z, P)) - { - SubPFrom(z); - } - } - - public static void AddExt(uint[] xx, uint[] yy, uint[] zz) - { - Nat.Add(16, xx, yy, zz); - if (Nat.Gte(16, zz, PExt)) - { - SubPExtFrom(zz); - } - } - - public static void AddOne(uint[] x, uint[] z) - { - Nat.Inc(8, x, z); - if (Nat256.Gte(z, P)) - { - SubPFrom(z); - } - } - - public static uint[] FromBigInteger(BigInteger x) - { - uint[] z = Nat.FromBigInteger(256, x); - while (Nat256.Gte(z, P)) - { - Nat256.SubFrom(P, z); - } - return z; - } - - public static void Half(uint[] x, uint[] z) - { - if ((x[0] & 1) == 0) - { - Nat.ShiftDownBit(8, x, 0, z); - } - else - { - Nat256.Add(x, P, z); - Nat.ShiftDownBit(8, z, 0); - } - } - - public static void Inv(uint[] x, uint[] z) - { - Mod.CheckedModOddInverse(P, x, z); - } - - public static int IsZero(uint[] x) - { - uint d = 0; - for (int i = 0; i < 8; ++i) - { - d |= x[i]; - } - d = (d >> 1) | (d & 1); - return ((int)d - 1) >> 31; - } - - public static void Multiply(uint[] x, uint[] y, uint[] z) - { - uint[] tt = Nat256.CreateExt(); - Nat256.Mul(x, y, tt); - Reduce(tt, z); - } - - public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz) - { - Nat256.MulAddTo(x, y, zz); - if (Nat.Gte(16, zz, PExt)) - { - SubPExtFrom(zz); - } - } - - public static void Negate(uint[] x, uint[] z) - { - if (0 != IsZero(x)) - { - Nat256.Sub(P, P, z); - } - else - { - Nat256.Sub(P, x, z); - } - } - - public static void Random(SecureRandom r, uint[] z) - { - byte[] bb = new byte[8 * 4]; - do - { - r.NextBytes(bb); - Pack.LE_To_UInt32(bb, 0, z, 0, 8); - z[7] &= P7; - } - while (0 == Nat.LessThan(8, z, P)); - } - - public static void RandomMult(SecureRandom r, uint[] z) - { - do - { - Random(r, z); - } - while (0 != IsZero(z)); - } - - public static void Reduce(uint[] xx, uint[] z) - { - Debug.Assert(xx[15] >> 30 == 0); - - uint xx07 = xx[7]; - Nat.ShiftUpBit(8, xx, 8, xx07, z, 0); - uint c = Nat256.MulByWordAddTo(PInv, xx, z) << 1; - uint z7 = z[7]; - c += (z7 >> 31) - (xx07 >> 31); - z7 &= P7; - z7 += Nat.AddWordTo(7, c * PInv, z); - z[7] = z7; - if (z7 >= P7 && Nat256.Gte(z, P)) - { - SubPFrom(z); - } - } - - public static void Reduce27(uint x, uint[] z) - { - Debug.Assert(x >> 26 == 0); - - uint z7 = z[7]; - uint c = (x << 1 | z7 >> 31); - z7 &= P7; - z7 += Nat.AddWordTo(7, c * PInv, z); - z[7] = z7; - if (z7 >= P7 && Nat256.Gte(z, P)) - { - SubPFrom(z); - } - } - - public static void Square(uint[] x, uint[] z) - { - uint[] tt = Nat256.CreateExt(); - Nat256.Square(x, tt); - Reduce(tt, z); - } - - public static void SquareN(uint[] x, int n, uint[] z) - { - Debug.Assert(n > 0); - - uint[] tt = Nat256.CreateExt(); - Nat256.Square(x, tt); - Reduce(tt, z); - - while (--n > 0) - { - Nat256.Square(z, tt); - Reduce(tt, z); - } - } - - public static void Subtract(uint[] x, uint[] y, uint[] z) - { - int c = Nat256.Sub(x, y, z); - if (c != 0) - { - AddPTo(z); - } - } - - public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz) - { - int c = Nat.Sub(16, xx, yy, zz); - if (c != 0) - { - AddPExtTo(zz); - } - } - - public static void Twice(uint[] x, uint[] z) - { - Nat.ShiftUpBit(8, x, 0, z); - if (Nat256.Gte(z, P)) - { - SubPFrom(z); - } - } - - private static uint AddPTo(uint[] z) - { - long c = (long)z[0] - PInv; - z[0] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.DecAt(7, z, 1); - } - c += (long)z[7] + (P7 + 1); - z[7] = (uint)c; - c >>= 32; - return (uint)c; - } - - private static uint AddPExtTo(uint[] zz) - { - long c = (long)zz[0] + PExt[0]; - zz[0] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.IncAt(8, zz, 1); - } - c += (long)zz[8] - PInv; - zz[8] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.DecAt(15, zz, 9); - } - c += (long)zz[15] + (PExt[15] + 1); - zz[15] = (uint)c; - c >>= 32; - return (uint)c; - } - - private static int SubPFrom(uint[] z) - { - long c = (long)z[0] + PInv; - z[0] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.IncAt(7, z, 1); - } - c += (long)z[7] - (P7 + 1); - z[7] = (uint)c; - c >>= 32; - return (int)c; - } - - private static int SubPExtFrom(uint[] zz) - { - long c = (long)zz[0] - PExt[0]; - zz[0] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.DecAt(8, zz, 1); - } - c += (long)zz[8] + PInv; - zz[8] = (uint)c; - c >>= 32; - if (c != 0) - { - c = Nat.IncAt(15, zz, 9); - } - c += (long)zz[15] - (PExt[15] + 1); - zz[15] = (uint)c; - c >>= 32; - return (int)c; - } - } -} diff --git a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs b/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs deleted file mode 100644 index a5509841d..000000000 --- a/crypto/src/math/ec/custom/djb/Curve25519FieldElement.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System; - -using Org.BouncyCastle.Math.Raw; -using Org.BouncyCastle.Utilities; - -namespace Org.BouncyCastle.Math.EC.Custom.Djb -{ - internal class Curve25519FieldElement - : AbstractFpFieldElement - { - public static readonly BigInteger Q = Nat256.ToBigInteger(Curve25519Field.P); - - // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q) - private static readonly uint[] PRECOMP_POW2 = new uint[]{ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806, - 0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480 }; - - protected internal readonly uint[] x; - - public Curve25519FieldElement(BigInteger x) - { - if (x == null || x.SignValue < 0 || x.CompareTo(Q) >= 0) - throw new ArgumentException("value invalid for Curve25519FieldElement", "x"); - - this.x = Curve25519Field.FromBigInteger(x); - } - - public Curve25519FieldElement() - { - this.x = Nat256.Create(); - } - - protected internal Curve25519FieldElement(uint[] x) - { - this.x = x; - } - - public override bool IsZero - { - get { return Nat256.IsZero(x); } - } - - public override bool IsOne - { - get { return Nat256.IsOne(x); } - } - - public override bool TestBitZero() - { - return Nat256.GetBit(x, 0) == 1; - } - - public override BigInteger ToBigInteger() - { - return Nat256.ToBigInteger(x); - } - - public override string FieldName - { - get { return "Curve25519Field"; } - } - - public override int FieldSize - { - get { return Q.BitLength; } - } - - public override ECFieldElement Add(ECFieldElement b) - { - uint[] z = Nat256.Create(); - Curve25519Field.Add(x, ((Curve25519FieldElement)b).x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement AddOne() - { - uint[] z = Nat256.Create(); - Curve25519Field.AddOne(x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Subtract(ECFieldElement b) - { - uint[] z = Nat256.Create(); - Curve25519Field.Subtract(x, ((Curve25519FieldElement)b).x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Multiply(ECFieldElement b) - { - uint[] z = Nat256.Create(); - Curve25519Field.Multiply(x, ((Curve25519FieldElement)b).x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Divide(ECFieldElement b) - { - //return Multiply(b.Invert()); - uint[] z = Nat256.Create(); - Curve25519Field.Inv(((Curve25519FieldElement)b).x, z); - Curve25519Field.Multiply(z, x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Negate() - { - uint[] z = Nat256.Create(); - Curve25519Field.Negate(x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Square() - { - uint[] z = Nat256.Create(); - Curve25519Field.Square(x, z); - return new Curve25519FieldElement(z); - } - - public override ECFieldElement Invert() - { - //return new Curve25519FieldElement(ToBigInteger().ModInverse(Q)); - uint[] z = Nat256.Create(); - Curve25519Field.Inv(x, z); - return new Curve25519FieldElement(z); - } - - /** - * return a sqrt root - the routine verifies that the calculation returns the right value - if - * none exists it returns null. - */ - public override ECFieldElement Sqrt() - { - /* - * Q == 8m + 5, so we use Pocklington's method for this case. - * - * First, raise this element to the exponent 2^252 - 2^1 (i.e. m + 1) - * - * Breaking up the exponent's binary representation into "repunits", we get: - * { 251 1s } { 1 0s } - * - * Therefore we need an addition chain containing 251 (the lengths of the repunits) - * We use: 1, 2, 3, 4, 7, 11, 15, 30, 60, 120, 131, [251] - */ - - uint[] x1 = this.x; - if (Nat256.IsZero(x1) || Nat256.IsOne(x1)) - return this; - - uint[] x2 = Nat256.Create(); - Curve25519Field.Square(x1, x2); - Curve25519Field.Multiply(x2, x1, x2); - uint[] x3 = x2; - Curve25519Field.Square(x2, x3); - Curve25519Field.Multiply(x3, x1, x3); - uint[] x4 = Nat256.Create(); - Curve25519Field.Square(x3, x4); - Curve25519Field.Multiply(x4, x1, x4); - uint[] x7 = Nat256.Create(); - Curve25519Field.SquareN(x4, 3, x7); - Curve25519Field.Multiply(x7, x3, x7); - uint[] x11 = x3; - Curve25519Field.SquareN(x7, 4, x11); - Curve25519Field.Multiply(x11, x4, x11); - uint[] x15 = x7; - Curve25519Field.SquareN(x11, 4, x15); - Curve25519Field.Multiply(x15, x4, x15); - uint[] x30 = x4; - Curve25519Field.SquareN(x15, 15, x30); - Curve25519Field.Multiply(x30, x15, x30); - uint[] x60 = x15; - Curve25519Field.SquareN(x30, 30, x60); - Curve25519Field.Multiply(x60, x30, x60); - uint[] x120 = x30; - Curve25519Field.SquareN(x60, 60, x120); - Curve25519Field.Multiply(x120, x60, x120); - uint[] x131 = x60; - Curve25519Field.SquareN(x120, 11, x131); - Curve25519Field.Multiply(x131, x11, x131); - uint[] x251 = x11; - Curve25519Field.SquareN(x131, 120, x251); - Curve25519Field.Multiply(x251, x120, x251); - - uint[] t1 = x251; - Curve25519Field.Square(t1, t1); - - uint[] t2 = x120; - Curve25519Field.Square(t1, t2); - - if (Nat256.Eq(x1, t2)) - { - return new Curve25519FieldElement(t1); - } - - /* - * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, - * which is ((4x)^(m + 1))/2 mod Q - */ - Curve25519Field.Multiply(t1, PRECOMP_POW2, t1); - - Curve25519Field.Square(t1, t2); - - if (Nat256.Eq(x1, t2)) - { - return new Curve25519FieldElement(t1); - } - - return null; - } - - public override bool Equals(object obj) - { - return Equals(obj as Curve25519FieldElement); - } - - public override bool Equals(ECFieldElement other) - { - return Equals(other as Curve25519FieldElement); - } - - public virtual bool Equals(Curve25519FieldElement other) - { - if (this == other) - return true; - if (null == other) - return false; - return Nat256.Eq(x, other.x); - } - - public override int GetHashCode() - { - return Q.GetHashCode() ^ Arrays.GetHashCode(x, 0, 8); - } - } -} diff --git a/crypto/src/math/ec/custom/djb/Curve25519Point.cs b/crypto/src/math/ec/custom/djb/Curve25519Point.cs deleted file mode 100644 index f61e28af8..000000000 --- a/crypto/src/math/ec/custom/djb/Curve25519Point.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System; - -using Org.BouncyCastle.Math.Raw; - -namespace Org.BouncyCastle.Math.EC.Custom.Djb -{ - internal class Curve25519Point - : AbstractFpPoint - { - internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y) - : base(curve, x, y) - { - } - - internal Curve25519Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs) - : base(curve, x, y, zs) - { - } - - protected override ECPoint Detach() - { - return new Curve25519Point(null, AffineXCoord, AffineYCoord); - } - - public override ECFieldElement GetZCoord(int index) - { - if (index == 1) - { - return GetJacobianModifiedW(); - } - - return base.GetZCoord(index); - } - - public override ECPoint Add(ECPoint b) - { - if (this.IsInfinity) - return b; - if (b.IsInfinity) - return this; - if (this == b) - return Twice(); - - ECCurve curve = this.Curve; - - Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, - Z1 = (Curve25519FieldElement)this.RawZCoords[0]; - Curve25519FieldElement X2 = (Curve25519FieldElement)b.RawXCoord, Y2 = (Curve25519FieldElement)b.RawYCoord, - Z2 = (Curve25519FieldElement)b.RawZCoords[0]; - - uint c; - uint[] tt1 = Nat256.CreateExt(); - uint[] t2 = Nat256.Create(); - uint[] t3 = Nat256.Create(); - uint[] t4 = Nat256.Create(); - - bool Z1IsOne = Z1.IsOne; - uint[] U2, S2; - if (Z1IsOne) - { - U2 = X2.x; - S2 = Y2.x; - } - else - { - S2 = t3; - Curve25519Field.Square(Z1.x, S2); - - U2 = t2; - Curve25519Field.Multiply(S2, X2.x, U2); - - Curve25519Field.Multiply(S2, Z1.x, S2); - Curve25519Field.Multiply(S2, Y2.x, S2); - } - - bool Z2IsOne = Z2.IsOne; - uint[] U1, S1; - if (Z2IsOne) - { - U1 = X1.x; - S1 = Y1.x; - } - else - { - S1 = t4; - Curve25519Field.Square(Z2.x, S1); - - U1 = tt1; - Curve25519Field.Multiply(S1, X1.x, U1); - - Curve25519Field.Multiply(S1, Z2.x, S1); - Curve25519Field.Multiply(S1, Y1.x, S1); - } - - uint[] H = Nat256.Create(); - Curve25519Field.Subtract(U1, U2, H); - - uint[] R = t2; - Curve25519Field.Subtract(S1, S2, R); - - // Check if b == this or b == -this - if (Nat256.IsZero(H)) - { - if (Nat256.IsZero(R)) - { - // this == b, i.e. this must be doubled - return this.Twice(); - } - - // this == -b, i.e. the result is the point at infinity - return curve.Infinity; - } - - uint[] HSquared = Nat256.Create(); - Curve25519Field.Square(H, HSquared); - - uint[] G = Nat256.Create(); - Curve25519Field.Multiply(HSquared, H, G); - - uint[] V = t3; - Curve25519Field.Multiply(HSquared, U1, V); - - Curve25519Field.Negate(G, G); - Nat256.Mul(S1, G, tt1); - - c = Nat256.AddBothTo(V, V, G); - Curve25519Field.Reduce27(c, G); - - Curve25519FieldElement X3 = new Curve25519FieldElement(t4); - Curve25519Field.Square(R, X3.x); - Curve25519Field.Subtract(X3.x, G, X3.x); - - Curve25519FieldElement Y3 = new Curve25519FieldElement(G); - Curve25519Field.Subtract(V, X3.x, Y3.x); - Curve25519Field.MultiplyAddToExt(Y3.x, R, tt1); - Curve25519Field.Reduce(tt1, Y3.x); - - Curve25519FieldElement Z3 = new Curve25519FieldElement(H); - if (!Z1IsOne) - { - Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); - } - if (!Z2IsOne) - { - Curve25519Field.Multiply(Z3.x, Z2.x, Z3.x); - } - - uint[] Z3Squared = (Z1IsOne && Z2IsOne) ? HSquared : null; - - // TODO If the result will only be used in a subsequent addition, we don't need W3 - Curve25519FieldElement W3 = CalculateJacobianModifiedW((Curve25519FieldElement)Z3, Z3Squared); - - ECFieldElement[] zs = new ECFieldElement[] { Z3, W3 }; - - return new Curve25519Point(curve, X3, Y3, zs); - } - - public override ECPoint Twice() - { - if (this.IsInfinity) - return this; - - ECCurve curve = this.Curve; - - ECFieldElement Y1 = this.RawYCoord; - if (Y1.IsZero) - return curve.Infinity; - - return TwiceJacobianModified(true); - } - - public override ECPoint TwicePlus(ECPoint b) - { - if (this == b) - return ThreeTimes(); - if (this.IsInfinity) - return b; - if (b.IsInfinity) - return Twice(); - - ECFieldElement Y1 = this.RawYCoord; - if (Y1.IsZero) - return b; - - return TwiceJacobianModified(false).Add(b); - } - - public override ECPoint ThreeTimes() - { - if (this.IsInfinity || this.RawYCoord.IsZero) - return this; - - return TwiceJacobianModified(false).Add(this); - } - - public override ECPoint Negate() - { - if (IsInfinity) - return this; - - return new Curve25519Point(Curve, RawXCoord, RawYCoord.Negate(), RawZCoords); - } - - protected virtual Curve25519FieldElement CalculateJacobianModifiedW(Curve25519FieldElement Z, uint[] ZSquared) - { - Curve25519FieldElement a4 = (Curve25519FieldElement)this.Curve.A; - if (Z.IsOne) - return a4; - - Curve25519FieldElement W = new Curve25519FieldElement(); - if (ZSquared == null) - { - ZSquared = W.x; - Curve25519Field.Square(Z.x, ZSquared); - } - Curve25519Field.Square(ZSquared, W.x); - Curve25519Field.Multiply(W.x, a4.x, W.x); - return W; - } - - protected virtual Curve25519FieldElement GetJacobianModifiedW() - { - ECFieldElement[] ZZ = this.RawZCoords; - Curve25519FieldElement W = (Curve25519FieldElement)ZZ[1]; - if (W == null) - { - // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here - ZZ[1] = W = CalculateJacobianModifiedW((Curve25519FieldElement)ZZ[0], null); - } - return W; - } - - protected virtual Curve25519Point TwiceJacobianModified(bool calculateW) - { - Curve25519FieldElement X1 = (Curve25519FieldElement)this.RawXCoord, Y1 = (Curve25519FieldElement)this.RawYCoord, - Z1 = (Curve25519FieldElement)this.RawZCoords[0], W1 = GetJacobianModifiedW(); - - uint c; - - uint[] M = Nat256.Create(); - Curve25519Field.Square(X1.x, M); - c = Nat256.AddBothTo(M, M, M); - c += Nat256.AddTo(W1.x, M); - Curve25519Field.Reduce27(c, M); - - uint[] _2Y1 = Nat256.Create(); - Curve25519Field.Twice(Y1.x, _2Y1); - - uint[] _2Y1Squared = Nat256.Create(); - Curve25519Field.Multiply(_2Y1, Y1.x, _2Y1Squared); - - uint[] S = Nat256.Create(); - Curve25519Field.Multiply(_2Y1Squared, X1.x, S); - Curve25519Field.Twice(S, S); - - uint[] _8T = Nat256.Create(); - Curve25519Field.Square(_2Y1Squared, _8T); - Curve25519Field.Twice(_8T, _8T); - - Curve25519FieldElement X3 = new Curve25519FieldElement(_2Y1Squared); - Curve25519Field.Square(M, X3.x); - Curve25519Field.Subtract(X3.x, S, X3.x); - Curve25519Field.Subtract(X3.x, S, X3.x); - - Curve25519FieldElement Y3 = new Curve25519FieldElement(S); - Curve25519Field.Subtract(S, X3.x, Y3.x); - Curve25519Field.Multiply(Y3.x, M, Y3.x); - Curve25519Field.Subtract(Y3.x, _8T, Y3.x); - - Curve25519FieldElement Z3 = new Curve25519FieldElement(_2Y1); - if (!Nat256.IsOne(Z1.x)) - { - Curve25519Field.Multiply(Z3.x, Z1.x, Z3.x); - } - - Curve25519FieldElement W3 = null; - if (calculateW) - { - W3 = new Curve25519FieldElement(_8T); - Curve25519Field.Multiply(W3.x, W1.x, W3.x); - Curve25519Field.Twice(W3.x, W3.x); - } - - return new Curve25519Point(this.Curve, X3, Y3, new ECFieldElement[] { Z3, W3 }); - } - } -} |