From 11ae28f007e8c932ca11f5351b93e5ebf1a9599a Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 3 Aug 2019 00:14:03 +0700 Subject: Improve caching behaviour for algorithms using endomorphisms --- crypto/BouncyCastle.Android.csproj | 1 + crypto/BouncyCastle.csproj | 1 + crypto/BouncyCastle.iOS.csproj | 1 + crypto/crypto.csproj | 5 ++ crypto/src/math/ec/ECAlgorithms.cs | 27 ++++---- crypto/src/math/ec/endo/EndoPreCompInfo.cs | 26 ++++++++ crypto/src/math/ec/endo/EndoUtilities.cs | 47 ++++++++++++- crypto/src/math/ec/multiplier/GlvMultiplier.cs | 7 +- crypto/src/math/ec/multiplier/WNafUtilities.cs | 91 +++++++++++++++++++++++++- 9 files changed, 187 insertions(+), 19 deletions(-) create mode 100644 crypto/src/math/ec/endo/EndoPreCompInfo.cs diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index 2c2c44f86..c1c53fc52 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -1342,6 +1342,7 @@ + diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index 6a5e58829..3ba21ac66 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -1336,6 +1336,7 @@ + diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index 8194180f5..b6810009b 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -1337,6 +1337,7 @@ + diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 4e6330818..7789d1858 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -6568,6 +6568,11 @@ SubType = "Code" BuildAction = "Compile" /> + = reqLen; } } + + private class PrecomputeWithPointMapCallback + : IPreCompCallback + { + private readonly ECPoint m_point; + private readonly ECPointMap m_pointMap; + private readonly WNafPreCompInfo m_fromWNaf; + private readonly bool m_includeNegated; + + internal PrecomputeWithPointMapCallback(ECPoint point, ECPointMap pointMap, WNafPreCompInfo fromWNaf, + bool includeNegated) + { + this.m_point = point; + this.m_pointMap = pointMap; + this.m_fromWNaf = fromWNaf; + this.m_includeNegated = includeNegated; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo; + + int width = m_fromWNaf.Width; + int reqPreCompLen = m_fromWNaf.PreComp.Length; + + if (CheckExisting(existingWNaf, width, reqPreCompLen, m_includeNegated)) + return existingWNaf; + + /* + * TODO Ideally this method would support incremental calculation, but given the + * existing use-cases it would be of little-to-no benefit. + */ + WNafPreCompInfo result = new WNafPreCompInfo(); + + ECPoint twiceFrom = m_fromWNaf.Twice; + if (null != twiceFrom) + { + ECPoint twice = m_pointMap.Map(twiceFrom); + result.Twice = twice; + } + + ECPoint[] preCompFrom = m_fromWNaf.PreComp; + ECPoint[] preComp = new ECPoint[preCompFrom.Length]; + for (int i = 0; i < preCompFrom.Length; ++i) + { + preComp[i] = m_pointMap.Map(preCompFrom[i]); + } + result.PreComp = preComp; + result.Width = width; + + if (m_includeNegated) + { + ECPoint[] preCompNeg = new ECPoint[preComp.Length]; + for (int i = 0; i < preCompNeg.Length; ++i) + { + preCompNeg[i] = preComp[i].Negate(); + } + result.PreCompNeg = preCompNeg; + } + + return result; + } + + private bool CheckExisting(WNafPreCompInfo existingWNaf, int width, int reqPreCompLen, bool includeNegated) + { + return null != existingWNaf + && existingWNaf.Width >= width + && CheckTable(existingWNaf.PreComp, reqPreCompLen) + && (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen)); + } + + private bool CheckTable(ECPoint[] table, int reqLen) + { + return null != table && table.Length >= reqLen; + } + } } } -- cgit 1.5.1