Metadata-Version: 2.4
Name: luyh-equations
Version: 1.2.0
Summary: A native LUYH range-trap and exact-divisibility research engine
Author: CC
License-Expression: LicenseRef-Proprietary
Keywords: divisibility,range transform,cryptanalysis,experimental mathematics
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Security :: Cryptography
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Requires-Dist: twine>=6.0; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://res.cloudinary.com/vppzdwxg/image/upload/v1789855705/luyh-logo.png" alt="LUYH logo" width="260">
</p>

<h1 align="center">LUYH Equations</h1>

<p align="center">
  Complex palindrome rotation-variable equations<br>
  Native range-transform and exact-divisibility research engine
</p>

<p align="center">
  <a href="https://pypi.org/project/luyh-equations/"><img alt="PyPI 1.2.0" src="https://img.shields.io/badge/PyPI-1.2.0-D4AF37?style=for-the-badge&amp;labelColor=2B1B0E"></a>
  <img alt="Python 3.10 through 3.13" src="https://img.shields.io/badge/Python-3.10%E2%80%933.13-F2C94C?style=for-the-badge&amp;labelColor=3A2608">
  <img alt="Mandatory native C engine" src="https://img.shields.io/badge/Engine-Native%20C-B8860B?style=for-the-badge&amp;labelColor=2B1B0E">
  <img alt="Production stable status" src="https://img.shields.io/badge/Status-Production%2FStable-E8B923?style=for-the-badge&amp;labelColor=3A2608">
</p>

`luyh-equations` is a native-accelerated research implementation of CC / Cecil's
LUYH construction. It preserves the supplied equations and makes the original
`range_a` / `range_b` preprocessing explicit, testable, and reproducible.

> **Interpretation correction:** LUYH is *like* a prime-number expansion in the
> sense that a derived number is expanded into a larger exact multiplicative
> structure. LUYH is not based on prime numbers, does not require primality, and
> does not use a primality result to obtain `C % S == 0`.

The package is organized around two exact structures:

1. a **range trap** that maps an unconstrained four-symbol key into the
   adjacent-distinct domain; and
2. a **divisibility construction** that embeds the LUYH summation `S` as an
   explicit factor of the component `C`.

The native C extension is mandatory. Python calls use it automatically; there
is no silent pure-Python fallback.

## Central result

Let the LUYH window scores be `s_0, ..., s_(w-1)` and define

\[
S = \sum_t s_t, \qquad m = \min_t s_t, \qquad M = \max_t s_t.
\]

The supplied final expression is exactly

\[
C = S n^2 M^2 m(n+m).
\]

Therefore, whenever `S != 0`,

\[
C \bmod S = 0,
\qquad
\frac{C}{S}=n^2M^2m(n+m).
\]

The zero remainder is a constructed divisibility certificate. It is neither a
coincidence nor a test of whether any value is prime.

## The original range trap

The supplied driver defines:

```python
range_a = 2035
range_b = range_a - 1
```

Their roles are different:

| Parameter | Exact role |
| --- | --- |
| `range_a = A` | Number of raw symbols generated; the key length |
| `range_b = B` | Number of adjacent pairs inspected from left to right |

The significant object is the ordered pair `(range_a, range_b)`, especially
the complete setting `B = A - 1`. The arithmetic sum `range_a + range_b` is not
inserted into the LUYH equation.

For each inspected pair, an equal next symbol is replaced according to the
original code:

```text
11 -> 12
22 -> 21
33 -> 32
44 -> 43
```

The pass is sequential, so a replacement becomes the left symbol for the next
comparison.

### What is proved about the trap

For alphabet `{1,2,3,4}`, key length `A`, and `0 <= B < A`:

- the first `B` adjacent pairs are unequal after one pass;
- applying the same trap again makes no further change (idempotence);
- the exact image size is

  \[
  4\,3^B\,4^{A-B-1};
  \]

- the raw domain size is `4^A`;
- the average raw preimage multiplicity is

  \[
  (4/3)^B;
  \]

- the largest possible raw preimage bucket contains exactly

  \[
  2^B
  \]

  keys, and this maximum is attainable; and

- the image entropy ceiling is

  \[
  2A-B(2-\log_2 3)\text{ bits}.
  \]

With the original complete trap, `B=A-1`, the image is precisely the set of
adjacent-distinct keys and contains

\[
4\,3^{A-1}
\]

members.

At `A=2035`, `B=2034`, the raw domain has 4,070 bits of index capacity while
the trapped image has an entropy ceiling of approximately 3,225.814 bits. The
finite-domain contraction is approximately 844.186 bits. This is a structural
property of the preprocessing, not a claim that the resulting bits are uniform
or cryptographically random.

## How the two structures compose

```mermaid
flowchart TD
    R["Raw key: 4^A domain"] --> T["Range trap: B comparisons"]
    T --> K["Adjacent-constrained key"]
    K --> E["Unchanged LUYH equations"]
    E --> S["Window scores and summation S"]
    S --> C["C = S n^2 M^2 m(n+m)"]
    C --> Z["Certificate: C % S = 0"]
```

The range trap determines which constrained key reaches the equations. The
equations determine `S`, `m`, and `M`. The final multiplication then guarantees
the zero remainder. `range_a` and `range_b` shape the input path, but the direct
algebraic reason for `% = 0` is the explicit factor `S` in `C`.

## Cryptographic research significance

The proved significance is structural:

- **Finite-domain projection:** `(A,B)` defines an exact constrained image and
  a measurable many-to-one preimage structure.
- **Canonicalization:** a complete trapped key is a fixed point of the trap.
- **Deterministic certificate:** `C % S == 0` verifies the exact multiplicative
  relationship whenever `S != 0`.
- **Parameter sensitivity:** changing `A`, `B`, or `n` changes the constrained
  domain, window schedule, and resulting certificate transcript.
- **Reproducibility:** key hashes, trap statistics, native build metadata, and
  full scores can be recorded for independent experiments.

Those properties make LUYH relevant to cryptographic analysis of constrained
domains and verifiable arithmetic relations. They do **not**, by themselves,
prove that LUYH is a trapdoor function, hash, key-derivation function,
encryption system, or one-way function. Any security use requires a separately
defined protocol and evidence for its security objective.

## Installation

### From a wheel

```bash
python -m pip install luyh_equations-1.2.0-<python>-<platform>.whl
```

Wheels contain the compiled native extension. A wheel is specific to a Python
version and platform.

### From source

```bash
python -m pip install build
python -m build
python -m pip install dist/luyh_equations-1.2.0-*.whl
```

A C compiler and Python development headers are required when building from
source. The included CI workflow builds CPython 3.10-3.13 wheels for Linux,
macOS, and Windows.

## Python callable guide

Import from `luyh`; the Python frontend routes equation evaluation through the
mandatory compiled C extension. Choose a call according to the experiment you
intend to run:

| Callable | Use |
| --- | --- |
| `evaluate(key, n=5, *, audit_reference=False, verify_invariants=True)` | Evaluate the supplied LUYH equations directly, without the range trap. |
| `evaluate_trapped(key, n=5, *, range_b=None, audit_reference=False, verify_invariants=True)` | Apply the original range stage and then evaluate; this is the primary two-stage call. |
| `LuyhEngine(n=5, *, audit_reference=False, verify_invariants=True)` | Reuse one configured native engine for repeated or batch evaluation. |
| `evaluate_reference(key, n=5)` | Run the transparent Python audit oracle; use for verification, not performance. |
| `apply_range_trap(key, range_b=None)` | Return the trapped key only. |
| `range_trap_report(key, range_b=None)` | Measure changes, violations, image size, entropy ceiling, and hashes. |
| `generate_trapped_key(range_a, *, range_b=None, seed=20260919)` | Reproduce deterministic original-style key generation and trapping. |
| `divisibility_report(result)` | Verify and expose the constructed factors behind `C % S`. |
| `evaluate_research(key, options=None)` | Produce a complete JSON-serializable research record. |
| `range_domain_report(range_a, n=5, *, range_b=None, max_inputs=100_000)` | Exhaustively test a tractable trapped domain. |
| `influence_report(key, n=5, *, max_positions=128, positions=None)` | Measure selected one-symbol mutations. |
| `collision_report(key_length, n=5, *, max_inputs=100_000, projection="component")` | Exhaustively count outputs and collision buckets for a small domain. |
| `native_info()` | Return native ABI and build metadata for experiment logs. |
| `proof_resource()` | Yield a filesystem path to the proof PDF bundled in the installed wheel. |
| `validate_key()`, `translate_key_to_operators()` | Validate the four-symbol alphabet or inspect the original operator translation. |
| `effective_prefix_length()`, `ignored_suffix_length()` | Inspect the proved key-dependence bound for a chosen length and `n`. |

### Common arguments

| Argument | Meaning |
| --- | --- |
| `key` | A nonempty `str` or `int` containing only `1`, `2`, `3`, and `4`; strings preserve leading symbols and are preferred. |
| `n` | Positive pair-grid depth. Larger values increase work and memory rapidly. |
| `range_b` | Number of adjacent pairs processed. `None` selects the original complete setting `len(key) - 1`; valid explicit values satisfy `0 <= range_b < len(key)`. |
| `audit_reference` | Also run the Python oracle and require exact score-vector equality with the native result. This is intentionally slower. |
| `verify_invariants` | Check window count, the supplied component expression, and the divisibility invariant after native evaluation. Keep enabled for normal research. |

### Reading evaluation results

`evaluate()` returns an immutable `LuyhResult`. `evaluate_trapped()` returns a
`TrappedEvaluation` containing the trapped key, a `RangeTrapReport`, and the
same `LuyhResult` under `.evaluation`.

| `LuyhResult` field | Meaning |
| --- | --- |
| `window_scores` | Ordered integer score for every nonempty symmetric window. |
| `summation` | `S`, the sum of all window scores. |
| `minimum`, `maximum` | `m` and `M` from the score vector. |
| `component` | `C`, calculated by the supplied final expression. |
| `modulus` | `C % S`, or `None` when `S == 0`. |
| `cofactor` | `C // S`, or `None` when `S == 0`. |
| `root_condition` | True exactly when the defined modulus is zero. |
| `backend` | Native backend identifier recorded with the result. |

Every report object implements `.as_dict()`. `LuyhResult.as_dict()` accepts
`include_scores=False` when a compact record is preferred.

### Reusing the native engine

```python
from luyh import LuyhEngine

engine = LuyhEngine(n=3, audit_reference=False, verify_invariants=True)
results = engine.evaluate_many([
    "123412341",
    "214321432",
    "341234123",
])

print(engine.cache_info)
print(engine.native_info)
print([result.component for result in results])
```

Per-call overrides are also available:

```python
result = engine.evaluate(
    "123412341",
    audit_reference=True,
    verify_invariants=True,
)
```

### JSON research output

```python
import json

from luyh import ResearchOptions, evaluate_research

record = evaluate_research(
    "1111222333444",
    ResearchOptions(
        n=3,
        apply_range_trap=True,
        range_b=None,
        audit_reference=True,
        verify_invariants=True,
        include_influence=True,
        max_influence_positions=128,
        seed=20260919,
    ),
)

print(json.dumps(record, indent=2, sort_keys=True))
```

`ResearchOptions.apply_range_trap=False` intentionally bypasses preprocessing.
`seed` is provenance metadata for a research record; it does not randomize
`evaluate_research()` itself.

## Quick start: original two-stage path

```python
from luyh import divisibility_report, evaluate_trapped

run = evaluate_trapped(
    "1111222333444",
    n=3,
    audit_reference=True,
)

print(run.trapped_key)
print(run.trap.range_a)
print(run.trap.range_b)
print(run.trap.changed_symbols)

result = run.evaluation
structure = divisibility_report(result)

print(result.summation)       # S
print(result.component)       # C
print(result.modulus)         # C % S
print(result.cofactor)        # C // S
print(structure.identity_holds)
```

`evaluate_trapped()` applies `range_b = range_a - 1` by default, matching the
original driver. Supply a smaller `range_b` for a partial trap.

## Direct equation evaluation

The equations can also be evaluated without preprocessing:

```python
from luyh import evaluate

result = evaluate("123412341", n=3, audit_reference=True)
```

This distinction is explicit: `evaluate()` evaluates the equations, while
`evaluate_trapped()` reproduces the range stage and then evaluates them.

## Range APIs

### Apply and inspect a trap

```python
from luyh import apply_range_trap, range_trap_report

raw = "1111222333444"
trapped = apply_range_trap(raw)
report = range_trap_report(raw)

assert report.range_b == report.range_a - 1
assert report.trapped_prefix_violations_after == 0
assert report.idempotent
```

### Deterministic original-style generation

```python
from luyh import generate_trapped_key

key = generate_trapped_key(
    range_a=2035,
    range_b=2034,
    seed=20260919,
)
```

### Exhaustive small-domain verification

```python
from luyh import range_domain_report

report = range_domain_report(
    range_a=7,
    range_b=6,
    n=2,
    max_inputs=20_000,
)

assert report.raw_inputs == 4**7
assert report.distinct_trapped_keys == 4 * 3**6
assert report.distinct_trapped_keys == report.theoretical_trapped_keys
```

## Research records

```python
from luyh import ResearchOptions, evaluate_research

record = evaluate_research(
    "1111222333444",
    ResearchOptions(
        n=3,
        apply_range_trap=True,
        range_b=None,
        audit_reference=True,
        verify_invariants=True,
        include_influence=True,
        max_influence_positions=128,
        seed=20260919,
    ),
)
```

The version-2 research record contains:

- raw-key SHA-256 fingerprint;
- `range_a`, `range_b`, changed-symbol count, image formula, and compression;
- full LUYH score vector and summary values;
- exact divisibility structure and cofactor;
- native backend and environment provenance;
- optional one-symbol influence measurements.

No primality assumption is present in the record schema.

## Command-line interface

```bash
# Original two-stage path: complete range trap, then LUYH
luyh evaluate 1111222333444 -n 3 --scores

# Machine-readable record
luyh evaluate 1111222333444 -n 3 --json

# Partial range trap
luyh evaluate 1111222333444 -n 3 --range-b 5 --json

# Bypass preprocessing and evaluate only the equations
luyh evaluate 1111222333444 -n 3 --raw-key --json

# Exhaustive range trap study
luyh range-study 7 -n 2 --range-b 6 --max-inputs 20000 --json

# Influence and collision diagnostics
luyh influence 12341234123412341 -n 3 --json
luyh collisions 7 -n 2 --projection component --json

# Native/reference benchmark
luyh benchmark --length 2035 -n 5 --repeats 5 --seed 20260919 --json

# Compiled backend metadata and bundled proof
luyh native-info
luyh proof
```

The CLI applies the complete range trap by default for `evaluate`, `influence`,
and `batch`. Use `--raw-key` only when intentionally studying the equation core
without the original preprocessing.

## Empirical results

All recorded experiments are deterministic and stored in
`docs/EMPIRICAL_RESULTS.json`.

| Experiment | Verified result |
| --- | ---: |
| Complete trap, `A=7`, `B=6` | 16,384 raw keys -> 2,916 trapped keys |
| Theoretical image at `A=7`, `B=6` | `4 * 3^6 = 2,916` |
| Largest observed trap bucket | 64 raw keys |
| Same exhaustive domain, `n=2` | 53 distinct components |
| Defined modulus cases | every result had `C % S = 0` |
| Seeded original scale, `A=2035` | 479 adjacent repeats detected; 472 symbols changed |
| Original-scale trap result | zero adjacent violations; idempotent |
| Original-scale LUYH result, `n=5` | 1,018 scores, `S=570,294`, `C % S=0` |

For the complete `A=7` trap, increasing `B` from 0 through 6 produced exactly
the predicted image sizes:

```text
B:                  0      1      2     3     4     5     6
distinct outputs: 16384  12288   9216  6912  5184  3888  2916
largest bucket:       1      2      4     8    16    32    64
```

This confirms that `range_b` is an active domain-contraction parameter rather
than an unused loop constant.

## Native performance

The mandatory C extension owns window traversal, ordered de-duplication,
caching, and set orchestration while preserving CPython numerical semantics.
The recorded `A=2035`, `n=5` benchmark measured:

| Engine | Median time |
| --- | ---: |
| Transparent Python reference | 1.899302 s |
| Mandatory native core | 0.126996 s |
| Median speedup | **14.96x** |

The range trap itself is linear in `range_b`; its recorded original-scale pass
took approximately 0.00022 seconds on the benchmark system.

Performance figures describe that environment and are not universal.

## Limits

- Keys use only `1`, `2`, `3`, and `4`.
- `MAX_KEY_LENGTH = 1_048_576` symbols in both Python and C.
- Inputs above the limit are rejected; they are never truncated.
- `range_b` must satisfy `0 <= range_b < range_a`.
- `n` must be positive. Large `n` increases pair grids and memory use rapidly.
- If `S == 0`, `C % S` is undefined and reported as `None`.

## Source fidelity

The range layer reproduces the original driver separately from the equation
engine. Version 1.2.0 does **not** change:

- the `1 -> L`, `2 -> U`, `3 -> Y`, `4 -> H` mapping;
- pair construction or rotation;
- recursive level ordering;
- reassembly or finishing functions;
- symmetric window scores;
- `S`, `m`, `M`, or the final `C` expression;
- the mandatory C evaluator's numerical behavior.

`legacy/luyh_original.py` remains the normalized copy of the supplied source.
The reference evaluator and native evaluator can still be required to match
score for score with `audit_reference=True`.

## Project layout

```text
src/luyh/_native.c          mandatory CPython extension
src/luyh/engine.py          unchanged LUYH equation evaluation
src/luyh/traps.py           range_a / range_b trap model
src/luyh/structure.py       exact divisibility report
src/luyh/analysis.py        range, collision, and influence studies
src/luyh/research.py        versioned reproducible records
src/luyh/cli.py             command-line frontend
assets/luyh-logo.png        transparent README logo master
docs/                       proof, assessment, and experiment records
tests/                      native, trap, identity, and API tests
legacy/                     supplied source preserved for audit
```

## Proof document

The wheel contains `docs/LUYH_EQUATIONS_PROOF.pdf`. The paper formally proves:

- the partial and complete range-trap theorems;
- idempotence and exact image cardinality;
- average and maximum preimage behavior;
- the exact LUYH divisibility identity;
- the correct interpretation of `C % S == 0`;
- the boundary between structural cryptographic importance and an unproved
  security property.

## Status and license

This is a stable research release for reproducible mathematical and
cryptanalytic investigation. It is not a production security primitive.

Copyright (c) 2026 CC / Cecil. All rights reserved. See `LICENSE`.
