diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-07-08 16:30:26 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-07-08 16:30:26 +0700 |
commit | 5268ce495106a67a3e167559b78c6dc1f857a423 (patch) | |
tree | 1b18df57d8e9dd6cf327f53608f9d1e228711332 /crypto/src/math/ec/rfc7748 | |
parent | Improved performance for BigInteger.ToString(int) (diff) | |
download | BouncyCastle.NET-ed25519-5268ce495106a67a3e167559b78c6dc1f857a423.tar.xz |
Add Ed25519 and Ed448 from RFC 8032
Diffstat (limited to 'crypto/src/math/ec/rfc7748')
-rw-r--r-- | crypto/src/math/ec/rfc7748/X25519.cs | 4 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X25519Field.cs | 147 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X448.cs | 8 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X448Field.cs | 123 |
4 files changed, 249 insertions, 33 deletions
diff --git a/crypto/src/math/ec/rfc7748/X25519.cs b/crypto/src/math/ec/rfc7748/X25519.cs index 16f680d90..a10d53da5 100644 --- a/crypto/src/math/ec/rfc7748/X25519.cs +++ b/crypto/src/math/ec/rfc7748/X25519.cs @@ -10,10 +10,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private const int C_A24 = (C_A + 2)/4; // 0x1 - //private static readonly int[] S_x = new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + //private static readonly int[] S_x = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 0x215132111D8354CB52385F46DCA2B71D440F6A51EB4D1207816B1E0137D48290 - private static readonly int[] PsubS_x = new int[]{ 0x03D48290, 0x02C7804D, 0x01207816, 0x028F5A68, 0x00881ED4, 0x00A2B71D, + private static readonly int[] PsubS_x = { 0x03D48290, 0x02C7804D, 0x01207816, 0x028F5A68, 0x00881ED4, 0x00A2B71D, 0x0217D1B7, 0x014CB523, 0x0088EC1A, 0x0042A264 }; private static int[] precompBase = null; diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs index 282f41628..fd5599657 100644 --- a/crypto/src/math/ec/rfc7748/X25519Field.cs +++ b/crypto/src/math/ec/rfc7748/X25519Field.cs @@ -11,6 +11,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private const int M25 = 0x01FFFFFF; private const int M26 = 0x03FFFFFF; + private static readonly int[] RootNegOne = { 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630, + 0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 }; + private X25519Field() {} public static void Add(int[] x, int[] y, int[] z) @@ -21,6 +24,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 } } + public static void AddOne(int[] z) + { + z[0] += 1; + } + + public static void AddOne(int[] z, int zOff) + { + z[zOff] += 1; + } + public static void Apm(int[] x, int[] y, int[] zp, int[] zm) { for (int i = 0; i < Size; ++i) @@ -54,6 +67,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[5] = z5; z[6] = z6; z[7] = z7; z[8] = z8; z[9] = z9; } + public static void CNegate(int negate, int[] z) + { + Debug.Assert(negate >> 1 == 0); + + int mask = 0 - negate; + for (int i = 0; i < Size; ++i) + { + z[i] = (z[i] ^ mask) - mask; + } + } + public static void Copy(int[] x, int xOff, int[] z, int zOff) { for (int i = 0; i < Size; ++i) @@ -67,6 +91,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 return new int[Size]; } + public static int[] CreateTable(int n) + { + return new int[Size * n]; + } + public static void CSwap(int swap, int[] a, int[] b) { Debug.Assert(swap >> 1 == 0); @@ -143,24 +172,23 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 // (250 1s) (1 0s) (1 1s) (1 0s) (2 1s) // Addition chain: [1] [2] 3 5 10 15 25 50 75 125 [250] - int[] x2 = Create(); Sqr(x, x2); Mul(x, x2, x2); - int[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); - int[] x5 = x3; Sqr(x3, 2, x5); Mul(x2, x5, x5); - int[] x10 = Create(); Sqr(x5, 5, x10); Mul(x5, x10, x10); - int[] x15 = Create(); Sqr(x10, 5, x15); Mul(x5, x15, x15); - int[] x25 = x5; Sqr(x15, 10, x25); Mul(x10, x25, x25); - int[] x50 = x10; Sqr(x25, 25, x50); Mul(x25, x50, x50); - int[] x75 = x15; Sqr(x50, 25, x75); Mul(x25, x75, x75); - int[] x125 = x25; Sqr(x75, 50, x125); Mul(x50, x125, x125); - int[] x250 = x50; Sqr(x125, 125, x250); Mul(x125, x250, x250); - - int[] t = x125; - Sqr(x250, 2, t); - Mul(t, x, t); + int[] x2 = Create(); + int[] t = Create(); + PowPm5d8(x, x2, t); Sqr(t, 3, t); Mul(t, x2, z); } + public static bool IsZeroVar(int[] x) + { + int d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i]; + } + return d == 0; + } + public static void Mul(int[] x, int y, int[] z) { int x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4]; @@ -345,6 +373,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[9] = z9 + (int)t; } + public static void Negate(int[] x, int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = -x[i]; + } + } + public static void Normalize(int[] z) { int x = (z[9] >> 23) & 1; @@ -353,6 +389,37 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Debug.Assert(z[9] >> 24 == 0); } + public static void One(int[] z) + { + z[0] = 1; + for (int i = 1; i < Size; ++i) + { + z[i] = 0; + } + } + + private static void PowPm5d8(int[] x, int[] rx2, int[] rz) + { + // z = x^((p-5)/8) = x^FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD + // (250 1s) (1 0s) (1 1s) + // Addition chain: [1] 2 3 5 10 15 25 50 75 125 [250] + + int[] x2 = rx2; Sqr(x, x2); Mul(x, x2, x2); + int[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); + int[] x5 = x3; Sqr(x3, 2, x5); Mul(x2, x5, x5); + int[] x10 = Create(); Sqr(x5, 5, x10); Mul(x5, x10, x10); + int[] x15 = Create(); Sqr(x10, 5, x15); Mul(x5, x15, x15); + int[] x25 = x5; Sqr(x15, 10, x25); Mul(x10, x25, x25); + int[] x50 = x10; Sqr(x25, 25, x50); Mul(x25, x50, x50); + int[] x75 = x15; Sqr(x50, 25, x75); Mul(x25, x75, x75); + int[] x125 = x25; Sqr(x75, 50, x125); Mul(x50, x125, x125); + int[] x250 = x50; Sqr(x125, 125, x250); Mul(x125, x250, x250); + + int[] t = x125; + Sqr(x250, 2, t); + Mul(t, x, rz); + } + private static void Reduce(int[] z, int c) { int z9 = z[9], t = z9; @@ -509,6 +576,45 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 } } + public static bool SqrtRatioVar(int[] u, int[] v, int[] z) + { + int[] uv3 = Create(); + int[] uv7 = Create(); + + Mul(u, v, uv3); + Sqr(v, uv7); + Mul(uv3, uv7, uv3); + Sqr(uv7, uv7); + Mul(uv7, uv3, uv7); + + int[] t = Create(); + int[] x = Create(); + PowPm5d8(uv7, t, x); + Mul(x, uv3, x); + + int[] vx2 = Create(); + Sqr(x, vx2); + Mul(vx2, v, vx2); + + Sub(vx2, u, t); + Normalize(t); + if (IsZeroVar(t)) + { + Copy(x, 0, z, 0); + return true; + } + + Add(vx2, u, t); + Normalize(t); + if (IsZeroVar(t)) + { + Mul(x, RootNegOne, z); + return true; + } + + return false; + } + public static void Sub(int[] x, int[] y, int[] z) { for (int i = 0; i < Size; ++i) @@ -516,5 +622,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[i] = x[i] - y[i]; } } + + public static void SubOne(int[] z) + { + z[0] -= 1; + } + + public static void Zero(int[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = 0; + } + } } } diff --git a/crypto/src/math/ec/rfc7748/X448.cs b/crypto/src/math/ec/rfc7748/X448.cs index 32a4a9e2a..88e8a5d76 100644 --- a/crypto/src/math/ec/rfc7748/X448.cs +++ b/crypto/src/math/ec/rfc7748/X448.cs @@ -10,14 +10,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private const uint C_A24 = (C_A + 2)/4; // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE - private static readonly uint[] S_x = new uint[]{ 0x0FFFFFFEU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, + private static readonly uint[] S_x = { 0x0FFFFFFEU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFEU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU, 0x0FFFFFFFU }; // 0xF0FAB725013244423ACF03881AFFEB7BDACDD1031C81B9672954459D84C1F823F1BD65643ACE1B5123AC33FF1C69BAF8ACB1197DC99D2720 - private static readonly uint[] PsubS_x = new uint[]{ 0x099d2720U, 0x0b1197dcU, 0x09baf8acU, 0x033ff1c6U, 0x0b5123acU, - 0x0643ace1U, 0x03f1bd65U, 0x084c1f82U, 0x0954459dU, 0x081b9672U, 0x0dd1031cU, 0x0eb7bdacU, 0x03881affU, 0x0423acf0U, - 0x05013244U, 0x0f0fab72U }; + private static readonly uint[] PsubS_x = { 0x099D2720U, 0x0B1197DCU, 0x09BAF8ACU, 0x033FF1C6U, 0x0B5123ACU, + 0x0643ACE1U, 0x03F1BD65U, 0x084C1F82U, 0x0954459DU, 0x081B9672U, 0x0DD1031CU, 0x0EB7BDACU, 0x03881AFFU, 0x0423ACF0U, + 0x05013244U, 0x0F0FAB72U }; private static uint[] precompBase = null; diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs index 0c44f1eb5..5a682714d 100644 --- a/crypto/src/math/ec/rfc7748/X448Field.cs +++ b/crypto/src/math/ec/rfc7748/X448Field.cs @@ -1,6 +1,8 @@ using System; using System.Diagnostics; +using Org.BouncyCastle.Math.Raw; + namespace Org.BouncyCastle.Math.EC.Rfc7748 { [CLSCompliantAttribute(false)] @@ -20,6 +22,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 } } + public static void AddOne(uint[] z) + { + z[0] += 1; + } + + public static void AddOne(uint[] z, int zOff) + { + z[zOff] += 1; + } + //public static void Apm(int[] x, int[] y, int[] zp, int[] zm) //{ // for (int i = 0; i < Size; ++i) @@ -62,6 +74,16 @@ 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 CNegate(int negate, uint[] z) + { + Debug.Assert(negate >> 1 == 0); + + uint[] t = Create(); + Sub(t, z, t); + + Nat.CMov(Size, negate, t, 0, z, 0); + } + public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { for (int i = 0; i < Size; ++i) @@ -166,25 +188,23 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 // z = x^(p-2) = x^(2^448 - 2^224 - 3) // (223 1s) (1 0s) (222 1s) (1 0s) (1 1s) // Addition chain: [1] 2 3 6 9 18 19 37 74 111 [222] [223] - uint[] x2 = Create(); Sqr(x, x2); Mul(x, x2, x2); - uint[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); - uint[] x6 = Create(); Sqr(x3, 3, x6); Mul(x3, x6, x6); - uint[] x9 = Create(); Sqr(x6, 3, x9); Mul(x3, x9, x9); - uint[] x18 = Create(); Sqr(x9, 9, x18); Mul(x9, x18, x18); - uint[] x19 = Create(); Sqr(x18, x19); Mul(x, x19, x19); - uint[] x37 = Create(); Sqr(x19, 18, x37); Mul(x18, x37, x37); - uint[] x74 = Create(); Sqr(x37, 37, x74); Mul(x37, x74, x74); - uint[] x111 = Create(); Sqr(x74, 37, x111); Mul(x37, x111, x111); - uint[] x222 = Create(); Sqr(x111, 111, x222); Mul(x111, x222, x222); - uint[] x223 = Create(); Sqr(x222, x223); Mul(x, x223, x223); uint[] t = Create(); - Sqr(x223, 223, t); - Mul(t, x222, t); + PowPm3d4(x, t); Sqr(t, 2, t); Mul(t, x, z); } + public static bool IsZeroVar(uint[] x) + { + uint d = 0; + for (int i = 0; i < Size; ++i) + { + d |= x[i]; + } + return d == 0U; + } + public static void Mul(uint[] x, uint y, uint[] z) { uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; @@ -563,6 +583,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[15] = z15; } + public static void Negate(uint[] x, uint[] z) + { + uint[] zero = Create(); + Sub(zero, x, z); + } + public static void Normalize(uint[] z) { //int x = (z[15] >> (28 - 1)) & 1; @@ -571,6 +597,37 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Debug.Assert(z[15] >> 28 == 0U); } + public static void One(uint[] z) + { + z[0] = 1U; + for (int i = 1; i < Size; ++i) + { + z[i] = 0; + } + } + + private static void PowPm3d4(uint[] x, uint[] z) + { + // z = x^((p-3)/4) = x^(2^446 - 2^222 - 1) + // (223 1s) (1 0s) (222 1s) + // Addition chain: 1 2 3 6 9 18 19 37 74 111 [222] [223] + uint[] x2 = Create(); Sqr(x, x2); Mul(x, x2, x2); + uint[] x3 = Create(); Sqr(x2, x3); Mul(x, x3, x3); + uint[] x6 = Create(); Sqr(x3, 3, x6); Mul(x3, x6, x6); + uint[] x9 = Create(); Sqr(x6, 3, x9); Mul(x3, x9, x9); + uint[] x18 = Create(); Sqr(x9, 9, x18); Mul(x9, x18, x18); + uint[] x19 = Create(); Sqr(x18, x19); Mul(x, x19, x19); + uint[] x37 = Create(); Sqr(x19, 18, x37); Mul(x18, x37, x37); + uint[] x74 = Create(); Sqr(x37, 37, x74); Mul(x37, x74, x74); + uint[] x111 = Create(); Sqr(x74, 37, x111); Mul(x37, x111, x111); + uint[] x222 = Create(); Sqr(x111, 111, x222); Mul(x111, x222, x222); + uint[] x223 = Create(); Sqr(x222, x223); Mul(x, x223, x223); + + uint[] t = Create(); + Sqr(x223, 223, t); + Mul(t, x222, z); + } + private static void Reduce(uint[] z, int c) { uint z15 = z[15]; @@ -836,6 +893,38 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 } } + public static bool SqrtRatioVar(uint[] u, uint[] v, uint[] z) + { + uint[] u3v = Create(); + uint[] u5v3 = Create(); + + Sqr(u, u3v); + Mul(u3v, v, u3v); + Sqr(u3v, u5v3); + Mul(u3v, u, u3v); + Mul(u5v3, u, u5v3); + Mul(u5v3, v, u5v3); + + uint[] x = Create(); + PowPm3d4(u5v3, x); + Mul(x, u3v, x); + + uint[] t = Create(); + Sqr(x, t); + Mul(t, v, t); + + Sub(u, t, t); + Normalize(t); + + if (IsZeroVar(t)) + { + Copy(x, 0, z, 0); + return true; + } + + return false; + } + public static void Sub(uint[] x, uint[] y, uint[] z) { uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; @@ -900,5 +989,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[14] = z14; z[15] = z15; } + + public static void Zero(uint[] z) + { + for (int i = 0; i < Size; ++i) + { + z[i] = 0; + } + } } } |