summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-03-01 23:13:06 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-03-01 23:13:06 +0700
commitae550a5f2d8bf1b8dbaec6e38d9eeef41558a1ff (patch)
tree8c149be7b388a0c681d38e8a87f4aad085b03681 /crypto
parentRefactor GenerateRandomByteArray (diff)
downloadBouncyCastle.NET-ed25519-ae550a5f2d8bf1b8dbaec6e38d9eeef41558a1ff.tar.xz
BIKE: split 'e' more efficiently
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/pqc/crypto/bike/BikeEngine.cs31
-rw-r--r--crypto/src/pqc/crypto/bike/BikeUtilities.cs22
2 files changed, 21 insertions, 32 deletions
diff --git a/crypto/src/pqc/crypto/bike/BikeEngine.cs b/crypto/src/pqc/crypto/bike/BikeEngine.cs
index 8d67541bb..fdb568b01 100644
--- a/crypto/src/pqc/crypto/bike/BikeEngine.cs
+++ b/crypto/src/pqc/crypto/bike/BikeEngine.cs
@@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike
 
         private byte[] FunctionH(byte[] seed)
         {
-            byte[] res = new byte[R2_BYTE];
+            byte[] res = new byte[2 * R_BYTE];
             IXof digest = new ShakeDigest(256);
             digest.BlockUpdate(seed, 0, seed.Length);
             BikeUtilities.GenerateRandomByteArray(res, 2 * r, t, digest);
@@ -186,14 +186,9 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike
             // 2. Calculate e0, e1
             byte[] eBytes = FunctionH(m);
 
-            byte[] eBits = new byte[2 * r];
-            BikeUtilities.FromByteArrayToBitArray(eBits, eBytes);
-
             byte[] e0Bytes = new byte[R_BYTE];
-            BikeUtilities.FromBitArrayToByteArray(e0Bytes, eBits, 0, r);
-
             byte[] e1Bytes = new byte[R_BYTE];
-            BikeUtilities.FromBitArrayToByteArray(e1Bytes, eBits, r, r);
+            SplitEBytes(eBytes, e0Bytes, e1Bytes);
 
             ulong[] e0Element = bikeRing.Create();
             ulong[] e1Element = bikeRing.Create();
@@ -243,13 +238,12 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike
 
             // 1. Compute e'
             byte[] ePrimeBits = BGFDecoder(syndromeBits, h0Compact, h1Compact);
-            byte[] ePrimeBytes = new byte[R2_BYTE];
+            byte[] ePrimeBytes = new byte[2 * R_BYTE];
             BikeUtilities.FromBitArrayToByteArray(ePrimeBytes, ePrimeBits, 0, 2 * r);
 
             byte[] e0Bytes = new byte[R_BYTE];
-            BikeUtilities.FromBitArrayToByteArray(e0Bytes, ePrimeBits, 0, r);
             byte[] e1Bytes = new byte[R_BYTE];
-            BikeUtilities.FromBitArrayToByteArray(e1Bytes, ePrimeBits, r, r);
+            SplitEBytes(ePrimeBytes, e0Bytes, e1Bytes);
 
             // 2. Compute m'
             byte[] mPrime = new byte[L_BYTE];
@@ -673,5 +667,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike
                 }
             }
         }
+
+        private void SplitEBytes(byte[] e, byte[] e0, byte[] e1)
+        {
+            int partial = r & 7;
+            Array.Copy(e, 0, e0, 0, R_BYTE - 1);
+            byte split = e[R_BYTE - 1];
+            byte mask = (byte)(uint.MaxValue << partial);
+            e0[R_BYTE - 1] = (byte)(split & ~mask);
+
+            byte c = (byte)(split & mask);
+            for (int i = 0; i < R_BYTE; ++i)
+            {
+                byte next = e[R_BYTE + i];
+                e1[i] = (byte)((next << (8 - partial)) | (c >> partial));
+                c = next;
+            }
+        }
     }
 }
diff --git a/crypto/src/pqc/crypto/bike/BikeUtilities.cs b/crypto/src/pqc/crypto/bike/BikeUtilities.cs
index 062ac3e26..0aeeaa30b 100644
--- a/crypto/src/pqc/crypto/bike/BikeUtilities.cs
+++ b/crypto/src/pqc/crypto/bike/BikeUtilities.cs
@@ -18,28 +18,6 @@ namespace Org.BouncyCastle.Pqc.Crypto.Bike
             return hammingWeight;
         }
 
-        internal static void FromByteArrayToBitArray(byte[] output, byte[] input)
-        {
-            int max = (output.Length / 8);
-            for (int i = 0; i < max; i++)
-            {
-                for (int j = 0; j != 8; j++)
-                {
-                    output[i * 8 + j] = (byte)((input[i] >> j) & 1);
-                }
-            }
-            if (output.Length % 8 != 0)
-            {
-                int off = max * 8;
-                int count = 0;
-                while (off < output.Length)
-                {
-                    output[off++] = (byte)((input[max] >> count) & 1);
-                    count++;
-                }
-            }
-        }
-
         internal static void FromBitArrayToByteArray(byte[] output, byte[] input, int inputOff, int inputLen)
         {
             int count = 0;