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

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.Vec[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.Vec[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.Vec[i].PolyEtaPack(s1_, i * engine.PolyEtaPackedBytes); } for (int i = 0; i < engine.K; i++) { s2.Vec[i].PolyEtaPack(s2_, i * engine.PolyEtaPackedBytes); } for (int i = 0; i < engine.K; i++) { t0.Vec[i].PolyT0Pack(t0_, i * 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.Vec[i].PolyEtaUnpack(s1Enc, i * engine.PolyEtaPackedBytes); } for (int i = 0; i < engine.K; i++) { s2.Vec[i].PolyEtaUnpack(s2Enc, i * engine.PolyEtaPackedBytes); } for (int i = 0; i < engine.K; i++) { t0.Vec[i].PolyT0Unpack(t0Enc, i * 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.Vec[i].PackZ(sig, num); num += engine.PolyZPackedBytes; } for (int i = 0; i < engine.Omega + engine.K; i++) { sig[num + i] = 0; } int num2 = 0; for (int i = 0; i < engine.K; i++) { for (int j = 0; j < 256; j++) { if (h.Vec[i].Coeffs[j] != 0) sig[num + num2++] = (byte)j; } sig[num + engine.Omega + i] = (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.Vec[i].UnpackZ(Arrays.CopyOfRange(sig, from, num)); } int num2 = 0; for (int i = 0; i < engine.K; i++) { for (int j = 0; j < 256; j++) { h.Vec[i].Coeffs[j] = 0; } int num3 = sig[num + engine.Omega + i]; if (num3 < num2 || num3 > engine.Omega) return false; for (int j = num2; j < num3; j++) { if (j > num2 && sig[num + j] <= sig[num + j - 1]) return false; h.Vec[i].Coeffs[sig[num + j]] = 1; } num2 = num3; } for (int j = num2; j < engine.Omega; j++) { if (sig[num + j] != 0) return false; } return true; } } }