summary refs log tree commit diff
path: root/crypto/src/math/raw
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2018-07-08 16:30:26 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2018-07-08 16:30:26 +0700
commit5268ce495106a67a3e167559b78c6dc1f857a423 (patch)
tree1b18df57d8e9dd6cf327f53608f9d1e228711332 /crypto/src/math/raw
parentImproved performance for BigInteger.ToString(int) (diff)
downloadBouncyCastle.NET-ed25519-5268ce495106a67a3e167559b78c6dc1f857a423.tar.xz
Add Ed25519 and Ed448 from RFC 8032
Diffstat (limited to 'crypto/src/math/raw')
-rw-r--r--crypto/src/math/raw/Interleave.cs71
-rw-r--r--crypto/src/math/raw/Nat.cs85
2 files changed, 156 insertions, 0 deletions
diff --git a/crypto/src/math/raw/Interleave.cs b/crypto/src/math/raw/Interleave.cs

index d21840644..591ba3f15 100644 --- a/crypto/src/math/raw/Interleave.cs +++ b/crypto/src/math/raw/Interleave.cs
@@ -6,6 +6,7 @@ namespace Org.BouncyCastle.Math.Raw { private const ulong M32 = 0x55555555UL; private const ulong M64 = 0x5555555555555555UL; + private const ulong M64R = 0xAAAAAAAAAAAAAAAAUL; /* * This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits. @@ -92,6 +93,65 @@ namespace Org.BouncyCastle.Math.Raw z[zOff + 1] = (x >> 1) & M64; } + internal static void Expand64To128Rev(ulong x, ulong[] z, int zOff) + { + // "shuffle" low half to even bits and high half to odd bits + ulong t; + t = (x ^ (x >> 16)) & 0x00000000FFFF0000UL; x ^= (t ^ (t << 16)); + t = (x ^ (x >> 8)) & 0x0000FF000000FF00UL; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F000F000F0UL; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CUL; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 1)) & 0x2222222222222222UL; x ^= (t ^ (t << 1)); + + z[zOff] = (x ) & M64R; + z[zOff + 1] = (x << 1) & M64R; + } + + internal static uint Shuffle(uint x) + { + // "shuffle" low half to even bits and high half to odd bits + uint t; + t = (x ^ (x >> 8)) & 0x0000FF00U; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F0U; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 2)) & 0x0C0C0C0CU; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 1)) & 0x22222222U; x ^= (t ^ (t << 1)); + return x; + } + + internal static ulong Shuffle(ulong x) + { + // "shuffle" low half to even bits and high half to odd bits + ulong t; + t = (x ^ (x >> 16)) & 0x00000000FFFF0000UL; x ^= (t ^ (t << 16)); + t = (x ^ (x >> 8)) & 0x0000FF000000FF00UL; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F000F000F0UL; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CUL; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 1)) & 0x2222222222222222UL; x ^= (t ^ (t << 1)); + return x; + } + + internal static uint Shuffle2(uint x) + { + // "shuffle" (twice) low half to even bits and high half to odd bits + uint t; + t = (x ^ (x >> 7)) & 0x00AA00AAU; x ^= (t ^ (t << 7)); + t = (x ^ (x >> 14)) & 0x0000CCCCU; x ^= (t ^ (t << 14)); + t = (x ^ (x >> 4)) & 0x00F000F0U; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 8)) & 0x0000FF00U; x ^= (t ^ (t << 8)); + return x; + } + + internal static uint Unshuffle(uint x) + { + // "unshuffle" even bits to low half and odd bits to high half + uint t; + t = (x ^ (x >> 1)) & 0x22222222U; x ^= (t ^ (t << 1)); + t = (x ^ (x >> 2)) & 0x0C0C0C0CU; x ^= (t ^ (t << 2)); + t = (x ^ (x >> 4)) & 0x00F000F0U; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 8)) & 0x0000FF00U; x ^= (t ^ (t << 8)); + return x; + } + internal static ulong Unshuffle(ulong x) { // "unshuffle" even bits to low half and odd bits to high half @@ -103,5 +163,16 @@ namespace Org.BouncyCastle.Math.Raw t = (x ^ (x >> 16)) & 0x00000000FFFF0000UL; x ^= (t ^ (t << 16)); return x; } + + internal static uint Unshuffle2(uint x) + { + // "unshuffle" (twice) even bits to low half and odd bits to high half + uint t; + t = (x ^ (x >> 8)) & 0x0000FF00U; x ^= (t ^ (t << 8)); + t = (x ^ (x >> 4)) & 0x00F000F0U; x ^= (t ^ (t << 4)); + t = (x ^ (x >> 14)) & 0x0000CCCCU; x ^= (t ^ (t << 14)); + t = (x ^ (x >> 7)) & 0x00AA00AAU; x ^= (t ^ (t << 7)); + return x; + } } } diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs
index cf6516c61..7ca60278a 100644 --- a/crypto/src/math/raw/Nat.cs +++ b/crypto/src/math/raw/Nat.cs
@@ -195,6 +195,64 @@ namespace Org.BouncyCastle.Math.Raw return c == 0 ? 0 : IncAt(len, z, zOff, 1); } + public static uint CAdd(int len, int mask, uint[] x, uint[] y, uint[] z) + { + uint MASK = (uint)-(mask & 1); + + ulong c = 0; + for (int i = 0; i < len; ++i) + { + c += (ulong)x[i] + (y[i] & MASK); + z[i] = (uint)c; + c >>= 32; + } + return (uint)c; + } + + public static void CMov(int len, int mask, uint[] x, int xOff, uint[] z, int zOff) + { + uint MASK = (uint)-(mask & 1); + + for (int i = 0; i < len; ++i) + { + uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & MASK); + z[zOff + i] = z_i; + } + + //uint half = 0x55555555U, rest = half << (-(int)MASK); + + //for (int i = 0; i < len; ++i) + //{ + // uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + // z_i ^= (diff & half); + // z_i ^= (diff & rest); + // z[zOff + i] = z_i; + //} + } + + public static void CMov(int len, int mask, int[] x, int xOff, int[] z, int zOff) + { + mask = -(mask & 1); + + for (int i = 0; i < len; ++i) + { + int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + z_i ^= (diff & mask); + z[zOff + i] = z_i; + } + + //int half = 0x55555555, rest = half << (-mask); + + //for (int i = 0; i < len; ++i) + //{ + // int z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; + // z_i ^= (diff & half); + // z_i ^= (diff & rest); + // z[zOff + i] = z_i; + //} + } + public static void Copy(int len, uint[] x, uint[] z) { Array.Copy(x, 0, z, 0, len); @@ -448,6 +506,33 @@ namespace Org.BouncyCastle.Math.Raw } } + public static uint MulAddTo(int len, uint[] x, uint[] y, uint[] zz) + { + ulong zc = 0; + for (int i = 0; i < len; ++i) + { + ulong c = MulWordAddTo(len, x[i], y, 0, zz, i) & M; + c += zc + (zz[i + len] & M); + zz[i + len] = (uint)c; + zc = c >> 32; + } + return (uint)zc; + } + + public static uint MulAddTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) + { + ulong zc = 0; + for (int i = 0; i < len; ++i) + { + ulong c = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; + c += zc + (zz[zzOff + len] & M); + zz[zzOff + len] = (uint)c; + zc = c >> 32; + ++zzOff; + } + return (uint)zc; + } + public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff) { ulong c = 0, aVal = (ulong)a, bVal = (ulong)b;