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;
}
}
}