kpqc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +174 -0
- data/Rakefile +57 -0
- data/THIRD_PARTY_NOTICES.md +53 -0
- data/ext/kpqc/aimer128f/extconf.rb +4 -0
- data/ext/kpqc/aimer128s/extconf.rb +4 -0
- data/ext/kpqc/aimer192f/extconf.rb +4 -0
- data/ext/kpqc/aimer192s/extconf.rb +4 -0
- data/ext/kpqc/aimer256f/extconf.rb +4 -0
- data/ext/kpqc/aimer256s/extconf.rb +4 -0
- data/ext/kpqc/extconf_helper.rb +93 -0
- data/ext/kpqc/haetae2/extconf.rb +4 -0
- data/ext/kpqc/haetae3/extconf.rb +4 -0
- data/ext/kpqc/haetae5/extconf.rb +4 -0
- data/ext/kpqc/module.c +195 -0
- data/ext/kpqc/ntruplus1152/extconf.rb +4 -0
- data/ext/kpqc/ntruplus768/extconf.rb +4 -0
- data/ext/kpqc/ntruplus864/extconf.rb +4 -0
- data/ext/kpqc/randombytes.c +107 -0
- data/ext/kpqc/smaugt128/extconf.rb +4 -0
- data/ext/kpqc/smaugt192/extconf.rb +4 -0
- data/ext/kpqc/smaugt256/extconf.rb +4 -0
- data/ext/kpqc/timer/extconf.rb +4 -0
- data/kpqc.gemspec +41 -0
- data/lib/kpqc/aimer.rb +38 -0
- data/lib/kpqc/api.rb +129 -0
- data/lib/kpqc/haetae.rb +25 -0
- data/lib/kpqc/ntruplus.rb +25 -0
- data/lib/kpqc/smaugt.rb +29 -0
- data/lib/kpqc/types.rb +103 -0
- data/lib/kpqc/version.rb +6 -0
- data/lib/kpqc.rb +33 -0
- data/test/algorithm_test.rb +111 -0
- data/test/api_test.rb +52 -0
- data/test/interop.mjs +34 -0
- data/test/interop_test.rb +82 -0
- data/test/kat/aimer128f.rsp +10 -0
- data/test/kat/aimer128s.rsp +10 -0
- data/test/kat/aimer192f.rsp +10 -0
- data/test/kat/aimer192s.rsp +10 -0
- data/test/kat/aimer256f.rsp +10 -0
- data/test/kat/aimer256s.rsp +10 -0
- data/test/kat/haetae2.rsp +10 -0
- data/test/kat/haetae3.rsp +10 -0
- data/test/kat/haetae5.rsp +10 -0
- data/test/kat/ntruplus1152.rsp +8 -0
- data/test/kat/ntruplus768.rsp +8 -0
- data/test/kat/ntruplus864.rsp +8 -0
- data/test/kat/smaugt128.rsp +8 -0
- data/test/kat/smaugt192.rsp +8 -0
- data/test/kat/smaugt256.rsp +8 -0
- data/test/kat/timer.rsp +8 -0
- data/test/kat_drbg.rb +155 -0
- data/test/kat_test.rb +99 -0
- data/test/test_helper.rb +21 -0
- data/vendor/AIMer/LICENSE +21 -0
- data/vendor/AIMer/aim2.c +163 -0
- data/vendor/AIMer/aim2.h +36 -0
- data/vendor/AIMer/aim2_constant.h +74 -0
- data/vendor/AIMer/api.h +42 -0
- data/vendor/AIMer/common/crypto_declassify.h +7 -0
- data/vendor/AIMer/common/fips202.c +878 -0
- data/vendor/AIMer/common/fips202.h +166 -0
- data/vendor/AIMer/common/rng.h +56 -0
- data/vendor/AIMer/field.h +43 -0
- data/vendor/AIMer/field128.c +454 -0
- data/vendor/AIMer/field192.c +485 -0
- data/vendor/AIMer/field256.c +564 -0
- data/vendor/AIMer/hash.c +50 -0
- data/vendor/AIMer/hash.h +37 -0
- data/vendor/AIMer/params/params-aimer-128f.h +34 -0
- data/vendor/AIMer/params/params-aimer-128s.h +34 -0
- data/vendor/AIMer/params/params-aimer-192f.h +34 -0
- data/vendor/AIMer/params/params-aimer-192s.h +34 -0
- data/vendor/AIMer/params/params-aimer-256f.h +34 -0
- data/vendor/AIMer/params/params-aimer-256s.h +34 -0
- data/vendor/AIMer/params.h +5 -0
- data/vendor/AIMer/sign.c +631 -0
- data/vendor/AIMer/sign.h +40 -0
- data/vendor/AIMer/tree.c +75 -0
- data/vendor/AIMer/tree.h +26 -0
- data/vendor/HAETAE/LICENSE +22 -0
- data/vendor/HAETAE/include/api.h +54 -0
- data/vendor/HAETAE/include/common.h +12 -0
- data/vendor/HAETAE/include/config.h +42 -0
- data/vendor/HAETAE/include/decompose.h +19 -0
- data/vendor/HAETAE/include/encoding.h +20 -0
- data/vendor/HAETAE/include/fft.h +26 -0
- data/vendor/HAETAE/include/fips202.h +40 -0
- data/vendor/HAETAE/include/fixpoint.h +125 -0
- data/vendor/HAETAE/include/ntt.h +16 -0
- data/vendor/HAETAE/include/packing.h +58 -0
- data/vendor/HAETAE/include/params.h +117 -0
- data/vendor/HAETAE/include/poly.h +65 -0
- data/vendor/HAETAE/include/polyfix.h +65 -0
- data/vendor/HAETAE/include/polymat.h +32 -0
- data/vendor/HAETAE/include/polyvec.h +131 -0
- data/vendor/HAETAE/include/randombytes.h +39 -0
- data/vendor/HAETAE/include/rans_byte.h +335 -0
- data/vendor/HAETAE/include/reduce.h +31 -0
- data/vendor/HAETAE/include/sampler.h +23 -0
- data/vendor/HAETAE/include/symmetric.h +52 -0
- data/vendor/HAETAE/src/decompose.c +73 -0
- data/vendor/HAETAE/src/encoding.c +700 -0
- data/vendor/HAETAE/src/fft.c +235 -0
- data/vendor/HAETAE/src/fips202.c +745 -0
- data/vendor/HAETAE/src/fixpoint.c +143 -0
- data/vendor/HAETAE/src/ntt.c +98 -0
- data/vendor/HAETAE/src/packing.c +595 -0
- data/vendor/HAETAE/src/poly.c +371 -0
- data/vendor/HAETAE/src/polyfix.c +298 -0
- data/vendor/HAETAE/src/polymat.c +82 -0
- data/vendor/HAETAE/src/polyvec.c +534 -0
- data/vendor/HAETAE/src/reduce.c +96 -0
- data/vendor/HAETAE/src/sampler.c +310 -0
- data/vendor/HAETAE/src/sign.c +558 -0
- data/vendor/HAETAE/src/symmetric-shake.c +50 -0
- data/vendor/NTRUplus/LICENSE +21 -0
- data/vendor/NTRUplus/NTRU+1152/api.h +24 -0
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+1152/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+1152/ntt.c +394 -0
- data/vendor/NTRUplus/NTRU+1152/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+1152/params.h +18 -0
- data/vendor/NTRUplus/NTRU+1152/poly.c +318 -0
- data/vendor/NTRUplus/NTRU+1152/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+1152/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+1152/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+1152/symmetric.h +12 -0
- data/vendor/NTRUplus/NTRU+768/api.h +24 -0
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+768/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+768/ntt.c +379 -0
- data/vendor/NTRUplus/NTRU+768/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+768/params.h +18 -0
- data/vendor/NTRUplus/NTRU+768/poly.c +320 -0
- data/vendor/NTRUplus/NTRU+768/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+768/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+768/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+768/symmetric.h +12 -0
- data/vendor/NTRUplus/NTRU+864/api.h +24 -0
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+864/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+864/ntt.c +383 -0
- data/vendor/NTRUplus/NTRU+864/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+864/params.h +18 -0
- data/vendor/NTRUplus/NTRU+864/poly.c +314 -0
- data/vendor/NTRUplus/NTRU+864/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+864/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+864/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+864/symmetric.h +12 -0
- data/vendor/SMAUG-T/LICENSE +22 -0
- data/vendor/SMAUG-T/include/api.h +37 -0
- data/vendor/SMAUG-T/include/cbd.h +15 -0
- data/vendor/SMAUG-T/include/ciphertext.h +45 -0
- data/vendor/SMAUG-T/include/common.h +12 -0
- data/vendor/SMAUG-T/include/config.h +48 -0
- data/vendor/SMAUG-T/include/dg.h +28 -0
- data/vendor/SMAUG-T/include/fips202.h +41 -0
- data/vendor/SMAUG-T/include/hash.h +21 -0
- data/vendor/SMAUG-T/include/hwt.h +28 -0
- data/vendor/SMAUG-T/include/indcpa.h +33 -0
- data/vendor/SMAUG-T/include/key.h +34 -0
- data/vendor/SMAUG-T/include/pack.h +78 -0
- data/vendor/SMAUG-T/include/packring.h +50 -0
- data/vendor/SMAUG-T/include/params.h +84 -0
- data/vendor/SMAUG-T/include/poly.h +41 -0
- data/vendor/SMAUG-T/include/randombytes.h +11 -0
- data/vendor/SMAUG-T/include/toomcook.h +14 -0
- data/vendor/SMAUG-T/include/verify.h +16 -0
- data/vendor/SMAUG-T/src/cbd.c +159 -0
- data/vendor/SMAUG-T/src/ciphertext.c +95 -0
- data/vendor/SMAUG-T/src/dg.c +112 -0
- data/vendor/SMAUG-T/src/fips202.c +745 -0
- data/vendor/SMAUG-T/src/hash.c +15 -0
- data/vendor/SMAUG-T/src/hwt.c +121 -0
- data/vendor/SMAUG-T/src/indcpa.c +187 -0
- data/vendor/SMAUG-T/src/kem.c +194 -0
- data/vendor/SMAUG-T/src/key.c +102 -0
- data/vendor/SMAUG-T/src/pack.c +349 -0
- data/vendor/SMAUG-T/src/packring.c +503 -0
- data/vendor/SMAUG-T/src/poly.c +200 -0
- data/vendor/SMAUG-T/src/toomcook.c +256 -0
- data/vendor/SMAUG-T/src/verify.c +48 -0
- data/vendor/SOURCES.json +130 -0
- metadata +280 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "sampler.h"
|
|
4
|
+
#include "fixpoint.h"
|
|
5
|
+
#include "symmetric.h"
|
|
6
|
+
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
/*************************************************
|
|
10
|
+
* Name: rej_uniform
|
|
11
|
+
*
|
|
12
|
+
* Description: Sample uniformly random coefficients in [0, HAETAE_Q-1] by
|
|
13
|
+
* performing rejection sampling on array of random bytes.
|
|
14
|
+
*
|
|
15
|
+
* Arguments: - int32_t *a: pointer to output array (allocated)
|
|
16
|
+
* - unsigned int len: number of coefficients to be sampled
|
|
17
|
+
* - const uint8_t *buf: array of random bytes
|
|
18
|
+
* - unsigned int buflen: length of array of random bytes
|
|
19
|
+
*
|
|
20
|
+
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
|
21
|
+
* random bytes were given.
|
|
22
|
+
*
|
|
23
|
+
* Specification: Implements Algorithm 7, RejUniform.
|
|
24
|
+
**************************************************/
|
|
25
|
+
unsigned int rej_uniform(int32_t *a, unsigned int len, const uint8_t *buf,
|
|
26
|
+
unsigned int buflen) {
|
|
27
|
+
unsigned int ctr, pos;
|
|
28
|
+
uint32_t t;
|
|
29
|
+
|
|
30
|
+
ctr = pos = 0;
|
|
31
|
+
while (ctr < len && pos + 2 <= buflen) {
|
|
32
|
+
t = buf[pos++];
|
|
33
|
+
t |= (uint32_t)buf[pos++] << 8;
|
|
34
|
+
|
|
35
|
+
if (t < HAETAE_Q)
|
|
36
|
+
a[ctr++] = t;
|
|
37
|
+
}
|
|
38
|
+
return ctr;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*************************************************
|
|
42
|
+
* Name: rej_eta
|
|
43
|
+
*
|
|
44
|
+
* Description: Sample uniformly random coefficients in [-HAETAE_ETA,
|
|
45
|
+
* HAETAE_ETA] by performing rejection sampling on array
|
|
46
|
+
* of random bytes.
|
|
47
|
+
*
|
|
48
|
+
* Arguments: - int32_t *a: pointer to output array (allocated)
|
|
49
|
+
* - unsigned int len: number of coefficients to be sampled
|
|
50
|
+
* - const uint8_t *buf: array of random bytes
|
|
51
|
+
* - unsigned int buflen: length of array of random bytes
|
|
52
|
+
*
|
|
53
|
+
* Returns number of sampled coefficients. Can be smaller than len if not enough
|
|
54
|
+
* random bytes were given.
|
|
55
|
+
*
|
|
56
|
+
* Specification: Implements Algorithm 10, RejEta.
|
|
57
|
+
**************************************************/
|
|
58
|
+
static int32_t mod3(uint8_t t) {
|
|
59
|
+
int32_t r;
|
|
60
|
+
r = (t >> 4) + (t & 0xf);
|
|
61
|
+
r = (r >> 2) + (r & 3);
|
|
62
|
+
r = (r >> 2) + (r & 3);
|
|
63
|
+
r = (r >> 2) + (r & 3);
|
|
64
|
+
return r - (3 * (r >> 1));
|
|
65
|
+
}
|
|
66
|
+
static int32_t mod3_leq26(uint8_t t) {
|
|
67
|
+
int32_t r;
|
|
68
|
+
r = (t >> 4) + (t & 0xf);
|
|
69
|
+
r = (r >> 2) + (r & 3);
|
|
70
|
+
r = (r >> 2) + (r & 3);
|
|
71
|
+
return r - (3 * (r >> 1));
|
|
72
|
+
}
|
|
73
|
+
static int32_t mod3_leq8(uint8_t t) {
|
|
74
|
+
int32_t r;
|
|
75
|
+
r = (t >> 2) + (t & 3);
|
|
76
|
+
r = (r >> 2) + (r & 3);
|
|
77
|
+
return r - (3 * (r >> 1));
|
|
78
|
+
}
|
|
79
|
+
unsigned int rej_eta(int32_t *a, unsigned int len, const uint8_t *buf,
|
|
80
|
+
unsigned int buflen) {
|
|
81
|
+
unsigned int ctr, pos;
|
|
82
|
+
|
|
83
|
+
ctr = pos = 0;
|
|
84
|
+
while (ctr < len && pos < buflen) {
|
|
85
|
+
uint32_t t = buf[pos++];
|
|
86
|
+
if (t < 243) {
|
|
87
|
+
// reduce mod 3
|
|
88
|
+
a[ctr++] = mod3(t);
|
|
89
|
+
|
|
90
|
+
if (ctr >= len)
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
t *= 171; // 171*3 = 1 mod 256
|
|
94
|
+
t >>= 9;
|
|
95
|
+
a[ctr++] = mod3(t);
|
|
96
|
+
|
|
97
|
+
if (ctr >= len)
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
t *= 171;
|
|
101
|
+
t >>= 9;
|
|
102
|
+
a[ctr++] = mod3_leq26(t);
|
|
103
|
+
|
|
104
|
+
if (ctr >= len)
|
|
105
|
+
break;
|
|
106
|
+
|
|
107
|
+
t *= 171;
|
|
108
|
+
t >>= 9;
|
|
109
|
+
a[ctr++] = mod3_leq8(t);
|
|
110
|
+
|
|
111
|
+
if (ctr >= len)
|
|
112
|
+
break;
|
|
113
|
+
|
|
114
|
+
t *= 171;
|
|
115
|
+
t >>= 9;
|
|
116
|
+
a[ctr++] = (int32_t)t - (int32_t)3 * (t >> 1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return ctr;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static uint64_t approx_exp(const uint64_t x) {
|
|
123
|
+
int64_t result;
|
|
124
|
+
result = -0x0000B6C6340925AELL;
|
|
125
|
+
result = ((smulh48(result, x) + (1LL << 2)) >> 3) + 0x0000B4BD4DF85227LL;
|
|
126
|
+
result = ((smulh48(result, x) + (1LL << 2)) >> 3) - 0x0000887F727491E2LL;
|
|
127
|
+
result = ((smulh48(result, x) + (1LL << 1)) >> 2) + 0x0000AAAA643C7E8DLL;
|
|
128
|
+
result = ((smulh48(result, x) + (1LL << 1)) >> 2) - 0x0000AAAAA98179E6LL;
|
|
129
|
+
result = ((smulh48(result, x) + 1LL) >> 1) + 0x0000FFFFFFFB2E7ALL;
|
|
130
|
+
result = ((smulh48(result, x) + 1LL) >> 1) - 0x0000FFFFFFFFF85FLL;
|
|
131
|
+
result = ((smulh48(result, x))) + 0x0000FFFFFFFFFFFCLL;
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#define CDTLEN 64
|
|
136
|
+
static const uint32_t CDT[CDTLEN] = {
|
|
137
|
+
3266, 6520, 9748, 12938, 16079, 19159, 22168, 25096, 27934, 30674, 33309,
|
|
138
|
+
35833, 38241, 40531, 42698, 44742, 46663, 48460, 50135, 51690, 53128, 54454,
|
|
139
|
+
55670, 56781, 57794, 58712, 59541, 60287, 60956, 61554, 62085, 62556, 62972,
|
|
140
|
+
63337, 63657, 63936, 64178, 64388, 64569, 64724, 64857, 64970, 65066, 65148,
|
|
141
|
+
65216, 65273, 65321, 65361, 65394, 65422, 65444, 65463, 65478, 65490, 65500,
|
|
142
|
+
65508, 65514, 65519, 65523, 65527, 65529, 65531, 65533, 65534};
|
|
143
|
+
|
|
144
|
+
/*************************************************
|
|
145
|
+
* Name: sample_gauss16
|
|
146
|
+
*
|
|
147
|
+
* Description: sample gauss using 16 bits integer
|
|
148
|
+
*
|
|
149
|
+
* Arguments: - const uint64_t rand16: input 16 bits integer
|
|
150
|
+
*
|
|
151
|
+
* Specification: Implements Algorithm 15, SampleGauss16.
|
|
152
|
+
**************************************************/
|
|
153
|
+
static uint64_t sample_gauss16(const uint64_t rand16) {
|
|
154
|
+
unsigned int i;
|
|
155
|
+
uint64_t r = 0;
|
|
156
|
+
for (i = 0; i < CDTLEN; i++) {
|
|
157
|
+
r += (((uint64_t)CDT[i] - rand16) >> 63) & 1;
|
|
158
|
+
}
|
|
159
|
+
return r;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/*************************************************
|
|
163
|
+
* Name: sample_gauss_sigma76
|
|
164
|
+
*
|
|
165
|
+
* Description: sample gauss with sigma 76
|
|
166
|
+
*
|
|
167
|
+
* Arguments: - uint64_t *r: pointer to output integer
|
|
168
|
+
* - fp96_76 *sqr: pointer to output fixed point
|
|
169
|
+
* - const uint8_t rand[]: pointer to input integer
|
|
170
|
+
*
|
|
171
|
+
* Specification: Implements Algorithm 14, SampleGaussSigma76.
|
|
172
|
+
**************************************************/
|
|
173
|
+
#define GAUSS_RAND (72 + 16 + 48)
|
|
174
|
+
#define GAUSS_RAND_BYTES ((GAUSS_RAND + 7) / 8) // 17
|
|
175
|
+
static int sample_gauss_sigma76(uint64_t *r, fp96_76 *sqr,
|
|
176
|
+
const uint8_t rand[GAUSS_RAND_BYTES]) {
|
|
177
|
+
const uint64_t rand_gauss16 = rand[0] | (((uint64_t)rand[1]) << 8);
|
|
178
|
+
const uint64_t rand_rej =
|
|
179
|
+
rand[2] | (((uint64_t)rand[3]) << 8) | (((uint64_t)rand[4]) << 16) |
|
|
180
|
+
(((uint64_t)rand[5]) << 24) | (((uint64_t)rand[6]) << 32) |
|
|
181
|
+
(((uint64_t)rand[7]) << 40);
|
|
182
|
+
uint64_t x, exp_in;
|
|
183
|
+
fp96_76 y;
|
|
184
|
+
|
|
185
|
+
// sample x
|
|
186
|
+
x = sample_gauss16(rand_gauss16);
|
|
187
|
+
|
|
188
|
+
// y := append x to y
|
|
189
|
+
// leave 16 bit for carries
|
|
190
|
+
y.limb48[0] = rand[8] | ((uint64_t)rand[9] << 8) |
|
|
191
|
+
((uint64_t)rand[10] << 16) | ((uint64_t)rand[11] << 24) |
|
|
192
|
+
((uint64_t)rand[12] << 32) | ((uint64_t)rand[13] << 40);
|
|
193
|
+
y.limb48[1] = rand[14] | ((uint64_t)rand[15] << 8) |
|
|
194
|
+
((uint64_t)rand[16] << 16) | (x << 24);
|
|
195
|
+
|
|
196
|
+
// r := round y
|
|
197
|
+
*r = (y.limb48[0] >> 15) ^ (y.limb48[1] << 33);
|
|
198
|
+
*r += 1; // rounding
|
|
199
|
+
*r >>= 1;
|
|
200
|
+
|
|
201
|
+
// sqr := y*y
|
|
202
|
+
fixpoint_square(sqr, &y);
|
|
203
|
+
|
|
204
|
+
// sqr[1] = y^2 >> (76+48) // 34 bit
|
|
205
|
+
// sqr[0] = (y^2 >> 76) & ((1UL<<48)-1) // 48 bit
|
|
206
|
+
// exp_in := sqr - ((x*x) << 68)
|
|
207
|
+
exp_in = sqr->limb48[1] - ((x * x) << (68 - 48));
|
|
208
|
+
exp_in <<= 20;
|
|
209
|
+
exp_in |= sqr->limb48[0] >> 28;
|
|
210
|
+
exp_in += 1; // rounding
|
|
211
|
+
exp_in >>= 1;
|
|
212
|
+
|
|
213
|
+
return ((((int64_t)(rand_rej ^
|
|
214
|
+
(rand_rej & 1)) // set lowest bit to zero in order to
|
|
215
|
+
// use it for rejection if sample==0
|
|
216
|
+
- (int64_t)approx_exp(exp_in)) >>
|
|
217
|
+
63) // reject with prob 1-approx_exp(exp_in)
|
|
218
|
+
& (((*r | -*r) >> 63) | rand_rej)) &
|
|
219
|
+
1; // if the sample is zero, clear the return value with prob 1/2
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/*************************************************
|
|
223
|
+
* Name: sample_gauss
|
|
224
|
+
*
|
|
225
|
+
* Description: sample gauss using smaple_gauss_sigma76
|
|
226
|
+
*
|
|
227
|
+
* Arguments: - uint64_t *r: pointer to output integer array
|
|
228
|
+
* - fp96_76 *sqsum: pointer to output fixed point
|
|
229
|
+
* - const uint8_t *buf: pointer to input byte array
|
|
230
|
+
* - size_t buflen: length of input byte array
|
|
231
|
+
* - size_t len: max length of samples
|
|
232
|
+
* - int dont_write_last: flag
|
|
233
|
+
*
|
|
234
|
+
* Specification: Implements Algorithm 13, SampleGauss.
|
|
235
|
+
**************************************************/
|
|
236
|
+
int sample_gauss(uint64_t *r, fp96_76 *sqsum, const uint8_t *buf, size_t buflen,
|
|
237
|
+
size_t len, int dont_write_last) {
|
|
238
|
+
const uint8_t *pos = buf;
|
|
239
|
+
fp96_76 sqr;
|
|
240
|
+
size_t bytecnt = buflen, coefcnt = 0;
|
|
241
|
+
int accepted;
|
|
242
|
+
uint64_t dummy;
|
|
243
|
+
|
|
244
|
+
while (coefcnt < len) {
|
|
245
|
+
if (bytecnt < GAUSS_RAND_BYTES) {
|
|
246
|
+
renormalize(sqsum);
|
|
247
|
+
return coefcnt;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (dont_write_last && coefcnt == len - 1) {
|
|
251
|
+
accepted = sample_gauss_sigma76(&dummy, &sqr, pos);
|
|
252
|
+
} else {
|
|
253
|
+
accepted = sample_gauss_sigma76(&r[coefcnt], &sqr, pos);
|
|
254
|
+
}
|
|
255
|
+
coefcnt += accepted;
|
|
256
|
+
pos += GAUSS_RAND_BYTES;
|
|
257
|
+
bytecnt -= GAUSS_RAND_BYTES;
|
|
258
|
+
|
|
259
|
+
sqsum->limb48[0] += sqr.limb48[0] & -(int64_t)accepted;
|
|
260
|
+
sqsum->limb48[1] += sqr.limb48[1] & -(int64_t)accepted;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
renormalize(sqsum);
|
|
264
|
+
return len;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/*************************************************
|
|
268
|
+
* Name: sample_gauss_N
|
|
269
|
+
*
|
|
270
|
+
* Description: sample gauss
|
|
271
|
+
*
|
|
272
|
+
* Arguments: - uint64_t *r: pointer to output integer array
|
|
273
|
+
* - uint8_t *signs: pointer to output byte array
|
|
274
|
+
* - fp96_76 *sqsum: pointer to output fixed point
|
|
275
|
+
* - const uint8_t seed[]: pointer to input seed
|
|
276
|
+
* - uint16_t nonce: input nonce
|
|
277
|
+
* - size_t len: number of samples
|
|
278
|
+
*
|
|
279
|
+
* Specification: Implements Algorithm 12, SampleGaussN.
|
|
280
|
+
**************************************************/
|
|
281
|
+
#define POLY_HYPERBALL_BUFLEN (GAUSS_RAND_BYTES * HAETAE_N)
|
|
282
|
+
#define POLY_HYPERBALL_NBLOCKS \
|
|
283
|
+
((POLY_HYPERBALL_BUFLEN + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES)
|
|
284
|
+
void sample_gauss_N(uint64_t *r, uint8_t *signs, fp96_76 *sqsum,
|
|
285
|
+
const uint8_t seed[HAETAE_CRHBYTES], uint16_t nonce,
|
|
286
|
+
size_t len) {
|
|
287
|
+
uint8_t buf[POLY_HYPERBALL_NBLOCKS * STREAM256_BLOCKBYTES];
|
|
288
|
+
size_t bytecnt, coefcnt, firstflag = 1;
|
|
289
|
+
stream256_state state;
|
|
290
|
+
stream256_init(&state, seed, nonce);
|
|
291
|
+
|
|
292
|
+
stream256_squeezeblocks(buf, POLY_HYPERBALL_NBLOCKS, &state);
|
|
293
|
+
for (size_t i = 0; i < len / 8; i++) {
|
|
294
|
+
signs[i] = buf[i];
|
|
295
|
+
}
|
|
296
|
+
bytecnt = POLY_HYPERBALL_NBLOCKS * STREAM256_BLOCKBYTES - len / 8;
|
|
297
|
+
coefcnt = sample_gauss(r, sqsum, buf + len / 8, bytecnt, len, len % HAETAE_N);
|
|
298
|
+
while (coefcnt < len) {
|
|
299
|
+
size_t off = bytecnt % GAUSS_RAND_BYTES;
|
|
300
|
+
for (size_t i = 0; i < off; i++) {
|
|
301
|
+
buf[i] = buf[bytecnt + len / 8 * firstflag - off + i];
|
|
302
|
+
}
|
|
303
|
+
stream256_squeezeblocks(buf + off, 1, &state);
|
|
304
|
+
bytecnt = STREAM256_BLOCKBYTES + off;
|
|
305
|
+
|
|
306
|
+
coefcnt += sample_gauss(r + coefcnt, sqsum, buf, bytecnt, len - coefcnt,
|
|
307
|
+
len % HAETAE_N);
|
|
308
|
+
firstflag = 0;
|
|
309
|
+
}
|
|
310
|
+
}
|