From e40da4e8bc5ec5b6605de2fc6f123f78fa62a232 Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Mon, 22 Jun 2026 14:42:58 +0200 Subject: [PATCH] BP matrix family --- src/tea3/cli.py | 9 ++++++--- src/tea3/variable_search.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/tea3/cli.py b/src/tea3/cli.py index 52e53ac..d5eb9f2 100644 --- a/src/tea3/cli.py +++ b/src/tea3/cli.py @@ -1,7 +1,7 @@ from tea3.pretty_print import pretty_print from tea3.cliutils import prompt_int, prompt_choice, prompt_list from tea3.tea3model import Tea3Model -from tea3.variable_search import run_exhaustive, run_exhaustive_staircase, run_exhaustive_staircase2 +from tea3.variable_search import run_exhaustive, run_exhaustive_staircase, run_exhaustive_staircase2, run_exhaustive_bp from tea3.sbox import run_sbox from tea3.variable_xor import run_variable_xor, run_exhaustive_xor from tea3.f31f32 import run_f31f32 @@ -41,8 +41,9 @@ def run_exhaustive_cli(): print(" 1) First-row matrix") print(" 2) Staircase matrix") print(" 3) Staircase 2 matrix") + print(" 4) BP matrix") - family = prompt_choice("Your choice (1, 2 or 3): ", {1, 2, 3}) + family = prompt_choice("Your choice (1, 2, 3 or 4): ", {1, 2, 3, 4}) print("\nR registers are indexed 0–7; bits within each register are 0–7.") print("Enter -1 to print all bits in the chosen register.") @@ -57,8 +58,10 @@ def run_exhaustive_cli(): run_exhaustive(steps, target_reg, target_bit) elif family == 2: run_exhaustive_staircase(steps, target_reg, target_bit) - else: + elif family == 3: run_exhaustive_staircase2(steps, target_reg, target_bit) + else: + run_exhaustive_bp(steps, target_reg, target_bit) print("\n" + "=" * 50) print("Done.") diff --git a/src/tea3/variable_search.py b/src/tea3/variable_search.py index 83b1c71..fef5973 100644 --- a/src/tea3/variable_search.py +++ b/src/tea3/variable_search.py @@ -96,6 +96,30 @@ def make_staircase2_matrix(coeffs): M[7, 6] = GF(2)(coeffs[7]) return M +def make_bp_matrix(coeffs): + """ + | 1 0 0 a1 0 0 0 0 | + | 0 1 0 0 0 0 0 a2| + | 0 0 1 0 0 0 a3 0 | + | 0 a4 0 1 0 0 0 0 | + | 0 0 a5 0 1 0 0 0 | + | 0 0 0 0 a6 1 0 0 | + | a7 0 0 0 0 0 1 0 | + | 0 0 0 0 0 a8 0 1 | + """ + M = identity_matrix(GF(2), 8) + + M[0, 3] = GF(2)(coeffs[0]) + M[1, 7] = GF(2)(coeffs[1]) + M[2, 6] = GF(2)(coeffs[2]) + M[3, 1] = GF(2)(coeffs[3]) + M[4, 2] = GF(2)(coeffs[4]) + M[5, 4] = GF(2)(coeffs[5]) + M[6, 0] = GF(2)(coeffs[6]) + M[7, 5] = GF(2)(coeffs[7]) + + return M + # wrappers def run_exhaustive_generic( @@ -169,3 +193,9 @@ def run_exhaustive_staircase2(steps: int, target_reg: int = 0, target_bit: int = steps, make_staircase2_matrix, n_params=8, target_reg=target_reg, target_bit=target_bit, ) + +def run_exhaustive_bp(steps: int, target_reg: int = 0, target_bit: int = -1): + return run_exhaustive_generic( + steps, make_bp_matrix, n_params=8, + target_reg=target_reg, target_bit=target_bit, + )