diff options
Diffstat (limited to 'crypto/src/pqc/crypto/hqc/ReedMuller.cs')
-rw-r--r-- | crypto/src/pqc/crypto/hqc/ReedMuller.cs | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/crypto/src/pqc/crypto/hqc/ReedMuller.cs b/crypto/src/pqc/crypto/hqc/ReedMuller.cs new file mode 100644 index 000000000..5f1f8e2bf --- /dev/null +++ b/crypto/src/pqc/crypto/hqc/ReedMuller.cs @@ -0,0 +1,196 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Pqc.Crypto.Hqc +{ + internal class ReedMuller + { + internal class Codeword + { + internal int[] type32; + internal int[] type8; + + public Codeword() + { + this.type32 = new int[4]; + this.type8 = new int[16]; + } + } + + static void EncodeSub(Codeword codeword, int m) + { + + int word1; + word1 = Bit0Mask(m >> 7); + + word1 ^= (int) (Bit0Mask(m >> 0) & 0xaaaaaaaa); + word1 ^= (int) (Bit0Mask(m >> 1) & 0xcccccccc); + word1 ^= (int) (Bit0Mask(m >> 2) & 0xf0f0f0f0); + word1 ^= (int) (Bit0Mask(m >> 3) & 0xff00ff00); + word1 ^= (int) (Bit0Mask(m >> 4) & 0xffff0000); + + codeword.type32[0] = word1; + + word1 ^= Bit0Mask(m >> 5); + codeword.type32[1] = word1; + + word1 ^= Bit0Mask(m >> 6); + codeword.type32[3] = word1; + + word1 ^= Bit0Mask(m >> 5); + codeword.type32[2] = word1; + } + + private static void HadamardTransform(int[] srcCode, int[] desCode) + { + int[] srcCodeCopy = Arrays.Clone(srcCode); + int[] desCodeCopy = Arrays.Clone(desCode); + + for (int i = 0; i < 7; i++) + { + for (int j = 0; j < 64; j++) + { + desCodeCopy[j] = srcCodeCopy[2 * j] + srcCodeCopy[2 * j + 1]; + desCodeCopy[j + 64] = srcCodeCopy[2 * j] - srcCodeCopy[2 * j + 1]; + } + + //swap srcCode and desCode + int[] tmp = srcCodeCopy; srcCodeCopy = desCodeCopy; desCodeCopy = tmp; + } + + // swap + Array.Copy(desCodeCopy, 0, srcCode, 0, srcCode.Length); + Array.Copy(srcCodeCopy, 0, desCode, 0, desCode.Length); + } + + + private static void ExpandThenSum(int[] desCode, Codeword[] srcCode, int off, int mulParam) + { + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 32; j++) + { + long ii = srcCode[0 + off].type32[i] >> j & 1; + desCode[i * 32 + j] = srcCode[0 + off].type32[i] >> j & 1; + } + } + + for (int i = 1; i < mulParam; i++) + { + for (int j = 0; j < 4; j++) + { + for (int k = 0; k < 32; k++) + { + desCode[j * 32 + k] += srcCode[i + off].type32[j] >> k & 1; + + } + } + } + + } + + private static int FindPeaks(int[] input) + { + int peakAbsVal = 0; + int peakVal = 0; + int peakPos = 0; + + for (int i = 0; i < 128; i++) + { + int t = input[i]; + int posMask = t > 0 ? -1 : 0; + int abs = (posMask & t) | (~posMask & -t); + + peakVal = abs > peakAbsVal ? t : peakVal; + peakPos = abs > peakAbsVal ? i : peakPos; + peakAbsVal = abs > peakAbsVal ? abs : peakAbsVal; + } + int tmp = peakVal > 0 ? 1 : 0; + peakPos |= 128 * tmp; + return peakPos; + } + + + private static int Bit0Mask(int b) + { + return (int) ((-(b & 1)) & 0xffffffff); + } + + public static void Encode(ulong[] codeword, byte[] m, int n1, int mulParam) + { + byte[] mBytes = Arrays.Clone(m); + + Codeword[] codewordCopy = new Codeword[n1 * mulParam]; + for (int i = 0; i < codewordCopy.Length; i++) + { + codewordCopy[i] = new Codeword(); + } + + for (int i = 0; i < n1; i++) + { + int pos = i * mulParam; + EncodeSub(codewordCopy[pos], mBytes[i]); + + for (int j = 1; j < mulParam; j++) + { + codewordCopy[pos + j] = codewordCopy[pos]; + } + } + + + int[] cwd64 = new int[codewordCopy.Length * 4]; + int off = 0; + for (int i = 0; i < codewordCopy.Length; i++) + { + Array.Copy(codewordCopy[i].type32, 0, cwd64, off, codewordCopy[i].type32.Length); + off += 4; + } + + Utils.FromByte32ArrayToULongArray(codeword, cwd64); + } + + public static void Decode(byte[] m, ulong[] codeword, int n1, int mulParam) + { + byte[] mBytes = Arrays.Clone(m); + + Codeword[] codewordCopy = new Codeword[codeword.Length / 2]; // because each codewordCopy has a 32 bit array size 4 + int[] byteCodeWords = new int[codeword.Length * 2]; + Utils.FromULongArrayToByte32Array(byteCodeWords, codeword); + + for (int i = 0; i < codewordCopy.Length; i++) + { + codewordCopy[i] = new Codeword(); + for (int j = 0; j < 4; j++) + { + codewordCopy[i].type32[j] = byteCodeWords[i * 4 + j]; + } + } + + int[] expandedCodeword = new int[128]; + + + for (int i = 0; i < n1; i++) + { + ExpandThenSum(expandedCodeword, codewordCopy, i * mulParam, mulParam); + + + int[] tmp = new int[128]; + HadamardTransform(expandedCodeword, tmp); + + tmp[0] -= 64 * mulParam; + mBytes[i] = (byte)FindPeaks(tmp); + } + + int[] cwd64 = new int[codewordCopy.Length * 4]; + int off = 0; + for (int i = 0; i < codewordCopy.Length; i++) + { + Array.Copy(codewordCopy[i].type32, 0, cwd64, off, codewordCopy[i].type32.Length); + off += 4; + } + Utils.FromByte32ArrayToULongArray(codeword, cwd64); + Array.Copy(mBytes, 0, m, 0, m.Length); + } + } +} |