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