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,371 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "poly.h"
|
|
4
|
+
#include "decompose.h"
|
|
5
|
+
#include "ntt.h"
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "reduce.h"
|
|
8
|
+
#include "sampler.h"
|
|
9
|
+
#include "symmetric.h"
|
|
10
|
+
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
|
|
13
|
+
/*************************************************
|
|
14
|
+
* Name: poly_add
|
|
15
|
+
*
|
|
16
|
+
* Description: Add polynomials. No modular reduction is performed.
|
|
17
|
+
*
|
|
18
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
19
|
+
* - const poly *a: pointer to first summand
|
|
20
|
+
* - const poly *b: pointer to second summand
|
|
21
|
+
**************************************************/
|
|
22
|
+
void poly_add(poly *c, const poly *a, const poly *b) {
|
|
23
|
+
unsigned int i;
|
|
24
|
+
|
|
25
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
26
|
+
c->coeffs[i] = a->coeffs[i] + b->coeffs[i];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*************************************************
|
|
30
|
+
* Name: poly_sub
|
|
31
|
+
*
|
|
32
|
+
* Description: Subtract polynomials. No modular reduction is
|
|
33
|
+
* performed.
|
|
34
|
+
*
|
|
35
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
36
|
+
* - const poly *a: pointer to first input polynomial
|
|
37
|
+
* - const poly *b: pointer to second input polynomial to be
|
|
38
|
+
* subtraced from first input polynomial
|
|
39
|
+
**************************************************/
|
|
40
|
+
void poly_sub(poly *c, const poly *a, const poly *b) {
|
|
41
|
+
unsigned int i;
|
|
42
|
+
|
|
43
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
44
|
+
c->coeffs[i] = a->coeffs[i] - b->coeffs[i];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*************************************************
|
|
48
|
+
* Name: poly_pointwise_montgomery
|
|
49
|
+
*
|
|
50
|
+
* Description: Pointwise multiplication of polynomials in NTT domain
|
|
51
|
+
* representation and multiplication of resulting polynomial
|
|
52
|
+
* by 2^{-32}.
|
|
53
|
+
*
|
|
54
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
55
|
+
* - const poly *a: pointer to first input polynomial
|
|
56
|
+
* - const poly *b: pointer to second input polynomial
|
|
57
|
+
**************************************************/
|
|
58
|
+
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b) {
|
|
59
|
+
unsigned int i;
|
|
60
|
+
|
|
61
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
62
|
+
c->coeffs[i] = montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/*************************************************
|
|
66
|
+
* Name: poly_reduce2q
|
|
67
|
+
*
|
|
68
|
+
* Description: Inplace reduction of all coefficients of polynomial to 2q
|
|
69
|
+
*
|
|
70
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
71
|
+
**************************************************/
|
|
72
|
+
void poly_reduce2q(poly *a) {
|
|
73
|
+
unsigned int i;
|
|
74
|
+
|
|
75
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
76
|
+
a->coeffs[i] = reduce32_2q(a->coeffs[i]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/*************************************************
|
|
80
|
+
* Name: poly_freeze2q
|
|
81
|
+
*
|
|
82
|
+
* Description: For all coefficients of in/out polynomial compute standard
|
|
83
|
+
* representative r = a mod^+ 2Q
|
|
84
|
+
*
|
|
85
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
86
|
+
**************************************************/
|
|
87
|
+
void poly_freeze2q(poly *a) {
|
|
88
|
+
unsigned int i;
|
|
89
|
+
|
|
90
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
91
|
+
a->coeffs[i] = freeze2q(a->coeffs[i]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/*************************************************
|
|
95
|
+
* Name: poly_freeze
|
|
96
|
+
*
|
|
97
|
+
* Description: For all coefficients of in/out polynomial compute standard
|
|
98
|
+
* representative r = a mod^+ HAETAE_Q
|
|
99
|
+
*
|
|
100
|
+
* Arguments: - poly *a: pointer to input/output polynomial
|
|
101
|
+
**************************************************/
|
|
102
|
+
void poly_freeze(poly *a) {
|
|
103
|
+
unsigned int i;
|
|
104
|
+
|
|
105
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
106
|
+
a->coeffs[i] = freeze(a->coeffs[i]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/*************************************************
|
|
110
|
+
* Name: poly_highbits
|
|
111
|
+
*
|
|
112
|
+
* Description: Compute HighBits of polynomial
|
|
113
|
+
*
|
|
114
|
+
* Arguments: - poly *a2: pointer to output polynomial
|
|
115
|
+
* - const poly *a: pointer to input polynomial
|
|
116
|
+
**************************************************/
|
|
117
|
+
void poly_highbits(poly *a2, const poly *a) {
|
|
118
|
+
unsigned int i;
|
|
119
|
+
int32_t a1tmp;
|
|
120
|
+
|
|
121
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
122
|
+
decompose_z1(&a2->coeffs[i], &a1tmp, a->coeffs[i]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/*************************************************
|
|
126
|
+
* Name: poly_lowbits
|
|
127
|
+
*
|
|
128
|
+
* Description: Compute LowBits of polynomial
|
|
129
|
+
*
|
|
130
|
+
* Arguments: - poly *a1: pointer to output polynomial
|
|
131
|
+
* - const poly *a: pointer to input polynomial
|
|
132
|
+
**************************************************/
|
|
133
|
+
void poly_lowbits(poly *a1, const poly *a) {
|
|
134
|
+
unsigned int i = 0;
|
|
135
|
+
int32_t a2tmp = 0;
|
|
136
|
+
|
|
137
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
138
|
+
decompose_z1(&a2tmp, &a1->coeffs[i], a->coeffs[i]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/*************************************************
|
|
142
|
+
* Name: poly_compose
|
|
143
|
+
*
|
|
144
|
+
* Description: Compose HighBits and LowBits to recreate the polynomial
|
|
145
|
+
*
|
|
146
|
+
* Arguments: - poly *a3: pointer to output polynomial
|
|
147
|
+
* - const poly *ha: pointer to HighBits polynomial
|
|
148
|
+
* - const poly *la: pointer to HighBits polynomial
|
|
149
|
+
**************************************************/
|
|
150
|
+
void poly_compose(poly *a, const poly *ha, const poly *la) {
|
|
151
|
+
unsigned int i = 0;
|
|
152
|
+
|
|
153
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
154
|
+
a->coeffs[i] = (ha->coeffs[i] * 256) + la->coeffs[i];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/*************************************************
|
|
158
|
+
* Name: poly_lsb
|
|
159
|
+
*
|
|
160
|
+
* Description: Compute least significant bits of polynomial
|
|
161
|
+
*
|
|
162
|
+
* Arguments: - poly *a0: pointer to output polynomial
|
|
163
|
+
* - const poly *a: pointer to input polynomial
|
|
164
|
+
**************************************************/
|
|
165
|
+
void poly_lsb(poly *a0, const poly *a) {
|
|
166
|
+
unsigned int i;
|
|
167
|
+
|
|
168
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
169
|
+
a0->coeffs[i] = a->coeffs[i] & 1;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/*************************************************
|
|
173
|
+
* Name: poly_uniform
|
|
174
|
+
*
|
|
175
|
+
* Description: Sample polynomial with uniformly random coefficients
|
|
176
|
+
* in [0,Q-1] by performing rejection sampling on the
|
|
177
|
+
* output stream of SHAKE128(seed|nonce)
|
|
178
|
+
*
|
|
179
|
+
* Arguments: - poly *a: pointer to output polynomial
|
|
180
|
+
* - const uint8_t seed[]: byte array with seed of length
|
|
181
|
+
* HAETAE_SEEDBYTES
|
|
182
|
+
* - uint16_t nonce: 2-byte nonce
|
|
183
|
+
*
|
|
184
|
+
* Specification: Implements Algorithm 6, PolyUniform.
|
|
185
|
+
**************************************************/
|
|
186
|
+
#define POLY_UNIFORM_NBLOCKS \
|
|
187
|
+
((512 + STREAM128_BLOCKBYTES - 1) / STREAM128_BLOCKBYTES)
|
|
188
|
+
// HAETAE_N * 2(random bytes for [0, HAETAE_Q - 1])
|
|
189
|
+
|
|
190
|
+
void poly_uniform(poly *a, const uint8_t seed[HAETAE_SEEDBYTES],
|
|
191
|
+
uint16_t nonce) {
|
|
192
|
+
unsigned int i, ctr, off;
|
|
193
|
+
unsigned int buflen = POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES;
|
|
194
|
+
uint8_t buf[POLY_UNIFORM_NBLOCKS * STREAM128_BLOCKBYTES + 1];
|
|
195
|
+
stream128_state state;
|
|
196
|
+
|
|
197
|
+
stream128_init(&state, seed, nonce);
|
|
198
|
+
stream128_squeezeblocks(buf, POLY_UNIFORM_NBLOCKS, &state);
|
|
199
|
+
|
|
200
|
+
ctr = rej_uniform(a->coeffs, HAETAE_N, buf, buflen);
|
|
201
|
+
|
|
202
|
+
while (ctr < HAETAE_N) {
|
|
203
|
+
off = buflen % 2;
|
|
204
|
+
for (i = 0; i < off; ++i)
|
|
205
|
+
buf[i] = buf[buflen - off + i];
|
|
206
|
+
|
|
207
|
+
stream128_squeezeblocks(buf + off, 1, &state);
|
|
208
|
+
buflen = STREAM128_BLOCKBYTES + off;
|
|
209
|
+
ctr += rej_uniform(a->coeffs + ctr, HAETAE_N - ctr, buf, buflen);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/*************************************************
|
|
214
|
+
* Name: poly_uniform_eta
|
|
215
|
+
*
|
|
216
|
+
* Description: Sample polynomial with uniformly random coefficients
|
|
217
|
+
* in [-ETA,ETA] by performing rejection sampling on the
|
|
218
|
+
* output stream from SHAKE256(seed|nonce)
|
|
219
|
+
*
|
|
220
|
+
* Arguments: - poly *a: pointer to output polynomial
|
|
221
|
+
* - const uint8_t seed[]: byte array with seed of length
|
|
222
|
+
* HAETAE_CRHBYTES
|
|
223
|
+
* - uint16_t nonce: 2-byte nonce
|
|
224
|
+
*
|
|
225
|
+
* Specification: Implements Algorithm 9, PolyUniformEta.
|
|
226
|
+
**************************************************/
|
|
227
|
+
#define POLY_UNIFORM_ETA_NBLOCKS \
|
|
228
|
+
((136 + STREAM256_BLOCKBYTES - 1) / STREAM256_BLOCKBYTES) // 1
|
|
229
|
+
|
|
230
|
+
void poly_uniform_eta(poly *a, const uint8_t seed[HAETAE_CRHBYTES],
|
|
231
|
+
uint16_t nonce) {
|
|
232
|
+
unsigned int ctr;
|
|
233
|
+
unsigned int buflen = POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES;
|
|
234
|
+
uint8_t buf[POLY_UNIFORM_ETA_NBLOCKS * STREAM256_BLOCKBYTES];
|
|
235
|
+
stream256_state state;
|
|
236
|
+
|
|
237
|
+
stream256_init(&state, seed, nonce);
|
|
238
|
+
stream256_squeezeblocks(buf, POLY_UNIFORM_ETA_NBLOCKS, &state);
|
|
239
|
+
|
|
240
|
+
ctr = rej_eta(a->coeffs, HAETAE_N, buf, buflen);
|
|
241
|
+
|
|
242
|
+
while (ctr < HAETAE_N) {
|
|
243
|
+
stream256_squeezeblocks(buf, 1, &state);
|
|
244
|
+
ctr += rej_eta(a->coeffs + ctr, HAETAE_N - ctr, buf, STREAM256_BLOCKBYTES);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
uint8_t hammingWeight_8(uint8_t x) {
|
|
249
|
+
x = (x & 0x55) + (x >> 1 & 0x55);
|
|
250
|
+
x = (x & 0x33) + (x >> 2 & 0x33);
|
|
251
|
+
x = (x & 0x0F) + (x >> 4 & 0x0F);
|
|
252
|
+
|
|
253
|
+
return x;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*************************************************
|
|
257
|
+
* Name: poly_challenge
|
|
258
|
+
*
|
|
259
|
+
* Description: Implementation of challenge. Samples polynomial with HAETAE_TAU
|
|
260
|
+
* 1 coefficients using the output stream of SHAKE256(seed).
|
|
261
|
+
*
|
|
262
|
+
* Arguments: - poly *c: pointer to output polynomial
|
|
263
|
+
* - const uint8_t highbits_lsb[]: packed highbits and lsb
|
|
264
|
+
* - const uint8_t mu[]: hash of vk and message
|
|
265
|
+
*
|
|
266
|
+
* Specification: Implements Algorithm 16, SampleChallenge.
|
|
267
|
+
**************************************************/
|
|
268
|
+
void poly_challenge(
|
|
269
|
+
poly *c,
|
|
270
|
+
const uint8_t highbits_lsb[HAETAE_POLYVECK_HIGHBITS_PACKEDBYTES +
|
|
271
|
+
HAETAE_POLYC_PACKEDBYTES],
|
|
272
|
+
const uint8_t mu[HAETAE_SEEDBYTES]) {
|
|
273
|
+
#if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
|
|
274
|
+
unsigned int i, b, pos = 0;
|
|
275
|
+
uint8_t buf[XOF256_BLOCKBYTES];
|
|
276
|
+
xof256_state state;
|
|
277
|
+
|
|
278
|
+
// H(HighBits(A * y mod 2q), LSB(round(y0) * j), HAETAE_M)
|
|
279
|
+
xof256_absorb_twice(&state, highbits_lsb,
|
|
280
|
+
HAETAE_POLYVECK_HIGHBITS_PACKEDBYTES +
|
|
281
|
+
HAETAE_POLYC_PACKEDBYTES,
|
|
282
|
+
mu, HAETAE_SEEDBYTES);
|
|
283
|
+
xof256_squeezeblocks(buf, 1, &state);
|
|
284
|
+
|
|
285
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
286
|
+
c->coeffs[i] = 0;
|
|
287
|
+
for (i = HAETAE_N - HAETAE_TAU; i < HAETAE_N; ++i) {
|
|
288
|
+
do {
|
|
289
|
+
if (pos >= XOF256_BLOCKBYTES) {
|
|
290
|
+
xof256_squeezeblocks(buf, 1, &state);
|
|
291
|
+
pos = 0;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
b = buf[pos++];
|
|
295
|
+
} while (b > i);
|
|
296
|
+
|
|
297
|
+
c->coeffs[i] = c->coeffs[b];
|
|
298
|
+
c->coeffs[b] = 1;
|
|
299
|
+
}
|
|
300
|
+
#elif HAETAE_MODE == HAETAE_MODE5
|
|
301
|
+
unsigned int i, hwt = 0, cond = 0;
|
|
302
|
+
uint8_t mask = 0, w0 = 0;
|
|
303
|
+
uint8_t buf[32] = {0};
|
|
304
|
+
xof256_state state;
|
|
305
|
+
|
|
306
|
+
// H(HighBits(A * y mod 2q), LSB(round(y0) * j), HAETAE_M)
|
|
307
|
+
xof256_absorb_twice(&state, highbits_lsb,
|
|
308
|
+
HAETAE_POLYVECK_HIGHBITS_PACKEDBYTES +
|
|
309
|
+
HAETAE_POLYC_PACKEDBYTES,
|
|
310
|
+
mu, HAETAE_SEEDBYTES);
|
|
311
|
+
xof256_squeeze(buf, 32, &state);
|
|
312
|
+
|
|
313
|
+
for (i = 0; i < 32; ++i)
|
|
314
|
+
hwt += hammingWeight_8(buf[i]);
|
|
315
|
+
|
|
316
|
+
cond = (128 - hwt);
|
|
317
|
+
mask = 0xff & (cond >> 8);
|
|
318
|
+
w0 = -(buf[0] & 1);
|
|
319
|
+
mask = w0 ^ ((-(!!cond & 1)) & (mask ^ w0)); // mask = !!cond ? mask : w0
|
|
320
|
+
for (i = 0; i < 32; ++i) {
|
|
321
|
+
buf[i] ^= mask;
|
|
322
|
+
c->coeffs[8 * i] = buf[i] & 1;
|
|
323
|
+
c->coeffs[8 * i + 1] = (buf[i] >> 1) & 1;
|
|
324
|
+
c->coeffs[8 * i + 2] = (buf[i] >> 2) & 1;
|
|
325
|
+
c->coeffs[8 * i + 3] = (buf[i] >> 3) & 1;
|
|
326
|
+
c->coeffs[8 * i + 4] = (buf[i] >> 4) & 1;
|
|
327
|
+
c->coeffs[8 * i + 5] = (buf[i] >> 5) & 1;
|
|
328
|
+
c->coeffs[8 * i + 6] = (buf[i] >> 6) & 1;
|
|
329
|
+
c->coeffs[8 * i + 7] = (buf[i] >> 7) & 1;
|
|
330
|
+
}
|
|
331
|
+
#endif
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
void poly_decomposed_pack(uint8_t *buf, const poly *a) {
|
|
335
|
+
unsigned int i;
|
|
336
|
+
for (i = 0; i < HAETAE_N; i++) {
|
|
337
|
+
buf[i] = a->coeffs[i];
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
void poly_decomposed_unpack(poly *a, const uint8_t *buf) {
|
|
342
|
+
unsigned int i;
|
|
343
|
+
for (i = 0; i < HAETAE_N; i++) {
|
|
344
|
+
a->coeffs[i] = (int8_t)buf[i];
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
void poly_fromcrt(poly *w, const poly *u, const poly *v) {
|
|
349
|
+
unsigned int i;
|
|
350
|
+
int32_t xq, x2;
|
|
351
|
+
|
|
352
|
+
for (i = 0; i < HAETAE_N; i++) {
|
|
353
|
+
xq = u->coeffs[i];
|
|
354
|
+
x2 = v->coeffs[i];
|
|
355
|
+
w->coeffs[i] = xq + (HAETAE_Q & -((xq ^ x2) & 1));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
void poly_fromcrt0(poly *w, const poly *u) {
|
|
360
|
+
unsigned int i;
|
|
361
|
+
int32_t xq;
|
|
362
|
+
|
|
363
|
+
for (i = 0; i < HAETAE_N; i++) {
|
|
364
|
+
xq = u->coeffs[i];
|
|
365
|
+
w->coeffs[i] = xq + (HAETAE_Q & -(xq & 1));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
void poly_ntt(poly *a) { ntt(&a->coeffs[0]); }
|
|
370
|
+
|
|
371
|
+
void poly_invntt_tomont(poly *a) { invntt_tomont(&a->coeffs[0]); }
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "polyfix.h"
|
|
4
|
+
#include "fips202.h"
|
|
5
|
+
#include "fixpoint.h"
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "sampler.h"
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
/*************************************************
|
|
12
|
+
* Name: polyfix_add
|
|
13
|
+
*
|
|
14
|
+
* Description: Add double polynomial and integer polynomial.
|
|
15
|
+
* No modular reduction is performed.
|
|
16
|
+
*
|
|
17
|
+
* Arguments: - polyfix *c: pointer to output double polynomial
|
|
18
|
+
* - const polyfix *a: pointer to first summand
|
|
19
|
+
* - const poly *b: pointer to second summand
|
|
20
|
+
**************************************************/
|
|
21
|
+
void polyfix_add(polyfix *c, const polyfix *a, const poly *b) {
|
|
22
|
+
unsigned int i;
|
|
23
|
+
|
|
24
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
25
|
+
c->coeffs[i] = a->coeffs[i] + HAETAE_LN * b->coeffs[i];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*************************************************
|
|
29
|
+
* Name: polyfixfix_sub
|
|
30
|
+
*
|
|
31
|
+
* Description: Subtract fixed polynomial and fixed polynomial.
|
|
32
|
+
* No modular reduction is performed.
|
|
33
|
+
*
|
|
34
|
+
* Arguments: - polyfix *c: pointer to output fixed polynomial
|
|
35
|
+
* - const polyfix *a: pointer to first summand
|
|
36
|
+
* - const polyfix *b: pointer to second summand
|
|
37
|
+
**************************************************/
|
|
38
|
+
void polyfixfix_sub(polyfix *c, const polyfix *a, const polyfix *b) {
|
|
39
|
+
unsigned int i;
|
|
40
|
+
|
|
41
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
42
|
+
c->coeffs[i] = a->coeffs[i] - b->coeffs[i];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
int32_t fix_round(int32_t num) {
|
|
46
|
+
return (num + HAETAE_LNHALF) >> HAETAE_LNBITS;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/*************************************************
|
|
50
|
+
* Name: polyfix_round
|
|
51
|
+
*
|
|
52
|
+
* Description: rounds a fixed polynomial to integer polynomial
|
|
53
|
+
*
|
|
54
|
+
* Arguments: - poly *a: output integer polynomial
|
|
55
|
+
* - poly *b: input fixed polynomial
|
|
56
|
+
**************************************************/
|
|
57
|
+
void polyfix_round(poly *a, const polyfix *b) {
|
|
58
|
+
unsigned i;
|
|
59
|
+
|
|
60
|
+
for (i = 0; i < HAETAE_N; ++i)
|
|
61
|
+
a->coeffs[i] = fix_round(b->coeffs[i]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*************************************************
|
|
65
|
+
* Name: polyfixveck_add
|
|
66
|
+
*
|
|
67
|
+
* Description: Add vector to a vector of double polynomials of length HAETAE_K.
|
|
68
|
+
* No modular reduction is performed.
|
|
69
|
+
*
|
|
70
|
+
* Arguments: - polyveck *w: pointer to output vector
|
|
71
|
+
* - const polyveck *u: pointer to first summand
|
|
72
|
+
* - const polyveck *v: pointer to second summand
|
|
73
|
+
**************************************************/
|
|
74
|
+
void polyfixveck_add(polyfixveck *w, const polyfixveck *u, const polyveck *v) {
|
|
75
|
+
unsigned int i;
|
|
76
|
+
|
|
77
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
78
|
+
polyfix_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*************************************************
|
|
82
|
+
* Name: polyfixfixveck_sub
|
|
83
|
+
*
|
|
84
|
+
* Description: subtract vector to a vector of fixed polynomials of length k.
|
|
85
|
+
* No modular reduction is performed.
|
|
86
|
+
*
|
|
87
|
+
* Arguments: - polyveck *w: pointer to output vector
|
|
88
|
+
* - const polyfixveck *u: pointer to first summand
|
|
89
|
+
* - const polyfixveck *v: pointer to second summand
|
|
90
|
+
**************************************************/
|
|
91
|
+
void polyfixfixveck_sub(polyfixveck *w, const polyfixveck *u,
|
|
92
|
+
const polyfixveck *v) {
|
|
93
|
+
unsigned int i;
|
|
94
|
+
|
|
95
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
96
|
+
polyfixfix_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/*************************************************
|
|
100
|
+
* Name: polyfixveck_double
|
|
101
|
+
*
|
|
102
|
+
* Description: Double vector of polynomials of length HAETAE_K.
|
|
103
|
+
*
|
|
104
|
+
* Arguments: - polyveck *b: pointer to output vector
|
|
105
|
+
* - polyveck *a: pointer to input vector
|
|
106
|
+
**************************************************/
|
|
107
|
+
void polyfixveck_double(polyfixveck *b, const polyfixveck *a) {
|
|
108
|
+
unsigned int i, j;
|
|
109
|
+
|
|
110
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
111
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
112
|
+
b->vec[i].coeffs[j] = 2 * a->vec[i].coeffs[j];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/*************************************************
|
|
116
|
+
* Name: polyfixveck_round
|
|
117
|
+
*
|
|
118
|
+
* Description: rounds a fixed polynomial vector of length HAETAE_K
|
|
119
|
+
*
|
|
120
|
+
* Arguments: - polyveck *a: output integer polynomial vector
|
|
121
|
+
* - polyfixveck *b: input fixed polynomial vector
|
|
122
|
+
**************************************************/
|
|
123
|
+
void polyfixveck_round(polyveck *a, const polyfixveck *b) {
|
|
124
|
+
unsigned i;
|
|
125
|
+
|
|
126
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
127
|
+
polyfix_round(&a->vec[i], &b->vec[i]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/*************************************************
|
|
131
|
+
* Name: polyfixvecl_add
|
|
132
|
+
*
|
|
133
|
+
* Description: Add vector to a vector of double polynomials of length L.
|
|
134
|
+
* No modular reduction is performed.
|
|
135
|
+
*
|
|
136
|
+
* Arguments: - polyvecl *w: pointer to output vector
|
|
137
|
+
* - const polyfixvecl *u: pointer to first summand
|
|
138
|
+
* - const polyvecl *v: pointer to second summand
|
|
139
|
+
**************************************************/
|
|
140
|
+
void polyfixvecl_add(polyfixvecl *w, const polyfixvecl *u, const polyvecl *v) {
|
|
141
|
+
unsigned int i;
|
|
142
|
+
|
|
143
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
144
|
+
polyfix_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/*************************************************
|
|
148
|
+
* Name: polyfixfixvecl_sub
|
|
149
|
+
*
|
|
150
|
+
* Description: subtract vector to a vector of fixed polynomials of length l.
|
|
151
|
+
* No modular reduction is performed.
|
|
152
|
+
*
|
|
153
|
+
* Arguments: - polyvecl *w: pointer to output vector
|
|
154
|
+
* - const polyfixvecl *u: pointer to first summand
|
|
155
|
+
* - const polyfixvecl *v: pointer to second summand
|
|
156
|
+
**************************************************/
|
|
157
|
+
void polyfixfixvecl_sub(polyfixvecl *w, const polyfixvecl *u,
|
|
158
|
+
const polyfixvecl *v) {
|
|
159
|
+
unsigned int i;
|
|
160
|
+
|
|
161
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
162
|
+
polyfixfix_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
163
|
+
}
|
|
164
|
+
/*************************************************
|
|
165
|
+
* Name: polyfixvecl_double
|
|
166
|
+
*
|
|
167
|
+
* Description: Double vector of polynomials of length L.
|
|
168
|
+
*
|
|
169
|
+
* Arguments: - polyveck *b: pointer to output vector
|
|
170
|
+
* - polyveck *a: pointer to input vector
|
|
171
|
+
**************************************************/
|
|
172
|
+
void polyfixvecl_double(polyfixvecl *b, const polyfixvecl *a) {
|
|
173
|
+
unsigned int i, j;
|
|
174
|
+
|
|
175
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
176
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
177
|
+
b->vec[i].coeffs[j] = 2 * a->vec[i].coeffs[j];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/*************************************************
|
|
181
|
+
* Name: polyfixvecl_round
|
|
182
|
+
*
|
|
183
|
+
* Description: rounds a fixed polynomial vector of length L
|
|
184
|
+
*
|
|
185
|
+
* Arguments: - polyvecl *a: output integer polynomial vector
|
|
186
|
+
* - polyfixvecl *b: input fixed polynomial vector
|
|
187
|
+
**************************************************/
|
|
188
|
+
void polyfixvecl_round(polyvecl *a, const polyfixvecl *b) {
|
|
189
|
+
unsigned i;
|
|
190
|
+
|
|
191
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
192
|
+
polyfix_round(&a->vec[i], &b->vec[i]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/*************************************************
|
|
196
|
+
* Name: polyfixveclk_norm2
|
|
197
|
+
*
|
|
198
|
+
* Description: Calculates L2 norm of a fixed point polynomial vector with
|
|
199
|
+
* length HAETAE_L + HAETAE_K The result is L2 norm * HAETAE_LN
|
|
200
|
+
* similar to the way polynomial is usually stored
|
|
201
|
+
*
|
|
202
|
+
* Arguments: - polyfixvecl *a: polynomial vector with length HAETAE_L to
|
|
203
|
+
* calculate norm
|
|
204
|
+
* - polyfixveck *b: polynomial vector with length HAETAE_K to
|
|
205
|
+
* calculate norm
|
|
206
|
+
**************************************************/
|
|
207
|
+
uint64_t polyfixveclk_sqnorm2(const polyfixvecl *a, const polyfixveck *b) {
|
|
208
|
+
unsigned int i, j;
|
|
209
|
+
uint64_t ret = 0;
|
|
210
|
+
|
|
211
|
+
for (i = 0; i < HAETAE_L; ++i) {
|
|
212
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
213
|
+
ret += (int64_t)a->vec[i].coeffs[j] * a->vec[i].coeffs[j];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
for (i = 0; i < HAETAE_K; ++i) {
|
|
217
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
218
|
+
ret += (int64_t)b->vec[i].coeffs[j] * b->vec[i].coeffs[j];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return ret;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/*************************************************
|
|
225
|
+
* Name: polyfixveclk_sample_hyperball
|
|
226
|
+
*
|
|
227
|
+
* Description: sample hyperball
|
|
228
|
+
*
|
|
229
|
+
* Arguments: - polyfixvecl *y1: polynomial vector with length HAETAE_L to
|
|
230
|
+
* calculate norm
|
|
231
|
+
* - polyfixveck *y2: polynomial vector with length HAETAE_K to
|
|
232
|
+
* calculate norm
|
|
233
|
+
* - uint8_t *b: output byte
|
|
234
|
+
* - uint8_t seed[HAETAE_CRHBYTES]: input seed bytes
|
|
235
|
+
* - const uint16_t nonce: input nonce
|
|
236
|
+
*
|
|
237
|
+
* Specification: Implements Algorithm 11, SampleHyperBall.
|
|
238
|
+
**************************************************/
|
|
239
|
+
uint16_t polyfixveclk_sample_hyperball(polyfixvecl *y1, polyfixveck *y2,
|
|
240
|
+
uint8_t *b,
|
|
241
|
+
const uint8_t seed[HAETAE_CRHBYTES],
|
|
242
|
+
const uint16_t nonce) {
|
|
243
|
+
uint16_t ni = nonce;
|
|
244
|
+
uint64_t samples[HAETAE_N * (HAETAE_L + HAETAE_K)];
|
|
245
|
+
fp96_76 sqsum, invsqrt;
|
|
246
|
+
unsigned int i, j;
|
|
247
|
+
uint8_t signs[HAETAE_N * (HAETAE_L + HAETAE_K) / 8];
|
|
248
|
+
|
|
249
|
+
do {
|
|
250
|
+
sqsum.limb48[0] = 0;
|
|
251
|
+
sqsum.limb48[1] = 0;
|
|
252
|
+
|
|
253
|
+
sample_gauss_N(&samples[0], &signs[0], &sqsum, seed, ni++, HAETAE_N + 1);
|
|
254
|
+
sample_gauss_N(&samples[HAETAE_N], &signs[HAETAE_N / 8], &sqsum, seed, ni++,
|
|
255
|
+
HAETAE_N + 1);
|
|
256
|
+
|
|
257
|
+
for (i = 2; i < HAETAE_L + HAETAE_K; i++)
|
|
258
|
+
sample_gauss_N(&samples[HAETAE_N * i], &signs[HAETAE_N / 8 * i], &sqsum,
|
|
259
|
+
seed, ni++, HAETAE_N);
|
|
260
|
+
|
|
261
|
+
// divide sqsum by 2 and approximate inverse square root
|
|
262
|
+
sqsum.limb48[0] += 1; // rounding
|
|
263
|
+
sqsum.limb48[0] >>= 1;
|
|
264
|
+
sqsum.limb48[0] += (sqsum.limb48[1] & 1) << 47;
|
|
265
|
+
sqsum.limb48[1] >>= 1;
|
|
266
|
+
sqsum.limb48[1] += sqsum.limb48[0] >> 48;
|
|
267
|
+
sqsum.limb48[0] &= (1ULL << 48) - 1;
|
|
268
|
+
fixpoint_newton_invsqrt(&invsqrt, &sqsum);
|
|
269
|
+
fixpoint_mul_high(&sqsum, &invsqrt,
|
|
270
|
+
(uint64_t)(HAETAE_B0 * HAETAE_LN + HAETAE_SQNM / 2)
|
|
271
|
+
<< (28 - 13));
|
|
272
|
+
|
|
273
|
+
for (i = 0; i < HAETAE_L; i++) {
|
|
274
|
+
for (j = 0; j < HAETAE_N; j++)
|
|
275
|
+
y1->vec[i].coeffs[j] = fixpoint_mul_rnd13(
|
|
276
|
+
samples[(i * HAETAE_N + j)], &sqsum,
|
|
277
|
+
(signs[(i * HAETAE_N + j) / 8] >> ((i * HAETAE_N + j) % 8)) & 1);
|
|
278
|
+
}
|
|
279
|
+
for (i = HAETAE_L; i < HAETAE_K + HAETAE_L; i++) {
|
|
280
|
+
for (j = 0; j < HAETAE_N; j++)
|
|
281
|
+
y2->vec[i - HAETAE_L].coeffs[j] = fixpoint_mul_rnd13(
|
|
282
|
+
samples[(i * HAETAE_N + j)], &sqsum,
|
|
283
|
+
(signs[(i * HAETAE_N + j) / 8] >> ((i * HAETAE_N + j) % 8)) & 1);
|
|
284
|
+
}
|
|
285
|
+
} while (polyfixveclk_sqnorm2(y1, y2) > HAETAE_B0SQ * HAETAE_LN * HAETAE_LN);
|
|
286
|
+
|
|
287
|
+
{
|
|
288
|
+
uint8_t tmp[HAETAE_CRHBYTES + 2];
|
|
289
|
+
for (i = 0; i < HAETAE_CRHBYTES; i++) {
|
|
290
|
+
tmp[i] = seed[i];
|
|
291
|
+
}
|
|
292
|
+
tmp[HAETAE_CRHBYTES + 0] = ni >> 0;
|
|
293
|
+
tmp[HAETAE_CRHBYTES + 1] = ni >> 8;
|
|
294
|
+
shake256(b, 1, tmp, HAETAE_CRHBYTES + 2);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return ni;
|
|
298
|
+
}
|