<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

SaberUtilities

namespace Org.BouncyCastle.Pqc.Crypto.Saber { internal class SaberUtilities { private readonly int SABER_N; private readonly int SABER_L; private readonly int SABER_ET; private readonly int SABER_POLYBYTES; private readonly int SABER_EP; private readonly int SABER_KEYBYTES; private readonly bool usingEffectiveMasking; internal SaberUtilities(SaberEngine engine) { SABER_N = engine.N; SABER_L = engine.L; SABER_ET = engine.ET; SABER_POLYBYTES = engine.PolyBytes; SABER_EP = engine.EP; SABER_KEYBYTES = engine.KeyBytes; usingEffectiveMasking = engine.UsingEffectiveMasking; } public void POLT2BS(byte[] bytes, int byteIndex, short[] data) { if (SABER_ET == 3) { for (short num = 0; num < SABER_N / 8; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(8 * num); bytes[byteIndex + num2] = (byte)((data[num3] & 7) | ((data[num3 + 1] & 7) << 3) | ((data[num3 + 2] & 3) << 6)); bytes[byteIndex + num2 + 1] = (byte)(((data[num3 + 2] >> 2) & 1) | ((data[num3 + 3] & 7) << 1) | ((data[num3 + 4] & 7) << 4) | ((data[num3 + 5] & 1) << 7)); bytes[byteIndex + num2 + 2] = (byte)(((data[num3 + 5] >> 1) & 3) | ((data[num3 + 6] & 7) << 2) | ((data[num3 + 7] & 7) << 5)); } } else if (SABER_ET == 4) { for (short num = 0; num < SABER_N / 2; num = (short)(num + 1)) { short num2 = num; short num3 = (short)(2 * num); bytes[byteIndex + num2] = (byte)((data[num3] & 15) | ((data[num3 + 1] & 15) << 4)); } } else if (SABER_ET == 6) { for (short num = 0; num < SABER_N / 4; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(4 * num); bytes[byteIndex + num2] = (byte)((data[num3] & 63) | ((data[num3 + 1] & 3) << 6)); bytes[byteIndex + num2 + 1] = (byte)(((data[num3 + 1] >> 2) & 15) | ((data[num3 + 2] & 15) << 4)); bytes[byteIndex + num2 + 2] = (byte)(((data[num3 + 2] >> 4) & 3) | ((data[num3 + 3] & 63) << 2)); } } } public void BS2POLT(byte[] bytes, int byteIndex, short[] data) { if (SABER_ET == 3) { for (short num = 0; num < SABER_N / 8; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(8 * num); data[num3] = (short)(bytes[byteIndex + num2] & 7); data[num3 + 1] = (short)((bytes[byteIndex + num2] >> 3) & 7); data[num3 + 2] = (short)(((bytes[byteIndex + num2] >> 6) & 3) | ((bytes[byteIndex + num2 + 1] & 1) << 2)); data[num3 + 3] = (short)((bytes[byteIndex + num2 + 1] >> 1) & 7); data[num3 + 4] = (short)((bytes[byteIndex + num2 + 1] >> 4) & 7); data[num3 + 5] = (short)(((bytes[byteIndex + num2 + 1] >> 7) & 1) | ((bytes[byteIndex + num2 + 2] & 3) << 1)); data[num3 + 6] = (short)((bytes[byteIndex + num2 + 2] >> 2) & 7); data[num3 + 7] = (short)((bytes[byteIndex + num2 + 2] >> 5) & 7); } } else if (SABER_ET == 4) { for (short num = 0; num < SABER_N / 2; num = (short)(num + 1)) { short num2 = num; short num3 = (short)(2 * num); data[num3] = (short)(bytes[byteIndex + num2] & 15); data[num3 + 1] = (short)((bytes[byteIndex + num2] >> 4) & 15); } } else if (SABER_ET == 6) { for (short num = 0; num < SABER_N / 4; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(4 * num); data[num3] = (short)(bytes[byteIndex + num2] & 63); data[num3 + 1] = (short)(((bytes[byteIndex + num2] >> 6) & 3) | ((bytes[byteIndex + num2 + 1] & 15) << 2)); data[num3 + 2] = (short)(((bytes[byteIndex + num2 + 1] & 255) >> 4) | ((bytes[byteIndex + num2 + 2] & 3) << 4)); data[num3 + 3] = (short)((bytes[byteIndex + num2 + 2] & 255) >> 2); } } } private void POLq2BS(byte[] bytes, int byteIndex, short[] data) { if (!usingEffectiveMasking) { for (short num = 0; num < SABER_N / 8; num = (short)(num + 1)) { short num2 = (short)(13 * num); short num3 = (short)(8 * num); bytes[byteIndex + num2] = (byte)(data[num3] & 255); bytes[byteIndex + num2 + 1] = (byte)(((data[num3] >> 8) & 31) | ((data[num3 + 1] & 7) << 5)); bytes[byteIndex + num2 + 2] = (byte)((data[num3 + 1] >> 3) & 255); bytes[byteIndex + num2 + 3] = (byte)(((data[num3 + 1] >> 11) & 3) | ((data[num3 + 2] & 63) << 2)); bytes[byteIndex + num2 + 4] = (byte)(((data[num3 + 2] >> 6) & 127) | ((data[num3 + 3] & 1) << 7)); bytes[byteIndex + num2 + 5] = (byte)((data[num3 + 3] >> 1) & 255); bytes[byteIndex + num2 + 6] = (byte)(((data[num3 + 3] >> 9) & 15) | ((data[num3 + 4] & 15) << 4)); bytes[byteIndex + num2 + 7] = (byte)((data[num3 + 4] >> 4) & 255); bytes[byteIndex + num2 + 8] = (byte)(((data[num3 + 4] >> 12) & 1) | ((data[num3 + 5] & 127) << 1)); bytes[byteIndex + num2 + 9] = (byte)(((data[num3 + 5] >> 7) & 63) | ((data[num3 + 6] & 3) << 6)); bytes[byteIndex + num2 + 10] = (byte)((data[num3 + 6] >> 2) & 255); bytes[byteIndex + num2 + 11] = (byte)(((data[num3 + 6] >> 10) & 7) | ((data[num3 + 7] & 31) << 3)); bytes[byteIndex + num2 + 12] = (byte)((data[num3 + 7] >> 5) & 255); } } else { for (short num = 0; num < SABER_N / 2; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(2 * num); bytes[byteIndex + num2] = (byte)(data[num3] & 255); bytes[byteIndex + num2 + 1] = (byte)(((data[num3] >> 8) & 15) | ((data[num3 + 1] & 15) << 4)); bytes[byteIndex + num2 + 2] = (byte)((data[num3 + 1] >> 4) & 255); } } } private void BS2POLq(byte[] bytes, int byteIndex, short[] data) { if (!usingEffectiveMasking) { for (short num = 0; num < SABER_N / 8; num = (short)(num + 1)) { short num2 = (short)(13 * num); short num3 = (short)(8 * num); data[num3] = (short)((bytes[byteIndex + num2] & 255) | ((bytes[byteIndex + num2 + 1] & 31) << 8)); data[num3 + 1] = (short)(((bytes[byteIndex + num2 + 1] >> 5) & 7) | ((bytes[byteIndex + num2 + 2] & 255) << 3) | ((bytes[byteIndex + num2 + 3] & 3) << 11)); data[num3 + 2] = (short)(((bytes[byteIndex + num2 + 3] >> 2) & 63) | ((bytes[byteIndex + num2 + 4] & 127) << 6)); data[num3 + 3] = (short)(((bytes[byteIndex + num2 + 4] >> 7) & 1) | ((bytes[byteIndex + num2 + 5] & 255) << 1) | ((bytes[byteIndex + num2 + 6] & 15) << 9)); data[num3 + 4] = (short)(((bytes[byteIndex + num2 + 6] >> 4) & 15) | ((bytes[byteIndex + num2 + 7] & 255) << 4) | ((bytes[byteIndex + num2 + 8] & 1) << 12)); data[num3 + 5] = (short)(((bytes[byteIndex + num2 + 8] >> 1) & 127) | ((bytes[byteIndex + num2 + 9] & 63) << 7)); data[num3 + 6] = (short)(((bytes[byteIndex + num2 + 9] >> 6) & 3) | ((bytes[byteIndex + num2 + 10] & 255) << 2) | ((bytes[byteIndex + num2 + 11] & 7) << 10)); data[num3 + 7] = (short)(((bytes[byteIndex + num2 + 11] >> 3) & 31) | ((bytes[byteIndex + num2 + 12] & 255) << 5)); } } else { for (short num = 0; num < SABER_N / 2; num = (short)(num + 1)) { short num2 = (short)(3 * num); short num3 = (short)(2 * num); data[num3] = (short)((bytes[byteIndex + num2] & 255) | ((bytes[byteIndex + num2 + 1] & 15) << 8)); data[num3 + 1] = (short)(((bytes[byteIndex + num2 + 1] >> 4) & 15) | ((bytes[byteIndex + num2 + 2] & 255) << 4)); } } } private void POLp2BS(byte[] bytes, int byteIndex, short[] data) { for (short num = 0; num < SABER_N / 4; num = (short)(num + 1)) { short num2 = (short)(5 * num); short num3 = (short)(4 * num); bytes[byteIndex + num2] = (byte)(data[num3] & 255); bytes[byteIndex + num2 + 1] = (byte)(((data[num3] >> 8) & 3) | ((data[num3 + 1] & 63) << 2)); bytes[byteIndex + num2 + 2] = (byte)(((data[num3 + 1] >> 6) & 15) | ((data[num3 + 2] & 15) << 4)); bytes[byteIndex + num2 + 3] = (byte)(((data[num3 + 2] >> 4) & 63) | ((data[num3 + 3] & 3) << 6)); bytes[byteIndex + num2 + 4] = (byte)((data[num3 + 3] >> 2) & 255); } } public void BS2POLp(byte[] bytes, int byteIndex, short[] data) { for (short num = 0; num < SABER_N / 4; num = (short)(num + 1)) { short num2 = (short)(5 * num); short num3 = (short)(4 * num); data[num3] = (short)((bytes[byteIndex + num2] & 255) | ((bytes[byteIndex + num2 + 1] & 3) << 8)); data[num3 + 1] = (short)(((bytes[byteIndex + num2 + 1] >> 2) & 63) | ((bytes[byteIndex + num2 + 2] & 15) << 6)); data[num3 + 2] = (short)(((bytes[byteIndex + num2 + 2] >> 4) & 15) | ((bytes[byteIndex + num2 + 3] & 63) << 4)); data[num3 + 3] = (short)(((bytes[byteIndex + num2 + 3] >> 6) & 3) | ((bytes[byteIndex + num2 + 4] & 255) << 2)); } } public void POLVECq2BS(byte[] bytes, short[][] data) { for (byte b = 0; b < SABER_L; b = (byte)(b + 1)) { POLq2BS(bytes, b * SABER_POLYBYTES, data[b]); } } public void BS2POLVECq(byte[] bytes, int byteIndex, short[][] data) { for (byte b = 0; b < SABER_L; b = (byte)(b + 1)) { BS2POLq(bytes, byteIndex + b * SABER_POLYBYTES, data[b]); } } public void POLVECp2BS(byte[] bytes, short[][] data) { for (byte b = 0; b < SABER_L; b = (byte)(b + 1)) { POLp2BS(bytes, b * (SABER_EP * SABER_N / 8), data[b]); } } public void BS2POLVECp(byte[] bytes, short[][] data) { for (byte b = 0; b < SABER_L; b = (byte)(b + 1)) { BS2POLp(bytes, b * (SABER_EP * SABER_N / 8), data[b]); } } public void BS2POLmsg(byte[] bytes, short[] data) { for (byte b = 0; b < SABER_KEYBYTES; b = (byte)(b + 1)) { for (byte b2 = 0; b2 < 8; b2 = (byte)(b2 + 1)) { data[b * 8 + b2] = (short)((bytes[b] >> (int)b2) & 1); } } } public void POLmsg2BS(byte[] bytes, short[] data) { for (byte b = 0; b < SABER_KEYBYTES; b = (byte)(b + 1)) { for (byte b2 = 0; b2 < 8; b2 = (byte)(b2 + 1)) { bytes[b] = (byte)(bytes[b] | ((data[b * 8 + b2] & 1) << (int)b2)); } } } } }