diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-04-15 21:12:11 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-04-15 21:12:11 +0700 |
commit | d79a501212d4012139c714e361577669c75171aa (patch) | |
tree | f78e8c7d34c9448698e17bc341fd8d293814dd3e /crypto/src/math/ec/custom/sec | |
parent | Update Readme.html for SHA-3 perf. opts. (diff) | |
download | BouncyCastle.NET-ed25519-d79a501212d4012139c714e361577669c75171aa.tar.xz |
Cache-safety for EC lookup tables
- creation of cache-safe lookup tables delegated to ECCurve - FixedPointCombMultiplier uses cache-safe lookup table - FixedPointCombMultiplier avoids BigInteger.TestBit
Diffstat (limited to 'crypto/src/math/ec/custom/sec')
38 files changed, 1830 insertions, 60 deletions
diff --git a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs index 9da27b470..cc50f50d2 100644 --- a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF")); - private const int SecP128R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP128R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP128R1_FE_INTS = 4; protected readonly SecP128R1Point m_infinity; @@ -26,7 +28,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFE0000000075A30D1B9038A115")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP128R1_DEFAULT_COORDS; + this.m_coord = SECP128R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -74,5 +76,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP128R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP128R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy(((SecP128R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS; + Nat128.Copy(((SecP128R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP128R1_FE_INTS; + } + } + + return new SecP128R1LookupTable(this, table, len); + } + + private class SecP128R1LookupTable + : ECLookupTable + { + private readonly SecP128R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP128R1LookupTable(SecP128R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat128.Create(), y = Nat128.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP128R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP128R1_FE_INTS + j] & MASK; + } + + pos += (SECP128R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP128R1FieldElement(x), new SecP128R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs index 7d45c6227..234c86b87 100644 --- a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = SecP160R2Curve.q; private const int SECP160K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160K1_FE_INTS = 5; protected readonly SecP160K1Point m_infinity; @@ -70,5 +72,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP160K1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS; + Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160K1_FE_INTS; + } + } + + return new SecP160K1LookupTable(this, table, len); + } + + private class SecP160K1LookupTable + : ECLookupTable + { + private readonly SecP160K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160K1LookupTable(SecP160K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual 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 < SECP160K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160K1_FE_INTS + j] & MASK; + } + + pos += (SECP160K1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs index 87389af36..958eb2765 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")); - private const int SecP160R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R1_FE_INTS = 5; protected readonly SecP160R1Point m_infinity; @@ -26,7 +28,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("0100000000000000000001F4C8F927AED3CA752257")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP160R1_DEFAULT_COORDS; + this.m_coord = SECP160R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -74,5 +76,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP160R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS; + Nat160.Copy(((SecP160R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R1_FE_INTS; + } + } + + return new SecP160R1LookupTable(this, table, len); + } + + private class SecP160R1LookupTable + : ECLookupTable + { + private readonly SecP160R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160R1LookupTable(SecP160R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP160R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160R1_FE_INTS + j] & MASK; + } + + pos += (SECP160R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP160R1FieldElement(x), new SecP160R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs index 100561453..252312e62 100644 --- a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73")); - private const int SecP160R2_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R2_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP160R2_FE_INTS = 5; protected readonly SecP160R2Point m_infinity; @@ -26,7 +28,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("0100000000000000000000351EE786A818F3A1A16B")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP160R2_DEFAULT_COORDS; + this.m_coord = SECP160R2_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -74,5 +76,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP160R2Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP160R2_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat160.Copy(((SecP160R2FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS; + Nat160.Copy(((SecP160R2FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP160R2_FE_INTS; + } + } + + return new SecP160R2LookupTable(this, table, len); + } + + private class SecP160R2LookupTable + : ECLookupTable + { + private readonly SecP160R2Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP160R2LookupTable(SecP160R2Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat160.Create(), y = Nat160.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP160R2_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP160R2_FE_INTS + j] & MASK; + } + + pos += (SECP160R2_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP160R2FieldElement(x), new SecP160R2FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs index 81f77197e..518e0a131 100644 --- a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -11,6 +12,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37")); private const int SECP192K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP192K1_FE_INTS = 6; protected readonly SecP192K1Point m_infinity; @@ -71,5 +73,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP192K1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP192K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy(((SecP192K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS; + Nat192.Copy(((SecP192K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192K1_FE_INTS; + } + } + + return new SecP192K1LookupTable(this, table, len); + } + + private class SecP192K1LookupTable + : ECLookupTable + { + private readonly SecP192K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP192K1LookupTable(SecP192K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP192K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP192K1_FE_INTS + j] & MASK; + } + + pos += (SECP192K1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP192K1FieldElement(x), new SecP192K1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs index cb3a981c8..91d31932a 100644 --- a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")); - private const int SecP192R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP192R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP192R1_FE_INTS = 6; protected readonly SecP192R1Point m_infinity; @@ -26,7 +28,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP192R1_DEFAULT_COORDS; + this.m_coord = SECP192R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -74,5 +76,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP192R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP192R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy(((SecP192R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS; + Nat192.Copy(((SecP192R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP192R1_FE_INTS; + } + } + + return new SecP192R1LookupTable(this, table, len); + } + + private class SecP192R1LookupTable + : ECLookupTable + { + private readonly SecP192R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP192R1LookupTable(SecP192R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat192.Create(), y = Nat192.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP192R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP192R1_FE_INTS + j] & MASK; + } + + pos += (SECP192R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP192R1FieldElement(x), new SecP192R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs index d4be7d8de..a9c55090f 100644 --- a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -11,6 +12,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D")); private const int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP224K1_FE_INTS = 7; protected readonly SecP224K1Point m_infinity; @@ -71,5 +73,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP224K1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP224K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat224.Copy(((SecP224K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS; + Nat224.Copy(((SecP224K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP224K1_FE_INTS; + } + } + + return new SecP224K1LookupTable(this, table, len); + } + + private class SecP224K1LookupTable + : ECLookupTable + { + private readonly SecP224K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP224K1LookupTable(SecP224K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP224K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP224K1_FE_INTS + j] & MASK; + } + + pos += (SECP224K1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs index cda8781ff..ec34390aa 100644 --- a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")); - private const int SecP224R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP224R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP224R1_FE_INTS = 7; protected readonly SecP224R1Point m_infinity; @@ -26,7 +28,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP224R1_DEFAULT_COORDS; + this.m_coord = SECP224R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -74,5 +76,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP224R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP224R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat224.Copy(((SecP224R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP224R1_FE_INTS; + Nat224.Copy(((SecP224R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP224R1_FE_INTS; + } + } + + return new SecP224R1LookupTable(this, table, len); + } + + private class SecP224R1LookupTable + : ECLookupTable + { + private readonly SecP224R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP224R1LookupTable(SecP224R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat224.Create(), y = Nat224.Create(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP224R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP224R1_FE_INTS + j] & MASK; + } + + pos += (SECP224R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP224R1FieldElement(x), new SecP224R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs index 59e2cefb2..b3a5dd646 100644 --- a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -11,6 +12,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); private const int SECP256K1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP256K1_FE_INTS = 8; protected readonly SecP256K1Point m_infinity; @@ -71,5 +73,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP256K1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP256K1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((SecP256K1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP256K1_FE_INTS; + Nat256.Copy(((SecP256K1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP256K1_FE_INTS; + } + } + + return new SecP256K1LookupTable(this, table, len); + } + + private class SecP256K1LookupTable + : ECLookupTable + { + private readonly SecP256K1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP256K1LookupTable(SecP256K1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual 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 < SECP256K1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP256K1_FE_INTS + j] & MASK; + } + + pos += (SECP256K1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP256K1FieldElement(x), new SecP256K1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs index 6b3448f06..2d9a88b72 100644 --- a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")); - private const int SecP256R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP256R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP256R1_FE_INTS = 8; protected readonly SecP256R1Point m_infinity; @@ -25,7 +27,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))); this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP256R1_DEFAULT_COORDS; + this.m_coord = SECP256R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -73,5 +75,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP256R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP256R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy(((SecP256R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP256R1_FE_INTS; + Nat256.Copy(((SecP256R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP256R1_FE_INTS; + } + } + + return new SecP256R1LookupTable(this, table, len); + } + + private class SecP256R1LookupTable + : ECLookupTable + { + private readonly SecP256R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP256R1LookupTable(SecP256R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual 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 < SECP256R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP256R1_FE_INTS + j] & MASK; + } + + pos += (SECP256R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP256R1FieldElement(x), new SecP256R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs index 7fd58276a..26b057198 100644 --- a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")); - private const int SecP384R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP384R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP384R1_FE_INTS = 12; protected readonly SecP384R1Point m_infinity; @@ -25,7 +27,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))); this.m_order = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP384R1_DEFAULT_COORDS; + this.m_coord = SECP384R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -73,5 +75,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP384R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP384R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat.Copy(SECP384R1_FE_INTS, ((SecP384R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP384R1_FE_INTS; + Nat.Copy(SECP384R1_FE_INTS, ((SecP384R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP384R1_FE_INTS; + } + } + + return new SecP384R1LookupTable(this, table, len); + } + + private class SecP384R1LookupTable + : ECLookupTable + { + private readonly SecP384R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP384R1LookupTable(SecP384R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat.Create(SECP384R1_FE_INTS), y = Nat.Create(SECP384R1_FE_INTS); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP384R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP384R1_FE_INTS + j] & MASK; + } + + pos += (SECP384R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP384R1FieldElement(x), new SecP384R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs index e5083c7f0..810be85b5 100644 --- a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -10,7 +11,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static readonly BigInteger q = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")); - private const int SecP521R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP521R1_DEFAULT_COORDS = COORD_JACOBIAN; + private const int SECP521R1_FE_INTS = 17; protected readonly SecP521R1Point m_infinity; @@ -25,7 +27,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Hex.Decode("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"))); this.m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409")); this.m_cofactor = BigInteger.One; - this.m_coord = SecP521R1_DEFAULT_COORDS; + this.m_coord = SECP521R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -73,5 +75,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { return new SecP521R1Point(this, x, y, zs, withCompression); } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + uint[] table = new uint[len * SECP521R1_FE_INTS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat.Copy(SECP521R1_FE_INTS, ((SecP521R1FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECP521R1_FE_INTS; + Nat.Copy(SECP521R1_FE_INTS, ((SecP521R1FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECP521R1_FE_INTS; + } + } + + return new SecP521R1LookupTable(this, table, len); + } + + private class SecP521R1LookupTable + : ECLookupTable + { + private readonly SecP521R1Curve m_outer; + private readonly uint[] m_table; + private readonly int m_size; + + internal SecP521R1LookupTable(SecP521R1Curve outer, uint[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + uint[] x = Nat.Create(SECP521R1_FE_INTS), y = Nat.Create(SECP521R1_FE_INTS); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + uint MASK = (uint)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECP521R1_FE_INTS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECP521R1_FE_INTS + j] & MASK; + } + + pos += (SECP521R1_FE_INTS * 2); + } + + return m_outer.CreateRawPoint(new SecP521R1FieldElement(x), new SecP521R1FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs index 2705c94aa..e85f68e60 100644 --- a/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT113R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT113R1Curve : AbstractF2mCurve { - private const int SecT113R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R1_FE_LONGS = 2; protected readonly SecT113R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("0100000000000000D9CCEC8A39E56F")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT113R1_DEFAULT_COORDS; + this.m_coord = SECT113R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT113R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy64(((SecT113FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT113R1_FE_LONGS; + Nat128.Copy64(((SecT113FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT113R1_FE_LONGS; + } + } + + return new SecT113R1LookupTable(this, table, len); + } + + private class SecT113R1LookupTable + : ECLookupTable + { + private readonly SecT113R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT113R1LookupTable(SecT113R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT113R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT113R1_FE_LONGS + j] & MASK; + } + + pos += (SECT113R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs index abfd26d5b..efe422806 100644 --- a/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT113R2Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT113R2Curve : AbstractF2mCurve { - private const int SecT113R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT113R2_FE_LONGS = 2; protected readonly SecT113R2Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("010000000000000108789B2496AF93")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT113R2_DEFAULT_COORDS; + this.m_coord = SECT113R2_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT113R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat128.Copy64(((SecT113FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT113R2_FE_LONGS; + Nat128.Copy64(((SecT113FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT113R2_FE_LONGS; + } + } + + return new SecT113R2LookupTable(this, table, len); + } + + private class SecT113R2LookupTable + : ECLookupTable + { + private readonly SecT113R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT113R2LookupTable(SecT113R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat128.Create64(), y = Nat128.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT113R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT113R2_FE_LONGS + j] & MASK; + } + + pos += (SECT113R2_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT113FieldElement(x), new SecT113FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs index e0ecc100f..c38e8eb0a 100644 --- a/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT131FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT131FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT131FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs index b73964c39..06f0a79ae 100644 --- a/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT131R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT131R1Curve : AbstractF2mCurve { - private const int SecT131R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R1_FE_LONGS = 3; protected readonly SecT131R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("0400000000000000023123953A9464B54D")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT131R1_DEFAULT_COORDS; + this.m_coord = SECT131R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 8; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT131R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT131FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT131R1_FE_LONGS; + Nat192.Copy64(((SecT131FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT131R1_FE_LONGS; + } + } + + return new SecT131R1LookupTable(this, table, len); + } + + private class SecT131R1LookupTable + : ECLookupTable + { + private readonly SecT131R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT131R1LookupTable(SecT131R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT131R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT131R1_FE_LONGS + j] & MASK; + } + + pos += (SECT131R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs index 724921c94..0120b3059 100644 --- a/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT131R2Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT131R2Curve : AbstractF2mCurve { - private const int SecT131R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT131R2_FE_LONGS = 3; protected readonly SecT131R2Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("0400000000000000016954A233049BA98F")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT131R2_DEFAULT_COORDS; + this.m_coord = SECT131R2_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 8; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT131R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT131FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT131R2_FE_LONGS; + Nat192.Copy64(((SecT131FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT131R2_FE_LONGS; + } + } + + return new SecT131R2LookupTable(this, table, len); + } + + private class SecT131R2LookupTable + : ECLookupTable + { + private readonly SecT131R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT131R2LookupTable(SecT131R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT131R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT131R2_FE_LONGS + j] & MASK; + } + + pos += (SECT131R2_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT131FieldElement(x), new SecT131FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs index 8953fb529..07bd07652 100644 --- a/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT163FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT163FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT163FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs index 68ff646ca..5e1431f46 100644 --- a/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT163K1Curve : AbstractF2mCurve { - private const int SecT163K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163K1_FE_LONGS = 3; protected readonly SecT163K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("04000000000000000000020108A2E0CC0D99F8A5EF")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT163K1_DEFAULT_COORDS; + this.m_coord = SECT163K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 7; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163K1_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163K1_FE_LONGS; + } + } + + return new SecT163K1LookupTable(this, table, len); + } + + private class SecT163K1LookupTable + : ECLookupTable + { + private readonly SecT163K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163K1LookupTable(SecT163K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163K1_FE_LONGS + j] & MASK; + } + + pos += (SECT163K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs index 8ae58ccef..e212ad4ea 100644 --- a/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT163R1Curve : AbstractF2mCurve { - private const int SecT163R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R1_FE_LONGS = 3; protected readonly SecT163R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT163R1_DEFAULT_COORDS; + this.m_coord = SECT163R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 7; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163R1_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163R1_FE_LONGS; + } + } + + return new SecT163R1LookupTable(this, table, len); + } + + private class SecT163R1LookupTable + : ECLookupTable + { + private readonly SecT163R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163R1LookupTable(SecT163R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163R1_FE_LONGS + j] & MASK; + } + + pos += (SECT163R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs index 5a4fa5ad1..b0365388a 100644 --- a/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT163R2Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT163R2Curve : AbstractF2mCurve { - private const int SecT163R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT163R2_FE_LONGS = 3; protected readonly SecT163R2Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("040000000000000000000292FE77E70C12A4234C33")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT163R2_DEFAULT_COORDS; + this.m_coord = SECT163R2_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 7; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT163R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat192.Copy64(((SecT163FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT163R2_FE_LONGS; + Nat192.Copy64(((SecT163FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT163R2_FE_LONGS; + } + } + + return new SecT163R2LookupTable(this, table, len); + } + + private class SecT163R2LookupTable + : ECLookupTable + { + private readonly SecT163R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT163R2LookupTable(SecT163R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat192.Create64(), y = Nat192.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT163R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT163R2_FE_LONGS + j] & MASK; + } + + pos += (SECT163R2_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT163FieldElement(x), new SecT163FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs index a1150b3f9..d04e68d3f 100644 --- a/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT193FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT193FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT193FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs index a2cb5a8ac..e6cb3b4d8 100644 --- a/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT193R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT193R1Curve : AbstractF2mCurve { - private const int SecT193R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R1_FE_LONGS = 4; protected readonly SecT193R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000C7F34A778F443ACC920EBA49")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT193R1_DEFAULT_COORDS; + this.m_coord = SECT193R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT193R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT193FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT193R1_FE_LONGS; + Nat256.Copy64(((SecT193FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT193R1_FE_LONGS; + } + } + + return new SecT193R1LookupTable(this, table, len); + } + + private class SecT193R1LookupTable + : ECLookupTable + { + private readonly SecT193R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT193R1LookupTable(SecT193R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT193R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT193R1_FE_LONGS + j] & MASK; + } + + pos += (SECT193R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs b/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs index 1c84a3eac..cfd690c65 100644 --- a/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT193R2Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT193R2Curve : AbstractF2mCurve { - private const int SecT193R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R2_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT193R2_FE_LONGS = 4; protected readonly SecT193R2Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("010000000000000000000000015AAB561B005413CCD4EE99D5")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT193R2_DEFAULT_COORDS; + this.m_coord = SECT193R2_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT193R2_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT193FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT193R2_FE_LONGS; + Nat256.Copy64(((SecT193FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT193R2_FE_LONGS; + } + } + + return new SecT193R2LookupTable(this, table, len); + } + + private class SecT193R2LookupTable + : ECLookupTable + { + private readonly SecT193R2Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT193R2LookupTable(SecT193R2Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT193R2_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT193R2_FE_LONGS + j] & MASK; + } + + pos += (SECT193R2_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT193FieldElement(x), new SecT193FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs index 91b8e2f1c..64d09bd6d 100644 --- a/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT233FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT233FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT233FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs index 72935913d..07eae1564 100644 --- a/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT233K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT233K1Curve : AbstractF2mCurve { - private const int SecT233K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233K1_FE_LONGS = 4; protected readonly SecT233K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF")); this.m_cofactor = BigInteger.ValueOf(4); - this.m_coord = SecT233K1_DEFAULT_COORDS; + this.m_coord = SECT233K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT233K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT233FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT233K1_FE_LONGS; + Nat256.Copy64(((SecT233FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT233K1_FE_LONGS; + } + } + + return new SecT233K1LookupTable(this, table, len); + } + + private class SecT233K1LookupTable + : ECLookupTable + { + private readonly SecT233K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT233K1LookupTable(SecT233K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT233K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT233K1_FE_LONGS + j] & MASK; + } + + pos += (SECT233K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs index db6e6e1d4..5e8dee875 100644 --- a/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT233R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT233R1Curve : AbstractF2mCurve { - private const int SecT233R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT233R1_FE_LONGS = 4; protected readonly SecT233R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT233R1_DEFAULT_COORDS; + this.m_coord = SECT233R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT233R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT233FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT233R1_FE_LONGS; + Nat256.Copy64(((SecT233FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT233R1_FE_LONGS; + } + } + + return new SecT233R1LookupTable(this, table, len); + } + + private class SecT233R1LookupTable + : ECLookupTable + { + private readonly SecT233R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT233R1LookupTable(SecT233R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT233R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT233R1_FE_LONGS + j] & MASK; + } + + pos += (SECT233R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT233FieldElement(x), new SecT233FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs index a32ffc5d2..18563f746 100644 --- a/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT239FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT239FieldElement : ECFieldElement { - protected ulong[] x; + protected internal readonly ulong[] x; public SecT239FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs index a499d48b4..33792e631 100644 --- a/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT239K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT239K1Curve : AbstractF2mCurve { - private const int SecT239K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT239K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT239K1_FE_LONGS = 4; protected readonly SecT239K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5")); this.m_cofactor = BigInteger.ValueOf(4); - this.m_coord = SecT239K1_DEFAULT_COORDS; + this.m_coord = SECT239K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT239K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat256.Copy64(((SecT239FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT239K1_FE_LONGS; + Nat256.Copy64(((SecT239FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT239K1_FE_LONGS; + } + } + + return new SecT239K1LookupTable(this, table, len); + } + + private class SecT239K1LookupTable + : ECLookupTable + { + private readonly SecT239K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT239K1LookupTable(SecT239K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat256.Create64(), y = Nat256.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT239K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT239K1_FE_LONGS + j] & MASK; + } + + pos += (SECT239K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT239FieldElement(x), new SecT239FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs index adfd4e0ed..b054bedfb 100644 --- a/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT283FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT283FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT283FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs index 4053287ec..51725bc20 100644 --- a/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT283K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT283K1Curve : AbstractF2mCurve { - private const int SecT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283K1_FE_LONGS = 5; protected readonly SecT283K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61")); this.m_cofactor = BigInteger.ValueOf(4); - this.m_coord = SecT283K1_DEFAULT_COORDS; + this.m_coord = SECT283K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 12; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT283K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat320.Copy64(((SecT283FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT283K1_FE_LONGS; + Nat320.Copy64(((SecT283FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT283K1_FE_LONGS; + } + } + + return new SecT283K1LookupTable(this, table, len); + } + + private class SecT283K1LookupTable + : ECLookupTable + { + private readonly SecT283K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT283K1LookupTable(SecT283K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT283K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT283K1_FE_LONGS + j] & MASK; + } + + pos += (SECT283K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs index e659675ce..567df7686 100644 --- a/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT283R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT283R1Curve : AbstractF2mCurve { - private const int SecT283R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT283R1_FE_LONGS = 5; protected readonly SecT283R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT283R1_DEFAULT_COORDS; + this.m_coord = SECT283R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 12; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT283R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat320.Copy64(((SecT283FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT283R1_FE_LONGS; + Nat320.Copy64(((SecT283FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT283R1_FE_LONGS; + } + } + + return new SecT283R1LookupTable(this, table, len); + } + + private class SecT283R1LookupTable + : ECLookupTable + { + private readonly SecT283R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT283R1LookupTable(SecT283R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat320.Create64(), y = Nat320.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT283R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT283R1_FE_LONGS + j] & MASK; + } + + pos += (SECT283R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT283FieldElement(x), new SecT283FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs index f954f46e7..7076905bb 100644 --- a/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT409FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT409FieldElement : ECFieldElement { - protected ulong[] x; + protected internal readonly ulong[] x; public SecT409FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs index 4f573553e..839ec8059 100644 --- a/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT409K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT409K1Curve : AbstractF2mCurve { - private const int SecT409K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409K1_FE_LONGS = 7; protected readonly SecT409K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF")); this.m_cofactor = BigInteger.ValueOf(4); - this.m_coord = SecT409K1_DEFAULT_COORDS; + this.m_coord = SECT409K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT409K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat448.Copy64(((SecT409FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT409K1_FE_LONGS; + Nat448.Copy64(((SecT409FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT409K1_FE_LONGS; + } + } + + return new SecT409K1LookupTable(this, table, len); + } + + private class SecT409K1LookupTable + : ECLookupTable + { + private readonly SecT409K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT409K1LookupTable(SecT409K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT409K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT409K1_FE_LONGS + j] & MASK; + } + + pos += (SECT409K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs index 9212fb5d2..f70dd5f8e 100644 --- a/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT409R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT409R1Curve : AbstractF2mCurve { - private const int SecT409R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT409R1_FE_LONGS = 7; protected readonly SecT409R1Point m_infinity; @@ -21,7 +23,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT409R1_DEFAULT_COORDS; + this.m_coord = SECT409R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -94,5 +96,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 0; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT409R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat448.Copy64(((SecT409FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT409R1_FE_LONGS; + Nat448.Copy64(((SecT409FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT409R1_FE_LONGS; + } + } + + return new SecT409R1LookupTable(this, table, len); + } + + private class SecT409R1LookupTable + : ECLookupTable + { + private readonly SecT409R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT409R1LookupTable(SecT409R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat448.Create64(), y = Nat448.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT409R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT409R1_FE_LONGS + j] & MASK; + } + + pos += (SECT409R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT409FieldElement(x), new SecT409FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs b/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs index c43b8dc3a..5f28c01be 100644 --- a/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs +++ b/crypto/src/math/ec/custom/sec/SecT571FieldElement.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT571FieldElement : ECFieldElement { - protected readonly ulong[] x; + protected internal readonly ulong[] x; public SecT571FieldElement(BigInteger x) { diff --git a/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs b/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs index f5806f09c..3d84797f7 100644 --- a/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT571K1Curve.cs @@ -1,6 +1,7 @@ using System; using Org.BouncyCastle.Math.EC.Multiplier; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -8,7 +9,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT571K1Curve : AbstractF2mCurve { - private const int SecT571K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571K1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571K1_FE_LONGS = 9; protected readonly SecT571K1Point m_infinity; @@ -22,7 +24,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001")); this.m_cofactor = BigInteger.ValueOf(4); - this.m_coord = SecT571K1_DEFAULT_COORDS; + this.m_coord = SECT571K1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -100,5 +102,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 10; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT571K1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat576.Copy64(((SecT571FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT571K1_FE_LONGS; + Nat576.Copy64(((SecT571FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT571K1_FE_LONGS; + } + } + + return new SecT571K1LookupTable(this, table, len); + } + + private class SecT571K1LookupTable + : ECLookupTable + { + private readonly SecT571K1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT571K1LookupTable(SecT571K1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT571K1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT571K1_FE_LONGS + j] & MASK; + } + + pos += (SECT571K1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), false); + } + } } } diff --git a/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs b/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs index 082afa5bd..7ebf90856 100644 --- a/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs +++ b/crypto/src/math/ec/custom/sec/SecT571R1Curve.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Math.Raw; using Org.BouncyCastle.Utilities.Encoders; namespace Org.BouncyCastle.Math.EC.Custom.Sec @@ -7,7 +8,8 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec internal class SecT571R1Curve : AbstractF2mCurve { - private const int SecT571R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571R1_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; + private const int SECT571R1_FE_LONGS = 9; protected readonly SecT571R1Point m_infinity; @@ -25,7 +27,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec this.m_order = new BigInteger(1, Hex.Decode("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47")); this.m_cofactor = BigInteger.Two; - this.m_coord = SecT571R1_DEFAULT_COORDS; + this.m_coord = SECT571R1_DEFAULT_COORDS; } protected override ECCurve CloneCurve() @@ -98,5 +100,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec { get { return 10; } } + + public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) + { + ulong[] table = new ulong[len * SECT571R1_FE_LONGS * 2]; + { + int pos = 0; + for (int i = 0; i < len; ++i) + { + ECPoint p = points[off + i]; + Nat576.Copy64(((SecT571FieldElement)p.RawXCoord).x, 0, table, pos); pos += SECT571R1_FE_LONGS; + Nat576.Copy64(((SecT571FieldElement)p.RawYCoord).x, 0, table, pos); pos += SECT571R1_FE_LONGS; + } + } + + return new SecT571R1LookupTable(this, table, len); + } + + private class SecT571R1LookupTable + : ECLookupTable + { + private readonly SecT571R1Curve m_outer; + private readonly ulong[] m_table; + private readonly int m_size; + + internal SecT571R1LookupTable(SecT571R1Curve outer, ulong[] table, int size) + { + this.m_outer = outer; + this.m_table = table; + this.m_size = size; + } + + public virtual int Size + { + get { return m_size; } + } + + public virtual ECPoint Lookup(int index) + { + ulong[] x = Nat576.Create64(), y = Nat576.Create64(); + int pos = 0; + + for (int i = 0; i < m_size; ++i) + { + ulong MASK = (ulong)(long)(((i ^ index) - 1) >> 31); + + for (int j = 0; j < SECT571R1_FE_LONGS; ++j) + { + x[j] ^= m_table[pos + j] & MASK; + y[j] ^= m_table[pos + SECT571R1_FE_LONGS + j] & MASK; + } + + pos += (SECT571R1_FE_LONGS * 2); + } + + return m_outer.CreateRawPoint(new SecT571FieldElement(x), new SecT571FieldElement(y), false); + } + } } } |