From 3dbf23547ae72e08089be7bbecc224b074639c35 Mon Sep 17 00:00:00 2001 From: jbb01 <32650546+jbb01@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:03:15 +0200 Subject: [PATCH] [07_weird_assembly_machine] reorder main loop to make use of a faster implementation of f(g(x)) --- res/07_weird_assembly_machine.sage | 42 ++++++++++++++++++++++++++++ src/bin/07_weird_assembly_machine.rs | 18 +++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 res/07_weird_assembly_machine.sage diff --git a/res/07_weird_assembly_machine.sage b/res/07_weird_assembly_machine.sage new file mode 100644 index 0000000..303e242 --- /dev/null +++ b/res/07_weird_assembly_machine.sage @@ -0,0 +1,42 @@ +F = GF(2) +R. = PolynomialRing(F) +S. = R.quotient_ring(x^64 + 1) +T. = PolynomialRing(S) +Ti. = T.quotient_ring(X^64 + 1) +Tj. = T.quotient_ring(X^64) + +def num_to_poly(num): + out = 0 + i = 0 + while num != 0: + if num % 2 == 1: + out += xi^i + i += 1 + num //= 2 + return out + +def poly_to_num(poly): + out = 0 + for i in range(0, 64): + if poly[i] == 1: + out |= 1 << i + return out + + +with open("./07_weird_assembly_machine.data") as f: + data = [int(line) for line in f.readlines() if line] + +f = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[:128]]) +g = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[128:]]) + +fg = f(g) +fgi = Ti([fg[i] for i in range(0, fg.degree())]) +fgj = Tj([fg[i] for i in range(0, fg.degree())]) + +print("\n\n======= f(g(x)) =======") +for i in reversed(range(0, 64)): + print(poly_to_num(fgi.lift()[i])) + +print("\n\n======= f(g(x)) =======") +for i in reversed(range(0, 64)): + print(poly_to_num(fgj.lift()[i])) \ No newline at end of file diff --git a/src/bin/07_weird_assembly_machine.rs b/src/bin/07_weird_assembly_machine.rs index 5ae1312..ef074e2 100644 --- a/src/bin/07_weird_assembly_machine.rs +++ b/src/bin/07_weird_assembly_machine.rs @@ -17,19 +17,24 @@ static DATA: LazyLock> = LazyLock::new(|| { data }); -const N: u64 = 10000045930000000; -const X: u64 = 16195396392266746892; +const N: u64 = 10000117800000000; +const X: u64 = 5905739161907566595; fn main() { compute_async(|tx| { let mut n = N; let mut x = X; loop { - for _ in 0..1_000_000 { + n += 1; + x = sub(f(x), n); + + for _ in 1..1_000_000 { n += 1; - x = h(x, n); + x = sub(fg(x), n); } + x = g(x); + tx.send((n, x)).unwrap(); } }); @@ -47,6 +52,11 @@ fn g(x: u64) -> u64 { evaluate(x, &DATA[128..256]) } +/// Quickly computes [`f`](f)([`g`](g)(x)). +fn fg(x: u64) -> u64 { + !x.rotate_left(17) +} + /// Evaluates a polynomial over `GF(2)[X] / (X^64 + 1)` fn evaluate(x: u64, data: &[u64]) -> u64 { let mut out = 0;