enc_rust 0.2.2

A pure rust implementation of the Module-Lattice-based standards ML-KEM and (soon) ML-DSA, also known as the PQC scheme Crystals Kyber and Dilithium.
Documentation
#![allow(warnings)]
#[cfg(test)]

mod vec_tests {
    use crate::{
        params::*,
        polynomials::*,
        tests::params::params_tests::sec_level_strategy,
        tests::polynomials::poly_tests::{new_limited_poly, new_ntt_poly, new_poly},
        vectors::*,
    };
    use proptest::prelude::*;
    use tinyvec::{array_vec, ArrayVec};

    prop_compose! {
        pub(in crate::tests) fn new_poly_vec()
            (sec_level in 2..=4usize, poly_1 in new_poly(), poly_2 in new_poly(), poly_3 in new_poly(), poly_4 in new_poly())
            -> PolyVec<Unreduced> {
                PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
            }
    }

    prop_compose! {
        // restrict sec_level here so that we can ensure two polyvecs are the same sec_level
        pub(in crate::tests) fn new_limited_poly_vec(sec_level: usize)
            (poly_1 in new_limited_poly(), poly_2 in new_limited_poly(), poly_3 in new_limited_poly(), poly_4 in new_limited_poly())
            -> PolyVec<Unreduced> {
                PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
            }
    }

    prop_compose! {
        // restrict sec_level here so that we can ensure two polyvecs are the same sec_level
        pub(in crate::tests) fn new_ntt_poly_vec(sec_level: usize)
            (poly_1 in new_ntt_poly(), poly_2 in new_ntt_poly(), poly_3 in new_ntt_poly(), poly_4 in new_ntt_poly())
            -> PolyVec<Unreduced> {
                PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::from_array_len([poly_1, poly_2, poly_3, poly_4], sec_level)).unwrap()
            }
    }

    #[test]
    #[should_panic]
    fn from_test() {
        // new should be empty so will fail
        let err_result = PolyVec::from(ArrayVec::<[Poly<Unreduced>; 4]>::new()).unwrap();
    }

    #[test]
    fn compare_inner_product_pointwise() {
        let coeffs = core::array::from_fn(|i| (i * 127) as i16);
        let poly = Poly::from_arr(&coeffs).mont_form();
        let v = PolyVec::from(array_vec!([Poly<Montgomery>; 4] => poly, poly, poly)).unwrap();
        let w = PolyVec::from(array_vec!([Poly<Montgomery>; 4] => poly, poly, poly)).unwrap();

        let output = v.inner_product_pointwise(&w);
        let want = [
            -333, 0, 5856, -1410, -1209, 8616, -5412, -9870, -5115, 3054, 2823, 7440, 7059, 3288,
            -627, -9402, 4089, 9318, -1950, -474, -1545, 1170, -240, -5724, 5175, -1182, 3267,
            -5178, -2979, 2262, 8367, 1164, 1053, -8472, -2406, -6672, 801, 6564, -1296, -8712,
            -1728, 7422, 525, -4956, -1044, -5898, 8322, 4596, 471, 6552, -3213, -30, -8382, 4824,
            1023, 1140, 2262, 8892, -4452, 8106, -6075, -1218, 2961, 894, -462, -5532, -4776, -522,
            3768, -4050, -2358, 3858, -4722, 3228, -1764, -5940, -489, -3672, 8559, -9942, -2724,
            -4776, 4683, -8148, 2658, -84, 3609, -558, -1050, -9570, 1035, -7146, -5886, 6714,
            6675, -7938, -9081, 8820, 4830, -2934, -66, -3252, -7635, 7866, 5187, -9528, 3033,
            4488, -1530, -10008, -732, 6906, 2226, -4692, 1509, -4854, -2994, 6420, -2937, 9156,
            -6090, 3354, 4533, 8988, 8142, 6084, -2274, -5358, -8832, -5364, 7920, 6066, -2583,
            8958, -210, 3312, 1386, 9102, -2943, 6354, -312, -4932, -2166, -4782, 5373, 6804,
            -3588, 9852, -3501, 4362, 996, -9666, -3084, 7716, 5682, -3414, -165, -3108, -6738,
            8634, -2304, -8136, -1782, 6504, -5442, -7368, 3117, -9804, -5019, -804, 1989, -342,
            6039, -8418, 2622, -5058, -3522, 9738, -7677, -3978, -1206, -6258, -4140, 2898, -3501,
            3516, 1593, -4404, 531, -888, -399, -5910, 6546, 504, -177, -1620, -1095, 7692, -3987,
            8466, -6381, 702, 3513, 4374, 5079, -492, -4086, 6078, 4353, 4110, 1290, -6396, -7218,
            -5466, -114, 6900, 2592, -9246, 6780, 6018, 1383, -7230, 4707, -9042, -2898, 582, 5898,
            1668, -78, -5784, 1242, -1800, 447, -6354, -1068, 528, 2043, -1128, 1257, 8652, 579,
            9894, 2841, 2598, 6, 6738, -4716, 2340, 780, 9378, -690, 7878, 2829, -2160, -2184,
            -762,
        ];
        assert_eq!(output.coeffs(), &want);
    }

    #[test]
    fn compare_compress_test_768() {
        let want: [u8; 960] = [
            0, 12, 96, 64, 2, 12, 60, 32, 129, 5, 25, 112, 240, 129, 8, 37, 160, 176, 130, 11, 49,
            208, 112, 131, 14, 62, 4, 65, 196, 17, 74, 52, 1, 197, 20, 86, 100, 193, 197, 23, 98,
            152, 145, 6, 27, 111, 200, 81, 7, 30, 123, 248, 17, 8, 33, 135, 40, 210, 72, 36, 148,
            92, 162, 73, 39, 160, 140, 98, 74, 42, 172, 188, 34, 75, 45, 185, 240, 242, 139, 48,
            197, 32, 179, 140, 51, 209, 80, 115, 141, 54, 221, 132, 67, 206, 57, 234, 180, 3, 207,
            60, 246, 228, 195, 207, 63, 2, 21, 148, 16, 67, 15, 73, 84, 17, 70, 27, 121, 20, 18,
            73, 39, 169, 212, 82, 76, 52, 221, 164, 83, 79, 64, 13, 101, 84, 82, 76, 61, 37, 85,
            85, 89, 113, 245, 149, 88, 101, 161, 181, 150, 91, 113, 209, 117, 151, 94, 125, 1, 70,
            216, 97, 138, 53, 6, 217, 100, 150, 101, 198, 217, 103, 162, 149, 134, 26, 107, 175,
            201, 86, 27, 110, 187, 249, 22, 28, 113, 199, 41, 215, 28, 116, 212, 93, 167, 93, 119,
            224, 141, 103, 94, 122, 236, 189, 39, 95, 125, 248, 241, 247, 159, 128, 5, 34, 184,
            160, 131, 17, 82, 120, 161, 134, 29, 130, 72, 226, 137, 42, 182, 8, 227, 140, 54, 230,
            200, 227, 143, 66, 22, 137, 36, 147, 79, 74, 89, 37, 150, 91, 122, 25, 38, 153, 103,
            170, 217, 38, 156, 116, 222, 169, 103, 159, 128, 14, 106, 104, 162, 140, 62, 42, 105,
            165, 152, 110, 250, 169, 168, 165, 162, 186, 170, 171, 177, 210, 122, 171, 174, 189, 2,
            59, 236, 177, 202, 54, 11, 237, 180, 214, 102, 203, 237, 183, 226, 150, 139, 238, 186,
            239, 202, 91, 47, 190, 251, 250, 27, 48, 193, 7, 43, 220, 48, 196, 0, 12, 96, 64, 2,
            12, 60, 32, 129, 5, 25, 112, 240, 129, 8, 37, 160, 176, 130, 11, 49, 208, 112, 131, 14,
            62, 4, 65, 196, 17, 74, 52, 1, 197, 20, 86, 100, 193, 197, 23, 98, 152, 145, 6, 27,
            111, 200, 81, 7, 30, 123, 248, 17, 8, 33, 135, 40, 210, 72, 36, 148, 92, 162, 73, 39,
            160, 140, 98, 74, 42, 172, 188, 34, 75, 45, 185, 240, 242, 139, 48, 197, 32, 179, 140,
            51, 209, 80, 115, 141, 54, 221, 132, 67, 206, 57, 234, 180, 3, 207, 60, 246, 228, 195,
            207, 63, 2, 21, 148, 16, 67, 15, 73, 84, 17, 70, 27, 121, 20, 18, 73, 39, 169, 212, 82,
            76, 52, 221, 164, 83, 79, 64, 13, 101, 84, 82, 76, 61, 37, 85, 85, 89, 113, 245, 149,
            88, 101, 161, 181, 150, 91, 113, 209, 117, 151, 94, 125, 1, 70, 216, 97, 138, 53, 6,
            217, 100, 150, 101, 198, 217, 103, 162, 149, 134, 26, 107, 175, 201, 86, 27, 110, 187,
            249, 22, 28, 113, 199, 41, 215, 28, 116, 212, 93, 167, 93, 119, 224, 141, 103, 94, 122,
            236, 189, 39, 95, 125, 248, 241, 247, 159, 128, 5, 34, 184, 160, 131, 17, 82, 120, 161,
            134, 29, 130, 72, 226, 137, 42, 182, 8, 227, 140, 54, 230, 200, 227, 143, 66, 22, 137,
            36, 147, 79, 74, 89, 37, 150, 91, 122, 25, 38, 153, 103, 170, 217, 38, 156, 116, 222,
            169, 103, 159, 128, 14, 106, 104, 162, 140, 62, 42, 105, 165, 152, 110, 250, 169, 168,
            165, 162, 186, 170, 171, 177, 210, 122, 171, 174, 189, 2, 59, 236, 177, 202, 54, 11,
            237, 180, 214, 102, 203, 237, 183, 226, 150, 139, 238, 186, 239, 202, 91, 47, 190, 251,
            250, 27, 48, 193, 7, 43, 220, 48, 196, 0, 12, 96, 64, 2, 12, 60, 32, 129, 5, 25, 112,
            240, 129, 8, 37, 160, 176, 130, 11, 49, 208, 112, 131, 14, 62, 4, 65, 196, 17, 74, 52,
            1, 197, 20, 86, 100, 193, 197, 23, 98, 152, 145, 6, 27, 111, 200, 81, 7, 30, 123, 248,
            17, 8, 33, 135, 40, 210, 72, 36, 148, 92, 162, 73, 39, 160, 140, 98, 74, 42, 172, 188,
            34, 75, 45, 185, 240, 242, 139, 48, 197, 32, 179, 140, 51, 209, 80, 115, 141, 54, 221,
            132, 67, 206, 57, 234, 180, 3, 207, 60, 246, 228, 195, 207, 63, 2, 21, 148, 16, 67, 15,
            73, 84, 17, 70, 27, 121, 20, 18, 73, 39, 169, 212, 82, 76, 52, 221, 164, 83, 79, 64,
            13, 101, 84, 82, 76, 61, 37, 85, 85, 89, 113, 245, 149, 88, 101, 161, 181, 150, 91,
            113, 209, 117, 151, 94, 125, 1, 70, 216, 97, 138, 53, 6, 217, 100, 150, 101, 198, 217,
            103, 162, 149, 134, 26, 107, 175, 201, 86, 27, 110, 187, 249, 22, 28, 113, 199, 41,
            215, 28, 116, 212, 93, 167, 93, 119, 224, 141, 103, 94, 122, 236, 189, 39, 95, 125,
            248, 241, 247, 159, 128, 5, 34, 184, 160, 131, 17, 82, 120, 161, 134, 29, 130, 72, 226,
            137, 42, 182, 8, 227, 140, 54, 230, 200, 227, 143, 66, 22, 137, 36, 147, 79, 74, 89,
            37, 150, 91, 122, 25, 38, 153, 103, 170, 217, 38, 156, 116, 222, 169, 103, 159, 128,
            14, 106, 104, 162, 140, 62, 42, 105, 165, 152, 110, 250, 169, 168, 165, 162, 186, 170,
            171, 177, 210, 122, 171, 174, 189, 2, 59, 236, 177, 202, 54, 11, 237, 180, 214, 102,
            203, 237, 183, 226, 150, 139, 238, 186, 239, 202, 91, 47, 190, 251, 250, 27, 48, 193,
            7, 43, 220, 48, 196,
        ];
        let coeffs: [i16; N] = core::array::from_fn(|i| (i * 10) as i16);
        let poly = Poly::from_arr_normal(&coeffs);
        let v = PolyVec::from(array_vec!([Poly<Normalised>; 4] => poly, poly, poly)).unwrap();

        let mut buf = [0u8; 960];

        v.compress(&mut buf);

        assert_eq!(buf, want);
    }

    #[test]
    fn compare_compress_test_1024() {
        let want: [u8; 1408] = [
            0, 48, 0, 3, 36, 144, 129, 15, 148, 96, 5, 49, 184, 129, 15, 136, 160, 4, 40, 88, 129,
            11, 98, 72, 195, 27, 234, 176, 135, 64, 28, 162, 17, 148, 208, 4, 40, 76, 193, 10, 89,
            228, 226, 23, 197, 88, 70, 52, 174, 209, 13, 114, 168, 3, 30, 246, 224, 135, 64, 18,
            242, 144, 138, 108, 36, 36, 39, 105, 9, 77, 116, 2, 20, 163, 48, 69, 42, 89, 249, 74,
            89, 214, 18, 151, 187, 244, 133, 48, 138, 129, 140, 101, 56, 35, 26, 212, 188, 166, 54,
            187, 9, 206, 113, 154, 67, 29, 237, 128, 199, 60, 236, 145, 15, 126, 254, 83, 160, 5,
            69, 232, 66, 29, 34, 145, 138, 96, 100, 35, 30, 9, 9, 73, 79, 170, 210, 150, 194, 116,
            166, 54, 209, 73, 79, 128, 50, 20, 163, 36, 133, 169, 79, 149, 106, 85, 177, 186, 85,
            175, 134, 165, 44, 104, 89, 139, 91, 226, 66, 215, 187, 234, 181, 175, 128, 29, 172,
            97, 19, 211, 24, 200, 76, 198, 50, 153, 225, 236, 103, 69, 91, 90, 212, 174, 214, 181,
            177, 169, 13, 110, 118, 227, 155, 224, 16, 231, 184, 202, 109, 46, 116, 167, 107, 221,
            236, 116, 7, 60, 227, 49, 79, 122, 216, 243, 94, 249, 214, 23, 191, 251, 245, 111, 128,
            10, 132, 160, 5, 57, 40, 66, 20, 186, 176, 134, 59, 12, 226, 17, 155, 56, 69, 45, 130,
            209, 140, 108, 148, 35, 30, 253, 88, 200, 69, 70, 242, 146, 157, 28, 101, 42, 97, 105,
            75, 94, 10, 19, 153, 206, 172, 230, 54, 195, 121, 206, 118, 206, 51, 159, 0, 53, 40,
            67, 37, 138, 81, 143, 150, 116, 165, 49, 189, 105, 79, 135, 154, 84, 168, 90, 149, 171,
            98, 69, 171, 91, 235, 186, 215, 192, 30, 182, 177, 147, 205, 44, 104, 77, 203, 90, 217,
            226, 214, 183, 196, 93, 110, 116, 175, 219, 221, 241, 166, 23, 190, 246, 229, 175, 128,
            17, 236, 96, 10, 111, 56, 196, 0, 48, 0, 3, 36, 144, 129, 15, 148, 96, 5, 49, 184, 129,
            15, 136, 160, 4, 40, 88, 129, 11, 98, 72, 195, 27, 234, 176, 135, 64, 28, 162, 17, 148,
            208, 4, 40, 76, 193, 10, 89, 228, 226, 23, 197, 88, 70, 52, 174, 209, 13, 114, 168, 3,
            30, 246, 224, 135, 64, 18, 242, 144, 138, 108, 36, 36, 39, 105, 9, 77, 116, 2, 20, 163,
            48, 69, 42, 89, 249, 74, 89, 214, 18, 151, 187, 244, 133, 48, 138, 129, 140, 101, 56,
            35, 26, 212, 188, 166, 54, 187, 9, 206, 113, 154, 67, 29, 237, 128, 199, 60, 236, 145,
            15, 126, 254, 83, 160, 5, 69, 232, 66, 29, 34, 145, 138, 96, 100, 35, 30, 9, 9, 73, 79,
            170, 210, 150, 194, 116, 166, 54, 209, 73, 79, 128, 50, 20, 163, 36, 133, 169, 79, 149,
            106, 85, 177, 186, 85, 175, 134, 165, 44, 104, 89, 139, 91, 226, 66, 215, 187, 234,
            181, 175, 128, 29, 172, 97, 19, 211, 24, 200, 76, 198, 50, 153, 225, 236, 103, 69, 91,
            90, 212, 174, 214, 181, 177, 169, 13, 110, 118, 227, 155, 224, 16, 231, 184, 202, 109,
            46, 116, 167, 107, 221, 236, 116, 7, 60, 227, 49, 79, 122, 216, 243, 94, 249, 214, 23,
            191, 251, 245, 111, 128, 10, 132, 160, 5, 57, 40, 66, 20, 186, 176, 134, 59, 12, 226,
            17, 155, 56, 69, 45, 130, 209, 140, 108, 148, 35, 30, 253, 88, 200, 69, 70, 242, 146,
            157, 28, 101, 42, 97, 105, 75, 94, 10, 19, 153, 206, 172, 230, 54, 195, 121, 206, 118,
            206, 51, 159, 0, 53, 40, 67, 37, 138, 81, 143, 150, 116, 165, 49, 189, 105, 79, 135,
            154, 84, 168, 90, 149, 171, 98, 69, 171, 91, 235, 186, 215, 192, 30, 182, 177, 147,
            205, 44, 104, 77, 203, 90, 217, 226, 214, 183, 196, 93, 110, 116, 175, 219, 221, 241,
            166, 23, 190, 246, 229, 175, 128, 17, 236, 96, 10, 111, 56, 196, 0, 48, 0, 3, 36, 144,
            129, 15, 148, 96, 5, 49, 184, 129, 15, 136, 160, 4, 40, 88, 129, 11, 98, 72, 195, 27,
            234, 176, 135, 64, 28, 162, 17, 148, 208, 4, 40, 76, 193, 10, 89, 228, 226, 23, 197,
            88, 70, 52, 174, 209, 13, 114, 168, 3, 30, 246, 224, 135, 64, 18, 242, 144, 138, 108,
            36, 36, 39, 105, 9, 77, 116, 2, 20, 163, 48, 69, 42, 89, 249, 74, 89, 214, 18, 151,
            187, 244, 133, 48, 138, 129, 140, 101, 56, 35, 26, 212, 188, 166, 54, 187, 9, 206, 113,
            154, 67, 29, 237, 128, 199, 60, 236, 145, 15, 126, 254, 83, 160, 5, 69, 232, 66, 29,
            34, 145, 138, 96, 100, 35, 30, 9, 9, 73, 79, 170, 210, 150, 194, 116, 166, 54, 209, 73,
            79, 128, 50, 20, 163, 36, 133, 169, 79, 149, 106, 85, 177, 186, 85, 175, 134, 165, 44,
            104, 89, 139, 91, 226, 66, 215, 187, 234, 181, 175, 128, 29, 172, 97, 19, 211, 24, 200,
            76, 198, 50, 153, 225, 236, 103, 69, 91, 90, 212, 174, 214, 181, 177, 169, 13, 110,
            118, 227, 155, 224, 16, 231, 184, 202, 109, 46, 116, 167, 107, 221, 236, 116, 7, 60,
            227, 49, 79, 122, 216, 243, 94, 249, 214, 23, 191, 251, 245, 111, 128, 10, 132, 160, 5,
            57, 40, 66, 20, 186, 176, 134, 59, 12, 226, 17, 155, 56, 69, 45, 130, 209, 140, 108,
            148, 35, 30, 253, 88, 200, 69, 70, 242, 146, 157, 28, 101, 42, 97, 105, 75, 94, 10, 19,
            153, 206, 172, 230, 54, 195, 121, 206, 118, 206, 51, 159, 0, 53, 40, 67, 37, 138, 81,
            143, 150, 116, 165, 49, 189, 105, 79, 135, 154, 84, 168, 90, 149, 171, 98, 69, 171, 91,
            235, 186, 215, 192, 30, 182, 177, 147, 205, 44, 104, 77, 203, 90, 217, 226, 214, 183,
            196, 93, 110, 116, 175, 219, 221, 241, 166, 23, 190, 246, 229, 175, 128, 17, 236, 96,
            10, 111, 56, 196, 0, 48, 0, 3, 36, 144, 129, 15, 148, 96, 5, 49, 184, 129, 15, 136,
            160, 4, 40, 88, 129, 11, 98, 72, 195, 27, 234, 176, 135, 64, 28, 162, 17, 148, 208, 4,
            40, 76, 193, 10, 89, 228, 226, 23, 197, 88, 70, 52, 174, 209, 13, 114, 168, 3, 30, 246,
            224, 135, 64, 18, 242, 144, 138, 108, 36, 36, 39, 105, 9, 77, 116, 2, 20, 163, 48, 69,
            42, 89, 249, 74, 89, 214, 18, 151, 187, 244, 133, 48, 138, 129, 140, 101, 56, 35, 26,
            212, 188, 166, 54, 187, 9, 206, 113, 154, 67, 29, 237, 128, 199, 60, 236, 145, 15, 126,
            254, 83, 160, 5, 69, 232, 66, 29, 34, 145, 138, 96, 100, 35, 30, 9, 9, 73, 79, 170,
            210, 150, 194, 116, 166, 54, 209, 73, 79, 128, 50, 20, 163, 36, 133, 169, 79, 149, 106,
            85, 177, 186, 85, 175, 134, 165, 44, 104, 89, 139, 91, 226, 66, 215, 187, 234, 181,
            175, 128, 29, 172, 97, 19, 211, 24, 200, 76, 198, 50, 153, 225, 236, 103, 69, 91, 90,
            212, 174, 214, 181, 177, 169, 13, 110, 118, 227, 155, 224, 16, 231, 184, 202, 109, 46,
            116, 167, 107, 221, 236, 116, 7, 60, 227, 49, 79, 122, 216, 243, 94, 249, 214, 23, 191,
            251, 245, 111, 128, 10, 132, 160, 5, 57, 40, 66, 20, 186, 176, 134, 59, 12, 226, 17,
            155, 56, 69, 45, 130, 209, 140, 108, 148, 35, 30, 253, 88, 200, 69, 70, 242, 146, 157,
            28, 101, 42, 97, 105, 75, 94, 10, 19, 153, 206, 172, 230, 54, 195, 121, 206, 118, 206,
            51, 159, 0, 53, 40, 67, 37, 138, 81, 143, 150, 116, 165, 49, 189, 105, 79, 135, 154,
            84, 168, 90, 149, 171, 98, 69, 171, 91, 235, 186, 215, 192, 30, 182, 177, 147, 205, 44,
            104, 77, 203, 90, 217, 226, 214, 183, 196, 93, 110, 116, 175, 219, 221, 241, 166, 23,
            190, 246, 229, 175, 128, 17, 236, 96, 10, 111, 56, 196,
        ];
        let coeffs: [i16; N] = core::array::from_fn(|i| (i * 10) as i16);
        let poly = Poly::from_arr_normal(&coeffs);
        let v = PolyVec::from(array_vec!([Poly<Normalised>; 4] => poly, poly, poly, poly)).unwrap();

        let mut buf = [0u8; 1408];
        v.compress(&mut buf);

        assert_eq!(buf, want);
    }

    #[test]
    fn compare_decompress_test_768() {
        let buf = [
            0, 12, 96, 64, 2, 12, 60, 32, 129, 5, 25, 112, 240, 129, 8, 37, 160, 176, 130, 11, 49,
            208, 112, 131, 14, 62, 4, 65, 196, 17, 74, 52, 1, 197, 20, 86, 100, 193, 197, 23, 98,
            152, 145, 6, 27, 111, 200, 81, 7, 30, 123, 248, 17, 8, 33, 135, 40, 210, 72, 36, 148,
            92, 162, 73, 39, 160, 140, 98, 74, 42, 172, 188, 34, 75, 45, 185, 240, 242, 139, 48,
            197, 32, 179, 140, 51, 209, 80, 115, 141, 54, 221, 132, 67, 206, 57, 234, 180, 3, 207,
            60, 246, 228, 195, 207, 63, 2, 21, 148, 16, 67, 15, 73, 84, 17, 70, 27, 121, 20, 18,
            73, 39, 169, 212, 82, 76, 52, 221, 164, 83, 79, 64, 13, 101, 84, 82, 76, 61, 37, 85,
            85, 89, 113, 245, 149, 88, 101, 161, 181, 150, 91, 113, 209, 117, 151, 94, 125, 1, 70,
            216, 97, 138, 53, 6, 217, 100, 150, 101, 198, 217, 103, 162, 149, 134, 26, 107, 175,
            201, 86, 27, 110, 187, 249, 22, 28, 113, 199, 41, 215, 28, 116, 212, 93, 167, 93, 119,
            224, 141, 103, 94, 122, 236, 189, 39, 95, 125, 248, 241, 247, 159, 128, 5, 34, 184,
            160, 131, 17, 82, 120, 161, 134, 29, 130, 72, 226, 137, 42, 182, 8, 227, 140, 54, 230,
            200, 227, 143, 66, 22, 137, 36, 147, 79, 74, 89, 37, 150, 91, 122, 25, 38, 153, 103,
            170, 217, 38, 156, 116, 222, 169, 103, 159, 128, 14, 106, 104, 162, 140, 62, 42, 105,
            165, 152, 110, 250, 169, 168, 165, 162, 186, 170, 171, 177, 210, 122, 171, 174, 189, 2,
            59, 236, 177, 202, 54, 11, 237, 180, 214, 102, 203, 237, 183, 226, 150, 139, 238, 186,
            239, 202, 91, 47, 190, 251, 250, 27, 48, 193, 7, 43, 220, 48, 196, 0, 12, 96, 64, 2,
            12, 60, 32, 129, 5, 25, 112, 240, 129, 8, 37, 160, 176, 130, 11, 49, 208, 112, 131, 14,
            62, 4, 65, 196, 17, 74, 52, 1, 197, 20, 86, 100, 193, 197, 23, 98, 152, 145, 6, 27,
            111, 200, 81, 7, 30, 123, 248, 17, 8, 33, 135, 40, 210, 72, 36, 148, 92, 162, 73, 39,
            160, 140, 98, 74, 42, 172, 188, 34, 75, 45, 185, 240, 242, 139, 48, 197, 32, 179, 140,
            51, 209, 80, 115, 141, 54, 221, 132, 67, 206, 57, 234, 180, 3, 207, 60, 246, 228, 195,
            207, 63, 2, 21, 148, 16, 67, 15, 73, 84, 17, 70, 27, 121, 20, 18, 73, 39, 169, 212, 82,
            76, 52, 221, 164, 83, 79, 64, 13, 101, 84, 82, 76, 61, 37, 85, 85, 89, 113, 245, 149,
            88, 101, 161, 181, 150, 91, 113, 209, 117, 151, 94, 125, 1, 70, 216, 97, 138, 53, 6,
            217, 100, 150, 101, 198, 217, 103, 162, 149, 134, 26, 107, 175, 201, 86, 27, 110, 187,
            249, 22, 28, 113, 199, 41, 215, 28, 116, 212, 93, 167, 93, 119, 224, 141, 103, 94, 122,
            236, 189, 39, 95, 125, 248, 241, 247, 159, 128, 5, 34, 184, 160, 131, 17, 82, 120, 161,
            134, 29, 130, 72, 226, 137, 42, 182, 8, 227, 140, 54, 230, 200, 227, 143, 66, 22, 137,
            36, 147, 79, 74, 89, 37, 150, 91, 122, 25, 38, 153, 103, 170, 217, 38, 156, 116, 222,
            169, 103, 159, 128, 14, 106, 104, 162, 140, 62, 42, 105, 165, 152, 110, 250, 169, 168,
            165, 162, 186, 170, 171, 177, 210, 122, 171, 174, 189, 2, 59, 236, 177, 202, 54, 11,
            237, 180, 214, 102, 203, 237, 183, 226, 150, 139, 238, 186, 239, 202, 91, 47, 190, 251,
            250, 27, 48, 193, 7, 43, 220, 48, 196, 0, 12, 96, 64, 2, 12, 60, 32, 129, 5, 25, 112,
            240, 129, 8, 37, 160, 176, 130, 11, 49, 208, 112, 131, 14, 62, 4, 65, 196, 17, 74, 52,
            1, 197, 20, 86, 100, 193, 197, 23, 98, 152, 145, 6, 27, 111, 200, 81, 7, 30, 123, 248,
            17, 8, 33, 135, 40, 210, 72, 36, 148, 92, 162, 73, 39, 160, 140, 98, 74, 42, 172, 188,
            34, 75, 45, 185, 240, 242, 139, 48, 197, 32, 179, 140, 51, 209, 80, 115, 141, 54, 221,
            132, 67, 206, 57, 234, 180, 3, 207, 60, 246, 228, 195, 207, 63, 2, 21, 148, 16, 67, 15,
            73, 84, 17, 70, 27, 121, 20, 18, 73, 39, 169, 212, 82, 76, 52, 221, 164, 83, 79, 64,
            13, 101, 84, 82, 76, 61, 37, 85, 85, 89, 113, 245, 149, 88, 101, 161, 181, 150, 91,
            113, 209, 117, 151, 94, 125, 1, 70, 216, 97, 138, 53, 6, 217, 100, 150, 101, 198, 217,
            103, 162, 149, 134, 26, 107, 175, 201, 86, 27, 110, 187, 249, 22, 28, 113, 199, 41,
            215, 28, 116, 212, 93, 167, 93, 119, 224, 141, 103, 94, 122, 236, 189, 39, 95, 125,
            248, 241, 247, 159, 128, 5, 34, 184, 160, 131, 17, 82, 120, 161, 134, 29, 130, 72, 226,
            137, 42, 182, 8, 227, 140, 54, 230, 200, 227, 143, 66, 22, 137, 36, 147, 79, 74, 89,
            37, 150, 91, 122, 25, 38, 153, 103, 170, 217, 38, 156, 116, 222, 169, 103, 159, 128,
            14, 106, 104, 162, 140, 62, 42, 105, 165, 152, 110, 250, 169, 168, 165, 162, 186, 170,
            171, 177, 210, 122, 171, 174, 189, 2, 59, 236, 177, 202, 54, 11, 237, 180, 214, 102,
            203, 237, 183, 226, 150, 139, 238, 186, 239, 202, 91, 47, 190, 251, 250, 27, 48, 193,
            7, 43, 220, 48, 196,
        ];

        let v = PolyVec::decompress(&buf).unwrap();
        let want = PolyVec::from(array_vec!([Poly<Normalised>; 4] =>
            Poly::from_arr_normal(&[0, 10, 20, 29, 39, 49, 59, 72, 81, 91, 101, 111, 120, 130, 140, 150, 159, 169, 179, 189, 202, 211, 221, 231, 241, 250, 260, 270, 280, 289, 299, 309, 319, 332, 341, 351, 361, 371, 380, 390, 400, 410, 419, 429, 439, 449, 458, 471, 481, 491, 501, 510, 520, 530, 540, 549, 559, 569, 579, 588, 601, 611, 621, 631, 640, 650, 660, 670, 679, 689, 699, 709, 718, 731, 741, 751, 761, 770, 780, 790, 800, 809, 819, 829, 839, 849, 862, 871, 881, 891, 901, 910, 920, 930, 940, 949, 959, 969, 979, 992, 1001, 1011, 1021, 1031, 1040, 1050, 1060, 1070, 1079, 1089, 1099, 1109, 1122, 1131, 1141, 1151, 1161, 1170, 1180, 1190, 1200, 1209, 1219, 1229, 1239, 1248, 1261, 1271, 1281, 1291, 1300, 1310, 1320, 1330, 1339, 1349, 1359, 1369, 1378, 1391, 1401, 1411, 1421, 1430, 1440, 1450, 1460, 1469, 1479, 1489, 1499, 1508, 1521, 1531, 1541, 1551, 1560, 1570, 1580, 1590, 1599, 1609, 1619, 1629, 1638, 1651, 1661, 1671, 1681, 1691, 1700, 1710, 1720, 1730, 1739, 1749, 1759, 1769, 1782, 1791, 1801, 1811, 1821, 1830, 1840, 1850, 1860, 1869, 1879, 1889, 1899, 1912, 1921, 1931, 1941, 1951, 1960, 1970, 1980, 1990, 1999, 2009, 2019, 2029, 2042, 2051, 2061, 2071, 2081, 2090, 2100, 2110, 2120, 2129, 2139, 2149, 2159, 2168, 2181, 2191, 2201, 2211, 2220, 2230, 2240, 2250, 2259, 2269, 2279, 2289, 2298, 2311, 2321, 2331, 2341, 2350, 2360, 2370, 2380, 2389, 2399, 2409, 2419, 2428, 2441, 2451, 2461, 2471, 2480, 2490, 2500, 2510, 2520, 2529, 2539, 2549]),
            Poly::from_arr_normal(&[0, 10, 20, 29, 39, 49, 59, 72, 81, 91, 101, 111, 120, 130, 140, 150, 159, 169, 179, 189, 202, 211, 221, 231, 241, 250, 260, 270, 280, 289, 299, 309, 319, 332, 341, 351, 361, 371, 380, 390, 400, 410, 419, 429, 439, 449, 458, 471, 481, 491, 501, 510, 520, 530, 540, 549, 559, 569, 579, 588, 601, 611, 621, 631, 640, 650, 660, 670, 679, 689, 699, 709, 718, 731, 741, 751, 761, 770, 780, 790, 800, 809, 819, 829, 839, 849, 862, 871, 881, 891, 901, 910, 920, 930, 940, 949, 959, 969, 979, 992, 1001, 1011, 1021, 1031, 1040, 1050, 1060, 1070, 1079, 1089, 1099, 1109, 1122, 1131, 1141, 1151, 1161, 1170, 1180, 1190, 1200, 1209, 1219, 1229, 1239, 1248, 1261, 1271, 1281, 1291, 1300, 1310, 1320, 1330, 1339, 1349, 1359, 1369, 1378, 1391, 1401, 1411, 1421, 1430, 1440, 1450, 1460, 1469, 1479, 1489, 1499, 1508, 1521, 1531, 1541, 1551, 1560, 1570, 1580, 1590, 1599, 1609, 1619, 1629, 1638, 1651, 1661, 1671, 1681, 1691, 1700, 1710, 1720, 1730, 1739, 1749, 1759, 1769, 1782, 1791, 1801, 1811, 1821, 1830, 1840, 1850, 1860, 1869, 1879, 1889, 1899, 1912, 1921, 1931, 1941, 1951, 1960, 1970, 1980, 1990, 1999, 2009, 2019, 2029, 2042, 2051, 2061, 2071, 2081, 2090, 2100, 2110, 2120, 2129, 2139, 2149, 2159, 2168, 2181, 2191, 2201, 2211, 2220, 2230, 2240, 2250, 2259, 2269, 2279, 2289, 2298, 2311, 2321, 2331, 2341, 2350, 2360, 2370, 2380, 2389, 2399, 2409, 2419, 2428, 2441, 2451, 2461, 2471, 2480, 2490, 2500, 2510, 2520, 2529, 2539, 2549]),
            Poly::from_arr_normal(&[0, 10, 20, 29, 39, 49, 59, 72, 81, 91, 101, 111, 120, 130, 140, 150, 159, 169, 179, 189, 202, 211, 221, 231, 241, 250, 260, 270, 280, 289, 299, 309, 319, 332, 341, 351, 361, 371, 380, 390, 400, 410, 419, 429, 439, 449, 458, 471, 481, 491, 501, 510, 520, 530, 540, 549, 559, 569, 579, 588, 601, 611, 621, 631, 640, 650, 660, 670, 679, 689, 699, 709, 718, 731, 741, 751, 761, 770, 780, 790, 800, 809, 819, 829, 839, 849, 862, 871, 881, 891, 901, 910, 920, 930, 940, 949, 959, 969, 979, 992, 1001, 1011, 1021, 1031, 1040, 1050, 1060, 1070, 1079, 1089, 1099, 1109, 1122, 1131, 1141, 1151, 1161, 1170, 1180, 1190, 1200, 1209, 1219, 1229, 1239, 1248, 1261, 1271, 1281, 1291, 1300, 1310, 1320, 1330, 1339, 1349, 1359, 1369, 1378, 1391, 1401, 1411, 1421, 1430, 1440, 1450, 1460, 1469, 1479, 1489, 1499, 1508, 1521, 1531, 1541, 1551, 1560, 1570, 1580, 1590, 1599, 1609, 1619, 1629, 1638, 1651, 1661, 1671, 1681, 1691, 1700, 1710, 1720, 1730, 1739, 1749, 1759, 1769, 1782, 1791, 1801, 1811, 1821, 1830, 1840, 1850, 1860, 1869, 1879, 1889, 1899, 1912, 1921, 1931, 1941, 1951, 1960, 1970, 1980, 1990, 1999, 2009, 2019, 2029, 2042, 2051, 2061, 2071, 2081, 2090, 2100, 2110, 2120, 2129, 2139, 2149, 2159, 2168, 2181, 2191, 2201, 2211, 2220, 2230, 2240, 2250, 2259, 2269, 2279, 2289, 2298, 2311, 2321, 2331, 2341, 2350, 2360, 2370, 2380, 2389, 2399, 2409, 2419, 2428, 2441, 2451, 2461, 2471, 2480, 2490, 2500, 2510, 2520, 2529, 2539, 2549]),
        )).unwrap();

        assert_eq!(v, want);
    }

    proptest! {
        #[test]
        fn sec_level_test(poly_vec in new_poly_vec()) {
            let sec_level = poly_vec.sec_level();
        }

        #[test]
        fn polynomials_test(poly_vec in new_poly_vec()) {
            let polys = poly_vec.polynomials();
        }

        #[test]
        fn add_test(a in new_limited_poly_vec(4), b in new_limited_poly_vec(4)) {
            let poly_vec = a.add(&b).unwrap();
        }

        #[test]
        #[should_panic]
        fn add_test_different_sec_levels(a in new_limited_poly_vec(2), b in new_limited_poly_vec(3)) {
            let poly_vec = a.add(&b).unwrap();
        }

        #[test]
        fn barrett_reduce_test(poly_vec in new_poly_vec()) {
            let output = poly_vec.barrett_reduce();
        }

        #[test]
        fn normalise_test(poly_vec in new_poly_vec()) {
            let output = poly_vec.normalise();
        }

        #[test]
        fn inv_ntt_test(poly_vec in new_ntt_poly_vec(4)) {
            let output = poly_vec.inv_ntt();
        }

        #[test]
        fn ntt_test(poly_vec in new_poly_vec()) {
            let output = poly_vec.normalise().ntt();
        }

        #[test]
        fn pack_test(poly_vec in new_poly_vec()) {
            let mut buf = [0u8; 4 * POLYBYTES]; // max buf length needed
            let k: usize = poly_vec.sec_level().k().into();

            let output = poly_vec.normalise().pack(&mut buf[..k * POLYBYTES]).unwrap();
        }

        #[test]
        fn compress_test(poly_vec in new_poly_vec()) {
            let mut buf = [0u8; 4 * 352]; // max poly_vec_compressed_bytes
            let end = poly_vec.sec_level().poly_vec_compressed_bytes();

            let output = poly_vec.normalise().compress(&mut buf[..end]).unwrap();
        }

        #[test]
        fn unpack_test(poly_vec in new_poly_vec()) {
            let mut buf = [0u8; 4 * POLYBYTES]; // max buf length
            let k: usize = poly_vec.sec_level().k().into();

            let _result = poly_vec.normalise().pack(&mut buf[..k * POLYBYTES]).unwrap();

            let unpacked = PolyVec::unpack(&buf[..k * POLYBYTES]).unwrap();
            assert_eq!(unpacked.normalise(), poly_vec.normalise());
        }

        #[test]
        fn decompress_test(poly_vec in new_poly_vec()) {
            let mut buf = [0u8; 4 * 352]; // max poly_vec_compressed_bytes
            let end = poly_vec.sec_level().poly_vec_compressed_bytes();

            let _result = poly_vec.normalise().compress(&mut buf[..end]).unwrap();

            let decompressed = PolyVec::decompress(&buf[..end]).unwrap();
            // assert_eq!(poly_vec.normalise(), decompressed);
        }

        #[test]
        fn derive_noise_test(
            sec_level in sec_level_strategy(),
            seed in prop::array::uniform32(u8::MIN..u8::MAX),
            nonce in (u8::MIN..u8::MAX - 4),
        ) {
            let output_1 = PolyVec::derive_noise(sec_level, &seed, nonce, sec_level.eta_1());
            let output_2 = PolyVec::derive_noise(sec_level, &seed, nonce, sec_level.eta_2());
        }

        #[test]
        fn inner_product_pointwise_test(
            poly_vec_1 in new_limited_poly_vec(4),
            poly_vec_2 in new_limited_poly_vec(4),
        ) {
            let poly = poly_vec_1.normalise().inner_product_pointwise(&poly_vec_2.normalise());
            let poly = poly_vec_1.barrett_reduce().inner_product_pointwise(&poly_vec_2.barrett_reduce());
        }
    }
}