graviola 0.4.0

graviola is a modern, fast cryptography library
Documentation
// Written for Graviola by Joe Birr-Pixton, 2026.
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0

// Plastering over the differences between (eg) mlkem_ntt() between x86-64 and aarch64.

/// Forward number-theoretic transform from ML-KEM
pub(crate) fn mlkem_ntt(a: &mut [i16; 256]) {
    super::mlkem_ntt::mlkem_ntt(a, &NTT_ZETAS_01234.0, &NTT_ZETAS_56.0);
}

/// Inverse number-theoretic transform from ML-KEM
pub(crate) fn mlkem_intt(a: &mut [i16; 256]) {
    super::mlkem_intt::mlkem_intt(a, &INTT_ZETAS_01234.0, &INTT_ZETAS_56.0);
}

/// Precompute the mulcache data for a polynomial in the NTT domain
pub(crate) fn mlkem_mulcache_compute(x: &mut [i16; 128], a: &[i16; 256]) {
    super::mlkem_mulcache_compute::mlkem_mulcache_compute(
        x,
        a,
        &MULCACHE_ZETAS.0,
        &MULCACHE_ZETAS_TWISTED.0,
    );
}

/// Do rejection sampling, where `input` is SHAKE128 bytes, and `r` is a
/// set of polynomial coefficients to write.
///
/// Returns the number of items of `r` written.
pub(crate) fn mlkem_rej_uniform_vartime(r: &mut [i16; 256], input: &[u8]) -> u64 {
    super::mlkem_rej_uniform_vartime::mlkem_rej_uniform_vartime(r, input, &MLKEM_REJ_UNIFORM_TABLE)
}

#[repr(align(32))]
struct Coeffs<const N: usize>([i16; N]);

const NTT_ZETAS_01234: Coeffs<80> = Coeffs([
    -1600, -15749, -749, -7373, -40, -394, -687, -6762, 630, 6201, -1432, -14095, 848, 8347, 0, 0,
    1062, 10453, 296, 2914, -882, -8682, 0, 0, -1410, -13879, 1339, 13180, 1476, 14529, 0, 0, 193,
    1900, -283, -2786, 56, 551, 0, 0, 797, 7845, -1089, -10719, 1333, 13121, 0, 0, -543, -5345,
    1426, 14036, -1235, -12156, 0, 0, -69, -679, 535, 5266, -447, -4400, 0, 0, 569, 5601, -936,
    -9213, -450, -4429, 0, 0, -1583, -15582, -1355, -13338, 821, 8081, 0, 0,
]);

const NTT_ZETAS_56: Coeffs<384> = Coeffs([
    289, 289, 331, 331, -76, -76, -1573, -1573, 2845, 2845, 3258, 3258, -748, -748, -15483, -15483,
    17, 17, 583, 583, 1637, 1637, -1041, -1041, 167, 167, 5739, 5739, 16113, 16113, -10247, -10247,
    -568, -568, -680, -680, 723, 723, 1100, 1100, -5591, -5591, -6693, -6693, 7117, 7117, 10828,
    10828, 1197, 1197, -1025, -1025, -1052, -1052, -1274, -1274, 11782, 11782, -10089, -10089,
    -10355, -10355, -12540, -12540, 1409, 1409, -48, -48, 756, 756, -314, -314, 13869, 13869, -472,
    -472, 7441, 7441, -3091, -3091, -667, -667, 233, 233, -1173, -1173, -279, -279, -6565, -6565,
    2293, 2293, -11546, -11546, -2746, -2746, 650, 650, -1352, -1352, -816, -816, 632, 632, 6398,
    6398, -13308, -13308, -8032, -8032, 6221, 6221, -1626, -1626, -540, -540, -1482, -1482, 1461,
    1461, -16005, -16005, -5315, -5315, -14588, -14588, 14381, 14381, 1651, 1651, -1540, -1540,
    952, 952, -642, -642, 16251, 16251, -15159, -15159, 9371, 9371, -6319, -6319, -464, -464, 33,
    33, 1320, 1320, -1414, -1414, -4567, -4567, 325, 325, 12993, 12993, -13918, -13918, 939, 939,
    -892, -892, 733, 733, 268, 268, 9243, 9243, -8780, -8780, 7215, 7215, 2638, 2638, -1021, -1021,
    -941, -941, -992, -992, 641, 641, -10050, -10050, -9262, -9262, -9764, -9764, 6309, 6309,
    -1010, -1010, 1435, 1435, 807, 807, 452, 452, -9942, -9942, 14125, 14125, 7943, 7943, 4449,
    4449, 1584, 1584, -1292, -1292, 375, 375, -1239, -1239, 15592, 15592, -12717, -12717, 3691,
    3691, -12196, -12196, -1031, -1031, -109, -109, -780, -780, 1645, 1645, -10148, -10148, -1073,
    -1073, -7678, -7678, 16192, 16192, 1438, 1438, -461, -461, 1534, 1534, -927, -927, 14155,
    14155, -4538, -4538, 15099, 15099, -9125, -9125, 1063, 1063, -556, -556, -1230, -1230, -863,
    -863, 10463, 10463, -5473, -5473, -12107, -12107, -8495, -8495, 319, 319, 757, 757, 561, 561,
    -735, -735, 3140, 3140, 7451, 7451, 5522, 5522, -7235, -7235, -682, -682, -712, -712, 1481,
    1481, 648, 648, -6713, -6713, -7008, -7008, 14578, 14578, 6378, 6378, -525, -525, 403, 403,
    1143, 1143, -554, -554, -5168, -5168, 3967, 3967, 11251, 11251, -5453, -5453, 1092, 1092, 1026,
    1026, -1179, -1179, 886, 886, 10749, 10749, 10099, 10099, -11605, -11605, 8721, 8721, -855,
    -855, -219, -219, 1227, 1227, 910, 910, -8416, -8416, -2156, -2156, 12078, 12078, 8957, 8957,
    -1607, -1607, -1455, -1455, -1219, -1219, 885, 885, -15818, -15818, -14322, -14322, -11999,
    -11999, 8711, 8711, 1212, 1212, 1029, 1029, -394, -394, -1175, -1175, 11930, 11930, 10129,
    10129, -3878, -3878, -11566, -11566,
]);

const INTT_ZETAS_01234: Coeffs<80> = Coeffs([
    1583, 15582, -821, -8081, 1355, 13338, 0, 0, -569, -5601, 450, 4429, 936, 9213, 0, 0, 69, 679,
    447, 4400, -535, -5266, 0, 0, 543, 5345, 1235, 12156, -1426, -14036, 0, 0, -797, -7845, -1333,
    -13121, 1089, 10719, 0, 0, -193, -1900, -56, -551, 283, 2786, 0, 0, 1410, 13879, -1476, -14529,
    -1339, -13180, 0, 0, -1062, -10453, 882, 8682, -296, -2914, 0, 0, 1600, 15749, 40, 394, 749,
    7373, -848, -8347, 1432, 14095, -630, -6201, 687, 6762, 0, 0,
]);

const INTT_ZETAS_56: Coeffs<384> = Coeffs([
    -910, -910, -1227, -1227, 219, 219, 855, 855, -8957, -8957, -12078, -12078, 2156, 2156, 8416,
    8416, 1175, 1175, 394, 394, -1029, -1029, -1212, -1212, 11566, 11566, 3878, 3878, -10129,
    -10129, -11930, -11930, -885, -885, 1219, 1219, 1455, 1455, 1607, 1607, -8711, -8711, 11999,
    11999, 14322, 14322, 15818, 15818, -648, -648, -1481, -1481, 712, 712, 682, 682, -6378, -6378,
    -14578, -14578, 7008, 7008, 6713, 6713, -886, -886, 1179, 1179, -1026, -1026, -1092, -1092,
    -8721, -8721, 11605, 11605, -10099, -10099, -10749, -10749, 554, 554, -1143, -1143, -403, -403,
    525, 525, 5453, 5453, -11251, -11251, -3967, -3967, 5168, 5168, 927, 927, -1534, -1534, 461,
    461, -1438, -1438, 9125, 9125, -15099, -15099, 4538, 4538, -14155, -14155, 735, 735, -561,
    -561, -757, -757, -319, -319, 7235, 7235, -5522, -5522, -7451, -7451, -3140, -3140, 863, 863,
    1230, 1230, 556, 556, -1063, -1063, 8495, 8495, 12107, 12107, 5473, 5473, -10463, -10463, -452,
    -452, -807, -807, -1435, -1435, 1010, 1010, -4449, -4449, -7943, -7943, -14125, -14125, 9942,
    9942, -1645, -1645, 780, 780, 109, 109, 1031, 1031, -16192, -16192, 7678, 7678, 1073, 1073,
    10148, 10148, 1239, 1239, -375, -375, 1292, 1292, -1584, -1584, 12196, 12196, -3691, -3691,
    12717, 12717, -15592, -15592, 1414, 1414, -1320, -1320, -33, -33, 464, 464, 13918, 13918,
    -12993, -12993, -325, -325, 4567, 4567, -641, -641, 992, 992, 941, 941, 1021, 1021, -6309,
    -6309, 9764, 9764, 9262, 9262, 10050, 10050, -268, -268, -733, -733, 892, 892, -939, -939,
    -2638, -2638, -7215, -7215, 8780, 8780, -9243, -9243, -632, -632, 816, 816, 1352, 1352, -650,
    -650, -6221, -6221, 8032, 8032, 13308, 13308, -6398, -6398, 642, 642, -952, -952, 1540, 1540,
    -1651, -1651, 6319, 6319, -9371, -9371, 15159, 15159, -16251, -16251, -1461, -1461, 1482, 1482,
    540, 540, 1626, 1626, -14381, -14381, 14588, 14588, 5315, 5315, 16005, 16005, 1274, 1274, 1052,
    1052, 1025, 1025, -1197, -1197, 12540, 12540, 10355, 10355, 10089, 10089, -11782, -11782, 279,
    279, 1173, 1173, -233, -233, 667, 667, 2746, 2746, 11546, 11546, -2293, -2293, 6565, 6565, 314,
    314, -756, -756, 48, 48, -1409, -1409, 3091, 3091, -7441, -7441, 472, 472, -13869, -13869,
    1573, 1573, 76, 76, -331, -331, -289, -289, 15483, 15483, 748, 748, -3258, -3258, -2845, -2845,
    -1100, -1100, -723, -723, 680, 680, 568, 568, -10828, -10828, -7117, -7117, 6693, 6693, 5591,
    5591, 1041, 1041, -1637, -1637, -583, -583, -17, -17, 10247, 10247, -16113, -16113, -5739,
    -5739, -167, -167,
]);

const MULCACHE_ZETAS: Coeffs<128> = Coeffs([
    17, -17, -568, 568, 583, -583, -680, 680, 1637, -1637, 723, -723, -1041, 1041, 1100, -1100,
    1409, -1409, -667, 667, -48, 48, 233, -233, 756, -756, -1173, 1173, -314, 314, -279, 279,
    -1626, 1626, 1651, -1651, -540, 540, -1540, 1540, -1482, 1482, 952, -952, 1461, -1461, -642,
    642, 939, -939, -1021, 1021, -892, 892, -941, 941, 733, -733, -992, 992, 268, -268, 641, -641,
    1584, -1584, -1031, 1031, -1292, 1292, -109, 109, 375, -375, -780, 780, -1239, 1239, 1645,
    -1645, 1063, -1063, 319, -319, -556, 556, 757, -757, -1230, 1230, 561, -561, -863, 863, -735,
    735, -525, 525, 1092, -1092, 403, -403, 1026, -1026, 1143, -1143, -1179, 1179, -554, 554, 886,
    -886, -1607, 1607, 1212, -1212, -1455, 1455, 1029, -1029, -1219, 1219, -394, 394, 885, -885,
    -1175, 1175,
]);

const MULCACHE_ZETAS_TWISTED: Coeffs<128> = Coeffs([
    167, -167, -5591, 5591, 5739, -5739, -6693, 6693, 16113, -16113, 7117, -7117, -10247, 10247,
    10828, -10828, 13869, -13869, -6565, 6565, -472, 472, 2293, -2293, 7441, -7441, -11546, 11546,
    -3091, 3091, -2746, 2746, -16005, 16005, 16251, -16251, -5315, 5315, -15159, 15159, -14588,
    14588, 9371, -9371, 14381, -14381, -6319, 6319, 9243, -9243, -10050, 10050, -8780, 8780, -9262,
    9262, 7215, -7215, -9764, 9764, 2638, -2638, 6309, -6309, 15592, -15592, -10148, 10148, -12717,
    12717, -1073, 1073, 3691, -3691, -7678, 7678, -12196, 12196, 16192, -16192, 10463, -10463,
    3140, -3140, -5473, 5473, 7451, -7451, -12107, 12107, 5522, -5522, -8495, 8495, -7235, 7235,
    -5168, 5168, 10749, -10749, 3967, -3967, 10099, -10099, 11251, -11251, -11605, 11605, -5453,
    5453, 8721, -8721, -15818, 15818, 11930, -11930, -14322, 14322, 10129, -10129, -11999, 11999,
    -3878, 3878, 8711, -8711, -11566, 11566,
]);

const MLKEM_REJ_UNIFORM_TABLE: [i8; 4096] = [
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0
    0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 1
    2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 2
    0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 3
    4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 4
    0, 1, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 5
    2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 6
    0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 7
    6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 8
    0, 1, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 9
    2, 3, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10
    0, 1, 2, 3, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 11
    4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 12
    0, 1, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 13
    2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 14
    0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, // 15
    8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16
    0, 1, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 17
    2, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 18
    0, 1, 2, 3, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 19
    4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20
    0, 1, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 21
    2, 3, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 22
    0, 1, 2, 3, 4, 5, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, // 23
    6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 24
    0, 1, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 25
    2, 3, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 26
    0, 1, 2, 3, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, // 27
    4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 28
    0, 1, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, // 29
    2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, // 30
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 31
    10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32
    0, 1, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 33
    2, 3, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 34
    0, 1, 2, 3, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 35
    4, 5, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 36
    0, 1, 4, 5, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 37
    2, 3, 4, 5, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 38
    0, 1, 2, 3, 4, 5, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 39
    6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 40
    0, 1, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 41
    2, 3, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 42
    0, 1, 2, 3, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 43
    4, 5, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 44
    0, 1, 4, 5, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 45
    2, 3, 4, 5, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 46
    0, 1, 2, 3, 4, 5, 6, 7, 10, 11, -1, -1, -1, -1, -1, -1, // 47
    8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 48
    0, 1, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 49
    2, 3, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 50
    0, 1, 2, 3, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 51
    4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 52
    0, 1, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 53
    2, 3, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 54
    0, 1, 2, 3, 4, 5, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, // 55
    6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 56
    0, 1, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 57
    2, 3, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 58
    0, 1, 2, 3, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, // 59
    4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, -1, // 60
    0, 1, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, // 61
    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, // 62
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, // 63
    12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64
    0, 1, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 65
    2, 3, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 66
    0, 1, 2, 3, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 67
    4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 68
    0, 1, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 69
    2, 3, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 70
    0, 1, 2, 3, 4, 5, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 71
    6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 72
    0, 1, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 73
    2, 3, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 74
    0, 1, 2, 3, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 75
    4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 76
    0, 1, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 77
    2, 3, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 78
    0, 1, 2, 3, 4, 5, 6, 7, 12, 13, -1, -1, -1, -1, -1, -1, // 79
    8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
    0, 1, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 81
    2, 3, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 82
    0, 1, 2, 3, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 83
    4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 84
    0, 1, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 85
    2, 3, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 86
    0, 1, 2, 3, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, // 87
    6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 88
    0, 1, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 89
    2, 3, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 90
    0, 1, 2, 3, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, // 91
    4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 92
    0, 1, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, // 93
    2, 3, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, // 94
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, -1, -1, -1, -1, // 95
    10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96
    0, 1, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 97
    2, 3, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 98
    0, 1, 2, 3, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 99
    4, 5, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 100
    0, 1, 4, 5, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 101
    2, 3, 4, 5, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 102
    0, 1, 2, 3, 4, 5, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 103
    6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 104
    0, 1, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 105
    2, 3, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 106
    0, 1, 2, 3, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 107
    4, 5, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 108
    0, 1, 4, 5, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 109
    2, 3, 4, 5, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 110
    0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, -1, -1, -1, -1, // 111
    8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112
    0, 1, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 113
    2, 3, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 114
    0, 1, 2, 3, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 115
    4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 116
    0, 1, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 117
    2, 3, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 118
    0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, // 119
    6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, // 120
    0, 1, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 121
    2, 3, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 122
    0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, // 123
    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, // 124
    0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, // 125
    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, // 126
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, // 127
    14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128
    0, 1, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 129
    2, 3, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 130
    0, 1, 2, 3, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 131
    4, 5, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 132
    0, 1, 4, 5, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 133
    2, 3, 4, 5, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 134
    0, 1, 2, 3, 4, 5, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 135
    6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 136
    0, 1, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 137
    2, 3, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 138
    0, 1, 2, 3, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 139
    4, 5, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 140
    0, 1, 4, 5, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 141
    2, 3, 4, 5, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 142
    0, 1, 2, 3, 4, 5, 6, 7, 14, 15, -1, -1, -1, -1, -1, -1, // 143
    8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144
    0, 1, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 145
    2, 3, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 146
    0, 1, 2, 3, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 147
    4, 5, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 148
    0, 1, 4, 5, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 149
    2, 3, 4, 5, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 150
    0, 1, 2, 3, 4, 5, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, // 151
    6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 152
    0, 1, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 153
    2, 3, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 154
    0, 1, 2, 3, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, // 155
    4, 5, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 156
    0, 1, 4, 5, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, // 157
    2, 3, 4, 5, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, -1, -1, // 158
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, -1, -1, -1, -1, // 159
    10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160
    0, 1, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 161
    2, 3, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 162
    0, 1, 2, 3, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 163
    4, 5, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 164
    0, 1, 4, 5, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 165
    2, 3, 4, 5, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 166
    0, 1, 2, 3, 4, 5, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 167
    6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 168
    0, 1, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 169
    2, 3, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 170
    0, 1, 2, 3, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 171
    4, 5, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 172
    0, 1, 4, 5, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 173
    2, 3, 4, 5, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 174
    0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, // 175
    8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176
    0, 1, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 177
    2, 3, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 178
    0, 1, 2, 3, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 179
    4, 5, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 180
    0, 1, 4, 5, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 181
    2, 3, 4, 5, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 182
    0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, // 183
    6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 184
    0, 1, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 185
    2, 3, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 186
    0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, // 187
    4, 5, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, // 188
    0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, // 189
    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, -1, -1, // 190
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, -1, -1, // 191
    12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192
    0, 1, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 193
    2, 3, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 194
    0, 1, 2, 3, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 195
    4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 196
    0, 1, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 197
    2, 3, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 198
    0, 1, 2, 3, 4, 5, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 199
    6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 200
    0, 1, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 201
    2, 3, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 202
    0, 1, 2, 3, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 203
    4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 204
    0, 1, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 205
    2, 3, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 206
    0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, -1, -1, -1, -1, // 207
    8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208
    0, 1, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 209
    2, 3, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 210
    0, 1, 2, 3, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 211
    4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 212
    0, 1, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 213
    2, 3, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 214
    0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, // 215
    6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 216
    0, 1, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 217
    2, 3, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 218
    0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, // 219
    4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 220
    0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, // 221
    2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, -1, -1, // 222
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, -1, -1, // 223
    10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224
    0, 1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 225
    2, 3, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 226
    0, 1, 2, 3, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 227
    4, 5, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 228
    0, 1, 4, 5, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 229
    2, 3, 4, 5, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 230
    0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 231
    6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 232
    0, 1, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 233
    2, 3, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 234
    0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 235
    4, 5, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 236
    0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 237
    2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 238
    0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, -1, -1, // 239
    8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, // 240
    0, 1, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 241
    2, 3, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 242
    0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 243
    4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 244
    0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 245
    2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 246
    0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, // 247
    6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, // 248
    0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 249
    2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 250
    0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, // 251
    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, // 252
    0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, // 253
    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, // 254
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 255
];