<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.1" />

Packing

class Packing
using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium { internal class Packing { internal static byte[] PackPublicKey(PolyVec t1, DilithiumEngine engine) { byte[] array = new byte[engine.CryptoPublicKeyBytes - 32]; for (int i = 0; i < engine.K; i++) { t1[i].PolyT1Pack(array, i * 320); } return array; } internal static void UnpackPublicKey(PolyVec t1, byte[] pk, DilithiumEngine engine) { for (int i = 0; i < engine.K; i++) { t1[i].PolyT1Unpack(pk, i * 320); } } internal static void PackSecretKey(byte[] t0_, byte[] s1_, byte[] s2_, PolyVec t0, PolyVec s1, PolyVec s2, DilithiumEngine engine) { for (int i = 0; i < engine.L; i++) { s1[i].PolyEtaPack(s1_, i * engine.PolyEtaPackedBytes); } for (int j = 0; j < engine.K; j++) { s2[j].PolyEtaPack(s2_, j * engine.PolyEtaPackedBytes); } for (int k = 0; k < engine.K; k++) { t0[k].PolyT0Pack(t0_, k * 416); } } internal static void UnpackSecretKey(PolyVec t0, PolyVec s1, PolyVec s2, byte[] t0Enc, byte[] s1Enc, byte[] s2Enc, DilithiumEngine engine) { for (int i = 0; i < engine.L; i++) { s1[i].PolyEtaUnpack(s1Enc, i * engine.PolyEtaPackedBytes); } for (int j = 0; j < engine.K; j++) { s2[j].PolyEtaUnpack(s2Enc, j * engine.PolyEtaPackedBytes); } for (int k = 0; k < engine.K; k++) { t0[k].PolyT0Unpack(t0Enc, k * 416); } } internal static void PackSignature(byte[] sig, PolyVec z, PolyVec h, DilithiumEngine engine) { int num = engine.CTilde; for (int i = 0; i < engine.L; i++) { z[i].PackZ(sig, num); num += engine.PolyZPackedBytes; } for (int j = 0; j < engine.Omega + engine.K; j++) { sig[num + j] = 0; } int num2 = 0; for (int k = 0; k < engine.K; k++) { for (int l = 0; l < 256; l++) { if (h[k].Coeffs[l] != 0) sig[num + num2++] = (byte)l; } sig[num + engine.Omega + k] = (byte)num2; } } internal static bool UnpackSignature(PolyVec z, PolyVec h, byte[] sig, DilithiumEngine engine) { int num = engine.CTilde; for (int i = 0; i < engine.L; i++) { int from = num; num += engine.PolyZPackedBytes; z[i].UnpackZ(Arrays.CopyOfRange(sig, from, num)); } int num2 = 0; for (int j = 0; j < engine.K; j++) { for (int k = 0; k < 256; k++) { h[j].Coeffs[k] = 0; } int num3 = sig[num + engine.Omega + j]; if (num3 < num2 || num3 > engine.Omega) return false; for (int l = num2; l < num3; l++) { if (l > num2 && sig[num + l] <= sig[num + l - 1]) return false; h[j].Coeffs[sig[num + l]] = 1; } num2 = num3; } for (int m = num2; m < engine.Omega; m++) { if (sig[num + m] != 0) return false; } return true; } } }