From d79a501212d4012139c714e361577669c75171aa Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sun, 15 Apr 2018 21:12:11 +0700 Subject: 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 --- crypto/src/math/ec/custom/djb/Curve25519.cs | 58 +++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'crypto/src/math/ec/custom/djb/Curve25519.cs') diff --git a/crypto/src/math/ec/custom/djb/Curve25519.cs b/crypto/src/math/ec/custom/djb/Curve25519.cs index 6ed7c0648..c0f911a9c 100644 --- a/crypto/src/math/ec/custom/djb/Curve25519.cs +++ b/crypto/src/math/ec/custom/djb/Curve25519.cs @@ -11,6 +11,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb public static readonly BigInteger q = Nat256.ToBigInteger(Curve25519Field.P); private const int Curve25519_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + private const int CURVE25519_FE_INTS = 8; protected readonly Curve25519Point m_infinity; @@ -73,5 +74,62 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb { return new Curve25519Point(this, x, y, zs, withCompression); } + + 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); + } + + private class Curve25519LookupTable + : ECLookupTable + { + 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 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 < 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 m_outer.CreateRawPoint(new Curve25519FieldElement(x), new Curve25519FieldElement(y), false); + } + } } } -- cgit 1.4.1