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,82 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "polymat.h"
|
|
4
|
+
#include "params.h"
|
|
5
|
+
#include "poly.h"
|
|
6
|
+
#include "polyvec.h"
|
|
7
|
+
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
|
|
10
|
+
/*************************************************
|
|
11
|
+
* Name: polymatkl_expand_matA
|
|
12
|
+
*
|
|
13
|
+
* Description: Implementation of ExpandA. Generates matrix A with uniformly
|
|
14
|
+
* random coefficients a_{i,j} by performing rejection
|
|
15
|
+
* sampling on the output stream of SHAKE128(rho|j|i)
|
|
16
|
+
* or AES256CTR(rho,j|i).
|
|
17
|
+
*
|
|
18
|
+
* Arguments: - polyvecm mat[HAETAE_K]: output matrix k \times m
|
|
19
|
+
* - const uint8_t rho[]: byte array containing seed rho
|
|
20
|
+
*
|
|
21
|
+
* Specification: Implements Algorithm 4, ExpandMatA.
|
|
22
|
+
**************************************************/
|
|
23
|
+
void polymatkl_expand_matA(polyvecl mat[HAETAE_K],
|
|
24
|
+
const uint8_t rho[HAETAE_SEEDBYTES]) {
|
|
25
|
+
unsigned int i, j;
|
|
26
|
+
|
|
27
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
28
|
+
for (j = 0; j < HAETAE_M; ++j)
|
|
29
|
+
poly_uniform(&mat[i].vec[j + 1], rho, (i << 8) + j);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/*************************************************
|
|
33
|
+
* Name: polymatkm_expand_matA
|
|
34
|
+
*
|
|
35
|
+
* Description: Implementation of ExpandA. Generates matrix A with uniformly
|
|
36
|
+
* random coefficients a_{i,j} by performing rejection
|
|
37
|
+
* sampling on the output stream of SHAKE128(rho|j|i)
|
|
38
|
+
* or AES256CTR(rho,j|i).
|
|
39
|
+
*
|
|
40
|
+
* Arguments: - polyvecm mat[HAETAE_K]: output matrix k \times m
|
|
41
|
+
* - const uint8_t rho[]: byte array containing seed rho
|
|
42
|
+
*
|
|
43
|
+
* Specification: Implements Algorithm 4, ExpandMatA.
|
|
44
|
+
**************************************************/
|
|
45
|
+
void polymatkm_expand_matA(polyvecm mat[HAETAE_K],
|
|
46
|
+
const uint8_t rho[HAETAE_SEEDBYTES]) {
|
|
47
|
+
unsigned int i, j;
|
|
48
|
+
|
|
49
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
50
|
+
for (j = 0; j < HAETAE_M; ++j)
|
|
51
|
+
poly_uniform(&mat[i].vec[j], rho, (i << 8) + j);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// doubles k * m sub-matrix of k * l mat
|
|
55
|
+
void polymatkl_double(polyvecl mat[HAETAE_K]) {
|
|
56
|
+
unsigned int i, j, k;
|
|
57
|
+
for (i = 0; i < HAETAE_K; ++i) {
|
|
58
|
+
for (j = 1; j < HAETAE_L; ++j) {
|
|
59
|
+
for (k = 0; k < HAETAE_N; ++k) {
|
|
60
|
+
mat[i].vec[j].coeffs[k] *= 2;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void polymatkl_pointwise_montgomery(polyveck *t, const polyvecl mat[HAETAE_K],
|
|
67
|
+
const polyvecl *v) {
|
|
68
|
+
unsigned int i;
|
|
69
|
+
|
|
70
|
+
for (i = 0; i < HAETAE_K; ++i) {
|
|
71
|
+
polyvecl_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void polymatkm_pointwise_montgomery(polyveck *t, const polyvecm mat[HAETAE_K],
|
|
76
|
+
const polyvecm *v) {
|
|
77
|
+
unsigned int i;
|
|
78
|
+
|
|
79
|
+
for (i = 0; i < HAETAE_K; ++i) {
|
|
80
|
+
polyvecm_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "polyvec.h"
|
|
4
|
+
#include "decompose.h"
|
|
5
|
+
#include "fft.h"
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "poly.h"
|
|
8
|
+
#include "reduce.h"
|
|
9
|
+
|
|
10
|
+
#include <stddef.h>
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
|
|
13
|
+
/*************************************************
|
|
14
|
+
* Name: polyveck_add
|
|
15
|
+
*
|
|
16
|
+
* Description: Add vectors of polynomials of length HAETAE_K.
|
|
17
|
+
* No modular reduction is performed.
|
|
18
|
+
*
|
|
19
|
+
* Arguments: - polyveck *w: pointer to output vector
|
|
20
|
+
* - const polyveck *u: pointer to first summand
|
|
21
|
+
* - const polyveck *v: pointer to second summand
|
|
22
|
+
**************************************************/
|
|
23
|
+
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
|
|
24
|
+
unsigned int i;
|
|
25
|
+
|
|
26
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
27
|
+
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*************************************************
|
|
31
|
+
* Name: polyveck_sub
|
|
32
|
+
*
|
|
33
|
+
* Description: Subtract vectors of polynomials of length HAETAE_K.
|
|
34
|
+
* No modular reduction is performed.
|
|
35
|
+
*
|
|
36
|
+
* Arguments: - polyveck *w: pointer to output vector
|
|
37
|
+
* - const polyveck *u: pointer to first input vector
|
|
38
|
+
* - const polyveck *v: pointer to second input vector to be
|
|
39
|
+
* subtracted from first input vector
|
|
40
|
+
**************************************************/
|
|
41
|
+
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
|
|
42
|
+
unsigned int i;
|
|
43
|
+
|
|
44
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
45
|
+
poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/*************************************************
|
|
49
|
+
* Name: polyveck_double
|
|
50
|
+
*
|
|
51
|
+
* Description: Double vector of polynomials of length HAETAE_K.
|
|
52
|
+
* No modular reduction is performed.
|
|
53
|
+
*
|
|
54
|
+
* Arguments: - polyveck *w: pointer to output vector
|
|
55
|
+
**************************************************/
|
|
56
|
+
void polyveck_double(polyveck *b) {
|
|
57
|
+
unsigned int i, j;
|
|
58
|
+
|
|
59
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
60
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
61
|
+
b->vec[i].coeffs[j] *= 2;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*************************************************
|
|
65
|
+
* Name: polyveck_reduce2q
|
|
66
|
+
*
|
|
67
|
+
* Description: Reduce coefficients to 2q
|
|
68
|
+
*
|
|
69
|
+
* Arguments: - polyveck *v: pointer to input/output vector
|
|
70
|
+
**************************************************/
|
|
71
|
+
void polyveck_reduce2q(polyveck *v) {
|
|
72
|
+
unsigned int i;
|
|
73
|
+
|
|
74
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
75
|
+
poly_reduce2q(&v->vec[i]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/*************************************************
|
|
79
|
+
* Name: polyveck_freeze
|
|
80
|
+
*
|
|
81
|
+
* Description: For all coefficients of polynomials in vector of length HAETAE_K
|
|
82
|
+
* compute standard representative r = a mod^+ HAETAE_Q.
|
|
83
|
+
*
|
|
84
|
+
* Arguments: - polyveck *v: pointer to input/output vector
|
|
85
|
+
**************************************************/
|
|
86
|
+
void polyveck_freeze(polyveck *v) {
|
|
87
|
+
unsigned int i;
|
|
88
|
+
|
|
89
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
90
|
+
poly_freeze(&v->vec[i]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*************************************************
|
|
94
|
+
* Name: polyveck_freeze2q
|
|
95
|
+
*
|
|
96
|
+
* Description: For all coefficients of polynomials in vector of length HAETAE_K
|
|
97
|
+
* compute standard representative r = a mod^+ 2Q.
|
|
98
|
+
*
|
|
99
|
+
* Arguments: - polyveck *v: pointer to input/output vector
|
|
100
|
+
**************************************************/
|
|
101
|
+
void polyveck_freeze2q(polyveck *v) {
|
|
102
|
+
unsigned int i;
|
|
103
|
+
|
|
104
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
105
|
+
poly_freeze2q(&v->vec[i]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*************************************************
|
|
109
|
+
* Name: polyveck_expand_vecA
|
|
110
|
+
*
|
|
111
|
+
* Description: Sample a vector of polynomials with uniformly random
|
|
112
|
+
* coefficients in Zq by rejection sampling on the
|
|
113
|
+
* output stream from SHAKE128(seed|nonce)
|
|
114
|
+
*
|
|
115
|
+
* Arguments: - polyveck *v: pointer to output a vector of polynomials of
|
|
116
|
+
* length HAETAE_K
|
|
117
|
+
* - const uint8_t seed[]: byte array with seed of length
|
|
118
|
+
* HAETAE_SEEDBYTES
|
|
119
|
+
*
|
|
120
|
+
* Specification: Implements Algorithm 5, ExpandVec_a.
|
|
121
|
+
**************************************************/
|
|
122
|
+
void polyveck_expand_vecA(polyveck *v, const uint8_t seed[HAETAE_SEEDBYTES]) {
|
|
123
|
+
unsigned int i, nonce = (HAETAE_K << 8) + HAETAE_M;
|
|
124
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
125
|
+
poly_uniform(&v->vec[i], seed, nonce++);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/*************************************************
|
|
129
|
+
* Name: polyvecmk_expand_S
|
|
130
|
+
*
|
|
131
|
+
* Description: Sample a vector of polynomials with uniformly random
|
|
132
|
+
* coefficients in [-ETA,ETA] by rejection sampling on the
|
|
133
|
+
* output stream from SHAKE256(seed|nonce)
|
|
134
|
+
*
|
|
135
|
+
* Arguments: - polyveck *v: pointer to output a vector of polynomials of
|
|
136
|
+
* length HAETAE_K
|
|
137
|
+
* - const uint8_t seed[]: byte array with seed of length
|
|
138
|
+
* HAETAE_CRHBYTES
|
|
139
|
+
* - uint16_t nonce: 2-byte nonce
|
|
140
|
+
*
|
|
141
|
+
* Specification: Implements Algorithm 8, ExpandS.
|
|
142
|
+
**************************************************/
|
|
143
|
+
void polyvecmk_expand_S(polyvecm *u, polyveck *v,
|
|
144
|
+
const uint8_t seed[HAETAE_CRHBYTES], uint16_t nonce) {
|
|
145
|
+
unsigned int i, n = nonce;
|
|
146
|
+
for (i = 0; i < HAETAE_M; i++)
|
|
147
|
+
poly_uniform_eta(&u->vec[i], seed, n++);
|
|
148
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
149
|
+
poly_uniform_eta(&v->vec[i], seed, n++);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/*************************************************
|
|
153
|
+
* Name: polyveck_double_negate
|
|
154
|
+
*
|
|
155
|
+
* Description: multiply each coefficient with -2
|
|
156
|
+
*
|
|
157
|
+
* Arguments: - polyveck *v: pointer to output vector of polynomials of
|
|
158
|
+
* length HAETAE_K
|
|
159
|
+
**************************************************/
|
|
160
|
+
void polyveck_double_negate(polyveck *v) {
|
|
161
|
+
unsigned int i, j;
|
|
162
|
+
|
|
163
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
164
|
+
for (j = 0; j < HAETAE_N; j++)
|
|
165
|
+
v->vec[i].coeffs[j] =
|
|
166
|
+
montgomery_reduce((int64_t)v->vec[i].coeffs[j] * MONT * -2);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/*************************************************
|
|
170
|
+
* Name: polyveck_frommont
|
|
171
|
+
*
|
|
172
|
+
* Description: multiply each coefficient with MONT
|
|
173
|
+
*
|
|
174
|
+
* Arguments: - polyveck *v: pointer to output vector of polynomials of
|
|
175
|
+
* length HAETAE_K
|
|
176
|
+
**************************************************/
|
|
177
|
+
void polyveck_frommont(polyveck *v) {
|
|
178
|
+
unsigned int i, j;
|
|
179
|
+
|
|
180
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
181
|
+
for (j = 0; j < HAETAE_N; j++)
|
|
182
|
+
v->vec[i].coeffs[j] =
|
|
183
|
+
montgomery_reduce((int64_t)v->vec[i].coeffs[j] * MONTSQ);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void polyveck_poly_pointwise_montgomery(polyveck *w, const polyveck *u,
|
|
187
|
+
const poly *v) {
|
|
188
|
+
unsigned int i;
|
|
189
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
190
|
+
poly_pointwise_montgomery(&w->vec[i], &u->vec[i], v);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*************************************************
|
|
195
|
+
* Name: polyveck_poly_fromcrt
|
|
196
|
+
*
|
|
197
|
+
* Description: recover polynomials from CRT domain, where all "mod q"
|
|
198
|
+
* polynomials are known and only the uppermost "mod 2" polynomial
|
|
199
|
+
* is non-zero
|
|
200
|
+
*
|
|
201
|
+
* Arguments: - polyveck *w: pointer to output vector of polynomials of
|
|
202
|
+
* length HAETAE_K
|
|
203
|
+
* - const polyveck *u: pointer to the input vector of polynomials
|
|
204
|
+
* of length HAETAE_K
|
|
205
|
+
* - const poly *v: pointer to the input polynomial ("mod 2")
|
|
206
|
+
**************************************************/
|
|
207
|
+
void polyveck_poly_fromcrt(polyveck *w, const polyveck *u, const poly *v) {
|
|
208
|
+
unsigned int i;
|
|
209
|
+
|
|
210
|
+
poly_fromcrt(&w->vec[0], &u->vec[0], v);
|
|
211
|
+
|
|
212
|
+
for (i = 1; i < HAETAE_K; i++) {
|
|
213
|
+
poly_fromcrt0(&w->vec[i], &u->vec[i]);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
void polyveck_highbits_hint(polyveck *w, const polyveck *v) {
|
|
218
|
+
unsigned int i, j;
|
|
219
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
220
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
221
|
+
decompose_hint(&w->vec[i].coeffs[j], v->vec[i].coeffs[j]);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
void polyveck_cneg(polyveck *v, const uint8_t b) {
|
|
227
|
+
unsigned int i, j;
|
|
228
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
229
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
230
|
+
v->vec[i].coeffs[j] *= 1 - 2 * b;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
void polyveck_caddDQ2ALPHA(polyveck *h) {
|
|
236
|
+
unsigned int i, j;
|
|
237
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
238
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
239
|
+
h->vec[i].coeffs[j] +=
|
|
240
|
+
(h->vec[i].coeffs[j] >> 31) & ((HAETAE_DQ - 2) / HAETAE_ALPHA_HINT);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void polyveck_csubDQ2ALPHA(polyveck *v) {
|
|
246
|
+
unsigned int i, j;
|
|
247
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
248
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
249
|
+
v->vec[i].coeffs[j] -=
|
|
250
|
+
~((v->vec[i].coeffs[j] - (HAETAE_DQ - 2) / HAETAE_ALPHA_HINT) >> 31) &
|
|
251
|
+
((HAETAE_DQ - 2) / HAETAE_ALPHA_HINT);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
void polyveck_mul_alpha(polyveck *v, const polyveck *u) {
|
|
257
|
+
unsigned int i, j;
|
|
258
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
259
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
260
|
+
v->vec[i].coeffs[j] = u->vec[i].coeffs[j] * HAETAE_ALPHA_HINT;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void polyveck_div2(polyveck *v) {
|
|
266
|
+
unsigned i, j;
|
|
267
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
268
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
269
|
+
v->vec[i].coeffs[j] >>= 1;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
void polyveck_caddq(polyveck *v) {
|
|
273
|
+
unsigned i, j;
|
|
274
|
+
for (i = 0; i < HAETAE_K; ++i)
|
|
275
|
+
for (j = 0; j < HAETAE_N; ++j)
|
|
276
|
+
v->vec[i].coeffs[j] = caddq(v->vec[i].coeffs[j]);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
void polyveck_decompose_vk(polyveck *v0, polyveck *v) {
|
|
280
|
+
for (int i = 0; i < HAETAE_K; i++) {
|
|
281
|
+
for (int j = 0; j < HAETAE_N; j++) {
|
|
282
|
+
v->vec[i].coeffs[j] =
|
|
283
|
+
decompose_vk(&v0->vec[i].coeffs[j], v->vec[i].coeffs[j]);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void polyveck_ntt(polyveck *x) {
|
|
289
|
+
unsigned int i;
|
|
290
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
291
|
+
poly_ntt(&x->vec[i]);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
void polyveck_invntt_tomont(polyveck *x) {
|
|
296
|
+
unsigned int i;
|
|
297
|
+
for (i = 0; i < HAETAE_K; i++) {
|
|
298
|
+
poly_invntt_tomont(&x->vec[i]);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/*************************************************
|
|
303
|
+
* Name: polyveck_sqnorm2
|
|
304
|
+
*
|
|
305
|
+
* Description: Calculates L2 norm of a polynomial vector with length k
|
|
306
|
+
*
|
|
307
|
+
* Arguments: - polyveck *b: polynomial vector with length k to calculate
|
|
308
|
+
* norm
|
|
309
|
+
**************************************************/
|
|
310
|
+
uint64_t polyveck_sqnorm2(const polyveck *b) {
|
|
311
|
+
unsigned int i, j;
|
|
312
|
+
uint64_t ret = 0;
|
|
313
|
+
|
|
314
|
+
for (i = 0; i < HAETAE_K; ++i) {
|
|
315
|
+
for (j = 0; j < HAETAE_N; ++j) {
|
|
316
|
+
ret += (uint64_t)b->vec[i].coeffs[j] * b->vec[i].coeffs[j];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return ret;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/*************************************************
|
|
323
|
+
* Name: polyvecl_highbits
|
|
324
|
+
*
|
|
325
|
+
* Description: Compute HighBits of a vector of polynomials
|
|
326
|
+
*
|
|
327
|
+
* Arguments: - polyvecl *v2: pointer to output vector of polynomials of
|
|
328
|
+
* length L
|
|
329
|
+
* - const polyvecl *v: pointer to input vector of polynomials of
|
|
330
|
+
* length L
|
|
331
|
+
**************************************************/
|
|
332
|
+
void polyvecl_highbits(polyvecl *v2, const polyvecl *v) {
|
|
333
|
+
unsigned int i;
|
|
334
|
+
|
|
335
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
336
|
+
poly_highbits(&v2->vec[i], &v->vec[i]);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/*************************************************
|
|
340
|
+
* Name: polyvecl_lowbits
|
|
341
|
+
*
|
|
342
|
+
* Description: Compute LowBits of a vector of polynomials
|
|
343
|
+
*
|
|
344
|
+
* Arguments: - polyvecl *v1: pointer to output vector of polynomials of
|
|
345
|
+
* length L
|
|
346
|
+
* - const polyvecl *v: pointer to input vector of polynomials of
|
|
347
|
+
* length L
|
|
348
|
+
**************************************************/
|
|
349
|
+
void polyvecl_lowbits(polyvecl *v1, const polyvecl *v) {
|
|
350
|
+
unsigned int i;
|
|
351
|
+
|
|
352
|
+
for (i = 0; i < HAETAE_L; ++i)
|
|
353
|
+
poly_lowbits(&v1->vec[i], &v->vec[i]);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
void polyvecl_cneg(polyvecl *v, const uint8_t b) {
|
|
357
|
+
unsigned int i, j;
|
|
358
|
+
for (i = 0; i < HAETAE_L; i++) {
|
|
359
|
+
for (j = 0; j < HAETAE_N; j++) {
|
|
360
|
+
v->vec[i].coeffs[j] *= 1 - 2 * b;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/*************************************************
|
|
366
|
+
* Name: polyvecl_sqnorm2
|
|
367
|
+
*
|
|
368
|
+
* Description: Calculates L2 norm of a polynomial vector with length l
|
|
369
|
+
*
|
|
370
|
+
* Arguments: - polyvecl *a: polynomial vector with length l to calculate
|
|
371
|
+
* norm
|
|
372
|
+
**************************************************/
|
|
373
|
+
uint64_t polyvecl_sqnorm2(const polyvecl *a) {
|
|
374
|
+
unsigned int i, j;
|
|
375
|
+
uint64_t ret = 0;
|
|
376
|
+
|
|
377
|
+
for (i = 0; i < HAETAE_L; ++i) {
|
|
378
|
+
for (j = 0; j < HAETAE_N; ++j) {
|
|
379
|
+
ret += (uint64_t)a->vec[i].coeffs[j] * a->vec[i].coeffs[j];
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return ret;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/*************************************************
|
|
387
|
+
* Name: polyvecl_pointwise_acc_montgomery
|
|
388
|
+
*
|
|
389
|
+
* Description: Pointwise multiply vectors of polynomials of length L, multiply
|
|
390
|
+
* resulting vector by 2^{-32} and add (accumulate) polynomials
|
|
391
|
+
* in it. Input/output vectors are in NTT domain representation.
|
|
392
|
+
*
|
|
393
|
+
* Arguments: - poly *w: output polynomial
|
|
394
|
+
* - const polyvecl *u: pointer to first input vector
|
|
395
|
+
* - const polyvecl *v: pointer to second input vector
|
|
396
|
+
**************************************************/
|
|
397
|
+
void polyvecl_pointwise_acc_montgomery(poly *w, const polyvecl *u,
|
|
398
|
+
const polyvecl *v) {
|
|
399
|
+
unsigned int i;
|
|
400
|
+
poly t;
|
|
401
|
+
|
|
402
|
+
poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
|
|
403
|
+
for (i = 1; i < HAETAE_L; ++i) {
|
|
404
|
+
poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
|
|
405
|
+
poly_add(w, w, &t);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
void polyvecl_ntt(polyvecl *x) {
|
|
410
|
+
unsigned int i;
|
|
411
|
+
for (i = 0; i < HAETAE_L; i++) {
|
|
412
|
+
poly_ntt(&x->vec[i]);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/*************************************************
|
|
417
|
+
* Name: polyvecm_pointwise_acc_montgomery
|
|
418
|
+
*
|
|
419
|
+
* Description: Pointwise multiply vectors of polynomials of length L, multiply
|
|
420
|
+
* resulting vector by 2^{-32} and add (accumulate) polynomials
|
|
421
|
+
* in it. Input/output vectors are in NTT domain representation.
|
|
422
|
+
*
|
|
423
|
+
* Arguments: - poly *w: output polynomial
|
|
424
|
+
* - const polyvecm *u: pointer to first input vector
|
|
425
|
+
* - const polyvecm *v: pointer to second input vector
|
|
426
|
+
**************************************************/
|
|
427
|
+
void polyvecm_pointwise_acc_montgomery(poly *w, const polyvecm *u,
|
|
428
|
+
const polyvecm *v) {
|
|
429
|
+
unsigned int i;
|
|
430
|
+
poly t;
|
|
431
|
+
|
|
432
|
+
poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
|
|
433
|
+
for (i = 1; i < HAETAE_M; ++i) {
|
|
434
|
+
poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
|
|
435
|
+
poly_add(w, w, &t);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
void polyvecm_ntt(polyvecm *x) {
|
|
440
|
+
unsigned int i;
|
|
441
|
+
for (i = 0; i < HAETAE_M; i++) {
|
|
442
|
+
poly_ntt(&x->vec[i]);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/*************************************************
|
|
447
|
+
* Name: minmax
|
|
448
|
+
*
|
|
449
|
+
* Description: compare and swap two integers
|
|
450
|
+
*
|
|
451
|
+
* Arguments: - int32_t *x: pointer to first input/output integer
|
|
452
|
+
* - int32_t *y: pointer to second input/output integer
|
|
453
|
+
*
|
|
454
|
+
* Specification: Implements Algorithm 44, minmax.
|
|
455
|
+
* **************************************************/
|
|
456
|
+
static inline void minmax(int32_t *x, int32_t *y) // taken from djbsort
|
|
457
|
+
{
|
|
458
|
+
int32_t a = *x;
|
|
459
|
+
int32_t b = *y;
|
|
460
|
+
int32_t ab = b ^ a;
|
|
461
|
+
int32_t c = b - a;
|
|
462
|
+
c ^= ab & (c ^ b);
|
|
463
|
+
c >>= 31;
|
|
464
|
+
c &= ab;
|
|
465
|
+
*x = a ^ c;
|
|
466
|
+
*y = b ^ c;
|
|
467
|
+
}
|
|
468
|
+
/*************************************************
|
|
469
|
+
* Name: polyvecmk_sk_singular_value
|
|
470
|
+
*
|
|
471
|
+
* Description: calculate singular value of signing key
|
|
472
|
+
*
|
|
473
|
+
* Arguments: - const polyvecm *s1: pointer to first input vector
|
|
474
|
+
* - const polyveck *s2: pointer to second input vector
|
|
475
|
+
*
|
|
476
|
+
* Returns:
|
|
477
|
+
*
|
|
478
|
+
* Specification: Implements Algorithm 42, skSingularValue.
|
|
479
|
+
**************************************************/
|
|
480
|
+
int64_t polyvecmk_sk_singular_value(const polyvecm *s1, const polyveck *s2) {
|
|
481
|
+
int32_t res = 0;
|
|
482
|
+
complex_fp32_16 input[FFT_N] = {0};
|
|
483
|
+
int32_t sum[HAETAE_N] = {0}, bestm[HAETAE_N / HAETAE_TAU + 1] = {0}, min = 0;
|
|
484
|
+
|
|
485
|
+
for (size_t i = 0; i < HAETAE_M; ++i) {
|
|
486
|
+
fft_init_and_bitrev(input, &s1->vec[i]);
|
|
487
|
+
fft(input);
|
|
488
|
+
// cumulative sum
|
|
489
|
+
for (size_t j = 0; j < HAETAE_N; j++) {
|
|
490
|
+
sum[j] += complex_fp_sqabs(input[j]);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
for (size_t i = 0; i < HAETAE_K; ++i) {
|
|
495
|
+
fft_init_and_bitrev(input, &s2->vec[i]);
|
|
496
|
+
fft(input);
|
|
497
|
+
|
|
498
|
+
// cumulative sum
|
|
499
|
+
for (size_t j = 0; j < HAETAE_N; j++) {
|
|
500
|
+
sum[j] += complex_fp_sqabs(input[j]);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// compute max m
|
|
505
|
+
for (size_t i = 0; i < HAETAE_N / HAETAE_TAU + 1; ++i) {
|
|
506
|
+
bestm[i] = sum[i];
|
|
507
|
+
}
|
|
508
|
+
for (size_t i = HAETAE_N / HAETAE_TAU + 1; i < HAETAE_N; i++) {
|
|
509
|
+
for (size_t j = 0; j < HAETAE_N / HAETAE_TAU + 1; j++) {
|
|
510
|
+
minmax(&sum[i], &bestm[j]);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// find minimum in bestm
|
|
514
|
+
min = bestm[0];
|
|
515
|
+
for (size_t i = 1; i < HAETAE_N / HAETAE_TAU + 1; i++) {
|
|
516
|
+
int32_t tmp = bestm[i];
|
|
517
|
+
minmax(&min, &tmp);
|
|
518
|
+
}
|
|
519
|
+
// multiply all but the minimum by HAETAE_N mod HAETAE_TAU
|
|
520
|
+
for (size_t i = 0; i < HAETAE_N / HAETAE_TAU + 1; i++) {
|
|
521
|
+
int32_t fac =
|
|
522
|
+
((min - bestm[i]) >>
|
|
523
|
+
31); // all-ones if bestm[i] != min
|
|
524
|
+
fac = (fac & (HAETAE_TAU)) ^
|
|
525
|
+
((~fac) & (HAETAE_N % HAETAE_TAU)); // fac = HAETAE_TAU for all != min
|
|
526
|
+
// and N%HAETAE_TAU for min
|
|
527
|
+
bestm[i] += 0x10200; // add 1 for the "1 poly" in S, and prepare rounding
|
|
528
|
+
bestm[i] >>= 10; // round off 10 bits
|
|
529
|
+
bestm[i] *= fac;
|
|
530
|
+
res += bestm[i];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return (res + (1 << 5)) >> 6; // return rounded, squared value
|
|
534
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include "reduce.h"
|
|
4
|
+
#include "params.h"
|
|
5
|
+
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
|
|
8
|
+
/*************************************************
|
|
9
|
+
* Name: montgomery_reduce
|
|
10
|
+
*
|
|
11
|
+
* Description: For finite field element a with -2^{31}Q <= a <= HAETAE_Q*2^31,
|
|
12
|
+
* compute r \equiv a*2^{-32} (mod HAETAE_Q) such that -HAETAE_Q <
|
|
13
|
+
* r < HAETAE_Q.
|
|
14
|
+
*
|
|
15
|
+
* Arguments: - int64_t: finite field element a
|
|
16
|
+
*
|
|
17
|
+
* Returns r.
|
|
18
|
+
**************************************************/
|
|
19
|
+
int32_t montgomery_reduce(int64_t a) {
|
|
20
|
+
int32_t t;
|
|
21
|
+
|
|
22
|
+
t = (int64_t)(int32_t)a * QINV;
|
|
23
|
+
t = (a - (int64_t)t * HAETAE_Q) >> 32;
|
|
24
|
+
return t;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/*************************************************
|
|
28
|
+
* Name: caddq
|
|
29
|
+
*
|
|
30
|
+
* Description: Add HAETAE_Q if input coefficient is negative.
|
|
31
|
+
*
|
|
32
|
+
* Arguments: - int32_t: finite field element a
|
|
33
|
+
*
|
|
34
|
+
* Returns r.
|
|
35
|
+
**************************************************/
|
|
36
|
+
int32_t caddq(int32_t a) {
|
|
37
|
+
a += (a >> 31) & HAETAE_Q;
|
|
38
|
+
return a;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*************************************************
|
|
42
|
+
* Name: freeze
|
|
43
|
+
*
|
|
44
|
+
* Description: For finite field element a, compute standard
|
|
45
|
+
* representative r = a mod^+ HAETAE_Q.
|
|
46
|
+
*
|
|
47
|
+
* Arguments: - int32_t: finite field element a
|
|
48
|
+
*
|
|
49
|
+
* Returns r.
|
|
50
|
+
**************************************************/
|
|
51
|
+
int32_t freeze(int32_t a) {
|
|
52
|
+
int64_t t = (int64_t)a * QREC;
|
|
53
|
+
t = t >> 32;
|
|
54
|
+
t = a - t * HAETAE_Q; // -2Q < t < 2Q
|
|
55
|
+
t += (t >> 31) & HAETAE_DQ; // 0 <= t < 2Q
|
|
56
|
+
t -= ~((t - HAETAE_Q) >> 31) & HAETAE_Q; // 0 <= t < HAETAE_Q
|
|
57
|
+
return t;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*************************************************
|
|
61
|
+
* Name: reduce32_2q
|
|
62
|
+
*
|
|
63
|
+
* Description: compute reduction with 2Q
|
|
64
|
+
*
|
|
65
|
+
* Arguments: - int32_t: finite field element a
|
|
66
|
+
*
|
|
67
|
+
* Returns r.
|
|
68
|
+
**************************************************/
|
|
69
|
+
int32_t reduce32_2q(int32_t a) {
|
|
70
|
+
int64_t t = (int64_t)a * DQREC;
|
|
71
|
+
t >>= 32;
|
|
72
|
+
t = a - t * HAETAE_DQ; // -4Q < t < 4Q
|
|
73
|
+
t += (t >> 31) & (HAETAE_DQ * 2); // 0 <= t < 4Q
|
|
74
|
+
t -= ~((t - HAETAE_DQ) >> 31) & HAETAE_DQ; // 0 <= t < HAETAE_Q
|
|
75
|
+
t -= ~((t - HAETAE_Q) >> 31) & HAETAE_DQ; // centered representation
|
|
76
|
+
return (int32_t)t;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/*************************************************
|
|
80
|
+
* Name: freeze2q
|
|
81
|
+
*
|
|
82
|
+
* Description: For finite field element a, compute standard
|
|
83
|
+
* representative r = a mod^+ 2Q.
|
|
84
|
+
*
|
|
85
|
+
* Arguments: - int32_t: finite field element a
|
|
86
|
+
*
|
|
87
|
+
* Returns r.
|
|
88
|
+
**************************************************/
|
|
89
|
+
int32_t freeze2q(int32_t a) {
|
|
90
|
+
int64_t t = (int64_t)a * DQREC;
|
|
91
|
+
t >>= 32;
|
|
92
|
+
t = a - t * HAETAE_DQ; // -4Q < t < 4Q
|
|
93
|
+
t += (t >> 31) & (HAETAE_DQ * 2); // 0 <= t < 4Q
|
|
94
|
+
t -= ~((t - HAETAE_DQ) >> 31) & HAETAE_DQ; // 0 <= t < HAETAE_Q
|
|
95
|
+
return (int32_t)t;
|
|
96
|
+
}
|