1#![no_std]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4#![allow(clippy::too_many_arguments)]
5
6mod flr;
62mod poly;
63mod sampler;
64
65pub use fn_dsa_comm::{
67 CryptoRng,
68 DOMAIN_NONE,
69 DomainContext,
70 FN_DSA_LOGN_512,
71 FN_DSA_LOGN_1024,
72 HASH_ID_RAW,
73 HASH_ID_SHA3_256,
74 HASH_ID_SHA3_384,
75 HASH_ID_SHA3_512,
76 HASH_ID_SHA256,
77 HASH_ID_SHA384,
78 HASH_ID_SHA512,
79 HASH_ID_SHA512_256,
80 HASH_ID_SHAKE128,
81 HASH_ID_SHAKE256,
82 HashIdentifier,
83 Rng,
84 RngError,
85 sign_key_size,
86 signature_size,
87 vrfy_key_size,
88};
89use fn_dsa_comm::{
90 PRNG,
91 codec,
92 hash_to_point,
93 mq,
94 shake,
95};
96use zeroize::{
97 Zeroize,
98 ZeroizeOnDrop,
99};
100
101pub trait SigningKey: Sized {
111 fn decode(sec: &[u8]) -> Option<Self>;
119
120 fn get_logn(&self) -> u32;
125
126 fn to_verifying_key(&self, vrfy_key: &mut [u8]);
130
131 fn sign<T: CryptoRng + Rng>(
144 &mut self,
145 rng: &mut T,
146 ctx: &DomainContext,
147 id: &HashIdentifier,
148 hv: &[u8],
149 sig: &mut [u8],
150 );
151}
152
153macro_rules! sign_key_impl {
154 ($typename:ident, $logn_min:expr, $logn_max:expr) => {
155 #[doc = concat!("Signature generator for degrees (`logn`) ",
156 stringify!($logn_min), " to ", stringify!($logn_max), " only.")]
157 #[derive(Zeroize, ZeroizeOnDrop)]
158 pub struct $typename {
159 f: [i8; 1 << ($logn_max)],
160 g: [i8; 1 << ($logn_max)],
161 F: [i8; 1 << ($logn_max)],
162 G: [i8; 1 << ($logn_max)],
163 vrfy_key: [u8; vrfy_key_size($logn_max)],
164 hashed_vrfy_key: [u8; 64],
165 tmp_i16: [i16; 1 << ($logn_max)],
166 tmp_u16: [u16; 2 << ($logn_max)],
167 tmp_flr: [flr::Flr; 9 << ($logn_max)],
168
169 #[cfg(not(feature = "small_context"))]
171 basis: [flr::Flr; 4 << ($logn_max)],
172
173 logn: u32,
174
175 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
180 use_avx2: bool,
181 }
182
183 impl $typename {
184 fn decode_key(&mut self, src: &[u8]) -> Option<u32> {
185 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
186 if self.use_avx2 {
187 unsafe {
188 return sign_avx2::decode_avx2_inner(
189 $logn_min,
190 $logn_max,
191 &mut self.f[..],
192 &mut self.g[..],
193 &mut self.F[..],
194 &mut self.G[..],
195 &mut self.vrfy_key[..],
196 &mut self.hashed_vrfy_key[..],
197 &mut self.tmp_u16[..],
198 src,
199 );
200 }
201 }
202
203 decode_inner(
204 $logn_min,
205 $logn_max,
206 &mut self.f[..],
207 &mut self.g[..],
208 &mut self.F[..],
209 &mut self.G[..],
210 &mut self.vrfy_key[..],
211 &mut self.hashed_vrfy_key[..],
212 &mut self.tmp_u16[..],
213 src,
214 )
215 }
216
217 #[cfg(not(feature = "small_context"))]
218 fn compute_basis(&mut self) {
219 let n = 1usize << self.logn;
220
221 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
222 if self.use_avx2 {
223 unsafe {
224 sign_avx2::compute_basis_avx2_inner(
225 self.logn,
226 &self.f[..n],
227 &self.g[..n],
228 &self.F[..n],
229 &self.G[..n],
230 &mut self.basis[..(4 * n)],
231 );
232 }
233 return;
234 }
235
236 compute_basis_inner(
237 self.logn,
238 &self.f[..n],
239 &self.g[..n],
240 &self.F[..n],
241 &self.G[..n],
242 &mut self.basis[..(4 * n)],
243 );
244 }
245 }
246
247 impl SigningKey for $typename {
248 fn decode(src: &[u8]) -> Option<Self> {
249 let f = [0i8; 1 << ($logn_max)];
250 let g = [0i8; 1 << ($logn_max)];
251 let F = [0i8; 1 << ($logn_max)];
252 let G = [0i8; 1 << ($logn_max)];
253 let vrfy_key = [0u8; vrfy_key_size($logn_max)];
254 let hashed_vrfy_key = [0u8; 64];
255 let tmp_i16 = [0i16; 1 << ($logn_max)];
256 let tmp_u16 = [0u16; 2 << ($logn_max)];
257 let tmp_flr = [flr::Flr::ZERO; 9 << ($logn_max)];
258
259 #[cfg(not(feature = "small_context"))]
260 let basis = [flr::Flr::ZERO; 4 << ($logn_max)];
261
262 let mut sk = Self {
263 f,
264 g,
265 F,
266 G,
267 vrfy_key,
268 hashed_vrfy_key,
269 tmp_i16,
270 tmp_u16,
271 tmp_flr,
272 #[cfg(not(feature = "small_context"))]
273 basis,
274 logn: 0,
275 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
276 use_avx2: fn_dsa_comm::has_avx2(),
277 };
278 sk.logn = sk.decode_key(src)?;
279
280 #[cfg(not(feature = "small_context"))]
281 sk.compute_basis();
282
283 Some(sk)
284 }
285
286 fn get_logn(&self) -> u32 {
287 self.logn
288 }
289
290 fn to_verifying_key(&self, vrfy_key: &mut [u8]) {
291 let len = vrfy_key_size(self.logn);
292 assert!(vrfy_key.len() == len);
293 vrfy_key.copy_from_slice(&self.vrfy_key[..len]);
294 }
295
296 fn sign<T: CryptoRng + Rng>(
297 &mut self,
298 rng: &mut T,
299 ctx: &DomainContext,
300 id: &HashIdentifier,
301 hv: &[u8],
302 sig: &mut [u8],
303 ) {
304 let n = 1usize << self.logn;
305
306 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
307 if self.use_avx2 {
308 unsafe {
309 #[cfg(feature = "shake256x4")]
310 sign_avx2::sign_avx2_inner::<T, shake::SHAKE256x4>(
311 self.logn,
312 rng,
313 &self.f[..n],
314 &self.g[..n],
315 &self.F[..n],
316 &self.G[..n],
317 &self.hashed_vrfy_key,
318 ctx,
319 id,
320 hv,
321 sig,
322 #[cfg(not(feature = "small_context"))]
323 &self.basis[..(4 * n)],
324 &mut self.tmp_i16,
325 &mut self.tmp_u16,
326 &mut self.tmp_flr,
327 );
328
329 #[cfg(not(feature = "shake256x4"))]
330 sign_avx2::sign_avx2_inner::<T, shake::SHAKE256_PRNG>(
331 self.logn,
332 rng,
333 &self.f[..n],
334 &self.g[..n],
335 &self.F[..n],
336 &self.G[..n],
337 &self.hashed_vrfy_key,
338 ctx,
339 id,
340 hv,
341 sig,
342 #[cfg(not(feature = "small_context"))]
343 &self.basis[..(4 * n)],
344 &mut self.tmp_i16,
345 &mut self.tmp_u16,
346 &mut self.tmp_flr,
347 );
348 }
349 return;
350 }
351
352 #[cfg(feature = "shake256x4")]
353 sign_inner::<T, shake::SHAKE256x4>(
354 self.logn,
355 rng,
356 &self.f[..n],
357 &self.g[..n],
358 &self.F[..n],
359 &self.G[..n],
360 &self.hashed_vrfy_key,
361 ctx,
362 id,
363 hv,
364 sig,
365 #[cfg(not(feature = "small_context"))]
366 &self.basis[..(4 * n)],
367 &mut self.tmp_i16,
368 &mut self.tmp_u16,
369 &mut self.tmp_flr,
370 );
371
372 #[cfg(not(feature = "shake256x4"))]
373 sign_inner::<T, shake::SHAKE256_PRNG>(
374 self.logn,
375 rng,
376 &self.f[..n],
377 &self.g[..n],
378 &self.F[..n],
379 &self.G[..n],
380 &self.hashed_vrfy_key,
381 ctx,
382 id,
383 hv,
384 sig,
385 #[cfg(not(feature = "small_context"))]
386 &self.basis[..(4 * n)],
387 &mut self.tmp_i16,
388 &mut self.tmp_u16,
389 &mut self.tmp_flr,
390 );
391 }
392 }
393 };
394}
395
396sign_key_impl!(SigningKeyStandard, 9, 10);
398
399sign_key_impl!(SigningKey512, 9, 9);
402
403sign_key_impl!(SigningKey1024, 10, 10);
406
407sign_key_impl!(SigningKeyWeak, 2, 8);
410
411#[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
412mod sign_avx2;
413
414fn decode_inner(
416 logn_min: u32,
417 logn_max: u32,
418 f: &mut [i8],
419 g: &mut [i8],
420 F: &mut [i8],
421 G: &mut [i8],
422 vrfy_key: &mut [u8],
423 hashed_vrfy_key: &mut [u8],
424 tmp_u16: &mut [u16],
425 src: &[u8],
426) -> Option<u32> {
427 if src.is_empty() {
428 return None;
429 }
430 let head = src[0];
431 if (head & 0xF0) != 0x50 {
432 return None;
433 }
434 let logn = (head & 0x0F) as u32;
435 if logn < logn_min || logn > logn_max {
436 return None;
437 }
438 if src.len() != sign_key_size(logn) {
439 return None;
440 }
441 let n = 1usize << logn;
442 assert!(f.len() >= n);
443 assert!(g.len() >= n);
444 assert!(F.len() >= n);
445 assert!(G.len() >= n);
446 assert!(vrfy_key.len() >= vrfy_key_size(logn));
447 assert!(hashed_vrfy_key.len() == 64);
448 let f = &mut f[..n];
449 let g = &mut g[..n];
450 let F = &mut F[..n];
451 let G = &mut G[..n];
452 let vk = &mut vrfy_key[..vrfy_key_size(logn)];
453
454 let nbits_fg = match logn {
456 2..=5 => 8,
457 6..=7 => 7,
458 8..=9 => 6,
459 _ => 5,
460 };
461 let j = 1 + codec::trim_i8_decode(&src[1..], f, nbits_fg)?;
462 let j = j + codec::trim_i8_decode(&src[j..], g, nbits_fg)?;
463 let j = j + codec::trim_i8_decode(&src[j..], F, 8)?;
464 assert!(j == src.len());
467
468 let (w0, w1) = tmp_u16.split_at_mut(n);
478
479 mq::mqpoly_small_to_int(logn, &*g, w0);
481 mq::mqpoly_small_to_int(logn, &*f, w1);
482 mq::mqpoly_int_to_NTT(logn, w0);
483 mq::mqpoly_int_to_NTT(logn, w1);
484 if !mq::mqpoly_div_ntt(logn, w0, w1) {
485 return None;
487 }
488
489 mq::mqpoly_small_to_int(logn, &*F, w1);
491 mq::mqpoly_int_to_NTT(logn, w1);
492 mq::mqpoly_mul_ntt(logn, w1, w0);
493
494 mq::mqpoly_NTT_to_int(logn, w0);
496 mq::mqpoly_int_to_ext(logn, w0);
497 vk[0] = logn as u8;
498 let j = 1 + codec::modq_encode(&w0[..n], &mut vk[1..]);
499 assert!(j == vk.len());
500 let mut sh = shake::SHAKE256::new();
501 sh.inject(vk);
502 sh.flip();
503 sh.extract(hashed_vrfy_key);
504
505 mq::mqpoly_NTT_to_int(logn, w1);
508 if !mq::mqpoly_int_to_small(logn, w1, G) {
509 return None;
510 }
511
512 Some(logn)
514}
515
516fn compute_basis_inner(logn: u32, f: &[i8], g: &[i8], F: &[i8], G: &[i8], basis: &mut [flr::Flr]) {
517 let n = 1usize << logn;
518
519 let (b00, work) = basis.split_at_mut(n);
521 let (b01, work) = work.split_at_mut(n);
522 let (b10, work) = work.split_at_mut(n);
523 let (b11, _) = work.split_at_mut(n);
524
525 poly::poly_set_small(logn, b01, f);
526 poly::poly_set_small(logn, b00, g);
527 poly::poly_set_small(logn, b11, F);
528 poly::poly_set_small(logn, b10, G);
529 poly::FFT(logn, b01);
530 poly::FFT(logn, b00);
531 poly::FFT(logn, b11);
532 poly::FFT(logn, b10);
533 poly::poly_neg(logn, b01);
534 poly::poly_neg(logn, b11);
535}
536
537const INV_Q: flr::Flr = flr::Flr::scaled(6004310871091074, -66);
539
540fn sign_inner<T: CryptoRng + Rng, P: PRNG>(
541 logn: u32,
542 rng: &mut T,
543 f: &[i8],
544 g: &[i8],
545 F: &[i8],
546 G: &[i8],
547 hashed_vrfy_key: &[u8],
548 ctx: &DomainContext,
549 id: &HashIdentifier,
550 hv: &[u8],
551 sig: &mut [u8],
552 #[cfg(not(feature = "small_context"))] basis: &[flr::Flr],
553 tmp_i16: &mut [i16],
554 tmp_u16: &mut [u16],
555 tmp_flr: &mut [flr::Flr],
556) {
557 let n = 1usize << logn;
558 assert!(f.len() == n);
559 assert!(g.len() == n);
560 assert!(F.len() == n);
561 assert!(G.len() == n);
562 assert!(sig.len() == signature_size(logn));
563
564 let mut nonce = [0u8; 40];
569 let mut first = true;
570
571 loop {
576 let hm = &mut tmp_u16[0..n];
577 if first {
581 rng.fill_bytes(&mut nonce);
582 hash_to_point(&nonce, hashed_vrfy_key, ctx, id, hv, hm);
583 first = false;
584 }
585
586 let mut seed = [0u8; 56];
590 rng.fill_bytes(&mut seed);
591 let mut samp = sampler::Sampler::<P>::new(logn, &seed);
592
593 #[cfg(feature = "small_context")]
609 {
610 compute_basis_inner(logn, f, g, F, G, tmp_flr);
612
613 let (b00, work) = tmp_flr.split_at_mut(n);
614 let (b01, work) = work.split_at_mut(n);
615 let (b10, work) = work.split_at_mut(n);
616 let (b11, work) = work.split_at_mut(n);
617 let (t0, work) = work.split_at_mut(n);
618 let (t1, _) = work.split_at_mut(n);
619
620 t0.copy_from_slice(&*b01);
622 poly::poly_mulownadj_fft(logn, t0);
623
624 t1.copy_from_slice(&*b00);
626 poly::poly_muladj_fft(logn, t1, b10);
627
628 poly::poly_mulownadj_fft(logn, b00);
630
631 poly::poly_add(logn, b00, t0);
633
634 t0.copy_from_slice(b01);
636
637 poly::poly_muladj_fft(logn, b01, b11);
639 poly::poly_add(logn, b01, t1);
640
641 poly::poly_mulownadj_fft(logn, b10);
643
644 t1.copy_from_slice(b11);
646 poly::poly_mulownadj_fft(logn, t1);
647 poly::poly_add(logn, b10, t1);
648 }
649
650 #[cfg(not(feature = "small_context"))]
651 {
652 let (b00, work) = basis.split_at(n);
654 let (b01, work) = work.split_at(n);
655 let (b10, work) = work.split_at(n);
656 let (b11, _) = work.split_at(n);
657
658 let (g00, work) = tmp_flr.split_at_mut(n);
659 let (g01, work) = work.split_at_mut(n);
660 let (g11, work) = work.split_at_mut(n);
661 let (t0, work) = work.split_at_mut(n);
662 let (t1, _) = work.split_at_mut(n);
663
664 g00.copy_from_slice(b00);
665 poly::poly_mulownadj_fft(logn, g00);
666 t0.copy_from_slice(b01);
667 poly::poly_mulownadj_fft(logn, t0);
668 poly::poly_add(logn, g00, t0);
669
670 g01.copy_from_slice(b00);
671 poly::poly_muladj_fft(logn, g01, b10);
672 t0.copy_from_slice(b01);
673 poly::poly_muladj_fft(logn, t0, b11);
674 poly::poly_add(logn, g01, t0);
675
676 g11.copy_from_slice(b10);
677 poly::poly_mulownadj_fft(logn, g11);
678 t0.copy_from_slice(b11);
679 poly::poly_mulownadj_fft(logn, t0);
680 poly::poly_add(logn, g11, t0);
681
682 t0.copy_from_slice(b11);
683 t1.copy_from_slice(b01);
684 }
685
686 {
690 let (_, work) = tmp_flr.split_at_mut(3 * n);
691 let (b11, work) = work.split_at_mut(n);
692 let (b01, work) = work.split_at_mut(n);
693 let (t0, work) = work.split_at_mut(n);
694 let (t1, _) = work.split_at_mut(n);
695
696 for i in 0..n {
700 t0[i] = flr::Flr::from_i32(hm[i] as i32);
701 }
702
703 poly::FFT(logn, t0);
706 t1.copy_from_slice(t0);
707 poly::poly_mul_fft(logn, t1, b01);
708 poly::poly_mulconst(logn, t1, -INV_Q);
709 poly::poly_mul_fft(logn, t0, b11);
710 poly::poly_mulconst(logn, t0, INV_Q);
711 }
712
713 tmp_flr.copy_within((5 * n)..(7 * n), 3 * n);
715
716 {
720 let (g00, work) = tmp_flr.split_at_mut(n);
722 let (g01, work) = work.split_at_mut(n);
723 let (g11, work) = work.split_at_mut(n);
724 let (t0, work) = work.split_at_mut(n);
725 let (t1, work) = work.split_at_mut(n);
726 samp.ffsamp_fft(t0, t1, g00, g01, g11, work);
727 }
728
729 tmp_flr.copy_within((3 * n)..(5 * n), 4 * n);
732
733 #[cfg(feature = "small_context")]
734 compute_basis_inner(logn, f, g, F, G, tmp_flr);
735
736 #[cfg(not(feature = "small_context"))]
737 tmp_flr[..(4 * n)].copy_from_slice(&basis[..(4 * n)]);
738
739 let (b00, work) = tmp_flr.split_at_mut(n);
740 let (b01, work) = work.split_at_mut(n);
741 let (b10, work) = work.split_at_mut(n);
742 let (b11, work) = work.split_at_mut(n);
743 let (t0, work) = work.split_at_mut(n);
744 let (t1, work) = work.split_at_mut(n);
745 let (tx, work) = work.split_at_mut(n);
746 let (ty, _) = work.split_at_mut(n);
747
748 tx.copy_from_slice(t0);
750 ty.copy_from_slice(t1);
751 poly::poly_mul_fft(logn, tx, b00);
752 poly::poly_mul_fft(logn, ty, b10);
753 poly::poly_add(logn, tx, ty);
754 ty.copy_from_slice(t0);
755 poly::poly_mul_fft(logn, ty, b01);
756 t0.copy_from_slice(tx);
757 poly::poly_mul_fft(logn, t1, b11);
758 poly::poly_add(logn, t1, ty);
759 poly::iFFT(logn, t0);
760 poly::iFFT(logn, t1);
761
762 let mut sqn = 0u32;
769 let mut ng = 0;
770 for i in 0..n {
771 let z = (hm[i] as i32) - (t0[i].rint() as i32);
772 let z = (z as i16) as i32;
773 sqn = sqn.wrapping_add((z * z) as u32);
774 ng |= sqn;
775 }
776
777 let s2 = &mut tmp_i16[..n];
782 for i in 0..n {
783 let sz = (-t1[i].rint()) as i16;
784 let z = sz as i32;
785 sqn = sqn.wrapping_add((z * z) as u32);
786 ng |= sqn;
787 s2[i] = sz;
788 }
789
790 sqn |= ((ng as i32) >> 31) as u32;
795 if sqn > mq::SQBETA[logn as usize] {
796 continue;
797 }
798
799 if codec::comp_encode(s2, &mut sig[41..]) {
803 sig[0] = 0x30 + (logn as u8);
804 sig[1..41].copy_from_slice(&nonce);
805 return;
806 }
807 }
808}
809
810#[cfg(test)]
811pub(crate) mod tests {
812 #![allow(clippy::unwrap_used)]
813
814 use fn_dsa_comm::shake::SHAKE256;
815 #[cfg(feature = "shake256x4")]
819 pub(crate) use fn_dsa_comm::shake::SHAKE256x4;
820 use fn_dsa_comm::{
821 Infallible,
822 TryCryptoRng,
823 TryRng,
824 };
825
826 use super::*;
827
828 #[cfg(not(feature = "shake256x4"))]
829 #[derive(Copy, Clone, Debug)]
830 pub(crate) struct SHAKE256x4 {
831 sh: [SHAKE256; 4],
832 buf: [u8; 4 * 136],
833 ptr: usize,
834 }
835
836 #[cfg(not(feature = "shake256x4"))]
837 impl SHAKE256x4 {
838 pub fn new(seed: &[u8]) -> Self {
839 let mut sh = [
840 SHAKE256::new(),
841 SHAKE256::new(),
842 SHAKE256::new(),
843 SHAKE256::new(),
844 ];
845 for (i, item) in sh.iter_mut().enumerate() {
846 item.inject(seed);
847 item.inject(&[i as u8]);
848 item.flip();
849 }
850 Self {
851 sh,
852 buf: [0u8; 4 * 136],
853 ptr: 4 * 136,
854 }
855 }
856
857 fn refill(&mut self) {
858 self.ptr = 0;
859 for i in 0..(4 * 136 / 32) {
860 for j in 0..4 {
861 let k = 32 * i + 8 * j;
862 self.sh[j].extract(&mut self.buf[k..(k + 8)]);
863 }
864 }
865 }
866
867 pub fn next_u8(&mut self) -> u8 {
868 if self.ptr >= 4 * 136 {
869 self.refill();
870 }
871 let x = self.buf[self.ptr];
872 self.ptr += 1;
873 x
874 }
875
876 pub fn next_u16(&mut self) -> u16 {
877 if self.ptr >= 4 * 136 - 1 {
878 self.refill();
879 }
880 let x = u16::from_le_bytes(
881 *<&[u8; 2]>::try_from(&self.buf[self.ptr..self.ptr + 2]).unwrap(),
882 );
883 self.ptr += 2;
884 x
885 }
886
887 pub fn next_u64(&mut self) -> u64 {
888 if self.ptr >= 4 * 136 - 7 {
889 self.refill();
890 }
891 let x = u64::from_le_bytes(
892 *<&[u8; 8]>::try_from(&self.buf[self.ptr..self.ptr + 8]).unwrap(),
893 );
894 self.ptr += 8;
895 x
896 }
897 }
898
899 #[cfg(not(feature = "shake256x4"))]
900 impl fn_dsa_comm::PRNG for SHAKE256x4 {
901 fn new(seed: &[u8]) -> Self {
902 SHAKE256x4::new(seed)
903 }
904
905 fn next_u8(&mut self) -> u8 {
906 SHAKE256x4::next_u8(self)
907 }
908
909 fn next_u16(&mut self) -> u16 {
910 SHAKE256x4::next_u16(self)
911 }
912
913 fn next_u64(&mut self) -> u64 {
914 SHAKE256x4::next_u64(self)
915 }
916 }
917
918 #[derive(Clone, Copy, Debug)]
922 struct ChaCha20PRNG {
923 buf: [u8; 512],
924 state: [u8; 256],
925 ptr: usize,
926 }
927
928 const CW: [u32; 4] = [0x61707865, 0x3320646E, 0x79622D32, 0x6B206574];
929
930 impl ChaCha20PRNG {
931 fn refill(&mut self) {
932 let mut cc = u64::from_le_bytes(*<&[u8; 8]>::try_from(&self.state[48..56]).unwrap());
933 for i in 0..8 {
934 let mut state = [0u32; 16];
935 state[0..4].copy_from_slice(&CW);
936 for j in 0..12 {
937 state[4 + j] = u32::from_le_bytes(
938 *<&[u8; 4]>::try_from(&self.state[(4 * j)..(4 * j + 4)]).unwrap(),
939 );
940 }
941 state[14] ^= cc as u32;
942 state[15] ^= (cc >> 32) as u32;
943 for _ in 0..10 {
944 fn qround(st: &mut [u32; 16], a: usize, b: usize, c: usize, d: usize) {
945 st[a] = st[a].wrapping_add(st[b]);
946 st[d] ^= st[a];
947 st[d] = st[d].rotate_left(16);
948 st[c] = st[c].wrapping_add(st[d]);
949 st[b] ^= st[c];
950 st[b] = st[b].rotate_left(12);
951 st[a] = st[a].wrapping_add(st[b]);
952 st[d] ^= st[a];
953 st[d] = st[d].rotate_left(8);
954 st[c] = st[c].wrapping_add(st[d]);
955 st[b] ^= st[c];
956 st[b] = st[b].rotate_left(7);
957 }
958 qround(&mut state, 0, 4, 8, 12);
959 qround(&mut state, 1, 5, 9, 13);
960 qround(&mut state, 2, 6, 10, 14);
961 qround(&mut state, 3, 7, 11, 15);
962 qround(&mut state, 0, 5, 10, 15);
963 qround(&mut state, 1, 6, 11, 12);
964 qround(&mut state, 2, 7, 8, 13);
965 qround(&mut state, 3, 4, 9, 14);
966 }
967
968 for j in 0..4 {
969 state[j] = state[j].wrapping_add(CW[j]);
970 }
971 for j in 0..10 {
972 state[4 + j] = state[4 + j].wrapping_add(u32::from_le_bytes(
973 *<&[u8; 4]>::try_from(&self.state[(4 * j)..(4 * j + 4)]).unwrap(),
974 ));
975 }
976 state[14] = state[14].wrapping_add(
977 u32::from_le_bytes(*<&[u8; 4]>::try_from(&self.state[40..44]).unwrap()) ^
978 (cc as u32),
979 );
980 state[15] = state[15].wrapping_add(
981 u32::from_le_bytes(*<&[u8; 4]>::try_from(&self.state[44..48]).unwrap()) ^
982 ((cc >> 32) as u32),
983 );
984 cc += 1;
985
986 for (j, item) in state.iter().enumerate() {
987 let k = (j << 2) + (i << 6);
988 self.buf[k..(k + 4)].copy_from_slice(&item.to_le_bytes());
989 }
990 }
991 self.state[48..56].copy_from_slice(&cc.to_le_bytes());
992 self.ptr = 0;
993 }
994 }
995
996 impl PRNG for ChaCha20PRNG {
997 fn new(seed: &[u8]) -> Self {
998 let mut p = Self {
999 buf: [0u8; 512],
1000 state: [0u8; 256],
1001 ptr: 0,
1002 };
1003 p.state[..56].copy_from_slice(seed);
1004 p.refill();
1005 p
1006 }
1007
1008 fn next_u8(&mut self) -> u8 {
1009 if self.ptr == self.buf.len() {
1010 self.refill();
1011 }
1012 let x = self.buf[self.ptr];
1013 self.ptr += 1;
1014 x
1015 }
1016
1017 fn next_u16(&mut self) -> u16 {
1018 let x0 = self.next_u8();
1019 let x1 = self.next_u8();
1020 (x0 as u16) | ((x1 as u16) << 1)
1021 }
1022
1023 fn next_u64(&mut self) -> u64 {
1024 let mut i = self.ptr;
1025 if i >= (self.buf.len() - 9) {
1026 self.refill();
1027 i = 0;
1028 }
1029 self.ptr = i + 8;
1030 u64::from_le_bytes(*<&[u8; 8]>::try_from(&self.buf[i..(i + 8)]).unwrap())
1031 }
1032 }
1033
1034 const KAT_RNG_1: [u64; 128] = [
1036 10118206865980352844,
1037 4186416994968924572,
1038 14407813434015218568,
1039 17999928204308794618,
1040 1281202863493570580,
1041 1215293592670952135,
1042 2662650687309711127,
1043 4950968403807295904,
1044 5162758428151459972,
1045 10844832002478462889,
1046 2152372350175039333,
1047 16663510599184623250,
1048 11748879267894739645,
1049 9315153642897576389,
1050 843976972260730699,
1051 1261701354592092221,
1052 8105821303884592444,
1053 7529634954489570079,
1054 575133564673458827,
1055 2093472206215043609,
1056 833393031138418875,
1057 7733850010291114247,
1058 13481871314116322223,
1059 11415547815848461648,
1060 2199402011451572558,
1061 8665283947099910497,
1062 8526838622528653153,
1063 9480927610656828044,
1064 2180302049036012308,
1065 12374959167662158686,
1066 12395725852717209259,
1067 2285950573032359990,
1068 3178894720812991391,
1069 13715355236500543103,
1070 13935188584178984125,
1071 9490268222115631411,
1072 15412630661220207885,
1073 9945702784445615473,
1074 17532343938726239310,
1075 8849181786919164502,
1076 14389227774839945492,
1077 11188424208367267411,
1078 8723730469410215675,
1079 6156120820198785454,
1080 5156565809544156914,
1081 2688897825680180598,
1082 15035334635217652153,
1083 17533008619055607030,
1084 8880420601663548525,
1085 1115094350924961784,
1086 2267453663324806620,
1087 8948565336726581792,
1088 9125975625518420122,
1089 15274140373700820667,
1090 7478801077138445484,
1091 1035450160594676773,
1092 11986213120279998009,
1093 17673958146477577562,
1094 12305459440141111064,
1095 14326368158202311078,
1096 1177814005100640761,
1097 8747661500288216167,
1098 2797765342783346840,
1099 4107359898270585920,
1100 11518238704365557048,
1101 6175352564507757509,
1102 4396475331278281679,
1103 3201421582953741656,
1104 11784142549909733272,
1105 5585412854666709543,
1106 2582853516077978199,
1107 9205210792867691364,
1108 12534618484258612970,
1109 7622943502960284153,
1110 11584269409789615882,
1111 8189573375121423581,
1112 9571905452515233284,
1113 716665414398392180,
1114 17528004569390045241,
1115 9235922718509541131,
1116 5829593106852634271,
1117 8814208540816662228,
1118 16133232462179240583,
1119 3305531072799582200,
1120 3517553763672608175,
1121 5072453735837072731,
1122 3087432279719960851,
1123 12018757166060582929,
1124 10295016195294092532,
1125 6915694762732032156,
1126 17598328482254484633,
1127 15636110532633868232,
1128 8803774359075619886,
1129 1830932215338098894,
1130 3962629290033382627,
1131 1916769747115319947,
1132 5482878565058858052,
1133 11823245115937445404,
1134 16582018945468735060,
1135 5447126734922287710,
1136 3807845955673994450,
1137 15934143589856303631,
1138 12266592860318918671,
1139 8383600949465076579,
1140 18303263099619098259,
1141 17645551392386460660,
1142 6749439027928258396,
1143 485438119962767056,
1144 3481957153076147354,
1145 3223851328808479444,
1146 8253146295282414289,
1147 4299195855338690944,
1148 6444506233343653792,
1149 9395364228380005075,
1150 11300796530137268589,
1151 10287453355807248725,
1152 14083145503895752763,
1153 17601794799780907610,
1154 3675357623818277351,
1155 5319896027624671966,
1156 5019668621475045549,
1157 3230679923130437320,
1158 3350076208214283281,
1159 3311388483548165406,
1160 14196905744269899417,
1161 12248417052101335070,
1162 14418418964481725733,
1163 9434739643424308990,
1164 ];
1165
1166 const KAT_RNG_2: [u8; 1024] = [
1168 7, 158, 53, 113, 114, 156, 140, 81, 188, 91, 102, 38, 11, 146, 21, 239, 105, 43, 133, 93,
1169 181, 57, 86, 237, 155, 76, 95, 232, 181, 119, 86, 59, 73, 176, 65, 210, 48, 182, 222, 115,
1170 240, 148, 33, 189, 23, 204, 251, 207, 46, 31, 53, 47, 64, 226, 127, 184, 198, 239, 254, 44,
1171 100, 83, 32, 160, 142, 35, 123, 157, 59, 227, 240, 49, 127, 125, 124, 149, 86, 69, 73, 148,
1172 35, 93, 16, 146, 43, 170, 83, 52, 5, 127, 120, 153, 185, 181, 61, 93, 41, 50, 156, 125,
1173 124, 4, 45, 182, 213, 9, 24, 120, 166, 207, 193, 50, 228, 122, 97, 154, 37, 139, 126, 146,
1174 212, 192, 4, 216, 143, 89, 178, 79, 35, 52, 122, 200, 17, 170, 89, 164, 93, 96, 224, 73,
1175 194, 208, 94, 149, 215, 220, 220, 248, 59, 176, 186, 31, 72, 58, 215, 203, 125, 43, 52,
1176 176, 112, 213, 61, 254, 223, 94, 76, 59, 124, 141, 30, 3, 62, 116, 12, 204, 163, 199, 39,
1177 135, 74, 140, 104, 27, 154, 81, 33, 205, 226, 90, 53, 136, 138, 23, 218, 123, 102, 172,
1178 170, 158, 21, 196, 86, 71, 196, 109, 0, 221, 96, 94, 237, 31, 188, 248, 88, 95, 150, 154,
1179 51, 151, 54, 45, 86, 233, 130, 39, 138, 56, 130, 246, 16, 228, 21, 177, 26, 232, 115, 178,
1180 190, 115, 201, 69, 188, 196, 119, 97, 30, 112, 91, 219, 159, 11, 57, 91, 108, 89, 162, 151,
1181 10, 120, 133, 217, 45, 173, 126, 141, 104, 60, 19, 147, 120, 194, 33, 178, 25, 39, 62, 208,
1182 77, 179, 98, 233, 189, 206, 36, 194, 90, 233, 25, 18, 20, 120, 148, 206, 144, 212, 114,
1183 183, 152, 95, 172, 142, 68, 81, 91, 103, 163, 37, 237, 194, 196, 165, 156, 71, 207, 232,
1184 89, 140, 16, 197, 43, 25, 173, 177, 202, 43, 105, 94, 84, 111, 32, 249, 133, 33, 93, 24,
1185 183, 183, 205, 73, 168, 94, 201, 184, 4, 114, 77, 133, 42, 248, 238, 131, 170, 42, 41, 226,
1186 35, 12, 189, 202, 35, 58, 145, 178, 69, 237, 246, 96, 151, 25, 100, 103, 223, 158, 118,
1187 237, 56, 107, 180, 148, 43, 243, 124, 73, 53, 189, 177, 231, 25, 159, 119, 21, 0, 67, 180,
1188 82, 146, 185, 72, 210, 152, 41, 144, 201, 210, 112, 211, 48, 103, 81, 105, 251, 116, 193,
1189 12, 128, 43, 187, 135, 79, 86, 183, 9, 108, 223, 253, 112, 105, 33, 61, 12, 227, 74, 152,
1190 212, 183, 73, 132, 61, 8, 220, 205, 154, 155, 253, 153, 12, 134, 116, 75, 130, 251, 67,
1191 240, 201, 159, 216, 70, 81, 252, 150, 69, 137, 13, 129, 205, 78, 68, 192, 60, 69, 137, 211,
1192 18, 188, 252, 173, 67, 92, 4, 122, 220, 192, 114, 172, 53, 168, 71, 196, 59, 250, 115, 62,
1193 27, 17, 85, 104, 26, 21, 151, 152, 91, 56, 122, 163, 200, 188, 30, 26, 132, 56, 27, 49, 33,
1194 56, 238, 194, 19, 105, 12, 2, 248, 252, 79, 97, 91, 69, 192, 66, 198, 133, 40, 184, 130,
1195 95, 121, 87, 88, 141, 47, 191, 67, 116, 35, 210, 30, 171, 235, 232, 111, 146, 119, 35, 29,
1196 61, 6, 147, 51, 138, 42, 128, 103, 35, 79, 7, 155, 2, 178, 21, 58, 198, 29, 116, 47, 116,
1197 51, 228, 228, 151, 250, 53, 205, 99, 2, 33, 208, 230, 242, 30, 47, 148, 66, 108, 27, 96,
1198 124, 97, 163, 12, 99, 130, 149, 87, 47, 40, 176, 61, 209, 182, 202, 78, 58, 120, 226, 52,
1199 173, 214, 42, 129, 196, 19, 130, 54, 61, 55, 245, 48, 61, 71, 137, 178, 37, 145, 25, 186,
1200 180, 224, 161, 130, 147, 145, 144, 196, 38, 112, 200, 161, 31, 123, 146, 118, 197, 250, 22,
1201 159, 250, 20, 47, 154, 23, 0, 203, 124, 185, 195, 161, 197, 177, 179, 140, 225, 40, 44, 71,
1202 89, 97, 79, 108, 255, 113, 67, 152, 253, 78, 34, 176, 156, 116, 5, 78, 207, 14, 239, 123,
1203 177, 176, 202, 40, 210, 87, 98, 182, 91, 158, 75, 165, 179, 125, 194, 190, 143, 252, 142,
1204 150, 108, 83, 213, 155, 96, 136, 16, 52, 39, 72, 48, 83, 244, 252, 241, 241, 152, 154, 2,
1205 62, 143, 127, 13, 160, 23, 207, 225, 146, 253, 237, 189, 133, 9, 41, 63, 206, 111, 204, 3,
1206 185, 47, 209, 165, 53, 57, 235, 124, 13, 113, 74, 78, 194, 230, 91, 51, 127, 90, 45, 206,
1207 5, 167, 63, 132, 62, 116, 29, 146, 25, 8, 2, 54, 178, 232, 211, 175, 172, 34, 113, 248,
1208 153, 116, 92, 221, 240, 91, 77, 221, 98, 111, 163, 161, 32, 202, 203, 17, 232, 54, 225,
1209 105, 255, 129, 232, 213, 214, 95, 121, 160, 28, 36, 244, 3, 213, 174, 150, 73, 126, 74,
1210 104, 84, 179, 1, 207, 204, 4, 61, 24, 213, 15, 152, 3, 49, 153, 109, 161, 234, 228, 157,
1211 103, 135, 77, 75, 75, 197, 172, 74, 50, 55, 150, 247, 115, 244, 114, 45, 176, 128, 50, 209,
1212 120, 206, 207, 7, 167, 174, 200, 87, 13, 246, 97, 21, 188, 219, 12, 108, 43, 109, 146, 112,
1213 39, 141, 8, 169, 216, 156, 13, 158, 151, 196, 19, 56, 13, 14, 106, 157, 73, 114, 203, 69,
1214 198, 228, 70, 46, 198, 158, 174, 105, 181, 233, 36, 207, 29, 115, 127, 188, 173, 178, 52,
1215 42, 225, 114, 104, 254, 174, 69, 140, 203, 178, 152, 235, 197, 42, 121, 128, 164, 215, 163,
1216 117, 71, 0, 130, 136, 182, 18, 234, 71, 252, 210, 1, 232, 84, 60, 76, 238, 129, 250, 3,
1217 174, 190, 112, 147, 186, 168, 113, 65, 225, 131, 66, 88, 4, 156, 3, 30, 41, 24, 124, 108,
1218 132, 252, 71, 99, 195, 91, 172, 115, 34, 215, 96, 220, 208, 152, 185, 69, 85, 220, 187, 10,
1219 91, 61, 180, 85, 50, 218, 127, 6, 117, 237, 23, 204, 42, 136, 111,
1220 ];
1221
1222 #[test]
1223 fn chacha20_prng() {
1224 let mut sh = SHAKE256::new();
1225 sh.inject(&b"rng"[..]);
1226 sh.flip();
1227 let mut seed = [0u8; 56];
1228 sh.extract(&mut seed);
1229 let mut p = ChaCha20PRNG::new(&seed);
1230
1231 #[allow(clippy::needless_range_loop)]
1232 for i in 0..KAT_RNG_1.len() {
1233 assert!(p.next_u64() == KAT_RNG_1[i]);
1234 }
1235 #[allow(clippy::needless_range_loop)]
1236 for i in 0..KAT_RNG_2.len() {
1237 assert!(p.next_u8() == KAT_RNG_2[i]);
1238 }
1239 }
1240
1241 struct FakeCryptoRng(usize);
1243 impl TryRng for FakeCryptoRng {
1244 type Error = Infallible;
1245
1246 fn try_next_u32(&mut self) -> core::result::Result<u32, Self::Error> {
1247 let mut buf = [0u8; 4];
1248 buf.copy_from_slice(&KAT_512_RND[self.0..(self.0 + 4)]);
1249 self.0 += 4;
1250 Ok(u32::from_le_bytes(buf))
1251 }
1252 fn try_next_u64(&mut self) -> core::result::Result<u64, Self::Error> {
1253 let mut buf = [0u8; 8];
1254 buf.copy_from_slice(&KAT_512_RND[self.0..(self.0 + 8)]);
1255 self.0 += 8;
1256 Ok(u64::from_le_bytes(buf))
1257 }
1258 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> core::result::Result<(), Self::Error> {
1259 dest.copy_from_slice(&KAT_512_RND[self.0..(self.0 + dest.len())]);
1260 self.0 += dest.len();
1261 Ok(())
1262 }
1263 }
1264 impl TryCryptoRng for FakeCryptoRng {}
1265
1266 #[test]
1269 fn test_fill_bytes_consumption_pattern() {
1270 use fn_dsa_comm::Rng;
1271 let mut rng = FakeCryptoRng(0);
1272 let mut nonce = [0u8; 40];
1273 rng.fill_bytes(&mut nonce);
1274 assert_eq!(
1275 nonce[..],
1276 KAT_512_RND[0..40],
1277 "nonce must match first 40 bytes"
1278 );
1279 let mut seed = [0u8; 56];
1280 rng.fill_bytes(&mut seed);
1281 assert_eq!(
1282 seed[..],
1283 KAT_512_RND[40..96],
1284 "seed must match bytes 40..96"
1285 );
1286 }
1287
1288 #[test]
1289 fn sign_512() {
1290 let mut rng = FakeCryptoRng(0);
1292
1293 let mut tmp_i16 = [0i16; 2 << 9];
1295 let mut tmp_u16 = [0u16; 2 << 9];
1296 let mut tmp_flr = [flr::Flr::ZERO; 9 << 9];
1297 let mut sig = [0u8; signature_size(9)];
1298
1299 let mut hvk = [0u8; 64];
1302 let mut sh = shake::SHAKE256::new();
1303 sh.inject(&KAT_512_VK);
1304 sh.flip();
1305 sh.extract(&mut hvk);
1306
1307 #[cfg(not(feature = "small_context"))]
1308 let basis = {
1309 let mut basis = [flr::Flr::ZERO; 4 << 9];
1310 compute_basis_inner(
1311 9, &KAT_512_f, &KAT_512_g, &KAT_512_F, &KAT_512_G, &mut basis,
1312 );
1313 basis
1314 };
1315
1316 sign_inner::<FakeCryptoRng, ChaCha20PRNG>(
1317 9,
1318 &mut rng,
1319 &KAT_512_f,
1320 &KAT_512_g,
1321 &KAT_512_F,
1322 &KAT_512_G,
1323 &hvk,
1324 &DOMAIN_NONE,
1325 &HASH_ID_SHA3_256,
1326 &b"data1"[..],
1327 &mut sig,
1328 #[cfg(not(feature = "small_context"))]
1329 &basis,
1330 &mut tmp_i16,
1331 &mut tmp_u16,
1332 &mut tmp_flr,
1333 );
1334
1335 assert!(sig[0] == 0x39);
1338 assert!(sig[1..41] == KAT_512_RND[0..40]);
1339 let mut sig_raw = [0i16; 512];
1340 assert!(codec::comp_decode(&sig[41..], &mut sig_raw[..]));
1341 assert_eq!(sig_raw, KAT_512_sig_raw);
1342 }
1343
1344 #[cfg(all(not(feature = "no_avx2"), target_arch = "x86_64"))]
1345 #[test]
1346 fn sign_avx2_512() {
1347 if !fn_dsa_comm::has_avx2() {
1348 return;
1349 }
1350 let mut rng = FakeCryptoRng(0);
1352
1353 let mut tmp_i16 = [0i16; 2 << 9];
1355 let mut tmp_u16 = [0u16; 2 << 9];
1356 let mut tmp_flr = [flr::Flr::ZERO; 9 << 9];
1357 let mut sig = [0u8; signature_size(9)];
1358
1359 let mut hvk = [0u8; 64];
1362 let mut sh = shake::SHAKE256::new();
1363 sh.inject(&KAT_512_VK);
1364 sh.flip();
1365 sh.extract(&mut hvk);
1366
1367 #[cfg(not(feature = "small_context"))]
1368 let basis = {
1369 let mut basis = [flr::Flr::ZERO; 4 << 9];
1370 unsafe {
1371 sign_avx2::compute_basis_avx2_inner(
1372 9, &KAT_512_f, &KAT_512_g, &KAT_512_F, &KAT_512_G, &mut basis,
1373 );
1374 }
1375 basis
1376 };
1377
1378 unsafe {
1379 sign_avx2::sign_avx2_inner::<FakeCryptoRng, ChaCha20PRNG>(
1380 9,
1381 &mut rng,
1382 &KAT_512_f,
1383 &KAT_512_g,
1384 &KAT_512_F,
1385 &KAT_512_G,
1386 &hvk,
1387 &DOMAIN_NONE,
1388 &HASH_ID_SHA3_256,
1389 &b"data1"[..],
1390 &mut sig,
1391 #[cfg(not(feature = "small_context"))]
1392 &basis,
1393 &mut tmp_i16,
1394 &mut tmp_u16,
1395 &mut tmp_flr,
1396 );
1397 }
1398
1399 assert!(sig[0] == 0x39);
1402 assert!(sig[1..41] == KAT_512_RND[0..40]);
1403 let mut sig_raw = [0i16; 512];
1404 assert!(codec::comp_decode(&sig[41..], &mut sig_raw[..]));
1405 assert_eq!(sig_raw, KAT_512_sig_raw);
1406 }
1407
1408 const KAT_512_f: [i8; 512] = [
1409 -4, -2, -5, -1, 4, -2, 0, -3, -1, 1, -2, -2, -6, -3, 3, -5, -1, 4, -3, -8, 4, -1, 2, -1,
1410 -8, 5, -6, -3, 6, 0, -2, 4, 5, -6, 2, 3, 6, 4, 2, 3, 3, 7, 0, 1, 5, -3, -1, -9, -1, 6, -2,
1411 -5, 4, 0, 4, -2, 10, -4, -3, 4, -7, -1, -7, -2, -1, -6, 5, -1, -9, 3, 2, -5, 4, -2, 2, -4,
1412 4, -3, -1, 0, 5, 2, 2, -1, -9, -7, -2, -1, 0, 3, 1, 0, -1, -2, -5, 4, -1, -1, 3, -1, 1, 4,
1413 -3, 2, -5, -2, 2, -4, 3, 6, 3, 9, 1, -2, 4, -1, -1, -6, -2, -2, 4, 5, -1, 0, 10, -2, 1, -2,
1414 -3, 0, -4, -4, -1, 0, 1, -5, -3, -7, -2, -1, 2, -6, 3, 0, 0, 4, -4, 0, 0, -5, -2, 5, -8, 8,
1415 5, 4, 10, -4, 3, 8, 5, 1, -7, 0, -5, 0, -4, 3, -4, -2, 2, -2, 6, 8, 2, -1, 4, -4, -2, 1, 0,
1416 3, 7, 0, 9, -3, 1, 4, -3, 2, -1, 5, -8, 4, -1, 1, -8, 2, 4, -9, -3, 1, 3, -1, -7, 5, 5, 4,
1417 -3, 0, -7, -3, -1, -6, -7, 0, -3, 0, 3, -3, 0, -3, 1, 3, 4, -6, -6, -3, 6, 0, 2, -5, 1, -3,
1418 -6, -6, -1, -7, -2, -4, 3, 0, -4, -1, 2, 7, -7, -2, 4, 2, 0, 1, -1, -3, 2, 1, 8, -1, 1, -2,
1419 1, -1, 1, 4, 0, -4, 4, 3, -2, 6, -3, -2, 1, 2, 3, 6, 5, -4, -7, -6, 4, 3, -4, 3, -3, 3, -3,
1420 2, -1, 1, 5, -2, 2, 1, 0, -7, 0, 0, -1, 4, -3, 2, 1, -3, 5, 4, -6, -1, -3, 2, -1, -8, 4, 2,
1421 4, 0, 1, -5, 8, 5, 4, -3, -1, -2, 4, 0, 2, -2, 0, -2, -1, -7, 5, 0, 1, 2, 1, -2, 2, -1, 1,
1422 -4, 1, 0, 4, -4, 0, 5, 1, 4, -5, -2, -3, -2, 1, 3, 1, 2, 5, 12, 0, -1, 4, -6, 1, -4, 3, -5,
1423 -4, 4, 2, -2, -6, 1, 1, 3, -1, 0, -4, -4, -4, 6, -2, 4, -3, 0, -2, -1, 0, -6, -3, -2, 0, 6,
1424 5, -5, -5, 3, 0, 3, -3, -2, 5, 7, -3, 1, -1, 0, 3, 0, 3, -7, 2, -4, -4, 1, 1, 1, 0, -3, -8,
1425 3, 6, 1, -2, -7, 3, 3, 4, -1, -2, -5, 9, 7, 1, 2, -4, 4, 0, -11, 3, 0, -3, -5, 5, -1, -1,
1426 7, 6, -1, 6, 3, 9, 5, -2, -3, -3, 1, -2, 0, -1, 1, -2, 2, 0, -5, -1, -4, -2, 2, -1, -3, 0,
1427 -3, 0, 1, 3, -3, 2, 5, 8, -2, 3, -4, -7, 0, 4, -8, 1, 8, -2, 1, -1, 2, 0, -2, 1, 3, 3, 4,
1428 -2, -4, 3, -4, 2, 3, -2, -4, 1, -4, 10, 2,
1429 ];
1430 const KAT_512_g: [i8; 512] = [
1431 -1, 5, -7, -1, -4, 6, 4, -1, -4, -13, -1, -5, -2, -8, 2, 1, 4, 2, 0, 0, 2, 0, -1, 2, 5, -5,
1432 -8, 8, 1, 11, 0, -8, -4, 1, 1, -6, -4, 1, -3, 0, -10, -4, -6, -3, -2, 1, 6, 2, 8, -2, 2,
1433 -2, 1, 3, -4, 2, -1, -1, -2, -2, -3, 0, -3, 2, -3, 2, -3, -4, 2, 3, 4, -5, 6, -3, -2, -1,
1434 -1, -6, -2, 1, -4, -7, 8, 0, 2, -2, 2, 0, 1, 0, 4, 9, 7, 0, -1, -1, 4, -3, -2, 6, 6, 0, 1,
1435 7, -6, -5, 5, 1, 4, -1, 0, -2, 3, -4, 1, -1, -3, -2, 0, -1, -7, -8, -1, 2, 0, -5, 0, 1, -4,
1436 6, -5, 6, 4, 1, -4, -5, 8, -1, 1, -2, 1, 1, 1, 3, 0, -1, 1, 1, -4, -5, -4, 2, -3, 2, -2, 3,
1437 7, -4, 4, -1, -2, 4, -4, -5, 2, 6, -7, 5, -1, 1, 3, 0, -5, -5, 3, -2, -3, -1, -6, 0, 2, 3,
1438 2, 7, -3, -2, -2, 1, -5, 3, 3, -7, 0, 4, 4, -1, 2, -3, 1, 3, -1, -1, 0, -7, -6, -3, 7, -3,
1439 5, -5, 1, -2, 0, 9, -2, 3, -1, -5, -3, -5, 3, 1, -4, -3, 2, -2, 2, 8, -1, 0, 5, -3, -2, -6,
1440 4, 0, 3, -3, -3, 4, -1, 0, 0, -2, -1, 3, 7, 4, 5, -1, 8, 0, -1, -6, -3, 4, 3, -3, 5, 2, -1,
1441 -2, 1, -1, 3, -2, -6, 4, 0, 0, -4, 1, 6, 2, 0, 10, 9, 2, -2, 0, 2, 1, -3, -1, -1, 3, 2, 1,
1442 1, -3, -2, 7, 2, -1, 5, -3, -2, 1, -2, 2, -2, -4, 3, 2, 1, -4, 1, 4, 3, -7, -4, 2, -5, -2,
1443 5, -3, 1, -4, -5, 1, 0, 0, 0, 7, -5, -1, 2, 2, -3, 6, -6, 4, -3, -5, -6, -7, -4, 3, -2, -2,
1444 -10, -3, 2, -1, -6, -4, 1, 2, 2, 1, 4, 1, -5, -10, -2, 2, -4, 4, 4, -2, 1, 4, -3, 0, -6,
1445 -3, 1, 5, -7, -6, -4, 8, -1, 0, -1, 6, -3, -2, -2, 6, 2, 3, -3, -3, 5, -2, 1, 1, -4, -4, 8,
1446 0, 3, 2, 3, 7, 4, 3, 2, -6, -9, 0, -8, 11, -2, 2, -2, -2, 3, 0, -6, 2, -1, 4, 2, -2, 0, -3,
1447 -7, -1, -1, 0, -1, -4, -2, -5, 3, -4, 2, 2, -1, -1, 7, -1, 3, 6, -7, 1, -5, 0, -7, 4, 3,
1448 -5, -1, 0, 3, -4, 1, 2, -7, 1, -2, -8, -2, -5, -5, 1, -4, -4, 4, -3, -2, 2, -4, -8, -1, 0,
1449 -9, 5, -1, -2, 3, 2, 6, -1, 1, -1, -5, 5, 9, 3, -6, -5, 1, -6, 0, 2, -4, 6, 2, 7, 2, 15, 0,
1450 -2, 9, 0, 1, 6, 4, -1, -1, -6, -3, 3, 1, -6, -3, 2, 2, -2,
1451 ];
1452 const KAT_512_F: [i8; 512] = [
1453 0, -25, -39, 21, 7, -5, -10, 4, -1, -38, -9, -1, 4, -23, 15, -1, 8, 1, -38, 41, 29, 22, 9,
1454 12, -46, 0, 9, -17, -19, 32, 38, -3, 14, 6, 2, -6, -18, -1, 23, 80, -12, -20, 24, 22, -31,
1455 -38, -11, 8, 17, 18, 19, -10, 0, -1, 28, -5, -28, -33, 4, -31, -33, -8, -9, -44, 46, -11,
1456 -5, -21, -22, -7, 1, -11, 33, -8, 12, -7, -6, 63, 17, 12, -49, -11, -31, -8, 7, -28, 33,
1457 -28, -19, 8, 46, -73, 9, 32, 18, 7, -43, 0, -6, -4, 8, -39, -17, 11, 15, -25, -9, -28, -2,
1458 24, -23, 10, -15, 4, 41, 46, 18, 2, -3, -29, 11, -3, 20, 35, 21, 23, 5, -8, -3, -27, -69,
1459 0, 26, -29, -24, 8, 19, 6, -14, -18, 47, 5, 21, -50, 17, -44, -36, 24, 9, 16, -38, -5, -54,
1460 34, 13, 31, -2, 9, 8, -12, -14, -17, 28, -59, -20, 19, 31, 14, 14, 7, -32, 37, 5, -3, -7,
1461 -6, 21, -29, -33, 23, -25, -23, 14, 38, -29, -33, -9, 23, -43, 18, -12, 2, 30, 32, -28,
1462 -21, 42, 1, 6, -6, 58, 34, -22, 1, 5, -2, -8, 14, -19, -4, -6, 10, -3, -3, 32, 18, -19,
1463 -12, 49, 13, 4, -18, 57, 37, -19, 25, 14, 18, -51, 13, 4, 4, 17, -37, -2, 1, 41, -36, -8,
1464 -13, 49, -6, 9, 46, -36, -6, -20, -18, -6, -29, -42, -21, -25, -29, 5, -41, 51, 49, -20,
1465 -22, -9, 3, -6, -52, 10, 41, 12, -27, -20, 31, -17, -23, -16, 3, 44, -3, -5, -2, 0, -22,
1466 14, -30, -41, 3, -27, 3, 18, 38, 10, 49, 45, -13, -27, -4, -10, -67, -1, -17, -2, 72, 46,
1467 20, 24, 22, 16, 25, 6, -6, -31, 2, 0, -13, -14, 9, 4, 31, 18, 22, 12, 59, -1, -3, -24, -47,
1468 -10, 48, 37, -34, -32, -4, 18, -2, 52, -8, -7, 34, -44, -14, -21, -49, -35, 41, -4, 31, 3,
1469 23, 9, 8, 0, -24, 38, -9, -9, 4, -10, -55, -19, 21, 27, 22, 41, 6, -23, 41, -2, 28, -46,
1470 20, 52, 16, 20, 32, 18, 2, -3, 9, 16, 33, -18, 12, 6, -9, -19, 1, -5, -15, -17, 6, -3, 4,
1471 -22, 30, -34, 43, -4, 9, -3, -33, -43, -5, -13, -56, 38, 16, 11, -36, 11, -4, -56, 2, 0,
1472 -19, -45, -8, -34, 16, 31, -3, 16, 27, -16, -9, 8, 45, -51, -20, 62, -17, -4, 4, 17, -45,
1473 4, -15, -19, 39, 39, 15, 17, -19, 2, 45, 36, -22, 16, -23, 28, 34, 12, 5, 10, -7, 28, -35,
1474 17, -37, -50, -28, 19, -25, 9, 45, -6, -7, -16, 57, 27, 50, -30, 2, -10, -1, -57, -49, -23,
1475 0, -9, -36, -4, -3, 32, -6, -25, 67, -27, -19, 25, -6, 1, -17, -14, 0, 29, 26, -12, -20,
1476 44, 14, 10, 8, -11, -18, -53, 22, 25, 27, 35, 6, -16, 12, 71, -8,
1477 ];
1478 const KAT_512_G: [i8; 512] = [
1479 27, 6, 12, -3, -31, -42, 27, 17, 11, 8, 34, 6, -3, 2, 11, -11, 18, 48, 1, 21, -7, -6, 9,
1480 33, -18, -40, -55, -9, -71, -50, 32, -36, 11, 4, 29, 33, 10, -19, -43, -10, 22, -36, -23,
1481 -21, -14, -47, 25, -4, -14, 30, 16, -18, -11, 6, -37, -27, -12, 6, 7, 33, -36, 33, -2, 12,
1482 -21, 1, 16, 49, -11, -16, -41, 15, 11, 8, 20, -15, 26, -8, 11, -43, -36, 28, 2, -47, -30,
1483 -47, -1, 1, 48, -6, -22, 24, -20, -3, -1, -15, -12, 62, 12, 7, -9, 15, -71, 49, 22, 27, 20,
1484 -8, -28, -13, -31, 18, 28, 54, 29, 5, 0, 33, -5, -22, -21, -12, -14, -2, 11, -24, 32, -26,
1485 -71, 21, -15, -20, -12, 36, -5, 35, 46, 13, -34, -8, 10, -10, 10, 40, -52, 8, 0, 18, -33,
1486 -10, 8, 43, -8, -6, -31, -17, 19, 30, 12, -9, 8, -19, -32, -18, -1, -37, 4, 43, 27, 14, -6,
1487 -14, -44, -34, -8, 16, -39, 13, 6, -32, 8, 17, -12, 23, -44, -25, -66, -12, -31, 30, 14,
1488 -9, -5, -10, 44, -12, -2, -43, -22, -18, -7, -9, -15, -7, -21, -27, -5, 1, -13, -10, 8, -8,
1489 29, 21, 64, 47, -28, -9, -28, 25, -47, -34, -3, -14, -26, -12, -5, -10, -27, -9, -14, -23,
1490 -2, -31, 28, 17, -4, -30, 31, 3, -15, 25, 9, -32, 0, -6, -22, 20, -37, 3, 12, -19, -17, 13,
1491 30, 11, -15, 15, 50, 66, -31, -31, 16, 2, 3, -8, 40, -21, -31, -2, 41, -29, -12, 9, 14, -4,
1492 9, 8, -20, 28, 12, 20, -10, 5, -6, -33, 6, 21, 51, 30, 9, 3, 8, 7, 19, -53, 19, 15, 4, -38,
1493 19, 29, 18, 6, 19, 3, -17, -32, 16, 3, 46, -6, -3, 47, 3, -66, 3, 25, -6, -6, 21, -24, -9,
1494 28, -39, -42, 42, -6, -19, -14, 6, -8, 9, 28, -4, 23, 12, -17, -13, 3, 3, 6, 44, 6, -5, 38,
1495 -4, -16, 12, -15, 8, -11, 45, 1, -16, 37, -35, 20, 26, 9, 13, 34, 25, -3, -10, -2, -42,
1496 -23, -22, -56, -56, 6, 17, -9, 0, 36, 20, 6, -58, 12, 0, -3, -29, -49, -24, -12, -13, 5,
1497 -39, -8, 36, -9, 44, 35, -64, -22, -12, 26, -15, 41, 36, -19, -37, -20, 46, 35, 9, 32, -5,
1498 27, 21, -36, -51, 19, 10, -23, 28, 46, 28, 8, 22, -31, 18, 2, -16, -9, 1, -22, -22, 31, 14,
1499 5, 44, -3, 38, 0, -12, 50, -23, -19, 1, 42, 15, 1, 13, 32, 45, 37, 15, 11, -9, -23, -6,
1500 -23, 36, 4, -34, -14, -14, -37, -28, 19, 20, 14, 24, -48, -34, -27, -34, -12, 9, -20, -30,
1501 25, 28, -51, -13, 11, -20, -1, -3, 6, -38, -46, -15, 28, 10, -4, 3, -1, 4, -40, 16, 61, 31,
1502 28, 8, -2, 21, -3, -25, -12, -32, -15, -38, 20, -7, -35, 28, 29, 9, -27,
1503 ];
1504 const KAT_512_VK: [u8; 897] = [
1505 0x09, 0x02, 0xCE, 0x21, 0x6B, 0xE4, 0x2C, 0xD0, 0x4F, 0xC8, 0x4C, 0x24, 0xC7, 0x1D, 0x13,
1506 0x07, 0x8E, 0xCA, 0x07, 0x97, 0x6E, 0xE4, 0xAD, 0xBA, 0x2C, 0x98, 0x23, 0x46, 0xD8, 0x78,
1507 0xC0, 0x94, 0x76, 0x7F, 0xE2, 0x9C, 0x34, 0x5C, 0xE2, 0xFA, 0x87, 0x4B, 0xEE, 0x23, 0x9E,
1508 0xA6, 0x0B, 0xDF, 0xA7, 0x27, 0xA5, 0x16, 0x82, 0xC3, 0xDF, 0x06, 0xA2, 0x68, 0x49, 0xC3,
1509 0xF7, 0x26, 0x46, 0x2A, 0x59, 0xE9, 0xC4, 0x16, 0x63, 0x87, 0xBA, 0x89, 0x56, 0xDF, 0xC9,
1510 0xFA, 0x62, 0x20, 0x95, 0x20, 0xED, 0x65, 0x39, 0xCA, 0xDD, 0xA8, 0xF9, 0xE8, 0x11, 0xA6,
1511 0x8E, 0xD8, 0x69, 0x70, 0x13, 0x5A, 0xD5, 0x02, 0x6D, 0xBD, 0x16, 0xF1, 0x59, 0x97, 0xA4,
1512 0xBB, 0xBE, 0x35, 0x68, 0x38, 0xD7, 0x5C, 0x7A, 0x91, 0x34, 0xED, 0xB8, 0xBF, 0x25, 0xBC,
1513 0xBA, 0x0A, 0x03, 0x13, 0x77, 0xEB, 0xF0, 0x11, 0x0D, 0x54, 0x73, 0xC8, 0x46, 0x82, 0x7B,
1514 0x25, 0x6B, 0x9A, 0xB4, 0xD0, 0x26, 0x1E, 0x41, 0xC8, 0xDB, 0xF1, 0xA4, 0x24, 0xB6, 0xDA,
1515 0x1F, 0x21, 0xD0, 0xE2, 0x1A, 0x89, 0xBD, 0x29, 0x94, 0x07, 0x4F, 0xA5, 0x36, 0x5E, 0xA7,
1516 0x70, 0x0E, 0xEB, 0xD2, 0x26, 0x94, 0x7C, 0xFA, 0x7B, 0xE1, 0xA7, 0x65, 0xF4, 0xD7, 0xF9,
1517 0x27, 0x50, 0x02, 0x3D, 0xF2, 0x68, 0x94, 0x51, 0x2E, 0x79, 0x48, 0xC5, 0x64, 0x69, 0xE8,
1518 0x81, 0xD1, 0x99, 0xDA, 0x81, 0x35, 0xAF, 0xC1, 0x6E, 0x52, 0x3A, 0xF8, 0xA2, 0x3F, 0xD5,
1519 0x80, 0x22, 0xAE, 0x22, 0x9A, 0xC9, 0x5C, 0xFF, 0x09, 0x5D, 0x6F, 0xF3, 0x2C, 0x89, 0x0D,
1520 0xB2, 0x29, 0x41, 0x19, 0x21, 0x90, 0x5B, 0x3B, 0xA5, 0x2D, 0x54, 0xB5, 0x0D, 0xEC, 0xB4,
1521 0x4D, 0xC3, 0xD7, 0xC8, 0x99, 0x66, 0x79, 0xE8, 0x28, 0xA4, 0x3B, 0x8D, 0x06, 0x87, 0xE8,
1522 0xBD, 0xE0, 0x60, 0xC5, 0x10, 0x15, 0xAA, 0x9E, 0x00, 0x0C, 0x92, 0x59, 0x8F, 0x05, 0xB8,
1523 0x70, 0xA9, 0x4B, 0x29, 0x01, 0xA9, 0xE1, 0x2A, 0xE9, 0xAB, 0xF2, 0x0A, 0x51, 0x71, 0x4A,
1524 0x03, 0x6A, 0x85, 0x1C, 0xCE, 0x89, 0x15, 0x42, 0xD1, 0xEB, 0x52, 0x7E, 0x73, 0x10, 0x76,
1525 0xD4, 0xFF, 0x2F, 0x09, 0xBA, 0x68, 0x94, 0xA2, 0x09, 0x03, 0xCA, 0x6F, 0xA7, 0x6E, 0x13,
1526 0xD1, 0x2D, 0xC0, 0xAB, 0xA6, 0xB9, 0x26, 0xED, 0x6E, 0x89, 0x54, 0x84, 0x1D, 0xC0, 0x52,
1527 0x4A, 0x55, 0xE3, 0x65, 0x6C, 0x9C, 0x19, 0x88, 0x5E, 0xAB, 0x65, 0x4D, 0x86, 0x94, 0x93,
1528 0x51, 0xFB, 0x8B, 0x02, 0xEA, 0x32, 0xAE, 0x71, 0x5F, 0x09, 0x8B, 0xE2, 0x4E, 0x83, 0xD2,
1529 0xE2, 0x71, 0xCC, 0x8C, 0x24, 0x14, 0x8E, 0x7B, 0xD5, 0x92, 0x59, 0x28, 0x38, 0xFA, 0x55,
1530 0xB8, 0x8A, 0xDB, 0x89, 0x7B, 0xE5, 0xD9, 0x96, 0x97, 0xE3, 0xFC, 0xAC, 0xFA, 0xC0, 0x25,
1531 0xB4, 0x51, 0xF6, 0x2B, 0x6C, 0x35, 0x62, 0xC9, 0xEF, 0x90, 0x71, 0x44, 0x57, 0xA2, 0xF6,
1532 0x49, 0x22, 0x5F, 0x70, 0x20, 0xE9, 0xAF, 0xDB, 0xB9, 0x2A, 0xE2, 0xBE, 0xDB, 0xA6, 0x19,
1533 0x33, 0xB9, 0x05, 0xCF, 0xD4, 0x1A, 0x03, 0x08, 0x2B, 0xD6, 0xDF, 0x8B, 0x24, 0x27, 0xEC,
1534 0x7B, 0xFC, 0xAB, 0x2A, 0xDE, 0x16, 0x78, 0x9C, 0x09, 0x67, 0x45, 0x67, 0xDE, 0x11, 0x29,
1535 0xC1, 0xB2, 0xF6, 0x9E, 0x9C, 0x0F, 0x8F, 0xB2, 0x37, 0xC5, 0x5D, 0x05, 0xCF, 0x8F, 0x69,
1536 0xAD, 0x8B, 0xB7, 0x27, 0xA2, 0x08, 0x9A, 0x43, 0x71, 0x1E, 0xC6, 0xCA, 0x54, 0xB6, 0x12,
1537 0xC1, 0xD7, 0x2F, 0xA0, 0x2B, 0x66, 0x40, 0x98, 0x78, 0x6D, 0x08, 0x53, 0xD1, 0xBC, 0x98,
1538 0xE1, 0x4A, 0x57, 0x90, 0xB2, 0xCA, 0xC6, 0xC7, 0xD2, 0x48, 0x57, 0xD0, 0xFB, 0x44, 0xF5,
1539 0xD9, 0x5F, 0x34, 0x21, 0x33, 0x96, 0x86, 0xE8, 0xAF, 0xA5, 0xBA, 0x92, 0x4B, 0xBA, 0x94,
1540 0xF0, 0x73, 0xC9, 0x09, 0xE9, 0xFB, 0x8A, 0xD0, 0xA4, 0x62, 0x24, 0xD6, 0xF8, 0x1B, 0x22,
1541 0xA2, 0x01, 0xAE, 0xDB, 0xA8, 0x94, 0xC2, 0xAA, 0x44, 0xBA, 0xD6, 0x87, 0x4D, 0x6E, 0x24,
1542 0xCE, 0x1B, 0xB8, 0x3F, 0x51, 0xE6, 0x9F, 0x34, 0xA1, 0x40, 0xAD, 0x88, 0x55, 0x4F, 0x6C,
1543 0x47, 0x48, 0xFF, 0x9F, 0x64, 0x6F, 0x0D, 0xDB, 0xD3, 0xA4, 0x85, 0xD0, 0xBA, 0xD8, 0x05,
1544 0xFA, 0x29, 0xEB, 0x99, 0x68, 0x18, 0x51, 0x71, 0x45, 0x05, 0xE3, 0x71, 0xA6, 0x4A, 0x7B,
1545 0xCF, 0x68, 0x97, 0x95, 0x81, 0x44, 0x91, 0xDC, 0x9D, 0xC5, 0x27, 0x52, 0xE9, 0xA2, 0x7F,
1546 0x96, 0xF4, 0x6C, 0xE8, 0xF8, 0xA4, 0x27, 0x95, 0xC7, 0x10, 0x7E, 0xC1, 0x86, 0x78, 0x92,
1547 0x49, 0x6C, 0x91, 0xA1, 0x77, 0xFB, 0x80, 0x95, 0x0D, 0x69, 0x3B, 0xD4, 0xAD, 0xDE, 0x30,
1548 0x2E, 0x90, 0x3C, 0x41, 0x32, 0xEC, 0x95, 0x38, 0x86, 0x8D, 0xE8, 0xCF, 0x80, 0x5F, 0x5A,
1549 0x21, 0x92, 0x96, 0x7F, 0xA6, 0xC3, 0x50, 0x6A, 0x1A, 0xAB, 0x3C, 0x11, 0xA1, 0x5F, 0x1E,
1550 0x47, 0xB3, 0xB4, 0x6E, 0x64, 0x97, 0xB1, 0x5A, 0x88, 0x2E, 0x2C, 0xC8, 0x49, 0xA1, 0xB4,
1551 0x42, 0x49, 0xE9, 0x7F, 0x61, 0xF1, 0x6B, 0xD0, 0xEC, 0xEA, 0xD5, 0x47, 0xDD, 0x71, 0xC5,
1552 0xDD, 0xA5, 0xAA, 0x8A, 0x56, 0xFE, 0x36, 0x31, 0x22, 0x15, 0x85, 0x2E, 0x78, 0xDA, 0x98,
1553 0x5D, 0x55, 0xA4, 0xA4, 0xD8, 0xF7, 0x14, 0x8E, 0x45, 0x67, 0xD1, 0xE4, 0x67, 0x87, 0xC2,
1554 0x23, 0x87, 0xCA, 0x4A, 0x85, 0xF0, 0x11, 0xE3, 0x75, 0xC4, 0x5C, 0xCA, 0x0C, 0xE0, 0xA1,
1555 0x5B, 0xCD, 0x13, 0x37, 0xBD, 0xC9, 0x27, 0x1B, 0xFA, 0x84, 0x73, 0xE1, 0x88, 0x2F, 0x33,
1556 0x85, 0x58, 0x69, 0x7D, 0x9A, 0xAF, 0x07, 0x5A, 0x90, 0x78, 0x33, 0x5A, 0x1F, 0xB8, 0xA1,
1557 0xB3, 0xB6, 0xE9, 0xD9, 0xCF, 0x43, 0x62, 0x84, 0x06, 0x7C, 0x58, 0xC5, 0xA4, 0x8E, 0x04,
1558 0x7A, 0x40, 0x08, 0xD0, 0x2B, 0x7C, 0x85, 0x07, 0xC2, 0xEE, 0x6F, 0x88, 0xDA, 0x4C, 0x97,
1559 0xF6, 0x0F, 0x75, 0x44, 0x4C, 0x78, 0x84, 0x96, 0x67, 0x84, 0x32, 0xC9, 0x5F, 0x3A, 0x92,
1560 0x08, 0xB4, 0xA8, 0xC1, 0xCB, 0xC6, 0xE2, 0xD4, 0xDA, 0x61, 0x25, 0x3D, 0xA0, 0x81, 0x27,
1561 0x5E, 0x8F, 0x34, 0xDB, 0xE4, 0xA1, 0xEC, 0xC2, 0x22, 0x24, 0xC3, 0x08, 0x00, 0xA7, 0x75,
1562 0x35, 0x74, 0xC8, 0x95, 0x86, 0x95, 0x66, 0x6C, 0x28, 0x95, 0xB3, 0x5C, 0xCE, 0x07, 0x89,
1563 0x44, 0xA3, 0x10, 0x41, 0xA5, 0x23, 0x83, 0x7C, 0xED, 0x72, 0x17, 0x69, 0x0F, 0xA1, 0x7C,
1564 0x36, 0xCB, 0x45, 0x92, 0x63, 0x35, 0xE6, 0x7B, 0x18, 0x04, 0x95, 0x9D,
1565 ];
1566
1567 const KAT_512_RND: [u8; 40 + 56] = [
1568 0x16, 0xC1, 0x25, 0x15, 0x25, 0x80, 0x93, 0x79, 0x99, 0x56, 0x36, 0x8C, 0xDF, 0xC1, 0x82,
1570 0xC1, 0xCA, 0x4A, 0x34, 0xF0, 0x77, 0xE9, 0x24, 0x44, 0x16, 0xA8, 0xC4, 0xC1, 0x3F, 0xB0,
1571 0xCA, 0x24, 0x1E, 0x8B, 0x7A, 0xC1, 0x71, 0x2D, 0x28, 0xEB,
1572 0xFF, 0xD8, 0x57, 0xF1, 0x49, 0x5C, 0xA5, 0x98, 0xDB, 0x2C, 0x88, 0x64, 0xAF, 0x31, 0xFA,
1574 0x8F, 0x37, 0xBC, 0x73, 0x8D, 0xCD, 0xB6, 0xDD, 0xAA, 0xFD, 0x25, 0x4A, 0xBF, 0xE3, 0x01,
1575 0xB7, 0x91, 0x9B, 0x7E, 0x9B, 0x9F, 0xEC, 0xEA, 0x4E, 0xF0, 0x01, 0xC9, 0x62, 0x9B, 0x96,
1576 0x6B, 0x58, 0xD6, 0x81, 0x25, 0x2F, 0xF3, 0x38, 0x9E, 0x81, 0x6B,
1577 ];
1578 const KAT_512_sig_raw: [i16; 512] = [
1581 -26, 98, -55, 235, 202, 440, 43, 53, -313, -11, 25, -155, -45, -34, 28, 136, -47, 68, 176,
1582 -165, 174, -196, -133, -74, 85, -5, -166, -15, 249, -125, 120, -62, 155, -153, 79, -82,
1583 -318, 63, -311, 69, 292, 40, 43, -164, 122, -91, 92, -11, 18, -7, 184, 10, -304, 364, 9,
1584 324, -374, -7, -85, 30, -36, 24, -106, -160, 71, -24, 78, 155, -281, 378, -64, -37, -122,
1585 2, 28, -26, -36, 98, -331, 110, -250, 51, 98, -6, -188, 223, -144, 200, -71, -5, -36, -53,
1586 -44, -11, -340, -2, -7, 136, -301, -3, -198, 308, -169, -33, 31, 43, -345, 145, 66, 97, 71,
1587 185, 99, -79, 261, -19, -146, -89, -85, 41, 164, -78, -18, 19, 74, 210, -113, 373, 1, 237,
1588 -255, 216, -25, 37, 278, -195, -2, 57, 137, 183, 28, -170, 57, -5, -28, 98, 17, 5, 60,
1589 -203, -122, 113, -274, 7, -30, -139, 76, 32, -103, -30, 205, 37, -98, -111, -44, -54, 75,
1590 -121, -344, 99, 374, -41, 189, -141, 10, -2, -329, -147, 4, -155, 255, 100, 71, -235, -421,
1591 169, 239, -113, 30, 138, 62, -242, 49, 1, 56, -147, 24, 88, -93, -344, -9, 328, -131, -218,
1592 44, -197, -12, -172, -273, 13, -102, -146, -8, 259, 193, -172, -11, -99, -232, -167, 140,
1593 125, 27, 31, -63, 126, -113, -222, 213, -164, -171, 150, -214, -191, -10, -77, -280, -39,
1594 -178, 136, -46, 170, -104, 167, -102, 89, 1, -94, 97, 36, 287, 222, 49, -106, 191, 3, 108,
1595 204, -385, -106, -101, 70, 178, -45, 381, -285, -254, -31, 77, 7, -12, 182, -206, 80, -93,
1596 -3, 85, 95, 112, 147, -141, 53, -30, 269, 172, 56, -143, -173, -139, 298, -242, 58, 136,
1597 -49, -269, 151, -64, 273, -139, 32, 179, -387, -249, 157, -92, -128, 109, -126, -51, -150,
1598 140, -117, -52, 306, -367, -117, -342, 141, 86, -303, 55, -296, 270, 44, 186, -30, -78,
1599 -69, 43, -173, -100, -61, -6, 136, 331, 188, 41, 121, -169, -250, 91, 112, -77, -153, -194,
1600 -237, -42, 118, -238, 14, 61, -90, 9, 208, -9, -24, 168, -123, 211, 124, 211, -103, 196, 1,
1601 70, -42, 223, 11, 81, 79, 112, -19, 45, 199, -50, 187, -88, 99, -56, -250, -72, 43, 103,
1602 -174, 208, 148, -138, 7, 3, -3, 471, 32, 260, -28, 172, 204, 23, -181, -196, 47, -57, 20,
1603 228, 212, -160, -345, -106, 138, 217, 52, 425, 319, 68, -170, 58, 203, 233, 90, 12, -36,
1604 -1, 46, -166, 207, 101, -177, 63, -83, 10, -45, -125, -66, -142, 165, -46, 51, 38, 17, 61,
1605 421, 5, -59, 89, -147, 169, 295, 48, 147, -162, 159, -136, 103, 107, -187, 39, 103, 267,
1606 -346, 12, 95, 98, -122, 115, 320, -122, 87, -19, 49, -143, -56, -45, 224, 314, 167, 14,
1607 -168, -11, -89, -47, -190, 188, 196, 62, 130, 6, 98, -18, 331, -65, 144, -195, -310, 238,
1608 186, 55, 186, 108, -49, -66, -3, -286, 143, 333, -242, -187, 161, 411, -136, 186, 107, 136,
1609 -201,
1610 ];
1611}