diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-08-04 19:07:38 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-08-04 19:07:38 +0700 |
commit | 022f35026b1945d81c4750cf80626685148ceb35 (patch) | |
tree | c29aedda9f8e084270b879f9b166658d038b7eee /crypto/src/math | |
parent | Implement promotion for ECPoint precomputations (diff) | |
download | BouncyCastle.NET-ed25519-022f35026b1945d81c4750cf80626685148ceb35.tar.xz |
EdDSA refactoring
- tighten scalar bounds for wNAF - provide CMov in field classes - fix spelling of Straus
Diffstat (limited to 'crypto/src/math')
-rw-r--r-- | crypto/src/math/ec/rfc7748/X25519Field.cs | 14 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X448Field.cs | 20 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed25519.cs | 24 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed448.cs | 22 |
4 files changed, 46 insertions, 34 deletions
diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs index b5938e2e7..3a06941dd 100644 --- a/crypto/src/math/ec/rfc7748/X25519Field.cs +++ b/crypto/src/math/ec/rfc7748/X25519Field.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private static readonly int[] RootNegOne = { 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630, 0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 }; - private X25519Field() {} + protected X25519Field() {} public static void Add(int[] x, int[] y, int[] z) { @@ -67,6 +67,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[5] = z5; z[6] = z6; z[7] = z7; z[8] = z8; z[9] = z9; } + public static void CMov(int cond, int[] x, int xOff, int[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + for (int i = 0; i < Size; ++i) + { + int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & cond); + z[zOff + i] = z_i; + } + } + public static void CNegate(int negate, int[] z) { Debug.Assert(negate >> 1 == 0); diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs index 7cda6ebcc..f1e89e520 100644 --- a/crypto/src/math/ec/rfc7748/X448Field.cs +++ b/crypto/src/math/ec/rfc7748/X448Field.cs @@ -1,8 +1,6 @@ using System; using System.Diagnostics; -using Org.BouncyCastle.Math.Raw; - namespace Org.BouncyCastle.Math.EC.Rfc7748 { [CLSCompliantAttribute(false)] @@ -12,7 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private const uint M28 = 0x0FFFFFFFU; - private X448Field() {} + protected X448Field() {} public static void Add(uint[] x, uint[] y, uint[] z) { @@ -74,6 +72,20 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[8] = z8; z[9] = z9; z[10] = z10; z[11] = z11; z[12] = z12; z[13] = z13; z[14] = z14; z[15] = z15; } + public static void CMov(int cond, uint[] x, int xOff, uint[] z, int zOff) + { + Debug.Assert(0 == cond || -1 == cond); + + uint MASK = (uint)cond; + + for (int i = 0; i < Size; ++i) + { + uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & MASK); + z[zOff + i] = z_i; + } + } + public static void CNegate(int negate, uint[] z) { Debug.Assert(negate >> 1 == 0); @@ -81,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 uint[] t = Create(); Sub(t, z, t); - Nat.CMov(Size, negate, t, 0, z, 0); + CMov(-negate, t, 0, z, 0); } public static void Copy(uint[] x, int xOff, uint[] z, int zOff) diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs index 702c48dd3..b798bdf2d 100644 --- a/crypto/src/math/ec/rfc8032/Ed25519.cs +++ b/crypto/src/math/ec/rfc8032/Ed25519.cs @@ -270,7 +270,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static sbyte[] GetWnaf(uint[] n, int width) { - Debug.Assert(n[ScalarUints - 1] >> 31 == 0); + Debug.Assert(n[ScalarUints - 1] >> 28 == 0); uint[] t = new uint[ScalarUints * 2]; { @@ -284,7 +284,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } } - sbyte[] ws = new sbyte[256]; + sbyte[] ws = new sbyte[253]; uint pow2 = 1U << width; uint mask = pow2 - 1U; @@ -423,7 +423,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 DecodeScalar(k, 0, nA); PointAccum pR = new PointAccum(); - ScalarMultStraussVar(nS, nA, pA, pR); + ScalarMultStrausVar(nS, nA, pA, pR); byte[] check = new byte[PointBytes]; EncodePoint(pR, check, 0); @@ -597,10 +597,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 for (int i = 0; i < PrecompPoints; ++i) { - int mask = ((i ^ index) - 1) >> 31; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ypx_h, 0); off += X25519Field.Size; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ymx_h, 0); off += X25519Field.Size; - Nat.CMov(X25519Field.Size, mask, precompBase, off, p.xyd, 0); off += X25519Field.Size; + int cond = ((i ^ index) - 1) >> 31; + X25519Field.CMov(cond, precompBase, off, p.ypx_h, 0); off += X25519Field.Size; + X25519Field.CMov(cond, precompBase, off, p.ymx_h, 0); off += X25519Field.Size; + X25519Field.CMov(cond, precompBase, off, p.xyd, 0); off += X25519Field.Size; } } @@ -945,7 +945,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 X25519Field.Copy(p.z, 0, z, 0); } - private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointAccum r) + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointAccum r) { Precompute(); @@ -958,13 +958,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointSetNeutral(r); - int bit = 255; - while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0) - { - --bit; - } - - for (; ; ) + for (int bit = 252;;) { int wb = ws_b[bit]; if (wb != 0) diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs index 597062269..842839396 100644 --- a/crypto/src/math/ec/rfc8032/Ed448.cs +++ b/crypto/src/math/ec/rfc8032/Ed448.cs @@ -279,7 +279,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static sbyte[] GetWnaf(uint[] n, int width) { - Debug.Assert(n[ScalarUints - 1] >> 31 == 0U); + Debug.Assert(n[ScalarUints - 1] >> 30 == 0U); uint[] t = new uint[ScalarUints * 2]; { @@ -293,7 +293,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } } - sbyte[] ws = new sbyte[448]; + sbyte[] ws = new sbyte[447]; uint pow2 = 1U << width; uint mask = pow2 - 1U; @@ -432,7 +432,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 DecodeScalar(k, 0, nA); PointExt pR = new PointExt(); - ScalarMultStraussVar(nS, nA, pA, pR); + ScalarMultStrausVar(nS, nA, pA, pR); byte[] check = new byte[PointBytes]; EncodePoint(pR, check, 0); @@ -568,9 +568,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 for (int i = 0; i < PrecompPoints; ++i) { - int mask = ((i ^ index) - 1) >> 31; - Nat.CMov(X448Field.Size, mask, precompBase, off, p.x, 0); off += X448Field.Size; - Nat.CMov(X448Field.Size, mask, precompBase, off, p.y, 0); off += X448Field.Size; + int cond = ((i ^ index) - 1) >> 31; + X448Field.CMov(cond, precompBase, off, p.x, 0); off += X448Field.Size; + X448Field.CMov(cond, precompBase, off, p.y, 0); off += X448Field.Size; } } @@ -1032,7 +1032,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 X448Field.Copy(p.y, 0, y, 0); } - private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointExt r) + private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointExt r) { Precompute(); @@ -1045,13 +1045,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointSetNeutral(r); - int bit = 447; - while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0) - { - --bit; - } - - for (;;) + for (int bit = 446;;) { int wb = ws_b[bit]; if (wb != 0) |