@pinkparrot/qsafe-mayo-wasm 0.0.3
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.
- package/.gitmodules +3 -0
- package/.vscode/launch.json +12 -0
- package/LICENSE +201 -0
- package/bridge/mayo1_bridge.c +26 -0
- package/bridge/mayo2_bridge.c +26 -0
- package/bridge/randombytes_inject.c +44 -0
- package/build_mayo1.ps1 +36 -0
- package/build_mayo2.ps1 +36 -0
- package/dist/mayo.browser.min.js +216 -0
- package/dist/mayo1.js +0 -0
- package/dist/mayo2.js +0 -0
- package/dist/mayo_api.js +139 -0
- package/dist/package.json +1 -0
- package/gitignore +2 -0
- package/index.mjs +1 -0
- package/mayo-c/.astylerc +16 -0
- package/mayo-c/.cmake/flags.cmake +45 -0
- package/mayo-c/.cmake/sanitizers.cmake +81 -0
- package/mayo-c/.cmake/target.cmake +71 -0
- package/mayo-c/.github/workflows/ci_clang.yml +61 -0
- package/mayo-c/.github/workflows/ci_gcc.yml +60 -0
- package/mayo-c/.github/workflows/cmake.yml +160 -0
- package/mayo-c/.github/workflows/macos_m1.yml +68 -0
- package/mayo-c/CMakeLists.txt +35 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.rsp +902 -0
- package/mayo-c/LICENSE +202 -0
- package/mayo-c/META/MAYO-1_META.yml +52 -0
- package/mayo-c/META/MAYO-2_META.yml +52 -0
- package/mayo-c/META/MAYO-3_META.yml +52 -0
- package/mayo-c/META/MAYO-5_META.yml +52 -0
- package/mayo-c/NOTICE +13 -0
- package/mayo-c/README.md +183 -0
- package/mayo-c/apps/CMakeLists.txt +31 -0
- package/mayo-c/apps/PQCgenKAT_sign.c +281 -0
- package/mayo-c/apps/example.c +151 -0
- package/mayo-c/apps/example_nistapi.c +124 -0
- package/mayo-c/include/mayo.h +442 -0
- package/mayo-c/include/mem.h +25 -0
- package/mayo-c/include/randombytes.h +31 -0
- package/mayo-c/scripts/contstants.py +141 -0
- package/mayo-c/scripts/find_irred_poly.sage +39 -0
- package/mayo-c/src/AVX2/arithmetic_common.h +159 -0
- package/mayo-c/src/AVX2/echelon_form.h +91 -0
- package/mayo-c/src/AVX2/echelon_form_loop.h +58 -0
- package/mayo-c/src/AVX2/shuffle_arithmetic.h +442 -0
- package/mayo-c/src/CMakeLists.txt +98 -0
- package/mayo-c/src/arithmetic.c +128 -0
- package/mayo-c/src/arithmetic.h +124 -0
- package/mayo-c/src/common/aes128ctr.c +293 -0
- package/mayo-c/src/common/aes_c.c +741 -0
- package/mayo-c/src/common/aes_ctr.h +32 -0
- package/mayo-c/src/common/aes_neon.c +201 -0
- package/mayo-c/src/common/debug_bench_tools.h +69 -0
- package/mayo-c/src/common/fips202.c +1093 -0
- package/mayo-c/src/common/fips202.h +12 -0
- package/mayo-c/src/common/mem.c +19 -0
- package/mayo-c/src/common/randombytes_ctrdrbg.c +141 -0
- package/mayo-c/src/common/randombytes_system.c +399 -0
- package/mayo-c/src/generic/arithmetic_dynamic.h +68 -0
- package/mayo-c/src/generic/arithmetic_fixed.h +84 -0
- package/mayo-c/src/generic/echelon_form.h +152 -0
- package/mayo-c/src/generic/ef_inner_loop.h +56 -0
- package/mayo-c/src/generic/generic_arithmetic.h +294 -0
- package/mayo-c/src/mayo.c +675 -0
- package/mayo-c/src/mayo_1/api.c +46 -0
- package/mayo-c/src/mayo_1/api.h +43 -0
- package/mayo-c/src/mayo_2/api.c +46 -0
- package/mayo-c/src/mayo_2/api.h +43 -0
- package/mayo-c/src/mayo_3/api.c +46 -0
- package/mayo-c/src/mayo_3/api.h +43 -0
- package/mayo-c/src/mayo_5/api.c +46 -0
- package/mayo-c/src/mayo_5/api.h +43 -0
- package/mayo-c/src/neon/arithmetic_common.h +132 -0
- package/mayo-c/src/neon/echelon_form.h +55 -0
- package/mayo-c/src/neon/echelon_form_loop.h +58 -0
- package/mayo-c/src/neon/shuffle_arithmetic.h +462 -0
- package/mayo-c/src/params.c +42 -0
- package/mayo-c/src/simple_arithmetic.h +138 -0
- package/mayo-c/test/CMakeLists.txt +51 -0
- package/mayo-c/test/bench.c +166 -0
- package/mayo-c/test/m1cycles.c +155 -0
- package/mayo-c/test/m1cycles.h +13 -0
- package/mayo-c/test/test_kat.c +271 -0
- package/mayo-c/test/test_mayo.c +139 -0
- package/mayo-c/test/test_sample_solution.c +75 -0
- package/mayo-c/test/test_various.c +680 -0
- package/package.json +39 -0
- package/publish.bat +22 -0
- package/readme.md +80 -0
- package/test/test.mjs +42 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
#ifndef SHUFFLE_ARITHMETIC_H
|
|
4
|
+
#define SHUFFLE_ARITHMETIC_H
|
|
5
|
+
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
#include <mayo.h>
|
|
8
|
+
#include <immintrin.h>
|
|
9
|
+
#include <arithmetic_common.h>
|
|
10
|
+
#include <arithmetic_fixed.h>
|
|
11
|
+
|
|
12
|
+
//#define TICTOC
|
|
13
|
+
//#include <debug_bench_tools.h>
|
|
14
|
+
|
|
15
|
+
#define O_AVX_ROUND_UP ((O_MAX + 1)/2*2)
|
|
16
|
+
|
|
17
|
+
#define AVX_REGISTER_PER_M_VEC ((M_MAX + 63)/64)
|
|
18
|
+
|
|
19
|
+
#if M_MAX <= 64
|
|
20
|
+
// Multiply an m_vec with a vec of "Len" scalars, and accumulate in temp
|
|
21
|
+
#define MULTIPLY_ACCUMULATE_M_VEC(vec, multabs, Len) \
|
|
22
|
+
__m256i in_odd = _mm256_loadu_si256((__m256i *) (vec)); \
|
|
23
|
+
__m256i in_even = _mm256_srli_epi16(in_odd, 4) & low_nibble_mask; \
|
|
24
|
+
in_odd &= low_nibble_mask; \
|
|
25
|
+
for (size_t k = 0; k < Len; k+=2) \
|
|
26
|
+
{ \
|
|
27
|
+
temp[k] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd); \
|
|
28
|
+
temp[k + 1] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even); \
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// convert to normal format and add to accumulator
|
|
32
|
+
#define DISENTANGLE_AND_ACCUMULATE_M_VECS(Len , acc, stride) \
|
|
33
|
+
for (size_t k = 0; k+1 < Len; k+=2) \
|
|
34
|
+
{ \
|
|
35
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + k * stride)); \
|
|
36
|
+
__m256i acc1 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride)); \
|
|
37
|
+
\
|
|
38
|
+
__m256i t = (temp[k + 1] ^ _mm256_srli_epi16(temp[k],4)) & low_nibble_mask; \
|
|
39
|
+
acc0 ^= temp[k] ^ _mm256_slli_epi16(t,4); \
|
|
40
|
+
acc1 ^= temp[k+1] ^ t; \
|
|
41
|
+
\
|
|
42
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride), acc0); \
|
|
43
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride), acc1); \
|
|
44
|
+
} \
|
|
45
|
+
if (Len % 2 == 1) \
|
|
46
|
+
{ \
|
|
47
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + (Len-1) * stride)); \
|
|
48
|
+
\
|
|
49
|
+
__m256i t = (temp[Len] ^ _mm256_srli_epi16(temp[Len - 1],4)) & low_nibble_mask; \
|
|
50
|
+
acc0 ^= temp[Len-1] ^ _mm256_slli_epi16(t,4); \
|
|
51
|
+
\
|
|
52
|
+
_mm256_storeu_si256((__m256i *)(acc + (Len-1) * stride), acc0); \
|
|
53
|
+
}
|
|
54
|
+
#elif M_MAX <= 128
|
|
55
|
+
// Multiply an m_vec with a vec of "Len" scalars, and accumulate in temp
|
|
56
|
+
#define MULTIPLY_ACCUMULATE_M_VEC(vec, multabs, Len) \
|
|
57
|
+
__m256i in_odd0 = _mm256_loadu_si256((__m256i *) (vec)); \
|
|
58
|
+
__m256i in_even0 = _mm256_srli_epi16(in_odd0, 4) & low_nibble_mask; \
|
|
59
|
+
__m256i in_odd1 = _mm256_loadu_si256((__m256i *) (vec + M_VEC_LIMBS_MAX - 4)); \
|
|
60
|
+
__m256i in_even1 = _mm256_srli_epi16(in_odd1, 4) & low_nibble_mask; \
|
|
61
|
+
in_odd0 &= low_nibble_mask; \
|
|
62
|
+
in_odd1 &= low_nibble_mask; \
|
|
63
|
+
for (size_t k = 0; k < Len; k+=2) \
|
|
64
|
+
{ \
|
|
65
|
+
temp[2*k] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd0); \
|
|
66
|
+
temp[2*k + 1] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even0); \
|
|
67
|
+
temp[2*k + 2] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd1); \
|
|
68
|
+
temp[2*k + 3] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even1); \
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// convert to normal format and add to accumulator
|
|
72
|
+
#define DISENTANGLE_AND_ACCUMULATE_M_VECS(Len , acc, stride) \
|
|
73
|
+
for (size_t k = 0; k+1 < Len; k+=2) \
|
|
74
|
+
{ \
|
|
75
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + k * stride)); \
|
|
76
|
+
__m256i acc1 = _mm256_loadu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4)); \
|
|
77
|
+
__m256i acc2 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride)); \
|
|
78
|
+
__m256i acc3 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride + M_VEC_LIMBS_MAX - 4)); \
|
|
79
|
+
\
|
|
80
|
+
__m256i t0 = (temp[2*k + 1] ^ _mm256_srli_epi16(temp[2*k ],4)) & low_nibble_mask; \
|
|
81
|
+
__m256i t1 = (temp[2*k + 3] ^ _mm256_srli_epi16(temp[2*k + 2],4)) & low_nibble_mask; \
|
|
82
|
+
acc0 ^= temp[2*k ] ^ _mm256_slli_epi16(t0,4); \
|
|
83
|
+
acc1 ^= temp[2*k + 2] ^ _mm256_slli_epi16(t1,4); \
|
|
84
|
+
acc2 ^= temp[2*k + 1] ^ t0; \
|
|
85
|
+
acc3 ^= temp[2*k + 3] ^ t1; \
|
|
86
|
+
\
|
|
87
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride), acc0); \
|
|
88
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4), acc1); \
|
|
89
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride), acc2); \
|
|
90
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride + M_VEC_LIMBS_MAX - 4), acc3); \
|
|
91
|
+
} \
|
|
92
|
+
if (Len % 2 == 1) \
|
|
93
|
+
{ \
|
|
94
|
+
const size_t k = Len - 1; \
|
|
95
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + k * stride)); \
|
|
96
|
+
__m256i acc1 = _mm256_loadu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4)); \
|
|
97
|
+
\
|
|
98
|
+
__m256i t0 = (temp[2*k + 1] ^ _mm256_srli_epi16(temp[2*k ],4)) & low_nibble_mask; \
|
|
99
|
+
__m256i t1 = (temp[2*k + 3] ^ _mm256_srli_epi16(temp[2*k + 2],4)) & low_nibble_mask; \
|
|
100
|
+
acc0 ^= temp[2*k ] ^ _mm256_slli_epi16(t0,4); \
|
|
101
|
+
acc1 ^= temp[2*k + 2] ^ _mm256_slli_epi16(t1,4); \
|
|
102
|
+
\
|
|
103
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride), acc0); \
|
|
104
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4), acc1); \
|
|
105
|
+
}
|
|
106
|
+
#elif M_MAX <= 192
|
|
107
|
+
// Multiply an m_vec with a vec of "Len" scalars, and accumulate in temp
|
|
108
|
+
#define MULTIPLY_ACCUMULATE_M_VEC(vec, multabs, Len) \
|
|
109
|
+
__m256i in_odd0 = _mm256_loadu_si256((__m256i *) (vec)); \
|
|
110
|
+
__m256i in_even0 = _mm256_srli_epi16(in_odd0, 4) & low_nibble_mask; \
|
|
111
|
+
__m256i in_odd1 = _mm256_loadu_si256((__m256i *) (vec + 4)); \
|
|
112
|
+
__m256i in_even1 = _mm256_srli_epi16(in_odd1, 4) & low_nibble_mask; \
|
|
113
|
+
__m256i in_odd2 = _mm256_loadu_si256((__m256i *) (vec + M_VEC_LIMBS_MAX - 4)); \
|
|
114
|
+
__m256i in_even2 = _mm256_srli_epi16(in_odd2, 4) & low_nibble_mask; \
|
|
115
|
+
in_odd0 &= low_nibble_mask; \
|
|
116
|
+
in_odd1 &= low_nibble_mask; \
|
|
117
|
+
in_odd2 &= low_nibble_mask; \
|
|
118
|
+
for (size_t k = 0; k < Len; k+=2) \
|
|
119
|
+
{ \
|
|
120
|
+
temp[3*k] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd0); \
|
|
121
|
+
temp[3*k + 1] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even0); \
|
|
122
|
+
temp[3*k + 2] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd1); \
|
|
123
|
+
temp[3*k + 3] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even1); \
|
|
124
|
+
temp[3*k + 4] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_odd2); \
|
|
125
|
+
temp[3*k + 5] ^= _mm256_shuffle_epi8(*(multabs + k/2), in_even2); \
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// convert to normal format and add to accumulator
|
|
129
|
+
#define DISENTANGLE_AND_ACCUMULATE_M_VECS(Len , acc, stride) \
|
|
130
|
+
for (size_t k = 0; k+1 < Len; k+=2) \
|
|
131
|
+
{ \
|
|
132
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + k * stride)); \
|
|
133
|
+
__m256i acc1 = _mm256_loadu_si256((__m256i *)(acc + k * stride + 4)); \
|
|
134
|
+
__m256i acc2 = _mm256_loadu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4)); \
|
|
135
|
+
__m256i acc3 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride)); \
|
|
136
|
+
__m256i acc4 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride + 4)); \
|
|
137
|
+
__m256i acc5 = _mm256_loadu_si256((__m256i *)(acc + (k + 1)* stride + M_VEC_LIMBS_MAX - 4)); \
|
|
138
|
+
\
|
|
139
|
+
__m256i t0 = (temp[3*k + 1] ^ _mm256_srli_epi16(temp[3*k ],4)) & low_nibble_mask; \
|
|
140
|
+
__m256i t1 = (temp[3*k + 3] ^ _mm256_srli_epi16(temp[3*k + 2],4)) & low_nibble_mask; \
|
|
141
|
+
__m256i t2 = (temp[3*k + 5] ^ _mm256_srli_epi16(temp[3*k + 4],4)) & low_nibble_mask; \
|
|
142
|
+
acc0 ^= temp[3*k ] ^ _mm256_slli_epi16(t0,4); \
|
|
143
|
+
acc1 ^= temp[3*k + 2] ^ _mm256_slli_epi16(t1,4); \
|
|
144
|
+
acc2 ^= temp[3*k + 4] ^ _mm256_slli_epi16(t2,4); \
|
|
145
|
+
acc3 ^= temp[3*k + 1] ^ t0; \
|
|
146
|
+
acc4 ^= temp[3*k + 3] ^ t1; \
|
|
147
|
+
acc5 ^= temp[3*k + 5] ^ t2; \
|
|
148
|
+
\
|
|
149
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride), acc0); \
|
|
150
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + 4), acc1); \
|
|
151
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4), acc2); \
|
|
152
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride), acc3); \
|
|
153
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride + 4), acc4); \
|
|
154
|
+
_mm256_storeu_si256((__m256i *)(acc + (k + 1) * stride + M_VEC_LIMBS_MAX - 4), acc5); \
|
|
155
|
+
} \
|
|
156
|
+
if (Len % 2 == 1) \
|
|
157
|
+
{ \
|
|
158
|
+
const size_t k = Len - 1; \
|
|
159
|
+
__m256i acc0 = _mm256_loadu_si256((__m256i *)(acc + k * stride)); \
|
|
160
|
+
__m256i acc1 = _mm256_loadu_si256((__m256i *)(acc + k * stride + 4)); \
|
|
161
|
+
__m256i acc2 = _mm256_loadu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4)); \
|
|
162
|
+
\
|
|
163
|
+
__m256i t0 = (temp[3*k + 1] ^ _mm256_srli_epi16(temp[3*k ],4)) & low_nibble_mask; \
|
|
164
|
+
__m256i t1 = (temp[3*k + 3] ^ _mm256_srli_epi16(temp[3*k + 2],4)) & low_nibble_mask; \
|
|
165
|
+
__m256i t2 = (temp[3*k + 5] ^ _mm256_srli_epi16(temp[3*k + 4],4)) & low_nibble_mask; \
|
|
166
|
+
acc0 ^= temp[3*k ] ^ _mm256_slli_epi16(t0,4); \
|
|
167
|
+
acc1 ^= temp[3*k + 2] ^ _mm256_slli_epi16(t1,4); \
|
|
168
|
+
acc2 ^= temp[3*k + 4] ^ _mm256_slli_epi16(t2,4); \
|
|
169
|
+
\
|
|
170
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride), acc0); \
|
|
171
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + 4), acc1); \
|
|
172
|
+
_mm256_storeu_si256((__m256i *)(acc + k * stride + M_VEC_LIMBS_MAX - 4), acc2); \
|
|
173
|
+
}
|
|
174
|
+
#else
|
|
175
|
+
NOT IMPLEMENTED
|
|
176
|
+
#endif
|
|
177
|
+
|
|
178
|
+
// P1*0 -> P1: v x v, O: v x o
|
|
179
|
+
static
|
|
180
|
+
inline void P1_times_O(const uint64_t *P1, __m256i *O_multabs, uint64_t *acc){
|
|
181
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
182
|
+
size_t limbs_used = 0;
|
|
183
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
184
|
+
{
|
|
185
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
186
|
+
__m256i temp[O_AVX_ROUND_UP*AVX_REGISTER_PER_M_VEC] = {0};
|
|
187
|
+
for (size_t c = r; c < V_MAX; c++)
|
|
188
|
+
{
|
|
189
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1 + limbs_used, O_multabs + O_AVX_ROUND_UP/2*c, O_MAX);
|
|
190
|
+
limbs_used += M_VEC_LIMBS_MAX;
|
|
191
|
+
}
|
|
192
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(O_MAX , acc + r*O_MAX*M_VEC_LIMBS_MAX, M_VEC_LIMBS_MAX);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static
|
|
197
|
+
inline void Ot_times_P1O_P2(const uint64_t *P1O_P2, __m256i *O_multabs, uint64_t *acc){
|
|
198
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
199
|
+
|
|
200
|
+
for (size_t c = 0; c < O_MAX; c++)
|
|
201
|
+
{
|
|
202
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
203
|
+
__m256i temp[O_AVX_ROUND_UP*AVX_REGISTER_PER_M_VEC] = {0};
|
|
204
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
205
|
+
{
|
|
206
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1O_P2 + (r*O_MAX + c)*M_VEC_LIMBS_MAX, O_multabs + O_AVX_ROUND_UP/2*r, O_MAX);
|
|
207
|
+
}
|
|
208
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(O_MAX , acc + c*M_VEC_LIMBS_MAX, O_MAX*M_VEC_LIMBS_MAX);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static
|
|
213
|
+
inline void P1P1t_times_O(const mayo_params_t* p, const uint64_t *P1, const unsigned char *O, uint64_t *acc){
|
|
214
|
+
(void) p;
|
|
215
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
216
|
+
|
|
217
|
+
__m256i O_multabs[O_AVX_ROUND_UP/2*V_MAX];
|
|
218
|
+
mayo_O_multabs(O, O_multabs);
|
|
219
|
+
|
|
220
|
+
size_t cols_used = 0;
|
|
221
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
222
|
+
{
|
|
223
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
224
|
+
__m256i temp[O_AVX_ROUND_UP*AVX_REGISTER_PER_M_VEC] = {0};
|
|
225
|
+
cols_used += 1;
|
|
226
|
+
size_t pos = r;
|
|
227
|
+
for (size_t c = 0; c < r; c++)
|
|
228
|
+
{
|
|
229
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1 + pos * M_VEC_LIMBS_MAX, O_multabs + O_AVX_ROUND_UP/2*c, O_MAX);
|
|
230
|
+
pos += (V_MAX -c - 1);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
for (size_t c = r+1; c < V_MAX; c++)
|
|
234
|
+
{
|
|
235
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1 + cols_used * M_VEC_LIMBS_MAX, O_multabs + O_AVX_ROUND_UP/2*c, O_MAX);
|
|
236
|
+
cols_used ++;
|
|
237
|
+
}
|
|
238
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(O_MAX , acc + r*O_MAX*M_VEC_LIMBS_MAX, M_VEC_LIMBS_MAX);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
static
|
|
244
|
+
inline void Vt_times_L(const uint64_t *L, const __m256i *V_multabs, uint64_t *acc){
|
|
245
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
246
|
+
|
|
247
|
+
for (size_t c = 0; c < O_MAX; c++)
|
|
248
|
+
{
|
|
249
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
250
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
251
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
252
|
+
{
|
|
253
|
+
MULTIPLY_ACCUMULATE_M_VEC(L + (r*O_MAX + c) * M_VEC_LIMBS_MAX, V_multabs + K_OVER_2*r, K_MAX);
|
|
254
|
+
}
|
|
255
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + c*M_VEC_LIMBS_MAX, O_MAX*M_VEC_LIMBS_MAX);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
static
|
|
261
|
+
inline void Vt_times_Pv(const uint64_t *Pv, const __m256i *V_multabs, uint64_t *acc){
|
|
262
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
263
|
+
|
|
264
|
+
for (size_t c = 0; c < K_MAX; c++)
|
|
265
|
+
{
|
|
266
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
267
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
268
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
269
|
+
{
|
|
270
|
+
MULTIPLY_ACCUMULATE_M_VEC(Pv + (r*K_MAX + c) * M_VEC_LIMBS_MAX, V_multabs + K_OVER_2*r, K_MAX);
|
|
271
|
+
}
|
|
272
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + c*M_VEC_LIMBS_MAX, K_MAX*M_VEC_LIMBS_MAX);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
static
|
|
277
|
+
inline void P1_times_Vt(const uint64_t *P1, __m256i *V_multabs, uint64_t *acc){
|
|
278
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
279
|
+
|
|
280
|
+
size_t cols_used = 0;
|
|
281
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
282
|
+
{
|
|
283
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
284
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
285
|
+
|
|
286
|
+
for (size_t c=r; c < V_MAX; c++)
|
|
287
|
+
{
|
|
288
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1 + cols_used, V_multabs + K_OVER_2*c, K_MAX);
|
|
289
|
+
cols_used += M_VEC_LIMBS_MAX;
|
|
290
|
+
}
|
|
291
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + r*K_MAX*M_VEC_LIMBS_MAX, M_VEC_LIMBS_MAX);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// P1*S1 -> P1: v x v, S1: v x k // P1 upper triangular
|
|
296
|
+
// same as mayo_12_P1_times_Vt
|
|
297
|
+
static
|
|
298
|
+
inline void P1_times_S1(const uint64_t *_P1, __m256i *S1_multabs, uint64_t *_acc){
|
|
299
|
+
P1_times_Vt(_P1, S1_multabs, _acc);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
static
|
|
303
|
+
inline void S1t_times_PS1(const uint64_t *_PS1, __m256i *S1_multabs, uint64_t *_acc){
|
|
304
|
+
Vt_times_Pv(_PS1, S1_multabs, _acc);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
static
|
|
308
|
+
inline void S2t_times_PS2(const uint64_t *PS2, __m256i *S2_multabs, uint64_t *acc){
|
|
309
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
310
|
+
|
|
311
|
+
for (size_t c = 0; c < K_MAX; c++)
|
|
312
|
+
{
|
|
313
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
314
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
315
|
+
for (size_t r = 0; r < O_MAX; r++)
|
|
316
|
+
{
|
|
317
|
+
MULTIPLY_ACCUMULATE_M_VEC(PS2 + (r*K_MAX + c)*M_VEC_LIMBS_MAX, S2_multabs + K_OVER_2*r, K_MAX);
|
|
318
|
+
}
|
|
319
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + c*M_VEC_LIMBS_MAX, K_MAX*M_VEC_LIMBS_MAX);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// P2*S2 -> P2: v x o, S2: o x k
|
|
324
|
+
static
|
|
325
|
+
inline void P1_times_S1_plus_P2_times_S2(const uint64_t *P1, const uint64_t *P2, __m256i *S1_multabs, __m256i *S2_multabs, uint64_t *acc){
|
|
326
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
327
|
+
|
|
328
|
+
size_t P1_cols_used = 0;
|
|
329
|
+
for (size_t r = 0; r < V_MAX; r++)
|
|
330
|
+
{
|
|
331
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
332
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
333
|
+
|
|
334
|
+
// P1 * S1
|
|
335
|
+
for (size_t c = r; c < V_MAX; c++)
|
|
336
|
+
{
|
|
337
|
+
MULTIPLY_ACCUMULATE_M_VEC(P1 + P1_cols_used, S1_multabs + K_OVER_2*c, K_MAX);
|
|
338
|
+
P1_cols_used += M_VEC_LIMBS_MAX;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// P2 * S2
|
|
342
|
+
for (size_t c = 0; c < O_MAX; c++)
|
|
343
|
+
{
|
|
344
|
+
MULTIPLY_ACCUMULATE_M_VEC(P2 + (r*O_MAX + c)*M_VEC_LIMBS_MAX, S2_multabs + K_OVER_2*c, K_MAX);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + r*K_MAX*M_VEC_LIMBS_MAX, M_VEC_LIMBS_MAX);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// P3*S2 -> P3: o x o, S2: o x k // P3 upper triangular
|
|
352
|
+
static
|
|
353
|
+
inline void P3_times_S2(const uint64_t *P3, __m256i *S2_multabs, uint64_t *acc){
|
|
354
|
+
const __m256i low_nibble_mask = _mm256_set_epi64x(0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f);
|
|
355
|
+
|
|
356
|
+
size_t cols_used = 0;
|
|
357
|
+
for (size_t r = 0; r < O_MAX; r++)
|
|
358
|
+
{
|
|
359
|
+
// do multiplications for one row and accumulate results in temporary format
|
|
360
|
+
__m256i temp[K_OVER_2*2*AVX_REGISTER_PER_M_VEC] = {0};
|
|
361
|
+
|
|
362
|
+
for (size_t c = r; c < O_MAX; c++)
|
|
363
|
+
{
|
|
364
|
+
MULTIPLY_ACCUMULATE_M_VEC(P3 + cols_used, S2_multabs + K_OVER_2*c, K_MAX);
|
|
365
|
+
cols_used += M_VEC_LIMBS_MAX;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
DISENTANGLE_AND_ACCUMULATE_M_VECS(K_MAX , acc + r*K_MAX*M_VEC_LIMBS_MAX, M_VEC_LIMBS_MAX);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
static inline
|
|
373
|
+
void compute_M_and_VPV(const mayo_params_t* p, const unsigned char* Vdec, const uint64_t *L, const uint64_t *P1, uint64_t *VL, uint64_t *VP1V){
|
|
374
|
+
(void) p;
|
|
375
|
+
__m256i V_multabs[(K_MAX+1)/2*V_MAX];
|
|
376
|
+
mayo_V_multabs(Vdec, V_multabs);
|
|
377
|
+
|
|
378
|
+
// M
|
|
379
|
+
Vt_times_L(L, V_multabs, VL);
|
|
380
|
+
|
|
381
|
+
// VP1V
|
|
382
|
+
uint64_t Pv[V_MAX * K_MAX * M_VEC_LIMBS_MAX] = {0};
|
|
383
|
+
P1_times_Vt(P1, V_multabs, Pv);
|
|
384
|
+
Vt_times_Pv(Pv, V_multabs, VP1V);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
static inline
|
|
389
|
+
void compute_P3(const mayo_params_t* p, const uint64_t* P1, uint64_t *P2, const unsigned char *O, uint64_t *P3){
|
|
390
|
+
(void) p;
|
|
391
|
+
__m256i O_multabs[O_AVX_ROUND_UP/2*V_MAX];
|
|
392
|
+
mayo_O_multabs(O, O_multabs);
|
|
393
|
+
P1_times_O(P1, O_multabs, P2);
|
|
394
|
+
Ot_times_P1O_P2(P2, O_multabs, P3);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// compute P * S^t = [ P1 P2 ] * [S1] = [P1*S1 + P2*S2]
|
|
398
|
+
// [ 0 P3 ] [S2] [ P3*S2]
|
|
399
|
+
// compute S * PS = [ S1 S2 ] * [ P1*S1 + P2*S2 = P1 ] = [ S1*P1 + S2*P2 ]
|
|
400
|
+
// [ P3*S2 = P2 ]
|
|
401
|
+
static inline void m_calculate_PS_SPS(const mayo_params_t *p, const uint64_t *P1, const uint64_t *P2, const uint64_t *P3, const unsigned char *S,
|
|
402
|
+
uint64_t *SPS) {
|
|
403
|
+
(void) p;
|
|
404
|
+
const int o = PARAM_NAME(o);
|
|
405
|
+
const int v = PARAM_NAME(v);
|
|
406
|
+
const int k = PARAM_NAME(k);
|
|
407
|
+
const int n = o + v;
|
|
408
|
+
/* Old approach which is constant time but doesn't have to be */
|
|
409
|
+
unsigned char S1[V_MAX*K_MAX]; // == N-O, K
|
|
410
|
+
unsigned char S2[O_MAX*K_MAX]; // == O, K
|
|
411
|
+
unsigned char *s1_write = S1;
|
|
412
|
+
unsigned char *s2_write = S2;
|
|
413
|
+
|
|
414
|
+
for (int r=0; r < k; r++)
|
|
415
|
+
{
|
|
416
|
+
for (int c = 0; c < n; c++)
|
|
417
|
+
{
|
|
418
|
+
if(c < v){
|
|
419
|
+
*(s1_write++) = S[r*n + c];
|
|
420
|
+
} else {
|
|
421
|
+
*(s2_write++) = S[r*n + c];
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
uint64_t PS[N_MAX * K_MAX * M_VEC_LIMBS_MAX] = { 0 };
|
|
427
|
+
|
|
428
|
+
__m256i S1_multabs[(K_MAX+1)/2*V_MAX];
|
|
429
|
+
__m256i S2_multabs[(K_MAX+1)/2*O_MAX];
|
|
430
|
+
mayo_S1_multabs(S1, S1_multabs);
|
|
431
|
+
mayo_S2_multabs(S2, S2_multabs);
|
|
432
|
+
|
|
433
|
+
P1_times_S1_plus_P2_times_S2(P1, P2, S1_multabs, S2_multabs, PS);
|
|
434
|
+
P3_times_S2(P3, S2_multabs, PS + V_MAX*K_MAX*M_VEC_LIMBS_MAX); // upper triangular
|
|
435
|
+
|
|
436
|
+
// S^T * PS = S1^t*PS1 + S2^t*PS2
|
|
437
|
+
S1t_times_PS1(PS, S1_multabs, SPS);
|
|
438
|
+
S2t_times_PS2(PS + V_MAX*K_MAX*M_VEC_LIMBS_MAX, S2_multabs, SPS);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
#undef K_OVER_2
|
|
442
|
+
#endif
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
set(SOURCE_FILES_COMMON_SYS common/randombytes_system.c common/aes_c.c common/aes128ctr.c common/aes_neon.c common/fips202.c common/mem.c)
|
|
4
|
+
|
|
5
|
+
add_library(mayo_common_sys ${SOURCE_FILES_COMMON_SYS})
|
|
6
|
+
target_include_directories(mayo_common_sys PRIVATE common ../include)
|
|
7
|
+
target_compile_options(mayo_common_sys PUBLIC ${C_OPT_FLAGS})
|
|
8
|
+
|
|
9
|
+
set(SOURCE_FILES_COMMON_TEST common/randombytes_ctrdrbg.c common/aes_c.c common/aes128ctr.c common/aes_neon.c common/fips202.c common/mem.c)
|
|
10
|
+
|
|
11
|
+
add_library(mayo_common_test ${SOURCE_FILES_COMMON_TEST})
|
|
12
|
+
target_include_directories(mayo_common_test PRIVATE common ../include)
|
|
13
|
+
target_compile_options(mayo_common_test PUBLIC ${C_OPT_FLAGS})
|
|
14
|
+
|
|
15
|
+
if (ENABLE_CT_TESTING)
|
|
16
|
+
target_compile_definitions(mayo_common_sys PUBLIC ENABLE_CT_TESTING)
|
|
17
|
+
target_compile_definitions(mayo_common_test PUBLIC ENABLE_CT_TESTING)
|
|
18
|
+
endif()
|
|
19
|
+
|
|
20
|
+
if (ENABLE_AESNI)
|
|
21
|
+
message("AES-NI enabled")
|
|
22
|
+
target_compile_definitions(mayo_common_sys PUBLIC ENABLE_AESNI)
|
|
23
|
+
target_compile_definitions(mayo_common_test PUBLIC ENABLE_AESNI)
|
|
24
|
+
endif()
|
|
25
|
+
|
|
26
|
+
if (ENABLE_AESNEON)
|
|
27
|
+
message("AES-NEON enabled")
|
|
28
|
+
target_compile_definitions(mayo_common_sys PUBLIC ENABLE_AESNEON)
|
|
29
|
+
target_compile_definitions(mayo_common_test PUBLIC ENABLE_AESNEON)
|
|
30
|
+
endif()
|
|
31
|
+
|
|
32
|
+
set(SOURCE_FILES_MAYO mayo.c params.c arithmetic.c)
|
|
33
|
+
|
|
34
|
+
if (${MAYO_BUILD_TYPE} MATCHES "avx2")
|
|
35
|
+
message("Building for avx2")
|
|
36
|
+
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/AVX2 ${PROJECT_SOURCE_DIR}/src/generic)
|
|
37
|
+
add_definitions(-DMAYO_AVX)
|
|
38
|
+
elseif (${MAYO_BUILD_TYPE} MATCHES "neon")
|
|
39
|
+
message("Building for neon")
|
|
40
|
+
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/neon ${PROJECT_SOURCE_DIR}/src/generic)
|
|
41
|
+
add_definitions(-DMAYO_NEON)
|
|
42
|
+
else()
|
|
43
|
+
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/generic)
|
|
44
|
+
endif()
|
|
45
|
+
|
|
46
|
+
if (ENABLE_PARAMS_DYNAMIC)
|
|
47
|
+
# mayo and mayo_test libraries
|
|
48
|
+
add_library(mayo ${SOURCE_FILES_MAYO})
|
|
49
|
+
target_link_libraries(mayo PUBLIC mayo_common_sys)
|
|
50
|
+
target_include_directories(mayo PUBLIC ../include . PRIVATE common ${INC_PLATFORM})
|
|
51
|
+
add_library(mayo_test ${SOURCE_FILES_MAYO})
|
|
52
|
+
target_link_libraries(mayo_test PUBLIC mayo_common_test)
|
|
53
|
+
target_include_directories(mayo_test PUBLIC ../include . PRIVATE common ${INC_PLATFORM})
|
|
54
|
+
|
|
55
|
+
target_compile_definitions(mayo PUBLIC ENABLE_PARAMS_DYNAMIC)
|
|
56
|
+
target_compile_definitions(mayo_test PUBLIC ENABLE_PARAMS_DYNAMIC)
|
|
57
|
+
|
|
58
|
+
# mayo_<x>_nistapi libraries
|
|
59
|
+
foreach(MVARIANT ${MVARIANT_S})
|
|
60
|
+
string(TOLOWER ${MVARIANT} MVARIANT_LOWER)
|
|
61
|
+
set(SOURCE_FILES_VARIANT ${MVARIANT_LOWER}/api.c)
|
|
62
|
+
add_library(${MVARIANT_LOWER}_nistapi ${SOURCE_FILES_VARIANT})
|
|
63
|
+
target_link_libraries(${MVARIANT_LOWER}_nistapi PRIVATE mayo)
|
|
64
|
+
target_compile_definitions(${MVARIANT_LOWER}_nistapi PUBLIC ENABLE_PARAMS_DYNAMIC)
|
|
65
|
+
target_include_directories(${MVARIANT_LOWER}_nistapi PUBLIC ${MVARIANT_LOWER} ${INC_PLATFORM})
|
|
66
|
+
add_library(${MVARIANT_LOWER}_test_nistapi ${SOURCE_FILES_VARIANT})
|
|
67
|
+
target_link_libraries(${MVARIANT_LOWER}_test_nistapi PRIVATE mayo_test)
|
|
68
|
+
target_compile_definitions(${MVARIANT_LOWER}_test_nistapi PUBLIC ENABLE_PARAMS_DYNAMIC)
|
|
69
|
+
target_include_directories(${MVARIANT_LOWER}_test_nistapi PUBLIC ${MVARIANT_LOWER} ${INC_PLATFORM})
|
|
70
|
+
endforeach()
|
|
71
|
+
|
|
72
|
+
else()
|
|
73
|
+
FOREACH(MVARIANT ${MVARIANT_S})
|
|
74
|
+
string(TOLOWER ${MVARIANT} MVARIANT_LOWER)
|
|
75
|
+
add_library(${MVARIANT_LOWER} ${SOURCE_FILES_MAYO})
|
|
76
|
+
target_link_libraries(${MVARIANT_LOWER} PUBLIC mayo_common_sys)
|
|
77
|
+
target_include_directories(${MVARIANT_LOWER} PUBLIC ../include . PRIVATE common ${INC_PLATFORM})
|
|
78
|
+
add_library(${MVARIANT_LOWER}_test ${SOURCE_FILES_MAYO})
|
|
79
|
+
target_link_libraries(${MVARIANT_LOWER}_test PUBLIC mayo_common_test)
|
|
80
|
+
target_include_directories(${MVARIANT_LOWER}_test PUBLIC ../include . PRIVATE common ${INC_PLATFORM})
|
|
81
|
+
target_compile_definitions(${MVARIANT_LOWER} PUBLIC MAYO_VARIANT=${MVARIANT})
|
|
82
|
+
target_compile_definitions(${MVARIANT_LOWER}_test PUBLIC MAYO_VARIANT=${MVARIANT})
|
|
83
|
+
ENDFOREACH()
|
|
84
|
+
|
|
85
|
+
foreach(MVARIANT ${MVARIANT_S})
|
|
86
|
+
string(TOLOWER ${MVARIANT} MVARIANT_LOWER)
|
|
87
|
+
set(SOURCE_FILES_VARIANT ${MVARIANT_LOWER}/api.c)
|
|
88
|
+
add_library(${MVARIANT_LOWER}_nistapi ${SOURCE_FILES_VARIANT})
|
|
89
|
+
target_link_libraries(${MVARIANT_LOWER}_nistapi PRIVATE ${MVARIANT_LOWER})
|
|
90
|
+
target_include_directories(${MVARIANT_LOWER}_nistapi PUBLIC ${MVARIANT_LOWER} PUBLIC ../include ${INC_PLATFORM})
|
|
91
|
+
add_library(${MVARIANT_LOWER}_test_nistapi ${SOURCE_FILES_VARIANT})
|
|
92
|
+
target_link_libraries(${MVARIANT_LOWER}_test_nistapi PRIVATE ${MVARIANT_LOWER}_test)
|
|
93
|
+
target_include_directories(${MVARIANT_LOWER}_test_nistapi PUBLIC ${MVARIANT_LOWER} ${INC_PLATFORM})
|
|
94
|
+
target_compile_definitions(${MVARIANT_LOWER}_nistapi PUBLIC MAYO_VARIANT=${MVARIANT})
|
|
95
|
+
target_compile_definitions(${MVARIANT_LOWER}_test_nistapi PUBLIC MAYO_VARIANT=${MVARIANT})
|
|
96
|
+
endforeach()
|
|
97
|
+
endif()
|
|
98
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
#include <arithmetic.h>
|
|
4
|
+
#include <simple_arithmetic.h>
|
|
5
|
+
#include <mem.h>
|
|
6
|
+
#include <echelon_form.h>
|
|
7
|
+
#include <stdalign.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#ifdef ENABLE_CT_TESTING
|
|
11
|
+
#include <valgrind/memcheck.h>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
void m_upper(const mayo_params_t* p, const uint64_t *in, uint64_t *out, int size) {
|
|
15
|
+
#ifndef ENABLE_PARAMS_DYNAMIC
|
|
16
|
+
(void) p;
|
|
17
|
+
#endif
|
|
18
|
+
// Look into AVX2'ing this
|
|
19
|
+
const int m_vec_limbs = PARAM_m_vec_limbs(p);
|
|
20
|
+
int m_vecs_stored = 0;
|
|
21
|
+
for (int r = 0; r < size; r++) {
|
|
22
|
+
for (int c = r; c < size; c++) {
|
|
23
|
+
m_vec_copy(m_vec_limbs, in + m_vec_limbs * (r * size + c), out + m_vec_limbs * m_vecs_stored );
|
|
24
|
+
if (r != c) {
|
|
25
|
+
m_vec_add(m_vec_limbs, in + m_vec_limbs * (c * size + r), out + m_vec_limbs * m_vecs_stored );
|
|
26
|
+
}
|
|
27
|
+
m_vecs_stored ++;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
// sample a solution x to Ax = y, with r used as randomness
|
|
34
|
+
// require:
|
|
35
|
+
// - A is a matrix with m rows and k*o+1 collumns (values in the last collum are
|
|
36
|
+
// not important, they will be overwritten by y) in row major order
|
|
37
|
+
// - y is a vector with m elements
|
|
38
|
+
// - r and x are k*o bytes long
|
|
39
|
+
// return: 1 on success, 0 on failure
|
|
40
|
+
int sample_solution(const mayo_params_t *p, unsigned char *A,
|
|
41
|
+
const unsigned char *y, const unsigned char *r,
|
|
42
|
+
unsigned char *x, int k, int o, int m, int A_cols) {
|
|
43
|
+
#ifdef MAYO_VARIANT
|
|
44
|
+
(void) p;
|
|
45
|
+
#endif
|
|
46
|
+
unsigned char finished;
|
|
47
|
+
int col_upper_bound;
|
|
48
|
+
unsigned char correct_column;
|
|
49
|
+
|
|
50
|
+
// x <- r
|
|
51
|
+
for (int i = 0; i < k * o; i++) {
|
|
52
|
+
x[i] = r[i];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// compute Ar;
|
|
56
|
+
unsigned char Ar[M_MAX];
|
|
57
|
+
for (int i = 0; i < m; i++) {
|
|
58
|
+
A[k * o + i * (k * o + 1)] = 0; // clear last col of A
|
|
59
|
+
}
|
|
60
|
+
mat_mul(A, r, Ar, k * o + 1, m, 1);
|
|
61
|
+
|
|
62
|
+
// move y - Ar to last column of matrix A
|
|
63
|
+
for (int i = 0; i < m; i++) {
|
|
64
|
+
A[k * o + i * (k * o + 1)] = sub_f(y[i], Ar[i]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
EF(A, m, k * o + 1);
|
|
68
|
+
|
|
69
|
+
// check if last row of A (excluding the last entry of y) is zero
|
|
70
|
+
unsigned char full_rank = 0;
|
|
71
|
+
for (int i = 0; i < A_cols - 1; i++) {
|
|
72
|
+
full_rank |= A[(m - 1) * A_cols + i];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// It is okay to leak if we need to restart or not
|
|
76
|
+
#ifdef ENABLE_CT_TESTING
|
|
77
|
+
VALGRIND_MAKE_MEM_DEFINED(&full_rank, 1);
|
|
78
|
+
#endif
|
|
79
|
+
|
|
80
|
+
if (full_rank == 0) {
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// back substitution in constant time
|
|
85
|
+
// the index of the first nonzero entry in each row is secret, which makes
|
|
86
|
+
// things less efficient
|
|
87
|
+
|
|
88
|
+
for (int row = m - 1; row >= 0; row--) {
|
|
89
|
+
finished = 0;
|
|
90
|
+
col_upper_bound = MAYO_MIN(row + (32/(m-row)), k*o);
|
|
91
|
+
// the first nonzero entry in row r is between r and col_upper_bound with probability at least ~1-q^{-32}
|
|
92
|
+
|
|
93
|
+
for (int col = row; col <= col_upper_bound; col++) {
|
|
94
|
+
|
|
95
|
+
// Compare two chars in constant time.
|
|
96
|
+
// Returns 0x00 if the byte arrays are equal, 0xff otherwise.
|
|
97
|
+
correct_column = ct_compare_8((A[row * A_cols + col]), 0) & ~finished;
|
|
98
|
+
|
|
99
|
+
unsigned char u = correct_column & A[row * A_cols + A_cols - 1];
|
|
100
|
+
x[col] ^= u;
|
|
101
|
+
|
|
102
|
+
for (int i = 0; i < row; i += 8) {
|
|
103
|
+
uint64_t tmp = ( (uint64_t) A[ i * A_cols + col] << 0) ^ ( (uint64_t) A[(i+1) * A_cols + col] << 8)
|
|
104
|
+
^ ( (uint64_t) A[(i+2) * A_cols + col] << 16) ^ ( (uint64_t) A[(i+3) * A_cols + col] << 24)
|
|
105
|
+
^ ( (uint64_t) A[(i+4) * A_cols + col] << 32) ^ ( (uint64_t) A[(i+5) * A_cols + col] << 40)
|
|
106
|
+
^ ( (uint64_t) A[(i+6) * A_cols + col] << 48) ^ ( (uint64_t) A[(i+7) * A_cols + col] << 56);
|
|
107
|
+
|
|
108
|
+
tmp = mul_fx8(u, tmp);
|
|
109
|
+
|
|
110
|
+
A[ i * A_cols + A_cols - 1] ^= (tmp ) & 0xf;
|
|
111
|
+
A[(i+1) * A_cols + A_cols - 1] ^= (tmp >> 8 ) & 0xf;
|
|
112
|
+
A[(i+2) * A_cols + A_cols - 1] ^= (tmp >> 16) & 0xf;
|
|
113
|
+
A[(i+3) * A_cols + A_cols - 1] ^= (tmp >> 24) & 0xf;
|
|
114
|
+
A[(i+4) * A_cols + A_cols - 1] ^= (tmp >> 32) & 0xf;
|
|
115
|
+
A[(i+5) * A_cols + A_cols - 1] ^= (tmp >> 40) & 0xf;
|
|
116
|
+
A[(i+6) * A_cols + A_cols - 1] ^= (tmp >> 48) & 0xf;
|
|
117
|
+
A[(i+7) * A_cols + A_cols - 1] ^= (tmp >> 56) & 0xf;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
finished = finished | correct_column;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
volatile uint32_t uint32_t_blocker = 0;
|
|
127
|
+
volatile uint64_t uint64_t_blocker = 0;
|
|
128
|
+
volatile unsigned char unsigned_char_blocker = 0;
|