diff --git a/scripts/poseidon2_rust_params.sage b/scripts/poseidon2_rust_params.sage index 8b490275..7d3a4a50 100644 --- a/scripts/poseidon2_rust_params.sage +++ b/scripts/poseidon2_rust_params.sage @@ -1,49 +1,48 @@ # NOTE: This script is a slightly modified version from https://github.com/HorizenLabs/poseidon2/blob/main/poseidon2_rust_params.sage # The modifications were made to support generating multiple constants for different t values. -# Remark: This script contains functionality for GF(2^n), but currently works only over GF(p)! A few small adaptations are needed for GF(2^n). -from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list +# A recent modification added generation for efficient partial MDS matrices +from functools import partial +from itertools import product, chain from math import * -import itertools +from multiprocessing import Pool +PRIME = 2013265921 # BabyBear +FIELD_SIZE = len(PRIME.bits()) def get_alpha(p): for alpha in range(3, p): if gcd(alpha, p-1) == 1: - break - return alpha - -def get_sbox_cost(R_F, R_P, N, t): - return int(t * R_F + R_P) - -def get_size_cost(R_F, R_P, N, t): - n = ceil(float(N) / t) - return int((N * R_F) + (n * R_P)) + return alpha + else: + # Note: Mathematically this will never happen + raise Exception(f"No alpha is generated for p = {p}") -def poseidon_calc_final_numbers_fixed(p, t, alpha, M, security_margin, FIELD_SIZE, NUM_CELLS): - # [Min. S-boxes] Find best possible for t and N - n = ceil(log(p, 2)) - N = int(n * t) - cost_function = get_sbox_cost - ret_list = [] - (R_F, R_P) = find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin, FIELD_SIZE, NUM_CELLS) - min_sbox_cost = cost_function(R_F, R_P, N, t) - ret_list.append(R_F) - ret_list.append(R_P) - ret_list.append(min_sbox_cost) +def sat_inequiv(p, t, r_f, r_p, alpha, M, field_size): + if alpha > 0: + R_F_1 = 6 if M <= ((floor(log(p, 2) - ((alpha-1)/2.0))) * (t + 1)) else 10 # Statistical + R_F_2 = 1 + ceil(log(2, alpha) * min(M, field_size)) + ceil(log(t, alpha)) - r_p # Interpolation + R_F_3 = (log(2, alpha) * min(M, log(p, 2))) - r_p # Groebner 1 + R_F_4 = t - 1 + log(2, alpha) * min(M / float(t + 1), log(p, 2) / float(2)) - r_p # Groebner 2 + R_F_5 = (t - 2 + (M / float(2 * log(alpha, 2))) - r_p) / float(t - 1) # Groebner 3 + R_F_max = max(ceil(R_F_1), ceil(R_F_2), ceil(R_F_3), ceil(R_F_4), ceil(R_F_5)) - # [Min. Size] Find best possible for t and N - # Minimum number of S-boxes for fixed n results in minimum size also (round numbers are the same)! - min_size_cost = get_size_cost(R_F, R_P, N, t) - ret_list.append(min_size_cost) + # Addition due to https://eprint.iacr.org/2023/537.pdf + r_temp = floor(t / 3.0) + over = (r_f - 1) * t + r_p + r_temp + r_temp * (r_f / 2.0) + r_p + alpha + under = r_temp * (r_f / 2.0) + r_p + alpha + binom_log = log(binomial(over, under), 2) + if binom_log == inf: + binom_log = M + 1 + cost_gb4 = ceil(2 * binom_log) # Paper uses 2.3727, we are more conservative here - return ret_list # [R_F, R_P, min_sbox_cost, min_size_cost] + return ((r_f >= R_F_max) and (cost_gb4 >= M)) + else: + raise Exception(f"Unexpected value of alpha: {alpha}") -def find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin, FIELD_SIZE, NUM_CELLS): +def find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin, field_size): n = ceil(log(p, 2)) N = int(n * t) - sat_inequiv = sat_inequiv_alpha - R_P = 0 R_F = 0 min_cost = float("inf") @@ -52,11 +51,11 @@ def find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin, FIELD_ for R_P_t in range(1, 500): for R_F_t in range(4, 100): if R_F_t % 2 == 0: - if (sat_inequiv(p, t, R_F_t, R_P_t, alpha, M, FIELD_SIZE, NUM_CELLS) == True): + if (sat_inequiv(p, t, R_F_t, R_P_t, alpha, M, field_size) == True): if security_margin == True: R_F_t += 2 R_P_t = int(ceil(float(R_P_t) * 1.075)) - cost = cost_function(R_F_t, R_P_t, N, t) + cost = cost_function(R_F_t, R_P_t, N) if (cost < min_cost) or ((cost == min_cost) and (R_F_t < max_cost_rf)): R_P = ceil(R_P_t) R_F = ceil(R_F_t) @@ -64,46 +63,45 @@ def find_FD_round_numbers(p, t, alpha, M, cost_function, security_margin, FIELD_ max_cost_rf = R_F return (int(R_F), int(R_P)) -def sat_inequiv_alpha(p, t, R_F, R_P, alpha, M, FIELD_SIZE, NUM_CELLS): - N = int(FIELD_SIZE * NUM_CELLS) +def get_sbox_cost(r_f, r_p, t): + return int(t * r_f + r_p) - if alpha > 0: - R_F_1 = 6 if M <= ((floor(log(p, 2) - ((alpha-1)/2.0))) * (t + 1)) else 10 # Statistical - R_F_2 = 1 + ceil(log(2, alpha) * min(M, FIELD_SIZE)) + ceil(log(t, alpha)) - R_P # Interpolation - R_F_3 = (log(2, alpha) * min(M, log(p, 2))) - R_P # Groebner 1 - R_F_4 = t - 1 + log(2, alpha) * min(M / float(t + 1), log(p, 2) / float(2)) - R_P # Groebner 2 - R_F_5 = (t - 2 + (M / float(2 * log(alpha, 2))) - R_P) / float(t - 1) # Groebner 3 - R_F_max = max(ceil(R_F_1), ceil(R_F_2), ceil(R_F_3), ceil(R_F_4), ceil(R_F_5)) - - # Addition due to https://eprint.iacr.org/2023/537.pdf - r_temp = floor(t / 3.0) - over = (R_F - 1) * t + R_P + r_temp + r_temp * (R_F / 2.0) + R_P + alpha - under = r_temp * (R_F / 2.0) + R_P + alpha - binom_log = log(binomial(over, under), 2) - if binom_log == inf: - binom_log = M + 1 - cost_gb4 = ceil(2 * binom_log) # Paper uses 2.3727, we are more conservative here +def poseidon_calc_final_numbers_fixed(p, t, alpha, M, security_margin, field_size): + # [Min. S-boxes] Find best possible for t and N + n = ceil(log(p, 2)) + N = int(n * t) + ret_list = [] + (R_F, R_P) = find_FD_round_numbers(p, t, alpha, M, get_sbox_cost, security_margin, field_size) + min_sbox_cost = get_sbox_cost(R_F, R_P, N) + ret_list.append(R_F) + ret_list.append(R_P) + ret_list.append(min_sbox_cost) - return ((R_F >= R_F_max) and (cost_gb4 >= M)) - else: - print("Invalid value for alpha!") - exit(1) + # [Min. Size] Find best possible for t and N + # Minimum number of S-boxes for fixed n results in minimum size also (round numbers are the same)! + min_size_cost = get_sbox_cost(R_F, R_P, N) + ret_list.append(min_size_cost) -# For STARK TODO -# r_p_mod = R_P_FIXED % NUM_CELLS -# if r_p_mod != 0: -# R_P_FIXED = R_P_FIXED + NUM_CELLS - r_p_mod + return ret_list # [R_F, R_P, min_sbox_cost, min_size_cost] -########################################################################### +def init_generator(n, t, r_f, r_p): + # Generate initial sequence based on parameters + field_tag = 1 + sbox_tag = 0 + bit_list_field = [_ for _ in (bin(field_tag)[2:].zfill(2))] + bit_list_sbox = [_ for _ in (bin(sbox_tag)[2:].zfill(4))] + bit_list_n = [_ for _ in (bin(n)[2:].zfill(12))] + bit_list_t = [_ for _ in (bin(t)[2:].zfill(12))] + bit_list_R_F = [_ for _ in (bin(r_f)[2:].zfill(10))] + bit_list_R_P = [_ for _ in (bin(r_p)[2:].zfill(10))] + bit_list_1 = [1] * 30 + init_sequence = bit_list_field + bit_list_sbox + bit_list_n + bit_list_t + bit_list_R_F + bit_list_R_P + bit_list_1 + init_sequence = [int(_) for _ in init_sequence] -# if FIELD == 1 and len(sys.argv) != 8: -# print("Please specify a prime number (in hex format)!") -# exit() -# elif FIELD == 1 and len(sys.argv) == 8: -# PRIME_NUMBER = int(sys.argv[7], 16) # e.g. 0xa7, 0xFFFFFFFFFFFFFEFF, 0xa1a42c3efd6dbfe08daa6041b36322ef + return init_sequence -def grain_sr_generator(INIT_SEQUENCE): - bit_sequence = INIT_SEQUENCE +def grain_sr_generator(init_sequence): + bit_sequence = init_sequence for _ in range(0, 160): new_bit = bit_sequence[62] ^^ bit_sequence[51] ^^ bit_sequence[38] ^^ bit_sequence[23] ^^ bit_sequence[13] ^^ bit_sequence[0] bit_sequence.pop(0) @@ -126,85 +124,40 @@ def grain_sr_generator(INIT_SEQUENCE): yield new_bit def grain_random_bits(grain_gen, num_bits): - random_bits = [next(grain_gen) for i in range(0, num_bits)] - # random_bits.reverse() ## Remove comment to start from least significant bit + random_bits = [next(grain_gen) for _ in range(num_bits)] random_int = int("".join(str(i) for i in random_bits), 2) - return random_int -def init_generator(field, sbox, n, t, R_F, R_P, FIELD, SBOX, FIELD_SIZE, NUM_CELLS): - # Generate initial sequence based on parameters - bit_list_field = [_ for _ in (bin(FIELD)[2:].zfill(2))] - bit_list_sbox = [_ for _ in (bin(SBOX)[2:].zfill(4))] - bit_list_n = [_ for _ in (bin(FIELD_SIZE)[2:].zfill(12))] - bit_list_t = [_ for _ in (bin(NUM_CELLS)[2:].zfill(12))] - bit_list_R_F = [_ for _ in (bin(R_F)[2:].zfill(10))] - bit_list_R_P = [_ for _ in (bin(R_P)[2:].zfill(10))] - bit_list_1 = [1] * 30 - INIT_SEQUENCE = bit_list_field + bit_list_sbox + bit_list_n + bit_list_t + bit_list_R_F + bit_list_R_P + bit_list_1 - INIT_SEQUENCE = [int(_) for _ in INIT_SEQUENCE] - - return INIT_SEQUENCE + return random_int -def generate_constants(field, n, t, R_F, R_P, prime_number, grain_gen): - round_constants = [] +def generate_constants(n, t, r_f, r_p, prime_number, grain_gen): full_round_constants = [] partial_round_constants = [] - # num_constants = (R_F + R_P) * t # Poseidon - num_constants = (R_F * t) + R_P # Poseidon2 + num_constants = (r_f * t) + r_p # Poseidon2 - if field == 0: - for i in range(0, num_constants): + for i in range(num_constants): + random_int = grain_random_bits(grain_gen, n) + while random_int >= prime_number: random_int = grain_random_bits(grain_gen, n) - round_constants.append(random_int) - elif field == 1: - for i in range(0, num_constants): - random_int = grain_random_bits(grain_gen, n) - while random_int >= prime_number: - # print("[Info] Round constant is not in prime field! Taking next one.") - random_int = grain_random_bits(grain_gen, n) - # Add (t-1) zeroes for Poseidon2 if partial round - if i >= ((R_F/2) * t) and i < (((R_F/2) * t) + R_P): - partial_round_constants.append(random_int) - else: - full_round_constants.append(random_int) + # Add (t-1) zeroes for Poseidon2 if partial round + if i >= ((r_f/2) * t) and i < (((r_f/2) * t) + r_p): + partial_round_constants.append(random_int) + else: + full_round_constants.append(random_int) return (full_round_constants, partial_round_constants) -def print_round_constants(round_constants, n, field): - print("Number of round constants:", len(round_constants)) - - if field == 0: - print("Round constants for GF(2^n):") - elif field == 1: - print("Round constants for GF(p):") - hex_length = int(ceil(float(n) / 4)) + 2 # +2 for "0x" - print(["{0:#0{1}x}".format(entry, hex_length) for entry in round_constants]) - -def create_mds_p(n, t, grain_gen, F): - M = matrix(F, t, t) - - # Sample random distinct indices and assign to xs and ys - while True: - flag = True - rand_list = [F(grain_random_bits(grain_gen, n)) for _ in range(0, 2*t)] - while len(rand_list) != len(set(rand_list)): # Check for duplicates - rand_list = [F(grain_random_bits(grain_gen, n)) for _ in range(0, 2*t)] - xs = rand_list[:t] - ys = rand_list[t:] - # xs = [F(ele) for ele in range(0, t)] - # ys = [F(ele) for ele in range(t, 2*t)] - for i in range(0, t): - for j in range(0, t): - if (flag == False) or ((xs[i] + ys[j]) == 0): - flag = False - else: - entry = (xs[i] + ys[j])^(-1) - M[i, j] = entry - if flag == False: - continue - return M +def check_minpoly_condition(M, num_cells): + max_period = 2*num_cells + all_fulfilled = True + M_temp = M + for _ in range(max_period): + if not ((M_temp.minimal_polynomial().degree() == num_cells) and (M_temp.minimal_polynomial().is_irreducible() == True)): + all_fulfilled = False + break + M_temp = M * M_temp + return all_fulfilled -def generate_vectorspace(round_num, M, M_round, NUM_CELLS, F): - t = NUM_CELLS +def generate_vectorspace(round_num, M_round, num_cells, F): + t = num_cells s = 1 V = VectorSpace(F, t) if round_num == 0: @@ -226,8 +179,8 @@ def generate_vectorspace(round_num, M, M_round, NUM_CELLS, F): return S -def subspace_times_matrix(subspace, M, NUM_CELLS, F): - t = NUM_CELLS +def subspace_times_matrix(subspace, M, num_cells, F): + t = num_cells V = VectorSpace(F, t) subspace_basis = subspace.basis() new_basis = [] @@ -236,9 +189,8 @@ def subspace_times_matrix(subspace, M, NUM_CELLS, F): new_subspace = V.subspace(new_basis) return new_subspace -# Returns True if the matrix is considered secure, False otherwise -def algorithm_1(M, NUM_CELLS, F): - t = NUM_CELLS +def algorithm_1(M, num_cells, F): + t = num_cells s = 1 r = floor((t - s) / float(s)) @@ -255,7 +207,7 @@ def algorithm_1(M, NUM_CELLS, F): if (mat_test - mat_target) == matrix.circulant(vector([F(0)] * (t))): return [False, 1] - S = generate_vectorspace(i, M, M_round, t, F) + S = generate_vectorspace(i, M_round, t, F) V = VectorSpace(F, t) basis_vectors= [] @@ -278,15 +230,14 @@ def algorithm_1(M, NUM_CELLS, F): return [True, 0] # Returns True if the matrix is considered secure, False otherwise -def algorithm_2(M, NUM_CELLS, F): - t = NUM_CELLS +def algorithm_2(M, num_cells, F): + t = num_cells s = 1 V = VectorSpace(F, t) - trail = [None, None] test_next = False I = range(0, s) - I_powerset = list(sage.misc.misc.powerset(I))[1:] + I_powerset = list(sage.combinat.subset.powerset(I))[1:] for I_s in I_powerset: test_next = False new_basis = [] @@ -316,392 +267,166 @@ def algorithm_2(M, NUM_CELLS, F): return [True, None] # Returns True if the matrix is considered secure, False otherwise -def algorithm_3(M, NUM_CELLS, F): - t = NUM_CELLS - s = 1 - - V = VectorSpace(F, t) +def algorithm_3(M, num_cells, F): + t = num_cells l = 4*t for r in range(2, l+1): - next_r = False res_alg_2 = algorithm_2(M^r, t, F) if res_alg_2[0] == False: return [False, None] - # if res_alg_2[1] == None: - # continue - # IS = res_alg_2[1][0] - # I_s = res_alg_2[1][1] - # for j in range(1, r): - # IS = subspace_times_matrix(IS, M, t) - # I_j = [] - # for i in range(0, s): - # new_basis = [] - # for k in range(0, t): - # if k != i: - # new_basis.append(V.basis()[k]) - # iota_space = V.subspace(new_basis) - # if IS.intersection(iota_space) != iota_space: - # single_iota_space = V.subspace([V.basis()[i]]) - # if IS.intersection(single_iota_space) == single_iota_space: - # I_j.append(i) - # else: - # next_r = True - # break - # if next_r == True: - # break - # if next_r == True: - # continue - # return [False, [IS, I_j, r]] - return [True, None] -def check_minpoly_condition(M, NUM_CELLS): - max_period = 2*NUM_CELLS - all_fulfilled = True - M_temp = M - for i in range(1, max_period + 1): - if not ((M_temp.minimal_polynomial().degree() == NUM_CELLS) and (M_temp.minimal_polynomial().is_irreducible() == True)): - all_fulfilled = False - break - M_temp = M * M_temp - return all_fulfilled +def generate_matrix_candidate(field_size, num_cells, grain_gen, F): + return matrix.diagonal([F(grain_random_bits(grain_gen, field_size)) for _ in range(0, num_cells)]) + +def get_skips(num_cells, num_skips): + return product(range(num_cells - 2), repeat=num_skips) + +def get_diags(num_cells, num_skips, F): + diags = list() + + for skip_list in get_skips(num_cells, num_skips): + steps = [0] * num_cells + for x in skip_list: + steps[x] += 1 + + shift_list = [0, 0] + for i in range(num_cells - 2): + shift_list.append(shift_list[-1] + 1 + steps[i]) -def generate_matrix(FIELD, FIELD_SIZE, NUM_CELLS, grain_gen, F): - if FIELD == 0: - print("Matrix generation not implemented for GF(2^n).") - exit(1) - elif FIELD == 1: - mds_matrix = create_mds_p(FIELD_SIZE, NUM_CELLS, grain_gen, F) - result_1 = algorithm_1(mds_matrix, NUM_CELLS, F) - result_2 = algorithm_2(mds_matrix, NUM_CELLS, F) - result_3 = algorithm_3(mds_matrix, NUM_CELLS, F) - while result_1[0] == False or result_2[0] == False or result_3[0] == False: - mds_matrix = create_mds_p(FIELD_SIZE, NUM_CELLS, grain_gen, F) - result_1 = algorithm_1(mds_matrix, NUM_CELLS, F) - result_2 = algorithm_2(mds_matrix, NUM_CELLS, F) - result_3 = algorithm_3(mds_matrix, NUM_CELLS, F) - return mds_matrix - -def generate_matrix_full(t, NUM_CELLS, F): + new_vect = vector(map(lambda x: F(1 << x), shift_list)) + new_vect[0] = -2 + diags.append(new_vect) + + diags.reverse() # Prioritize checking matrices with smaller entries first + + return diags + +def generate_efficient_matrix_candidates(num_cells, num_skips, F) -> list: + return [matrix.diagonal(F, vect) for vect in get_diags(num_cells, num_skips, F)] + +def generate_matrix_partial(field_size, num_cells, grain_gen, F): M = None - if t == 2: - M = matrix.circulant(vector([F(2), F(1)])) - elif t == 3: - M = matrix.circulant(vector([F(2), F(1), F(1)])) - elif t == 4: - M = matrix(F, [[F(5), F(7), F(1), F(3)], [F(4), F(6), F(1), F(1)], [F(1), F(3), F(5), F(7)], [F(1), F(1), F(4), F(6)]]) - elif (t % 4) == 0: - M = matrix(F, t, t) - # M_small = matrix.circulant(vector([F(3), F(2), F(1), F(1)])) - M_small = matrix(F, [[F(5), F(7), F(1), F(3)], [F(4), F(6), F(1), F(1)], [F(1), F(3), F(5), F(7)], [F(1), F(1), F(4), F(6)]]) - small_num = t // 4 - for i in range(0, small_num): - for j in range(0, small_num): - if i == j: - M[i*4:(i+1)*4,j*4:(j+1)*4] = 2* M_small - else: - M[i*4:(i+1)*4,j*4:(j+1)*4] = M_small + if num_cells == 2: + M = matrix(F, [[F(2), F(1)], [F(1), F(3)]]) + elif num_cells == 3: + M = matrix(F, [[F(2), F(1), F(1)], [F(1), F(2), F(1)], [F(1), F(1), F(3)]]) else: - print("Error: No matrix for these parameters.") - exit() - return M - -def generate_matrix_partial(FIELD, FIELD_SIZE, NUM_CELLS, t, grain_gen, F): ## TODO: Prioritize small entries - entry_max_bit_size = FIELD_SIZE - if FIELD == 0: - print("Matrix generation not implemented for GF(2^n).") - exit(1) - elif FIELD == 1: - M = None - if t == 2: - M = matrix(F, [[F(2), F(1)], [F(1), F(3)]]) - elif t == 3: - M = matrix(F, [[F(2), F(1), F(1)], [F(1), F(2), F(1)], [F(1), F(1), F(3)]]) + M_circulant = matrix.circulant(vector([F(0)] + [F(1) for _ in range(num_cells - 1)])) + for i in range(4): # 4 is a random choice here, but anything bigger would take too long + candidates = generate_efficient_matrix_candidates(num_cells, i, F) + for candidate in candidates: + M = M_circulant + candidate + matrix.identity(F, num_cells) + if check_minpoly_condition(M, num_cells) == True: + return M else: - M_circulant = matrix.circulant(vector([F(0)] + [F(1) for _ in range(0, NUM_CELLS - 1)])) - M_diagonal = matrix.diagonal([F(grain_random_bits(grain_gen, entry_max_bit_size)) for _ in range(0, NUM_CELLS)]) + M_diagonal = generate_matrix_candidate(field_size, num_cells, grain_gen, F) M = M_circulant + M_diagonal - # while algorithm_1(M, NUM_CELLS)[0] == False or algorithm_2(M, NUM_CELLS)[0] == False or algorithm_3(M, NUM_CELLS)[0] == False: - while check_minpoly_condition(M, NUM_CELLS) == False: - M_diagonal = matrix.diagonal([F(grain_random_bits(grain_gen, entry_max_bit_size)) for _ in range(0, NUM_CELLS)]) + while check_minpoly_condition(M, num_cells) == False: + M_diagonal = generate_matrix_candidate(field_size, num_cells, grain_gen, F) M = M_circulant + M_diagonal - if(algorithm_1(M, NUM_CELLS, F)[0] == False or algorithm_2(M, NUM_CELLS, F)[0] == False or algorithm_3(M, NUM_CELLS, F)[0] == False): - print("Error: Generated partial matrix is not secure w.r.t. subspace trails.") - exit() - return M - -def generate_matrix_partial_small_entries(FIELD, FIELD_SIZE, NUM_CELLS, F): - if FIELD == 0: - print("Matrix generation not implemented for GF(2^n).") - exit(1) - elif FIELD == 1: - M_circulant = matrix.circulant(vector([F(0)] + [F(1) for _ in range(0, NUM_CELLS - 1)])) - combinations = list(itertools.product(range(2, 6), repeat=NUM_CELLS)) - for entry in combinations: - M = M_circulant + matrix.diagonal(vector(F, list(entry))) - print(M) - # if M.is_invertible() == False or algorithm_1(M, NUM_CELLS)[0] == False or algorithm_2(M, NUM_CELLS)[0] == False or algorithm_3(M, NUM_CELLS)[0] == False: - if M.is_invertible() == False or check_minpoly_condition(M, NUM_CELLS) == False: - continue - return M - -def matrix_partial_m_1(matrix_partial, NUM_CELLS, F): - M_circulant = matrix.identity(F, NUM_CELLS) - return matrix_partial - M_circulant - -def print_linear_layer(M, n, t, NUM_CELLS, PRIME_NUMBER): - print("n:", n) - print("t:", t) - print("N:", (n * t)) - print("Result Algorithm 1:\n", algorithm_1(M, NUM_CELLS)) - print("Result Algorithm 2:\n", algorithm_2(M, NUM_CELLS)) - print("Result Algorithm 3:\n", algorithm_3(M, NUM_CELLS)) - hex_length = int(ceil(float(n) / 4)) + 2 # +2 for "0x" - print("Prime number:", "0x" + hex(PRIME_NUMBER)) - matrix_string = "[" - for i in range(0, t): - matrix_string += str(["{0:#0{1}x}".format(int(entry), hex_length) for entry in M[i]]) - if i < (t-1): - matrix_string += "," - matrix_string += "]" - print("MDS matrix:\n", matrix_string) - -def calc_equivalent_matrices(MDS_matrix_field, R_P_FIXED, F, t): - # Following idea: Split M into M' * M'', where M'' is "cheap" and M' can move before the partial nonlinear layer - # The "previous" matrix layer is then M * M'. Due to the construction of M', the M[0,0] and v values will be the same for the new M' (and I also, obviously) - # Thus: Compute the matrices, store the w_hat and v_hat values - - MDS_matrix_field_transpose = MDS_matrix_field.transpose() - - w_hat_collection = [] - v_collection = [] - v = MDS_matrix_field_transpose[[0], list(range(1,t))] - - M_mul = MDS_matrix_field_transpose - M_i = matrix(F, t, t) - for i in range(R_P_FIXED - 1, -1, -1): - M_hat = M_mul[list(range(1,t)), list(range(1,t))] - w = M_mul[list(range(1,t)), [0]] - v = M_mul[[0], list(range(1,t))] - v_collection.append(v.list()) - w_hat = M_hat.inverse() * w - w_hat_collection.append(w_hat.list()) - - # Generate new M_i, and multiplication M * M_i for "previous" round - M_i = matrix.identity(t) - M_i[list(range(1,t)), list(range(1,t))] = M_hat - M_mul = MDS_matrix_field_transpose * M_i - - return M_i, v_collection, w_hat_collection, MDS_matrix_field_transpose[0, 0] - -def calc_equivalent_constants(constants, MDS_matrix_field, t, R_F_FIXED, R_P_FIXED): - constants_temp = [constants[index:index+t] for index in range(0, len(constants), t)] - - MDS_matrix_field_transpose = MDS_matrix_field.transpose() - - # Start moving round constants up - # Calculate c_i' = M^(-1) * c_(i+1) - # Split c_i': Add c_i'[0] AFTER the S-box, add the rest to c_i - # I.e.: Store c_i'[0] for each of the partial rounds, and make c_i = c_i + c_i' (where now c_i'[0] = 0) - num_rounds = R_F_FIXED + R_P_FIXED - R_f = R_F_FIXED / 2 - for i in range(num_rounds - 2 - R_f, R_f - 1, -1): - inv_cip1 = list(vector(constants_temp[i+1]) * MDS_matrix_field_transpose.inverse()) - constants_temp[i] = list(vector(constants_temp[i]) + vector([0] + inv_cip1[1:])) - constants_temp[i+1] = [inv_cip1[0]] + [0] * (t-1) - - return constants_temp - -def poseidon(input_words, matrix, round_constants, R_F_FIXED, t, R_P_FIXED, alpha): - - R_f = int(R_F_FIXED / 2) - - round_constants_counter = 0 - - state_words = list(input_words) - - # First full rounds - for r in range(0, R_f): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - for i in range(0, t): - state_words[i] = (state_words[i])^alpha - state_words = list(matrix * vector(state_words)) - - # Middle partial rounds - for r in range(0, R_P_FIXED): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - state_words[0] = (state_words[0])^alpha - state_words = list(matrix * vector(state_words)) - - # Last full rounds - for r in range(0, R_f): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - for i in range(0, t): - state_words[i] = (state_words[i])^alpha - state_words = list(matrix * vector(state_words)) - - return state_words - -def poseidon2(input_words, matrix_full, matrix_partial, round_constants, R_F_FIXED, t, alpha): - - R_f = int(R_F_FIXED / 2) - - round_constants_counter = 0 - - state_words = list(input_words) - - # First matrix mul - state_words = list(matrix_full * vector(state_words)) - - # First full rounds - for r in range(0, R_f): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - for i in range(0, t): - state_words[i] = (state_words[i])^alpha - state_words = list(matrix_full * vector(state_words)) - - # Middle partial rounds - for r in range(0, R_P_FIXED): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - state_words[0] = (state_words[0])^alpha - state_words = list(matrix_partial * vector(state_words)) - - # Last full rounds - for r in range(0, R_f): - # Round constants, nonlinear layer, matrix multiplication - for i in range(0, t): - state_words[i] = state_words[i] + round_constants[round_constants_counter] - round_constants_counter += 1 - for i in range(0, t): - state_words[i] = (state_words[i])^alpha - state_words = list(matrix_full * vector(state_words)) - - return state_words - -def to_field(value, p): + return M + +def final_check(M, num_cells, F): + if(algorithm_1(M, num_cells, F)[0] == False or algorithm_2(M, num_cells, F)[0] == False or algorithm_3(M, num_cells, F)[0] == False): + raise Exception("Generated partial matrix is not secure w.r.t. subspace trails.") + + +def printed_field_elt(value, p): l = len(hex(p - 1)) if l % 2 == 1: l = l + 1 value = hex(int(value))[2:] value = "0x" + value.zfill(l - 2) - # print("from_hex(\"{}\"),".format(value)) - print(f"BabyBear::from_canonical_u32({value}),") + return f"BabyBear::from_canonical_u32({value})," -def generate_constants_file(): - print(""" -//! This module defines all of the constants +def generate_head(): + header_strings = [ +""" +//! This module defines all of the constants used by the Poseidon 2 hasher //! The constants are generated using the `poseidon2_rust_params.sage` script which is a //! modified version of the script found at //! https://github.com/HorizenLabs/poseidon2/blob/main/poseidon2_rust_params.sage - """) - print() - print("use lazy_static::*;") - print("use hybrid_array::{Array, typenum::*};") - print("use p3_baby_bear::BabyBear;") - print("use p3_field::AbstractField;") - print() - for t in range(4, 52, 4): - p = 2013265921 # BabyBear - n = len(p.bits()) - FIELD = 1 - SBOX = 0 - FIELD_SIZE = n - NUM_CELLS = t - alpha = get_alpha(p) - R_F_FIXED, R_P_FIXED, _, _ = poseidon_calc_final_numbers_fixed(p, t, alpha, 128, True, FIELD_SIZE, NUM_CELLS) - - print("// +++ t = {0}, R_F = {1}, R_P = {2} +++".format(t, R_F_FIXED, R_P_FIXED)) - print("lazy_static! {") - INIT_SEQUENCE = init_generator(FIELD, SBOX, FIELD_SIZE, NUM_CELLS, R_F_FIXED, R_P_FIXED, FIELD, SBOX, FIELD_SIZE, NUM_CELLS) - - PRIME_NUMBER = p - F = GF(PRIME_NUMBER) - grain_gen = grain_sr_generator(INIT_SEQUENCE) - - # Round constants - (full_round_constants, partial_round_constants) = generate_constants(FIELD, FIELD_SIZE, NUM_CELLS, R_F_FIXED, R_P_FIXED, PRIME_NUMBER, grain_gen) - # print_round_constants(round_constants, FIELD_SIZE, FIELD) - - # Matrix - # MDS = generate_matrix(FIELD, FIELD_SIZE, NUM_CELLS) - MATRIX_FULL = generate_matrix_full(t, NUM_CELLS, F) - MATRIX_PARTIAL = generate_matrix_partial(FIELD, FIELD_SIZE, NUM_CELLS, t, grain_gen, F) - MATRIX_PARTIAL_DIAGONAL_M_1 = [matrix_partial_m_1(MATRIX_PARTIAL, NUM_CELLS, F)[i,i] for i in range(0, NUM_CELLS)] - - # Efficient partial matrix (diagonal - 1) - print("pub static ref MATRIX_DIAG_{}_BABYBEAR: Array = Array::clone_from_slice([".format(t, t)) - for val in MATRIX_PARTIAL_DIAGONAL_M_1: - to_field(val - 1, p) - print("].as_ref());") - print() - - - # Round constants - R = R_F_FIXED + R_P_FIXED - - print("pub static ref FULL_RC_{}_{}: [[BabyBear; {}]; {}] = [".format(t, R_F_FIXED, t, R_F_FIXED)) - for (i,val) in enumerate(full_round_constants): - if i % t == 0: - print("[", end="") - to_field(val, p) - if i % t == t - 1: - print("],") - print("];") - - print() - - print("pub static ref PART_RC_{}_{}: [BabyBear; {}] = [".format(t, R_P_FIXED, R_P_FIXED)) - for val in partial_round_constants: - to_field(val, p) - print("];") - print("}") - print() - -generate_constants_file() - -### TODO: find a way of uncommenting this to get the test cases - -# print("pub static ref POSEIDON_{}_PARAMS: Arc> = Arc::new(PoseidonParams::new({}, {}, {}, {}, &MAT_DIAG{}_M_1, &RC{}));".format(t, t, alpha, R_F_FIXED, R_P_FIXED , t, t)) - -# print("}") -# print() -# print() - -# state_in = vector([F(i) for i in range(t)]) -# # state_out = poseidon(state_in, MDS, round_constants) -# state_out = poseidon2(state_in, MATRIX_FULL, MATRIX_PARTIAL, round_constants) - -# for (i,val) in enumerate(state_in): -# if i % t == 0: -# print("vec![", end="") -# to_hex(val) -# if i % t == t - 1: -# print("],") -# print("];") - -# for (i,val) in enumerate(state_out): -# if i % t == 0: -# print("vec![", end="") -# to_hex(val) -# if i % t == t - 1: -# print("],") -# print("];") +""", + "\n", + "use lazy_static::lazy_static;", + "use hybrid_array::{Array, typenum::*};", + "use p3_baby_bear::BabyBear;", + "use p3_field::AbstractField;", + "\n" + ] + return "\n".join(header_strings) + +def generate_arity_data(t, alpha): + r_f_fixed, r_p_fixed, _, _ = poseidon_calc_final_numbers_fixed(PRIME, t, alpha, 128, True, FIELD_SIZE) + init_sequence = init_generator(FIELD_SIZE, t, r_f_fixed, r_p_fixed) + F = GF(PRIME) + grain_gen = grain_sr_generator(init_sequence) + + # Round constants + (full_round_constants, partial_round_constants) = generate_constants(FIELD_SIZE, t, r_f_fixed, r_p_fixed, PRIME, grain_gen) + + # Matrix + matrix_partial = generate_matrix_partial(FIELD_SIZE, t, grain_gen, F) + final_check(matrix_partial, t, F) + matrix_partial_diag_plus_one = [matrix_partial[i,i] for i in range(t)] + + return r_f_fixed, r_p_fixed, full_round_constants, partial_round_constants, matrix_partial_diag_plus_one + +def generate_arity_string(t, r_f_fixed, r_p_fixed, matrix_partial_diag_plus_one, full_round_constants, partial_round_constants): + header = f"// +++ t = {t}, R_F = {r_f_fixed}, R_P = {r_p_fixed} +++" + lazy_static_start = "lazy_static! {" + lazy_static_end = "}\n" + + # Partial round Matrix + partial_matrix_header = f"pub static ref MATRIX_DIAG_{t}_BABYBEAR: Array = Array::try_from([" + partial_matrix_vals = [printed_field_elt(val - 1, PRIME) for val in matrix_partial_diag_plus_one] + partial_matrix_end = "].as_ref()).unwrap();\n" + + # Full round constants + full_rc_header = f"pub static ref FULL_RC_{t}_{r_f_fixed}: [[BabyBear; {t}]; {r_f_fixed}] = [" + full_rc_vals = [] + for (i,val) in enumerate(full_round_constants): + if i % t == 0: + full_rc_vals.append("[") + full_rc_vals.append(printed_field_elt(val, PRIME)) + if i % t == t - 1: + full_rc_vals.append("],\n") + full_rc_end = "];\n" + + # Partial round constants + partial_rc_header = f"pub static ref PART_RC_{t}_{r_p_fixed}: [BabyBear; {r_p_fixed}] = [" + partial_rc_vals = [] + for val in partial_round_constants: + partial_rc_vals.append(printed_field_elt(val, PRIME)) + partial_rc_end = "];\n" + + return "\n".join(chain( + [header], [lazy_static_start], [partial_matrix_header], + partial_matrix_vals, [partial_matrix_end], [full_rc_header], + full_rc_vals, [full_rc_end], [partial_rc_header], partial_rc_vals, + [partial_rc_end], [lazy_static_end] + )) + +def arity_func(t, alpha): + r_f_fixed, r_p_fixed, full_rc, part_rc, part_mat = generate_arity_data(t, alpha) + return generate_arity_string(t, r_f_fixed, r_p_fixed, part_mat, full_rc, part_rc) + +def generate_constants_file(): + alpha = get_alpha(PRIME) + + pool = Pool(processes=12) + + file_head = generate_head() + inputs = range(4, 52, 4) + outputs = pool.map(partial(arity_func, alpha=alpha), inputs) + + print(file_head) + print("\n".join(outputs)) + +if __name__ == '__main__': + generate_constants_file() diff --git a/src/poseidon/constants.rs b/src/poseidon/constants.rs index 6d980fe1..44b60b64 100644 --- a/src/poseidon/constants.rs +++ b/src/poseidon/constants.rs @@ -1,4 +1,4 @@ -//! This module defines all of the constants +//! This module defines all of the constants used by the Poseidon 2 hasher //! The constants are generated using the `poseidon2_rust_params.sage` script which is a //! modified version of the script found at //! https://github.com/HorizenLabs/poseidon2/blob/main/poseidon2_rust_params.sage @@ -12,10 +12,10 @@ use p3_field::AbstractField; lazy_static! { pub static ref MATRIX_DIAG_4_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x35bf6f46), - BabyBear::from_canonical_u32(0x6982669e), - BabyBear::from_canonical_u32(0x41f852b1), - BabyBear::from_canonical_u32(0x375cdab7), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), ] .as_ref() ) @@ -99,14 +99,14 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_8_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x17a3691a), - BabyBear::from_canonical_u32(0x00849878), - BabyBear::from_canonical_u32(0x1f7b62e2), - BabyBear::from_canonical_u32(0x05967b0f), - BabyBear::from_canonical_u32(0x427c8659), - BabyBear::from_canonical_u32(0x3f3341ad), - BabyBear::from_canonical_u32(0x52490f5a), - BabyBear::from_canonical_u32(0x468846c4), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), ] .as_ref() ) @@ -213,18 +213,18 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_12_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x5ce6d17e), - BabyBear::from_canonical_u32(0x392b0106), - BabyBear::from_canonical_u32(0x0cbd124b), - BabyBear::from_canonical_u32(0x06f099b5), - BabyBear::from_canonical_u32(0x6cb3ebb3), - BabyBear::from_canonical_u32(0x363069b0), - BabyBear::from_canonical_u32(0x4de47c36), - BabyBear::from_canonical_u32(0x06af5a0a), - BabyBear::from_canonical_u32(0x52a0045d), - BabyBear::from_canonical_u32(0x3e9f380c), - BabyBear::from_canonical_u32(0x0df8c11d), - BabyBear::from_canonical_u32(0x63a32984), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00001000), ] .as_ref() ) @@ -361,22 +361,22 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_16_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x0a632d93), - BabyBear::from_canonical_u32(0x6db657b6), - BabyBear::from_canonical_u32(0x56fbdc9d), - BabyBear::from_canonical_u32(0x052b3d89), - BabyBear::from_canonical_u32(0x33745200), - BabyBear::from_canonical_u32(0x5c03108b), - BabyBear::from_canonical_u32(0x0beba37a), - BabyBear::from_canonical_u32(0x258c2e8a), - BabyBear::from_canonical_u32(0x12029f38), - BabyBear::from_canonical_u32(0x694909cd), - BabyBear::from_canonical_u32(0x6d231723), - BabyBear::from_canonical_u32(0x21c3b221), - BabyBear::from_canonical_u32(0x3c0904a4), - BabyBear::from_canonical_u32(0x01d6acd9), - BabyBear::from_canonical_u32(0x27705c82), - BabyBear::from_canonical_u32(0x5231c801), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00008000), ] .as_ref() ) @@ -548,26 +548,26 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_20_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x60531da2), - BabyBear::from_canonical_u32(0x332932da), - BabyBear::from_canonical_u32(0x61f05e56), - BabyBear::from_canonical_u32(0x614050f7), - BabyBear::from_canonical_u32(0x4323c6dc), - BabyBear::from_canonical_u32(0x10b33546), - BabyBear::from_canonical_u32(0x5e5ce1d7), - BabyBear::from_canonical_u32(0x19a24084), - BabyBear::from_canonical_u32(0x3c697e92), - BabyBear::from_canonical_u32(0x365de6b8), - BabyBear::from_canonical_u32(0x71f95067), - BabyBear::from_canonical_u32(0x350c9227), - BabyBear::from_canonical_u32(0x3883d124), - BabyBear::from_canonical_u32(0x51502e2d), - BabyBear::from_canonical_u32(0x1a4a8173), - BabyBear::from_canonical_u32(0x01e081b1), - BabyBear::from_canonical_u32(0x54c10869), - BabyBear::from_canonical_u32(0x1253bc29), - BabyBear::from_canonical_u32(0x50599b33), - BabyBear::from_canonical_u32(0x025b97c2), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00100000), ] .as_ref() ) @@ -776,30 +776,30 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_24_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x409133ef), - BabyBear::from_canonical_u32(0x1667a8a0), - BabyBear::from_canonical_u32(0x06a6c7b5), - BabyBear::from_canonical_u32(0x6f53160d), - BabyBear::from_canonical_u32(0x273b11d0), - BabyBear::from_canonical_u32(0x03176c5c), - BabyBear::from_canonical_u32(0x72f9bbf8), - BabyBear::from_canonical_u32(0x73ceba90), - BabyBear::from_canonical_u32(0x5cdef81c), - BabyBear::from_canonical_u32(0x01393284), - BabyBear::from_canonical_u32(0x46daee05), - BabyBear::from_canonical_u32(0x065d7ba5), - BabyBear::from_canonical_u32(0x52d72d6e), - BabyBear::from_canonical_u32(0x05dd05df), - BabyBear::from_canonical_u32(0x3bab4b62), - BabyBear::from_canonical_u32(0x6ada3841), - BabyBear::from_canonical_u32(0x2fc5fbeb), - BabyBear::from_canonical_u32(0x770d61af), - BabyBear::from_canonical_u32(0x5715aae8), - BabyBear::from_canonical_u32(0x03ef0e8f), - BabyBear::from_canonical_u32(0x75b6c76f), - BabyBear::from_canonical_u32(0x242adf5e), - BabyBear::from_canonical_u32(0x00d0ca4b), - BabyBear::from_canonical_u32(0x36c0e387), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), ] .as_ref() ) @@ -1043,34 +1043,34 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_28_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x283b2716), - BabyBear::from_canonical_u32(0x2c6fc85a), - BabyBear::from_canonical_u32(0x025908bb), - BabyBear::from_canonical_u32(0x67b2d7a6), - BabyBear::from_canonical_u32(0x4e8b4f2a), - BabyBear::from_canonical_u32(0x08300cca), - BabyBear::from_canonical_u32(0x2125f9d3), - BabyBear::from_canonical_u32(0x498385d4), - BabyBear::from_canonical_u32(0x138ec8eb), - BabyBear::from_canonical_u32(0x2d31b7fc), - BabyBear::from_canonical_u32(0x2eb4d120), - BabyBear::from_canonical_u32(0x3213ae75), - BabyBear::from_canonical_u32(0x6ec11de9), - BabyBear::from_canonical_u32(0x26380599), - BabyBear::from_canonical_u32(0x4606b73d), - BabyBear::from_canonical_u32(0x0703e2c7), - BabyBear::from_canonical_u32(0x201416e0), - BabyBear::from_canonical_u32(0x00226398), - BabyBear::from_canonical_u32(0x062e93e9), - BabyBear::from_canonical_u32(0x73d7ff9a), - BabyBear::from_canonical_u32(0x404b55a8), - BabyBear::from_canonical_u32(0x49cfa105), - BabyBear::from_canonical_u32(0x4df1c571), - BabyBear::from_canonical_u32(0x131cd3ae), - BabyBear::from_canonical_u32(0x33b6cff3), - BabyBear::from_canonical_u32(0x38b2ece9), - BabyBear::from_canonical_u32(0x14a8ad14), - BabyBear::from_canonical_u32(0x29cd05b9), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), ] .as_ref() ) @@ -1350,38 +1350,38 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_32_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x08529dda), - BabyBear::from_canonical_u32(0x082b3a31), - BabyBear::from_canonical_u32(0x30e3bf36), - BabyBear::from_canonical_u32(0x64013853), - BabyBear::from_canonical_u32(0x1c9f1369), - BabyBear::from_canonical_u32(0x02eb2be6), - BabyBear::from_canonical_u32(0x2fe5a852), - BabyBear::from_canonical_u32(0x1e9eadcd), - BabyBear::from_canonical_u32(0x19459c0d), - BabyBear::from_canonical_u32(0x24f2724c), - BabyBear::from_canonical_u32(0x63a84df1), - BabyBear::from_canonical_u32(0x02a44c1e), - BabyBear::from_canonical_u32(0x18e1fccf), - BabyBear::from_canonical_u32(0x3599bc43), - BabyBear::from_canonical_u32(0x76f799b8), - BabyBear::from_canonical_u32(0x229dd5f5), - BabyBear::from_canonical_u32(0x58050cfb), - BabyBear::from_canonical_u32(0x6b1f557e), - BabyBear::from_canonical_u32(0x5b66fbaf), - BabyBear::from_canonical_u32(0x3c017aa8), - BabyBear::from_canonical_u32(0x412a175f), - BabyBear::from_canonical_u32(0x305f00d5), - BabyBear::from_canonical_u32(0x01d8afcd), - BabyBear::from_canonical_u32(0x07a6e83d), - BabyBear::from_canonical_u32(0x2ffd14a4), - BabyBear::from_canonical_u32(0x0a25ed64), - BabyBear::from_canonical_u32(0x5d39e005), - BabyBear::from_canonical_u32(0x5ed5ce5e), - BabyBear::from_canonical_u32(0x453da739), - BabyBear::from_canonical_u32(0x5c6a17f0), - BabyBear::from_canonical_u32(0x390ef2ac), - BabyBear::from_canonical_u32(0x524b3356), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), + BabyBear::from_canonical_u32(0x20000000), + BabyBear::from_canonical_u32(0x40000000), + BabyBear::from_canonical_u32(0x07ffffff), ] .as_ref() ) @@ -1698,42 +1698,42 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_36_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x14fe3780), - BabyBear::from_canonical_u32(0x24a66ad4), - BabyBear::from_canonical_u32(0x4ee43956), - BabyBear::from_canonical_u32(0x068f9cc3), - BabyBear::from_canonical_u32(0x2fb11120), - BabyBear::from_canonical_u32(0x39cfb5fb), - BabyBear::from_canonical_u32(0x152c1e7d), - BabyBear::from_canonical_u32(0x087b32bd), - BabyBear::from_canonical_u32(0x06a7975d), - BabyBear::from_canonical_u32(0x0f8c144d), - BabyBear::from_canonical_u32(0x2794dc72), - BabyBear::from_canonical_u32(0x30dd60c4), - BabyBear::from_canonical_u32(0x254bd985), - BabyBear::from_canonical_u32(0x26994695), - BabyBear::from_canonical_u32(0x1c4f67fa), - BabyBear::from_canonical_u32(0x4dea40ba), - BabyBear::from_canonical_u32(0x011f3fc1), - BabyBear::from_canonical_u32(0x6fa5cf5c), - BabyBear::from_canonical_u32(0x4dae4e61), - BabyBear::from_canonical_u32(0x5064a984), - BabyBear::from_canonical_u32(0x4a8a172f), - BabyBear::from_canonical_u32(0x0f468905), - BabyBear::from_canonical_u32(0x1c01dfe0), - BabyBear::from_canonical_u32(0x6098d590), - BabyBear::from_canonical_u32(0x5651e583), - BabyBear::from_canonical_u32(0x11415766), - BabyBear::from_canonical_u32(0x651097f7), - BabyBear::from_canonical_u32(0x0021192c), - BabyBear::from_canonical_u32(0x1efa9644), - BabyBear::from_canonical_u32(0x0af6fec6), - BabyBear::from_canonical_u32(0x764987ae), - BabyBear::from_canonical_u32(0x613bceac), - BabyBear::from_canonical_u32(0x475c8fa9), - BabyBear::from_canonical_u32(0x60397fc6), - BabyBear::from_canonical_u32(0x34eb3f0e), - BabyBear::from_canonical_u32(0x3835c26b), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), + BabyBear::from_canonical_u32(0x10000000), + BabyBear::from_canonical_u32(0x20000000), + BabyBear::from_canonical_u32(0x40000000), + BabyBear::from_canonical_u32(0x07ffffff), + BabyBear::from_canonical_u32(0x0ffffffe), + BabyBear::from_canonical_u32(0x1ffffffc), + BabyBear::from_canonical_u32(0x3ffffff8), ] .as_ref() ) @@ -2086,46 +2086,46 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_40_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x1777e9b2), - BabyBear::from_canonical_u32(0x0543f0b4), - BabyBear::from_canonical_u32(0x389b8f6b), - BabyBear::from_canonical_u32(0x5165974d), - BabyBear::from_canonical_u32(0x268bf772), - BabyBear::from_canonical_u32(0x03911e90), - BabyBear::from_canonical_u32(0x4b044d42), - BabyBear::from_canonical_u32(0x0f521fef), - BabyBear::from_canonical_u32(0x4adc8c09), - BabyBear::from_canonical_u32(0x4b1b25f1), - BabyBear::from_canonical_u32(0x63418d54), - BabyBear::from_canonical_u32(0x568f6e7b), - BabyBear::from_canonical_u32(0x06200af8), - BabyBear::from_canonical_u32(0x28db6a19), - BabyBear::from_canonical_u32(0x62df9494), - BabyBear::from_canonical_u32(0x4fb85a03), - BabyBear::from_canonical_u32(0x640d7076), - BabyBear::from_canonical_u32(0x02d7a4eb), - BabyBear::from_canonical_u32(0x30c1a996), - BabyBear::from_canonical_u32(0x03f2870f), - BabyBear::from_canonical_u32(0x06bf2d97), - BabyBear::from_canonical_u32(0x5808f4ae), - BabyBear::from_canonical_u32(0x377d5fb1), - BabyBear::from_canonical_u32(0x4c0e5621), - BabyBear::from_canonical_u32(0x629e4241), - BabyBear::from_canonical_u32(0x1bbee30c), - BabyBear::from_canonical_u32(0x69dc7ec0), - BabyBear::from_canonical_u32(0x52acbacb), - BabyBear::from_canonical_u32(0x15f59363), - BabyBear::from_canonical_u32(0x21842f30), - BabyBear::from_canonical_u32(0x3a08b55a), - BabyBear::from_canonical_u32(0x468ac82e), - BabyBear::from_canonical_u32(0x56fe58b6), - BabyBear::from_canonical_u32(0x2da33c73), - BabyBear::from_canonical_u32(0x1b9cbca3), - BabyBear::from_canonical_u32(0x11cc15f3), - BabyBear::from_canonical_u32(0x340679cb), - BabyBear::from_canonical_u32(0x365e5beb), - BabyBear::from_canonical_u32(0x151f0efb), - BabyBear::from_canonical_u32(0x77215247), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), + BabyBear::from_canonical_u32(0x10000000), + BabyBear::from_canonical_u32(0x20000000), + BabyBear::from_canonical_u32(0x40000000), + BabyBear::from_canonical_u32(0x07ffffff), + BabyBear::from_canonical_u32(0x0ffffffe), + BabyBear::from_canonical_u32(0x1ffffffc), + BabyBear::from_canonical_u32(0x3ffffff8), + BabyBear::from_canonical_u32(0x0fffffde), + BabyBear::from_canonical_u32(0x1fffffbc), + BabyBear::from_canonical_u32(0x07fffeef), + BabyBear::from_canonical_u32(0x0ffffdde), ] .as_ref() ) @@ -2514,50 +2514,50 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_44_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x15c26880), - BabyBear::from_canonical_u32(0x20f77f08), - BabyBear::from_canonical_u32(0x2b56c7ae), - BabyBear::from_canonical_u32(0x01c30fe5), - BabyBear::from_canonical_u32(0x58f3e6f5), - BabyBear::from_canonical_u32(0x541b7182), - BabyBear::from_canonical_u32(0x6f1aa866), - BabyBear::from_canonical_u32(0x56a1ed37), - BabyBear::from_canonical_u32(0x2e9d83ad), - BabyBear::from_canonical_u32(0x6c0adf0b), - BabyBear::from_canonical_u32(0x0df23283), - BabyBear::from_canonical_u32(0x77d55138), - BabyBear::from_canonical_u32(0x460b3c08), - BabyBear::from_canonical_u32(0x16d90ee3), - BabyBear::from_canonical_u32(0x35d82c68), - BabyBear::from_canonical_u32(0x5e445ab5), - BabyBear::from_canonical_u32(0x2fbca986), - BabyBear::from_canonical_u32(0x32eee54c), - BabyBear::from_canonical_u32(0x0a64b411), - BabyBear::from_canonical_u32(0x1b5aa242), - BabyBear::from_canonical_u32(0x23dbd463), - BabyBear::from_canonical_u32(0x640d1433), - BabyBear::from_canonical_u32(0x3d3914e8), - BabyBear::from_canonical_u32(0x05e17bf7), - BabyBear::from_canonical_u32(0x2897a862), - BabyBear::from_canonical_u32(0x597f6ea1), - BabyBear::from_canonical_u32(0x3d2b87ad), - BabyBear::from_canonical_u32(0x5c8c9f48), - BabyBear::from_canonical_u32(0x1b029b5d), - BabyBear::from_canonical_u32(0x46b0e9ee), - BabyBear::from_canonical_u32(0x41ef9340), - BabyBear::from_canonical_u32(0x7159a1b4), - BabyBear::from_canonical_u32(0x75007050), - BabyBear::from_canonical_u32(0x14dab136), - BabyBear::from_canonical_u32(0x0cb9e77a), - BabyBear::from_canonical_u32(0x56a913c9), - BabyBear::from_canonical_u32(0x6fe9560a), - BabyBear::from_canonical_u32(0x35cd1c98), - BabyBear::from_canonical_u32(0x173e8c90), - BabyBear::from_canonical_u32(0x4575132b), - BabyBear::from_canonical_u32(0x12bce120), - BabyBear::from_canonical_u32(0x056e7b79), - BabyBear::from_canonical_u32(0x43ec983e), - BabyBear::from_canonical_u32(0x1c3102da), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), + BabyBear::from_canonical_u32(0x10000000), + BabyBear::from_canonical_u32(0x20000000), + BabyBear::from_canonical_u32(0x40000000), + BabyBear::from_canonical_u32(0x07ffffff), + BabyBear::from_canonical_u32(0x0ffffffe), + BabyBear::from_canonical_u32(0x1ffffffc), + BabyBear::from_canonical_u32(0x3ffffff8), + BabyBear::from_canonical_u32(0x07ffffef), + BabyBear::from_canonical_u32(0x0fffffde), + BabyBear::from_canonical_u32(0x1fffffbc), + BabyBear::from_canonical_u32(0x3fffff78), + BabyBear::from_canonical_u32(0x07fffeef), + BabyBear::from_canonical_u32(0x0ffffdde), + BabyBear::from_canonical_u32(0x3ffff778), + BabyBear::from_canonical_u32(0x07ffeeef), + BabyBear::from_canonical_u32(0x0fffddde), ] .as_ref() ) @@ -2982,54 +2982,54 @@ lazy_static! { lazy_static! { pub static ref MATRIX_DIAG_48_BABYBEAR: Array = Array::try_from( [ - BabyBear::from_canonical_u32(0x1c9a964a), - BabyBear::from_canonical_u32(0x5f04c2b2), - BabyBear::from_canonical_u32(0x5fbc3d49), - BabyBear::from_canonical_u32(0x3228c523), - BabyBear::from_canonical_u32(0x75248d9c), - BabyBear::from_canonical_u32(0x32f418df), - BabyBear::from_canonical_u32(0x4e08083f), - BabyBear::from_canonical_u32(0x48b83caa), - BabyBear::from_canonical_u32(0x573b6f62), - BabyBear::from_canonical_u32(0x0903bea6), - BabyBear::from_canonical_u32(0x2a981b3f), - BabyBear::from_canonical_u32(0x277427e0), - BabyBear::from_canonical_u32(0x6f703c9a), - BabyBear::from_canonical_u32(0x55ef66c1), - BabyBear::from_canonical_u32(0x0c0497c0), - BabyBear::from_canonical_u32(0x043b209d), - BabyBear::from_canonical_u32(0x66cf8a91), - BabyBear::from_canonical_u32(0x7568ee42), - BabyBear::from_canonical_u32(0x07aa99dc), - BabyBear::from_canonical_u32(0x36df1e67), - BabyBear::from_canonical_u32(0x6a043f40), - BabyBear::from_canonical_u32(0x31eb6898), - BabyBear::from_canonical_u32(0x53be0ee5), - BabyBear::from_canonical_u32(0x27ac867c), - BabyBear::from_canonical_u32(0x54f0005d), - BabyBear::from_canonical_u32(0x5c0e13ce), - BabyBear::from_canonical_u32(0x1112eae4), - BabyBear::from_canonical_u32(0x0d98cce7), - BabyBear::from_canonical_u32(0x2bf40fb2), - BabyBear::from_canonical_u32(0x21ac265f), - BabyBear::from_canonical_u32(0x042a0673), - BabyBear::from_canonical_u32(0x73d895d9), - BabyBear::from_canonical_u32(0x19f257b5), - BabyBear::from_canonical_u32(0x22a635c4), - BabyBear::from_canonical_u32(0x1150ed08), - BabyBear::from_canonical_u32(0x7719527f), - BabyBear::from_canonical_u32(0x45890d7f), - BabyBear::from_canonical_u32(0x0398cf13), - BabyBear::from_canonical_u32(0x33a917d9), - BabyBear::from_canonical_u32(0x4f877bb9), - BabyBear::from_canonical_u32(0x4d59fbfb), - BabyBear::from_canonical_u32(0x113219b1), - BabyBear::from_canonical_u32(0x59bcf60e), - BabyBear::from_canonical_u32(0x315b2720), - BabyBear::from_canonical_u32(0x714ad74e), - BabyBear::from_canonical_u32(0x3ed1e528), - BabyBear::from_canonical_u32(0x1dbc73eb), - BabyBear::from_canonical_u32(0x3b3bd3b0), + BabyBear::from_canonical_u32(0x77ffffff), + BabyBear::from_canonical_u32(0x00000001), + BabyBear::from_canonical_u32(0x00000002), + BabyBear::from_canonical_u32(0x00000004), + BabyBear::from_canonical_u32(0x00000008), + BabyBear::from_canonical_u32(0x00000010), + BabyBear::from_canonical_u32(0x00000020), + BabyBear::from_canonical_u32(0x00000040), + BabyBear::from_canonical_u32(0x00000080), + BabyBear::from_canonical_u32(0x00000100), + BabyBear::from_canonical_u32(0x00000200), + BabyBear::from_canonical_u32(0x00000400), + BabyBear::from_canonical_u32(0x00000800), + BabyBear::from_canonical_u32(0x00001000), + BabyBear::from_canonical_u32(0x00002000), + BabyBear::from_canonical_u32(0x00004000), + BabyBear::from_canonical_u32(0x00008000), + BabyBear::from_canonical_u32(0x00010000), + BabyBear::from_canonical_u32(0x00020000), + BabyBear::from_canonical_u32(0x00040000), + BabyBear::from_canonical_u32(0x00080000), + BabyBear::from_canonical_u32(0x00100000), + BabyBear::from_canonical_u32(0x00200000), + BabyBear::from_canonical_u32(0x00400000), + BabyBear::from_canonical_u32(0x00800000), + BabyBear::from_canonical_u32(0x01000000), + BabyBear::from_canonical_u32(0x02000000), + BabyBear::from_canonical_u32(0x04000000), + BabyBear::from_canonical_u32(0x08000000), + BabyBear::from_canonical_u32(0x10000000), + BabyBear::from_canonical_u32(0x20000000), + BabyBear::from_canonical_u32(0x40000000), + BabyBear::from_canonical_u32(0x07ffffff), + BabyBear::from_canonical_u32(0x0ffffffe), + BabyBear::from_canonical_u32(0x1ffffffc), + BabyBear::from_canonical_u32(0x3ffffff8), + BabyBear::from_canonical_u32(0x0fffffde), + BabyBear::from_canonical_u32(0x1fffffbc), + BabyBear::from_canonical_u32(0x3fffff78), + BabyBear::from_canonical_u32(0x07fffeef), + BabyBear::from_canonical_u32(0x0ffffdde), + BabyBear::from_canonical_u32(0x1ffffbbc), + BabyBear::from_canonical_u32(0x3ffff778), + BabyBear::from_canonical_u32(0x07ffeeef), + BabyBear::from_canonical_u32(0x0fffddde), + BabyBear::from_canonical_u32(0x1fffbbbc), + BabyBear::from_canonical_u32(0x3fff7778), + BabyBear::from_canonical_u32(0x0ffdddde), ] .as_ref() )