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)]
pub(in crate::tests) mod indcpa_tests {
    use crate::{
        indcpa::*, matrix::*, params::*, polynomials::*,
        tests::params::params_tests::sec_level_strategy, vectors::*,
    };
    use proptest::prelude::*;
    use rand::rngs::StdRng;
    use rand::{Rng, SeedableRng};
    use tinyvec::{array_vec, ArrayVec};

    pub(in crate::tests) fn generate_random_seed() -> [u8; 32] {
        let mut rng = StdRng::from_entropy();
        let mut seed = [0u8; 32];
        rng.fill(&mut seed);
        seed
    }

    prop_compose! {
        fn new_indcpa_keypair()
            (key_seed in prop::array::uniform32(u8::MIN..u8::MAX), sec_level in sec_level_strategy())
            -> (PrivateKey, PublicKey) {
                generate_indcpa_key_pair(&key_seed, sec_level).unwrap()
            }
    }
    // #[test]
    // fn compare_key() {
    //     let sec_level = SecurityLevel::new(K::Three);
    //     let noise = PolyVec::from(array_vec!([Poly<Unreduced>; 4] =>
    //         Poly::from_arr(&[2284, 2613, 2232, 272, 2401, 971, 1701, 896, 1089, 3312, 1724, 1716, 2665, 3079, 436, 1381, 2072, 2631, 1185, 2871, 660, 1181, 117, 112, 840, 994, 3325, 1675, 2134, 304, 1137, 1974, 2746, 2970, 1294, 441, 270, 2775, 1278, 1812, 2062, 799, 1069, 605, 1290, 510, 3283, 1129, 1403, 526, 446, 3119, 154, 1581, 666, 2506, 144, 388, 344, 3057, 943, 1642, 3209, 2923, 1163, 2771, 1481, 1863, 2067, 2637, 2070, 283, 751, 3220, 2362, 2469, 2446, 1697, 2695, 2777, 710, 627, 940, 3211, 344, 2855, 2158, 1559, 983, 1710, 777, 110, 2701, 2627, 1587, 3205, 1390, 822, 1774, 311, 2217, 3160, 1436, 370, 2041, 2882, 2672, 1778, 225, 710, 1247, 1889, 3152, 2823, 1797, 1980, 864, 419, 760, 2454, 2348, 1637, 1808, 2529, 720, 1155, 3277, 2403, 445, 1974, 3007, 2013, 3218, 2344, 1738, 2214, 926, 2525, 841, 1164, 2037, 3179, 746, 2483, 2278, 711, 310, 2567, 1083, 900, 1177, 760, 609, 393, 219, 3228, 837, 2241, 2229, 2232, 1967, 1274, 776, 1661, 2051, 1287, 685, 2598, 2986, 2072, 2686, 555, 2117, 1071, 465, 2307, 1849, 173, 442, 814, 1798, 36, 2225, 197, 2494, 1922, 1395, 865, 1929, 1452, 1991, 959, 1032, 2287, 2155, 527, 341, 3240, 1140, 2756, 2930, 756, 191, 2014, 2917, 1167, 2086, 1404, 2844, 1286, 845, 3227, 1762, 2462, 2925, 2188, 1774, 2050, 1220, 1721, 305, 770, 2447, 1866, 2506, 317, 1448, 867, 2027, 1160, 1134, 3160, 2421, 3073, 1174, 741, 2231, 2868, 2957, 708, 1987, 1744, 1105, 2679, 1087, 2607, 1688, 110, 1992, 2212, 3191, 1366, 1590, 552, 3323, 1019]),
    //         Poly::from_arr(&[839, 2612, 370, 315, 3133, 63, 1354, 740, 1000, 1216, 1154, 339, 567, 1765, 2590, 1415, 1857, 1003, 1235, 3280, 2488, 2798, 368, 1946, 3066, 1995, 1280, 1214, 1735, 933, 1887, 1519, 1487, 866, 1723, 1549, 965, 2112, 2753, 1571, 1901, 1245, 3326, 917, 2086, 1689, 1407, 3035, 3126, 802, 1352, 1262, 2405, 2166, 2617, 3298, 1757, 5, 2720, 685, 994, 2773, 510, 764, 3001, 1060, 2965, 1792, 377, 2960, 1228, 297, 2634, 2849, 3104, 1531, 283, 186, 2459, 1134, 2691, 1305, 2549, 1631, 3247, 2798, 3193, 915, 1015, 1772, 1518, 1130, 1977, 1782, 153, 2007, 3073, 1768, 1633, 2394, 3041, 2616, 815, 3221, 2632, 330, 2815, 2023, 787, 814, 3165, 3145, 2195, 322, 540, 616, 3233, 1205, 2852, 2032, 2668, 1089, 2074, 2726, 1009, 170, 589, 1110, 882, 3293, 328, 2213, 1211, 1703, 2271, 2204, 193, 2104, 777, 1622, 1852, 969, 18, 2437, 1314, 1229, 2870, 2901, 3297, 1955, 2052, 1243, 2642, 267, 504, 2783, 53, 2867, 2852, 2468, 887, 2438, 3213, 2025, 184, 1313, 1150, 2355, 2728, 1578, 2236, 2808, 2071, 2166, 562, 1102, 1718, 411, 1174, 2815, 2221, 2688, 1782, 2244, 3316, 3186, 2020, 2820, 1212, 446, 700, 2068, 40, 499, 2702, 136, 3283, 354, 328, 2887, 942, 1958, 1765, 2886, 3126, 2066, 3058, 1237, 2445, 1728, 2944, 414, 2094, 467, 1130, 3099, 858, 2599, 1191, 2554, 1260, 2032, 1021, 937, 1103, 1662, 59, 503, 3013, 1996, 3151, 3267, 2128, 2635, 1646, 790, 790, 2381, 33, 1177, 2911, 1991, 3108, 1365, 2806, 736, 2960, 2455, 2878, 1924, 598, 438, 2600, 1709, 636, 669]),
    //         Poly::from_arr(&[2032, 2146, 1885, 322, 661, 1949, 2919, 2568, 1834, 3056, 851, 1849, 1226, 2985, 575, 2127, 1046, 1447, 2024, 639, 2568, 692, 939, 1166, 53, 3041, 1518, 2338, 2342, 2560, 2589, 2307, 1704, 1029, 1496, 3063, 2596, 480, 3297, 875, 484, 818, 2808, 2581, 408, 112, 807, 1692, 3086, 2110, 410, 759, 409, 3298, 718, 2057, 2588, 1478, 1169, 752, 887, 1657, 1142, 2087, 1369, 580, 2157, 2452, 1573, 1366, 1069, 1405, 2168, 1989, 2205, 981, 310, 414, 2606, 1448, 2414, 2339, 267, 2160, 2904, 2200, 2013, 470, 3324, 2243, 1129, 1428, 1787, 1434, 471, 1273, 2678, 3145, 3292, 123, 521, 803, 2409, 186, 2351, 402, 873, 2649, 1823, 487, 1689, 678, 40, 966, 2863, 1508, 2931, 2261, 1970, 1261, 1541, 828, 2034, 599, 1950, 3269, 1201, 3241, 1880, 3144, 3266, 318, 155, 1798, 863, 2358, 666, 3121, 1575, 2342, 2596, 1796, 2634, 2104, 2532, 1814, 1656, 3265, 307, 970, 3051, 2909, 3306, 2672, 1968, 2102, 1706, 1536, 1323, 838, 2666, 1152, 1818, 2430, 1318, 1254, 3089, 439, 182, 2589, 100, 564, 1617, 1377, 2359, 2963, 263, 2358, 2750, 216, 227, 3289, 3083, 445, 2727, 2488, 2384, 2665, 2290, 2506, 1095, 933, 145, 1087, 2430, 994, 869, 1436, 574, 2171, 1823, 2011, 2154, 371, 1110, 2333, 367, 2668, 2797, 3311, 1383, 3184, 497, 3008, 858, 423, 2143, 464, 193, 2513, 1151, 1288, 2321, 989, 3109, 25, 2695, 272, 201, 79, 1031, 980, 1455, 2950, 191, 1015, 2480, 2153, 2891, 260, 1656, 504, 893, 1774, 2108, 325, 839, 251, 1573, 2213, 249, 1819, 2891, 2648, 2986, 686])
    //     )).unwrap().normalise();

    //     let rho = [203, 211, 246, 238, 186, 103, 107, 33, 224, 242, 196, 117, 34, 41, 36, 130, 253, 131, 15, 51, 12, 29, 132, 167, 148, 187, 148, 114, 139, 45, 147, 254];

    //     let a_t = Matrix::derive(&rho, true, K::Three).unwrap();

    //     let pk = PublicKey {
    //         noise,
    //         rho,
    //         a_t,
    //     };

    //     let secret = PolyVec::from(array_vec!([Poly<Normalised>; 4] =>
    //         Poly::from_arr_normal(&[230, 1153, 2638, 1390, 2083, 1749, 1530, 3269, 2020, 899, 1047, 2149, 1095, 492, 3209, 2665, 595, 301, 1761, 1154, 1857, 581, 141, 2313, 874, 942, 369, 1159, 110, 2722, 3167, 1462, 561, 1579, 1550, 539, 596, 750, 2272, 1192, 139, 3320, 238, 666, 3279, 1064, 2629, 2728, 208, 264, 193, 1867, 2992, 2019, 2796, 2840, 3218, 2069, 2756, 2585, 2009, 198, 1939, 2503, 1058, 108, 2921, 784, 702, 2878, 524, 1082, 1367, 425, 2022, 3096, 615, 2828, 1109, 2958, 1937, 2432, 150, 1525, 2517, 504, 1412, 409, 830, 1329, 2309, 2536, 2798, 732, 3269, 930, 2002, 2955, 1758, 785, 933, 2115, 1215, 2381, 600, 1440, 3009, 3186, 2633, 1194, 2999, 2022, 1257, 1096, 2925, 2950, 1322, 3295, 2951, 2099, 2081, 1661, 1837, 817, 2582, 2752, 2445, 1376, 1300, 917, 2983, 2484, 1720, 127, 1375, 2737, 857, 3153, 2774, 1648, 1753, 1074, 771, 1054, 3039, 1472, 931, 2269, 2126, 501, 321, 2104, 97, 1265, 1021, 1605, 18, 2469, 3090, 2291, 2361, 2910, 2748, 1728, 1889, 514, 22, 1204, 3029, 2949, 1627, 2401, 2334, 3140, 2892, 2688, 2109, 1539, 2107, 2786, 505, 2549, 2219, 2090, 1957, 3021, 3024, 2723, 224, 119, 1323, 240, 278, 571, 2513, 2142, 717, 1312, 903, 2608, 1196, 3037, 3089, 1387, 2552, 1663, 264, 2229, 2841, 2836, 1184, 1931, 2328, 1036, 2591, 1864, 1333, 2878, 329, 1530, 204, 3277, 2540, 892, 298, 926, 1477, 587, 329, 2452, 3193, 1105, 698, 695, 1631, 1572, 362, 2541, 2456, 2163, 1742, 2163, 1182, 481, 780, 306, 1441, 2675, 545, 1483, 142, 127, 78, 2545, 2574, 2867]),
    //         Poly::from_arr_normal(&[3061, 2321, 2992, 376, 2221, 3157, 3037, 1538, 3028, 2896, 837, 1676, 2635, 2955, 314, 1310, 261, 2835, 27, 381, 2669, 2588, 240, 3160, 189, 402, 1451, 845, 1821, 2951, 8, 985, 137, 1507, 2071, 319, 136, 2330, 1271, 2830, 493, 263, 150, 2922, 1323, 2364, 1592, 2575, 2641, 1182, 746, 451, 1913, 913, 164, 2624, 2439, 2159, 634, 783, 2895, 3089, 32, 2501, 1328, 444, 1350, 2962, 1143, 398, 1540, 865, 400, 2009, 892, 41, 290, 3167, 2856, 1617, 1509, 965, 2070, 2726, 2965, 851, 1029, 976, 2105, 2145, 3156, 1552, 3200, 2526, 764, 1187, 3292, 1294, 122, 1047, 1763, 396, 260, 2805, 1606, 143, 63, 891, 474, 1712, 1164, 1608, 2766, 2374, 1499, 2790, 1274, 1609, 2347, 3144, 622, 822, 316, 3316, 2313, 1281, 840, 207, 1879, 996, 902, 2986, 1810, 2441, 390, 118, 1751, 1437, 178, 1851, 3296, 57, 231, 2756, 1692, 2214, 1404, 2331, 718, 1906, 1697, 2265, 2773, 1976, 2723, 2736, 3200, 964, 1571, 591, 649, 2295, 2198, 2014, 3286, 2353, 353, 2389, 1702, 1734, 201, 1161, 2682, 1639, 1439, 1114, 3267, 1964, 2509, 228, 1097, 1228, 1258, 1524, 987, 810, 843, 730, 1285, 3067, 2645, 2684, 2309, 2441, 359, 2797, 529, 166, 2898, 1815, 2801, 2364, 2494, 1598, 2485, 431, 2519, 2101, 3205, 514, 1166, 681, 1235, 1923, 1554, 2014, 818, 875, 485, 577, 61, 2803, 1011, 141, 645, 1802, 3320, 2196, 1532, 1600, 3168, 1852, 3271, 2456, 366, 3198, 963, 1929, 2271, 0, 870, 277, 3161, 2362, 1487, 666, 2492, 1213, 2415, 2809, 1275, 1528, 2909, 3253, 432, 2386]),
    //         Poly::from_arr_normal(&[312, 3010, 1181, 2787, 721, 2908, 1063, 732, 2871, 1018, 2764, 364, 1799, 2384, 2380, 2696, 741, 657, 1558, 2632, 1426, 2208, 442, 2383, 3029, 2927, 2674, 2401, 2088, 1189, 1109, 3122, 1644, 582, 2009, 138, 209, 2718, 270, 1954, 214, 2682, 1983, 782, 2131, 2724, 2284, 185, 1078, 253, 1089, 1856, 306, 3117, 483, 4, 580, 1255, 1515, 2965, 1799, 2849, 773, 646, 2154, 2238, 3328, 2834, 3004, 927, 733, 2840, 1200, 706, 2700, 2590, 1987, 1732, 2921, 460, 1453, 870, 1947, 1075, 2586, 125, 2820, 2395, 380, 2568, 522, 2036, 142, 2473, 516, 363, 489, 1811, 2048, 1759, 6, 1240, 1037, 2518, 1102, 596, 354, 1576, 1337, 1391, 2522, 337, 121, 1384, 581, 40, 788, 2612, 652, 3163, 2971, 361, 1735, 55, 753, 1760, 405, 2428, 2963, 1661, 2715, 430, 1369, 1592, 2498, 1437, 804, 1600, 1480, 1468, 522, 2363, 2603, 1920, 158, 1612, 3080, 2958, 1161, 2743, 1105, 3327, 3202, 3213, 555, 2247, 540, 2602, 1172, 1527, 2472, 1291, 869, 1887, 1478, 947, 472, 240, 2374, 2116, 1151, 1492, 2974, 2134, 985, 1267, 1423, 1273, 780, 3056, 796, 321, 1966, 2302, 1714, 474, 3268, 93, 2485, 2739, 2763, 2997, 2031, 1882, 1009, 2706, 790, 1047, 1201, 1305, 2552, 2530, 2822, 2422, 1764, 2332, 2013, 674, 933, 2501, 279, 647, 2849, 1477, 1628, 2430, 1514, 317, 2522, 2344, 929, 1714, 2973, 1816, 1523, 422, 2641, 390, 2083, 1989, 628, 2825, 1643, 1962, 1149, 1509, 1483, 442, 3160, 3326, 2345, 350, 443, 1439, 247, 463, 1128, 753, 3082, 1916, 3149, 3241, 582, 288, 2801, 2334])
    //     )).unwrap();

    //     let sk = PrivateKey { secret };

    //     let cipher_seed: [u8; 32] = core::array::from_fn(|i| i as u8);
    //     let coeffs: [i16; N] = core::array::from_fn(|i| (i * 10) as i16);
    //     let msg = Poly::from_arr(&coeffs).normalise().write_msg().unwrap();

    //     let ciphertext = pk.encrypt(&msg, &cipher_seed).unwrap();
    //     let message = sk.decrypt(&ciphertext).unwrap();

    //     assert_eq!(message, msg);
    // }

    proptest! {
        #[test]
        fn key_gen_enc_dec(
            (priv_key, pub_key) in new_indcpa_keypair(),
            cipher_seed in prop::array::uniform32(u8::MIN..u8::MAX),
            plaintext in prop::array::uniform32(u8::MIN..u8::MAX)
        ) {
            let mut ciphertext = [0u8; 1568]; // max length
            let sec_level = priv_key.sec_level();

            let _ = pub_key.encrypt(&plaintext, &cipher_seed, &mut ciphertext[..sec_level.indcpa_bytes()]).unwrap();

            let message = priv_key.decrypt(&ciphertext[..sec_level.indcpa_bytes()]).unwrap();

            assert_eq!(message, plaintext, "security level: {:?}", sec_level);
        }

        #[cfg(feature = "decap_key")]
        #[test]
        fn key_pack_unpack(
            (priv_key, pub_key) in new_indcpa_keypair(),
        ) {
            let mut buf = [0u8; 2 * (4 * POLYBYTES) + SYMBYTES];

            let k:usize = priv_key.sec_level().k().into();
            let _ = priv_key.pack(&mut buf[..k * POLYBYTES]);
            let _ = pub_key.pack(&mut buf[k * POLYBYTES..2 * (k * POLYBYTES) + SYMBYTES]);

            let unpacked_priv = PrivateKey::unpack(&buf[..k * POLYBYTES]).unwrap();
            let unpacked_pub = PublicKey::unpack(&buf[k * POLYBYTES..2 * (k * POLYBYTES) + SYMBYTES]).unwrap();

            assert_eq!(unpacked_pub, pub_key);
            assert_eq!(unpacked_priv, priv_key);
        }

        #[test]
        #[should_panic]
        fn pub_key_pack_bad_buf_len(
            bad_bytes_len in 1..4 * POLYBYTES + SYMBYTES + 100,
            (_, pub_key) in new_indcpa_keypair(),
        ) {
            if bad_bytes_len == <K as Into<usize>>::into(pub_key.sec_level().k()) * POLYBYTES + SYMBYTES {
                panic!()
            }
            let mut bad_key_bytes = [0u8; 4 * POLYBYTES + SYMBYTES + 100];

            let pack_err = pub_key.pack(&mut bad_key_bytes[..bad_bytes_len]).unwrap();
        }

        #[test]
        #[should_panic]
        fn pub_key_unpack_bad_buf_len(
            bad_bytes_len in 1..4 * POLYBYTES + SYMBYTES + 100,
            (_, pub_key) in new_indcpa_keypair(),
        ) {
            if bad_bytes_len == <K as Into<usize>>::into(pub_key.sec_level().k()) * POLYBYTES + SYMBYTES {
                panic!()
            }
            let mut bad_key_bytes = [0u8; 4 * POLYBYTES + SYMBYTES + 100];

            let unpack_err = PublicKey::unpack(&bad_key_bytes[..bad_bytes_len]).unwrap();
        }

        #[test]
        #[should_panic]
        fn decrypt_bad_ciphertext_len(
            bad_bytes_len in 1..2048usize,
            (priv_key, _) in new_indcpa_keypair()
        ) {
            if bad_bytes_len as usize == priv_key.sec_level().indcpa_bytes() {
                panic!()
            }
            let bad_ciphertext = ArrayVec::<[u8; 2048]>::from_array_len([0u8; 2048], bad_bytes_len);

            let decrypt_err = priv_key.decrypt(&bad_ciphertext).unwrap();
        }
    }
}