@theqrl/dilithium5 0.0.1

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/src/packing.js ADDED
@@ -0,0 +1,185 @@
1
+ import {
2
+ K,
3
+ L,
4
+ N,
5
+ OMEGA,
6
+ PolyETAPackedBytes,
7
+ PolyT0PackedBytes,
8
+ PolyT1PackedBytes,
9
+ PolyZPackedBytes,
10
+ SeedBytes,
11
+ } from './const.js';
12
+ import {
13
+ polyEtaPack,
14
+ polyEtaUnpack,
15
+ polyT0Pack,
16
+ polyT0Unpack,
17
+ polyT1Pack,
18
+ polyT1Unpack,
19
+ polyZPack,
20
+ polyZUnpack,
21
+ } from './poly.js';
22
+
23
+ export function packPk(pkp, rho, t1) {
24
+ const pk = pkp;
25
+ for (let i = 0; i < SeedBytes; ++i) {
26
+ pk[i] = rho[i];
27
+ }
28
+ for (let i = 0; i < K; ++i) {
29
+ polyT1Pack(pk, SeedBytes + i * PolyT1PackedBytes, t1.vec[i]);
30
+ }
31
+ }
32
+
33
+ export function unpackPk(rhop, t1, pk) {
34
+ const rho = rhop;
35
+ for (let i = 0; i < SeedBytes; ++i) {
36
+ rho[i] = pk[i];
37
+ }
38
+
39
+ for (let i = 0; i < K; ++i) {
40
+ polyT1Unpack(t1.vec[i], pk, SeedBytes + i * PolyT1PackedBytes);
41
+ }
42
+ }
43
+
44
+ export function packSk(skp, rho, tr, key, t0, s1, s2) {
45
+ let skOffset = 0;
46
+ const sk = skp;
47
+ for (let i = 0; i < SeedBytes; ++i) {
48
+ sk[i] = rho[i];
49
+ }
50
+ skOffset += SeedBytes;
51
+
52
+ for (let i = 0; i < SeedBytes; ++i) {
53
+ sk[skOffset + i] = key[i];
54
+ }
55
+ skOffset += SeedBytes;
56
+
57
+ for (let i = 0; i < SeedBytes; ++i) {
58
+ sk[skOffset + i] = tr[i];
59
+ }
60
+ skOffset += SeedBytes;
61
+
62
+ for (let i = 0; i < L; ++i) {
63
+ polyEtaPack(sk, skOffset + i * PolyETAPackedBytes, s1.vec[i]);
64
+ }
65
+ skOffset += L * PolyETAPackedBytes;
66
+
67
+ for (let i = 0; i < K; ++i) {
68
+ polyEtaPack(sk, skOffset + i * PolyETAPackedBytes, s2.vec[i]);
69
+ }
70
+ skOffset += K * PolyETAPackedBytes;
71
+
72
+ for (let i = 0; i < K; ++i) {
73
+ polyT0Pack(sk, skOffset + i * PolyT0PackedBytes, t0.vec[i]);
74
+ }
75
+ }
76
+
77
+ export function unpackSk(rhoP, trP, keyP, t0, s1, s2, sk) {
78
+ let skOffset = 0;
79
+ const rho = rhoP;
80
+ const tr = trP;
81
+ const key = keyP;
82
+ for (let i = 0; i < SeedBytes; ++i) {
83
+ rho[i] = sk[skOffset + i];
84
+ }
85
+ skOffset += SeedBytes;
86
+
87
+ for (let i = 0; i < SeedBytes; ++i) {
88
+ key[i] = sk[skOffset + i];
89
+ }
90
+ skOffset += SeedBytes;
91
+
92
+ for (let i = 0; i < SeedBytes; ++i) {
93
+ tr[i] = sk[skOffset + i];
94
+ }
95
+ skOffset += SeedBytes;
96
+
97
+ for (let i = 0; i < L; ++i) {
98
+ polyEtaUnpack(s1.vec[i], sk, skOffset + i * PolyETAPackedBytes);
99
+ }
100
+ skOffset += L * PolyETAPackedBytes;
101
+
102
+ for (let i = 0; i < K; ++i) {
103
+ polyEtaUnpack(s2.vec[i], sk, skOffset + i * PolyETAPackedBytes);
104
+ }
105
+ skOffset += K * PolyETAPackedBytes;
106
+
107
+ for (let i = 0; i < K; ++i) {
108
+ polyT0Unpack(t0.vec[i], sk, skOffset + i * PolyT0PackedBytes);
109
+ }
110
+ }
111
+
112
+ export function packSig(sigP, c, z, h) {
113
+ let sigOffset = 0;
114
+ const sig = sigP;
115
+ for (let i = 0; i < SeedBytes; ++i) {
116
+ sig[i] = c[i];
117
+ }
118
+ sigOffset += SeedBytes;
119
+
120
+ for (let i = 0; i < L; ++i) {
121
+ polyZPack(sig, sigOffset + i * PolyZPackedBytes, z.vec[i]);
122
+ }
123
+ sigOffset += L * PolyZPackedBytes;
124
+
125
+ for (let i = 0; i < OMEGA + K; ++i) {
126
+ sig[sigOffset + i] = 0;
127
+ }
128
+
129
+ let k = 0;
130
+ for (let i = 0; i < K; ++i) {
131
+ for (let j = 0; j < N; ++j) {
132
+ if (h.vec[i].coeffs[j] !== 0) {
133
+ sig[sigOffset + k++] = j;
134
+ }
135
+ }
136
+
137
+ sig[sigOffset + OMEGA + i] = k;
138
+ }
139
+ }
140
+
141
+ export function unpackSig(cP, z, hP, sig) {
142
+ let sigOffset = 0;
143
+ const c = cP;
144
+ const h = hP;
145
+ for (let i = 0; i < SeedBytes; ++i) {
146
+ c[i] = sig[i];
147
+ }
148
+ sigOffset += SeedBytes;
149
+
150
+ for (let i = 0; i < L; ++i) {
151
+ polyZUnpack(z.vec[i], sig, sigOffset + i * PolyZPackedBytes);
152
+ }
153
+ sigOffset += L * PolyZPackedBytes;
154
+
155
+ /* Decode h */
156
+ let k = 0;
157
+ for (let i = 0; i < K; ++i) {
158
+ for (let j = 0; j < N; ++j) {
159
+ h.vec[i].coeffs[j] = 0;
160
+ }
161
+
162
+ if (sig[sigOffset + OMEGA + i] < k || sig[sigOffset + OMEGA + i] > OMEGA) {
163
+ return 1;
164
+ }
165
+
166
+ for (let j = k; j < sig[sigOffset + OMEGA + i]; ++j) {
167
+ /* Coefficients are ordered for strong unforgeability */
168
+ if (j > k && sig[sigOffset + j] <= sig[sigOffset + j - 1]) {
169
+ return 1;
170
+ }
171
+ h.vec[i].coeffs[sig[sigOffset + j]] = 1;
172
+ }
173
+
174
+ k = sig[sigOffset + OMEGA + i];
175
+ }
176
+
177
+ /* Extra indices are zero for strong unforgeability */
178
+ for (let j = k; j < OMEGA; ++j) {
179
+ if (sig[sigOffset + j]) {
180
+ return 1;
181
+ }
182
+ }
183
+
184
+ return 0;
185
+ }
package/src/poly.js ADDED
@@ -0,0 +1,438 @@
1
+ import {
2
+ D,
3
+ ETA,
4
+ GAMMA1,
5
+ N,
6
+ PolyUniformETANBlocks,
7
+ PolyUniformGamma1NBlocks,
8
+ PolyUniformNBlocks,
9
+ Q,
10
+ SeedBytes,
11
+ Shake256Rate,
12
+ Stream128BlockBytes,
13
+ Stream256BlockBytes,
14
+ TAU,
15
+ } from './const.js';
16
+ import {
17
+ KeccakState,
18
+ shake128SqueezeBlocks,
19
+ shake256Absorb,
20
+ shake256Finalize,
21
+ shake256Init,
22
+ shake256SqueezeBlocks,
23
+ } from './fips202.js';
24
+ import { dilithiumShake128StreamInit, dilithiumShake256StreamInit } from './symmetric-shake.js';
25
+ import { invNTTToMont, ntt } from './ntt.js';
26
+ import { cAddQ, montgomeryReduce, reduce32 } from './reduce.js';
27
+ import { decompose, makeHint, power2round, useHint } from './rounding.js';
28
+
29
+ export class Poly {
30
+ constructor() {
31
+ this.coeffs = new Int32Array(N);
32
+ }
33
+
34
+ copy(poly) {
35
+ for (let i = N - 1; i >= 0; i--) {
36
+ this.coeffs[i] = poly.coeffs[i];
37
+ }
38
+ }
39
+ }
40
+
41
+ export function polyReduce(aP) {
42
+ const a = aP;
43
+ for (let i = 0; i < N; ++i) a.coeffs[i] = reduce32(a.coeffs[i]);
44
+ }
45
+
46
+ export function polyCAddQ(aP) {
47
+ const a = aP;
48
+ for (let i = 0; i < N; ++i) a.coeffs[i] = cAddQ(a.coeffs[i]);
49
+ }
50
+
51
+ export function polyAdd(cP, a, b) {
52
+ const c = cP;
53
+ for (let i = 0; i < N; ++i) c.coeffs[i] = a.coeffs[i] + b.coeffs[i];
54
+ }
55
+
56
+ export function polySub(cP, a, b) {
57
+ const c = cP;
58
+ for (let i = 0; i < N; ++i) c.coeffs[i] = a.coeffs[i] - b.coeffs[i];
59
+ }
60
+
61
+ export function polyShiftL(aP) {
62
+ const a = aP;
63
+ for (let i = 0; i < N; ++i) a.coeffs[i] <<= D;
64
+ }
65
+
66
+ export function polyNTT(a) {
67
+ ntt(a.coeffs);
68
+ }
69
+
70
+ export function polyInvNTTToMont(a) {
71
+ invNTTToMont(a.coeffs);
72
+ }
73
+
74
+ export function polyPointWiseMontgomery(cP, a, b) {
75
+ const c = cP;
76
+ for (let i = 0; i < N; ++i) c.coeffs[i] = Number(montgomeryReduce(BigInt(a.coeffs[i]) * BigInt(b.coeffs[i])));
77
+ }
78
+
79
+ export function polyPower2round(a1p, a0, a) {
80
+ const a1 = a1p;
81
+ for (let i = 0; i < N; ++i) a1.coeffs[i] = power2round(a0.coeffs, i, a.coeffs[i]);
82
+ }
83
+
84
+ export function polyDecompose(a1p, a0, a) {
85
+ const a1 = a1p;
86
+ for (let i = 0; i < N; ++i) a1.coeffs[i] = decompose(a0.coeffs, i, a.coeffs[i]);
87
+ }
88
+
89
+ export function polyMakeHint(hp, a0, a1) {
90
+ let s = 0;
91
+ const h = hp;
92
+ for (let i = 0; i < N; ++i) {
93
+ h.coeffs[i] = makeHint(a0.coeffs[i], a1.coeffs[i]);
94
+ s += h.coeffs[i];
95
+ }
96
+
97
+ return s;
98
+ }
99
+
100
+ export function polyUseHint(bp, a, h) {
101
+ const b = bp;
102
+ for (let i = 0; i < N; ++i) {
103
+ b.coeffs[i] = useHint(a.coeffs[i], h.coeffs[i]);
104
+ }
105
+ }
106
+
107
+ export function polyChkNorm(a, b) {
108
+ if (b > Math.floor((Q - 1) / 8)) {
109
+ return 1;
110
+ }
111
+
112
+ for (let i = 0; i < N; i++) {
113
+ let t = a.coeffs[i] >> 31;
114
+ t = a.coeffs[i] - (t & (2 * a.coeffs[i]));
115
+
116
+ if (t >= b) {
117
+ return 1;
118
+ }
119
+ }
120
+
121
+ return 0;
122
+ }
123
+
124
+ export function rejUniform(ap, aOffset, len, buf, bufLen) {
125
+ let ctr = 0;
126
+ let pos = 0;
127
+ const a = ap;
128
+ while (ctr < len && pos + 3 <= bufLen) {
129
+ let t = buf[pos++];
130
+ t |= buf[pos++] << 8;
131
+ t |= buf[pos++] << 16;
132
+ t &= 0x7fffff;
133
+
134
+ if (t < Q) {
135
+ a[aOffset + ctr++] = t;
136
+ }
137
+ }
138
+
139
+ return ctr;
140
+ }
141
+
142
+ export function polyUniform(a, seed, nonce) {
143
+ let off = 0;
144
+ let bufLen = PolyUniformNBlocks * Stream128BlockBytes;
145
+ const buf = new Uint8Array(PolyUniformNBlocks * Stream128BlockBytes + 2);
146
+
147
+ const state = new KeccakState();
148
+ dilithiumShake128StreamInit(state, seed, nonce);
149
+ shake128SqueezeBlocks(buf, off, PolyUniformNBlocks, state);
150
+
151
+ let ctr = rejUniform(a.coeffs, 0, N, buf, bufLen);
152
+
153
+ while (ctr < N) {
154
+ off = bufLen % 3;
155
+ for (let i = 0; i < off; ++i) buf[i] = buf[bufLen - off + i];
156
+
157
+ shake128SqueezeBlocks(buf, off, 1, state);
158
+ bufLen = Stream128BlockBytes + off;
159
+ ctr += rejUniform(a.coeffs, ctr, N - ctr, buf, bufLen);
160
+ }
161
+ }
162
+
163
+ export function rejEta(aP, aOffset, len, buf, bufLen) {
164
+ let ctr;
165
+ let pos;
166
+ let t0;
167
+ let t1;
168
+ const a = aP;
169
+ ctr = 0;
170
+ pos = 0;
171
+ while (ctr < len && pos < bufLen) {
172
+ t0 = buf[pos] & 0x0f;
173
+ t1 = buf[pos++] >> 4;
174
+
175
+ if (t0 < 15) {
176
+ t0 -= ((205 * t0) >> 10) * 5;
177
+ a[aOffset + ctr++] = 2 - t0;
178
+ }
179
+ if (t1 < 15 && ctr < len) {
180
+ t1 -= ((205 * t1) >> 10) * 5;
181
+ a[aOffset + ctr++] = 2 - t1;
182
+ }
183
+ }
184
+
185
+ return ctr;
186
+ }
187
+
188
+ export function polyUniformEta(a, seed, nonce) {
189
+ let ctr;
190
+ const bufLen = PolyUniformETANBlocks * Stream256BlockBytes;
191
+ const buf = new Uint8Array(bufLen);
192
+
193
+ const state = new KeccakState();
194
+ dilithiumShake256StreamInit(state, seed, nonce);
195
+ shake256SqueezeBlocks(buf, 0, PolyUniformETANBlocks, state);
196
+
197
+ ctr = rejEta(a.coeffs, 0, N, buf, bufLen);
198
+ while (ctr < N) {
199
+ shake256SqueezeBlocks(buf, 0, 1, state);
200
+ ctr += rejEta(a.coeffs, ctr, N - ctr, buf, Stream256BlockBytes);
201
+ }
202
+ }
203
+
204
+ export function polyZUnpack(rP, a, aOffset) {
205
+ const r = rP;
206
+ for (let i = 0; i < N / 2; ++i) {
207
+ r.coeffs[2 * i] = a[aOffset + 5 * i];
208
+ r.coeffs[2 * i] |= a[aOffset + 5 * i + 1] << 8;
209
+ r.coeffs[2 * i] |= a[aOffset + 5 * i + 2] << 16;
210
+ r.coeffs[2 * i] &= 0xfffff;
211
+
212
+ r.coeffs[2 * i + 1] = a[aOffset + 5 * i + 2] >> 4;
213
+ r.coeffs[2 * i + 1] |= a[aOffset + 5 * i + 3] << 4;
214
+ r.coeffs[2 * i + 1] |= a[aOffset + 5 * i + 4] << 12;
215
+ r.coeffs[2 * i] &= 0xfffff;
216
+
217
+ r.coeffs[2 * i] = GAMMA1 - r.coeffs[2 * i];
218
+ r.coeffs[2 * i + 1] = GAMMA1 - r.coeffs[2 * i + 1];
219
+ }
220
+ }
221
+
222
+ export function polyUniformGamma1(a, seed, nonce) {
223
+ const buf = new Uint8Array(PolyUniformGamma1NBlocks * Stream256BlockBytes);
224
+
225
+ const state = new KeccakState();
226
+ dilithiumShake256StreamInit(state, seed, nonce);
227
+ shake256SqueezeBlocks(buf, 0, PolyUniformGamma1NBlocks, state);
228
+ polyZUnpack(a, buf, 0);
229
+ }
230
+
231
+ export function polyChallenge(cP, seed) {
232
+ let b;
233
+ let pos;
234
+ const c = cP;
235
+ const buf = new Uint8Array(Shake256Rate);
236
+
237
+ const state = new KeccakState();
238
+ shake256Init(state);
239
+ shake256Absorb(state, seed.slice(0, SeedBytes));
240
+ shake256Finalize(state);
241
+ shake256SqueezeBlocks(buf, 0, 1, state);
242
+
243
+ let signs = 0n;
244
+ for (let i = 0; i < 8; ++i) {
245
+ signs = BigInt.asUintN(64, signs | (BigInt(buf[i]) << BigInt(8 * i)));
246
+ }
247
+ pos = 8;
248
+
249
+ for (let i = 0; i < N; ++i) {
250
+ c.coeffs[i] = 0;
251
+ }
252
+ for (let i = N - TAU; i < N; ++i) {
253
+ do {
254
+ if (pos >= Shake256Rate) {
255
+ shake256SqueezeBlocks(buf, 0, 1, state);
256
+ pos = 0;
257
+ }
258
+
259
+ b = buf[pos++];
260
+ } while (b > i);
261
+
262
+ c.coeffs[i] = c.coeffs[b];
263
+ c.coeffs[b] = Number(1n - 2n * (signs & 1n));
264
+ signs >>= 1n;
265
+ }
266
+ }
267
+
268
+ export function polyEtaPack(rP, rOffset, a) {
269
+ const t = new Uint8Array(8);
270
+ const r = rP;
271
+ for (let i = 0; i < N / 8; ++i) {
272
+ t[0] = ETA - a.coeffs[8 * i];
273
+ t[1] = ETA - a.coeffs[8 * i + 1];
274
+ t[2] = ETA - a.coeffs[8 * i + 2];
275
+ t[3] = ETA - a.coeffs[8 * i + 3];
276
+ t[4] = ETA - a.coeffs[8 * i + 4];
277
+ t[5] = ETA - a.coeffs[8 * i + 5];
278
+ t[6] = ETA - a.coeffs[8 * i + 6];
279
+ t[7] = ETA - a.coeffs[8 * i + 7];
280
+
281
+ r[rOffset + 3 * i] = (t[0] >> 0) | (t[1] << 3) | (t[2] << 6);
282
+ r[rOffset + 3 * i + 1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
283
+ r[rOffset + 3 * i + 2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
284
+ }
285
+ }
286
+
287
+ export function polyEtaUnpack(rP, a, aOffset) {
288
+ const r = rP;
289
+ for (let i = 0; i < N / 8; ++i) {
290
+ r.coeffs[8 * i] = (a[aOffset + 3 * i] >> 0) & 7;
291
+ r.coeffs[8 * i + 1] = (a[aOffset + 3 * i] >> 3) & 7;
292
+ r.coeffs[8 * i + 2] = ((a[aOffset + 3 * i] >> 6) | (a[aOffset + 3 * i + 1] << 2)) & 7;
293
+ r.coeffs[8 * i + 3] = (a[aOffset + 3 * i + 1] >> 1) & 7;
294
+ r.coeffs[8 * i + 4] = (a[aOffset + 3 * i + 1] >> 4) & 7;
295
+ r.coeffs[8 * i + 5] = ((a[aOffset + 3 * i + 1] >> 7) | (a[aOffset + 3 * i + 2] << 1)) & 7;
296
+ r.coeffs[8 * i + 6] = (a[aOffset + 3 * i + 2] >> 2) & 7;
297
+ r.coeffs[8 * i + 7] = (a[aOffset + 3 * i + 2] >> 5) & 7;
298
+
299
+ r.coeffs[8 * i] = ETA - r.coeffs[8 * i];
300
+ r.coeffs[8 * i + 1] = ETA - r.coeffs[8 * i + 1];
301
+ r.coeffs[8 * i + 2] = ETA - r.coeffs[8 * i + 2];
302
+ r.coeffs[8 * i + 3] = ETA - r.coeffs[8 * i + 3];
303
+ r.coeffs[8 * i + 4] = ETA - r.coeffs[8 * i + 4];
304
+ r.coeffs[8 * i + 5] = ETA - r.coeffs[8 * i + 5];
305
+ r.coeffs[8 * i + 6] = ETA - r.coeffs[8 * i + 6];
306
+ r.coeffs[8 * i + 7] = ETA - r.coeffs[8 * i + 7];
307
+ }
308
+ }
309
+
310
+ export function polyT1Pack(rP, rOffset, a) {
311
+ const r = rP;
312
+ for (let i = 0; i < N / 4; ++i) {
313
+ r[rOffset + 5 * i] = a.coeffs[4 * i] >> 0;
314
+ r[rOffset + 5 * i + 1] = (a.coeffs[4 * i] >> 8) | (a.coeffs[4 * i + 1] << 2);
315
+ r[rOffset + 5 * i + 2] = (a.coeffs[4 * i + 1] >> 6) | (a.coeffs[4 * i + 2] << 4);
316
+ r[rOffset + 5 * i + 3] = (a.coeffs[4 * i + 2] >> 4) | (a.coeffs[4 * i + 3] << 6);
317
+ r[rOffset + 5 * i + 4] = a.coeffs[4 * i + 3] >> 2;
318
+ }
319
+ }
320
+
321
+ export function polyT1Unpack(rP, a, aOffset) {
322
+ const r = rP;
323
+ for (let i = 0; i < N / 4; ++i) {
324
+ r.coeffs[4 * i] = ((a[aOffset + 5 * i] >> 0) | (a[aOffset + 5 * i + 1] << 8)) & 0x3ff;
325
+ r.coeffs[4 * i + 1] = ((a[aOffset + 5 * i + 1] >> 2) | (a[aOffset + 5 * i + 2] << 6)) & 0x3ff;
326
+ r.coeffs[4 * i + 2] = ((a[aOffset + 5 * i + 2] >> 4) | (a[aOffset + 5 * i + 3] << 4)) & 0x3ff;
327
+ r.coeffs[4 * i + 3] = ((a[aOffset + 5 * i + 3] >> 6) | (a[aOffset + 5 * i + 4] << 2)) & 0x3ff;
328
+ }
329
+ }
330
+
331
+ export function polyT0Pack(rP, rOffset, a) {
332
+ const t = new Uint32Array(8);
333
+ const r = rP;
334
+ for (let i = 0; i < N / 8; ++i) {
335
+ t[0] = (1 << (D - 1)) - a.coeffs[8 * i];
336
+ t[1] = (1 << (D - 1)) - a.coeffs[8 * i + 1];
337
+ t[2] = (1 << (D - 1)) - a.coeffs[8 * i + 2];
338
+ t[3] = (1 << (D - 1)) - a.coeffs[8 * i + 3];
339
+ t[4] = (1 << (D - 1)) - a.coeffs[8 * i + 4];
340
+ t[5] = (1 << (D - 1)) - a.coeffs[8 * i + 5];
341
+ t[6] = (1 << (D - 1)) - a.coeffs[8 * i + 6];
342
+ t[7] = (1 << (D - 1)) - a.coeffs[8 * i + 7];
343
+
344
+ r[rOffset + 13 * i] = t[0]; // eslint-disable-line prefer-destructuring
345
+ r[rOffset + 13 * i + 1] = t[0] >> 8;
346
+ r[rOffset + 13 * i + 1] |= t[1] << 5;
347
+ r[rOffset + 13 * i + 2] = t[1] >> 3;
348
+ r[rOffset + 13 * i + 3] = t[1] >> 11;
349
+ r[rOffset + 13 * i + 3] |= t[2] << 2;
350
+ r[rOffset + 13 * i + 4] = t[2] >> 6;
351
+ r[rOffset + 13 * i + 4] |= t[3] << 7;
352
+ r[rOffset + 13 * i + 5] = t[3] >> 1;
353
+ r[rOffset + 13 * i + 6] = t[3] >> 9;
354
+ r[rOffset + 13 * i + 6] |= t[4] << 4;
355
+ r[rOffset + 13 * i + 7] = t[4] >> 4;
356
+ r[rOffset + 13 * i + 8] = t[4] >> 12;
357
+ r[rOffset + 13 * i + 8] |= t[5] << 1;
358
+ r[rOffset + 13 * i + 9] = t[5] >> 7;
359
+ r[rOffset + 13 * i + 9] |= t[6] << 6;
360
+ r[rOffset + 13 * i + 10] = t[6] >> 2;
361
+ r[rOffset + 13 * i + 11] = t[6] >> 10;
362
+ r[rOffset + 13 * i + 11] |= t[7] << 3;
363
+ r[rOffset + 13 * i + 12] = t[7] >> 5;
364
+ }
365
+ }
366
+
367
+ export function polyT0Unpack(rP, a, aOffset) {
368
+ const r = rP;
369
+ for (let i = 0; i < N / 8; ++i) {
370
+ r.coeffs[8 * i] = a[aOffset + 13 * i];
371
+ r.coeffs[8 * i] |= a[aOffset + 13 * i + 1] << 8;
372
+ r.coeffs[8 * i] &= 0x1fff;
373
+
374
+ r.coeffs[8 * i + 1] = a[aOffset + 13 * i + 1] >> 5;
375
+ r.coeffs[8 * i + 1] |= a[aOffset + 13 * i + 2] << 3;
376
+ r.coeffs[8 * i + 1] |= a[aOffset + 13 * i + 3] << 11;
377
+ r.coeffs[8 * i + 1] &= 0x1fff;
378
+
379
+ r.coeffs[8 * i + 2] = a[aOffset + 13 * i + 3] >> 2;
380
+ r.coeffs[8 * i + 2] |= a[aOffset + 13 * i + 4] << 6;
381
+ r.coeffs[8 * i + 2] &= 0x1fff;
382
+
383
+ r.coeffs[8 * i + 3] = a[aOffset + 13 * i + 4] >> 7;
384
+ r.coeffs[8 * i + 3] |= a[aOffset + 13 * i + 5] << 1;
385
+ r.coeffs[8 * i + 3] |= a[aOffset + 13 * i + 6] << 9;
386
+ r.coeffs[8 * i + 3] &= 0x1fff;
387
+
388
+ r.coeffs[8 * i + 4] = a[aOffset + 13 * i + 6] >> 4;
389
+ r.coeffs[8 * i + 4] |= a[aOffset + 13 * i + 7] << 4;
390
+ r.coeffs[8 * i + 4] |= a[aOffset + 13 * i + 8] << 12;
391
+ r.coeffs[8 * i + 4] &= 0x1fff;
392
+
393
+ r.coeffs[8 * i + 5] = a[aOffset + 13 * i + 8] >> 1;
394
+ r.coeffs[8 * i + 5] |= a[aOffset + 13 * i + 9] << 7;
395
+ r.coeffs[8 * i + 5] &= 0x1fff;
396
+
397
+ r.coeffs[8 * i + 6] = a[aOffset + 13 * i + 9] >> 6;
398
+ r.coeffs[8 * i + 6] |= a[aOffset + 13 * i + 10] << 2;
399
+ r.coeffs[8 * i + 6] |= a[aOffset + 13 * i + 11] << 10;
400
+ r.coeffs[8 * i + 6] &= 0x1fff;
401
+
402
+ r.coeffs[8 * i + 7] = a[aOffset + 13 * i + 11] >> 3;
403
+ r.coeffs[8 * i + 7] |= a[aOffset + 13 * i + 12] << 5;
404
+ r.coeffs[8 * i + 7] &= 0x1fff;
405
+
406
+ r.coeffs[8 * i] = (1 << (D - 1)) - r.coeffs[8 * i];
407
+ r.coeffs[8 * i + 1] = (1 << (D - 1)) - r.coeffs[8 * i + 1];
408
+ r.coeffs[8 * i + 2] = (1 << (D - 1)) - r.coeffs[8 * i + 2];
409
+ r.coeffs[8 * i + 3] = (1 << (D - 1)) - r.coeffs[8 * i + 3];
410
+ r.coeffs[8 * i + 4] = (1 << (D - 1)) - r.coeffs[8 * i + 4];
411
+ r.coeffs[8 * i + 5] = (1 << (D - 1)) - r.coeffs[8 * i + 5];
412
+ r.coeffs[8 * i + 6] = (1 << (D - 1)) - r.coeffs[8 * i + 6];
413
+ r.coeffs[8 * i + 7] = (1 << (D - 1)) - r.coeffs[8 * i + 7];
414
+ }
415
+ }
416
+
417
+ export function polyZPack(rP, rOffset, a) {
418
+ const t = new Uint32Array(4);
419
+ const r = rP;
420
+ for (let i = 0; i < N / 2; ++i) {
421
+ t[0] = GAMMA1 - a.coeffs[2 * i];
422
+ t[1] = GAMMA1 - a.coeffs[2 * i + 1];
423
+
424
+ r[rOffset + 5 * i] = t[0]; // eslint-disable-line prefer-destructuring
425
+ r[rOffset + 5 * i + 1] = t[0] >> 8;
426
+ r[rOffset + 5 * i + 2] = t[0] >> 16;
427
+ r[rOffset + 5 * i + 2] |= t[1] << 4;
428
+ r[rOffset + 5 * i + 3] = t[1] >> 4;
429
+ r[rOffset + 5 * i + 4] = t[1] >> 12;
430
+ }
431
+ }
432
+
433
+ export function polyW1Pack(rP, rOffset, a) {
434
+ const r = rP;
435
+ for (let i = 0; i < N / 2; ++i) {
436
+ r[rOffset + i] = a.coeffs[2 * i] | (a.coeffs[2 * i + 1] << 4);
437
+ }
438
+ }