SamplerZ
class SamplerZ
namespace Org.BouncyCastle.Pqc.Crypto.Falcon
{
internal class SamplerZ
{
private FalconRNG p;
private FalconFPR sigma_min;
private FprEngine fpre;
internal SamplerZ(FalconRNG p, FalconFPR sigma_min, FprEngine fpre)
{
this.p = p;
this.sigma_min = sigma_min;
this.fpre = fpre;
}
internal int Sample(FalconFPR mu, FalconFPR isigma)
{
return sampler(mu, isigma);
}
private int gaussian0_sampler(FalconRNG p)
{
uint[] array = new uint[54] {
10745844,
3068844,
3741698,
5559083,
1580863,
8248194,
2260429,
13669192,
2736639,
708981,
4421575,
10046180,
169348,
7122675,
4136815,
30538,
13063405,
7650655,
4132,
14505003,
7826148,
417,
16768101,
11363290,
31,
8444042,
8086568,
1,
12844466,
265321,
0,
1232676,
13644283,
0,
38047,
9111839,
0,
870,
6138264,
0,
14,
12545723,
0,
0,
3104126,
0,
0,
28824,
0,
0,
198,
0,
0,
1
};
ulong num = p.prng_get_u64();
uint num2 = p.prng_get_u8();
uint num3 = (uint)((int)num & 16777215);
uint num4 = (uint)((int)(num >> 24) & 16777215);
uint num5 = (uint)((int)(num >> 48) | (int)(num2 << 16));
int num6 = 0;
for (int i = 0; i < array.Length; i += 3) {
uint num7 = array[i + 2];
uint num8 = array[i + 1];
uint num9 = array[i];
uint num10 = num3 - num7 >> 31;
num10 = num4 - num8 - num10 >> 31;
num10 = num5 - num9 - num10 >> 31;
num6 += (int)num10;
}
return num6;
}
private int BerExp(FalconRNG p, FalconFPR x, FalconFPR ccs)
{
int num = (int)fpre.fpr_trunc(fpre.fpr_mul(x, fpre.fpr_inv_log2));
FalconFPR x2 = fpre.fpr_sub(x, fpre.fpr_mul(fpre.fpr_of(num), fpre.fpr_log2));
uint num2 = (uint)num;
num2 = (uint)((int)num2 ^ (int)((num2 ^ 63) & (0 - (63 - num2 >> 31))));
num = (int)num2;
ulong num3 = (fpre.fpr_expm_p63(x2, ccs) << 1) - 1 >> num;
int num4 = 64;
uint num5;
do {
num4 -= 8;
num5 = (uint)((int)p.prng_get_u8() - ((int)(num3 >> num4) & 255));
} while (num5 == 0 && num4 > 0);
return (int)(num5 >> 31);
}
private int sampler(FalconFPR mu, FalconFPR isigma)
{
int num = (int)fpre.fpr_floor(mu);
FalconFPR y = fpre.fpr_sub(mu, fpre.fpr_of(num));
FalconFPR y2 = fpre.fpr_half(fpre.fpr_sqr(isigma));
FalconFPR ccs = fpre.fpr_mul(isigma, sigma_min);
int num4;
FalconFPR x;
do {
int num2 = gaussian0_sampler(p);
uint num3 = p.prng_get_u8() & 1;
num4 = (int)num3 + (int)((num3 << 1) - 1) * num2;
x = fpre.fpr_mul(fpre.fpr_sqr(fpre.fpr_sub(fpre.fpr_of(num4), y)), y2);
x = fpre.fpr_sub(x, fpre.fpr_mul(fpre.fpr_of(num2 * num2), fpre.fpr_inv_2sqrsigma0));
} while (BerExp(p, x, ccs) == 0);
return num + num4;
}
}
}