Skip to content

Use x86 assembly for Pasta field addition and subtraction - #435

Merged
ValarDragon merged 3 commits into
mainfrom
x86-add-sub-asm
Sep 13, 2026
Merged

Use x86 assembly for Pasta field addition and subtraction#435
ValarDragon merged 3 commits into
mainfrom
x86-add-sub-asm

Conversation

@ValarDragon

@ValarDragon ValarDragon commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add constant-time x86-64 inline-assembly paths for Pasta field addition and
    subtraction
  • use the addition path for [ff::Field::double]
  • extend the randomized canonical-residue sweep to cover add and subtract
  • make the existing double Criterion cases measure the selected trait
    backend instead of the inherent portable helper

The implementation remains behind the existing opt-in x86_64-asm feature,
which requires BMI2 and ADX because the same backend also contains the
multiplication and squaring kernels.

Companion PR #432 forwards that feature through zakura-halo2-proofs and
zakura-orchard, so top-level consumers can select the backend without
patching dependency manifests.

Validation

  • 200,000 random operand pairs per field matched the portable add, subtract,
    multiply, and square implementations on Intel Ice Lake and AMD Zen 4
  • cargo test --locked -p zakura-pasta-curves passes on macOS
  • source-isolated benchmark builds used separate Cargo target directories and
    distinct executable hashes; measurements ran control-candidate-candidate-
    control to expose order effects

Benchmarks

Criterion: 2 s warm-up, 8 s measurement, 100 samples. Midpoint averages from
the two measurement orders:

Host Kernel Fp Fq
Intel Ice Lake add 11.2% faster 12.2% faster
Intel Ice Lake subtract 13.0% faster 12.8% faster
Intel Ice Lake double 2.2% faster 2.0% faster
AMD Zen 4 add 11.0% slower 10.7% slower
AMD Zen 4 subtract 0.5% faster 2.8% faster
AMD Zen 4 double 15.0% faster 15.3% faster

The AMD add regression is real, but doubling is substantially faster and is
the more important path in the prover. End-to-end Ironwood k=11 proving was
consistently faster across both action counts and thread counts:

Host 1 thread 8 threads
Intel Ice Lake 3.1–4.3% faster 4.3–4.9% faster
AMD Zen 4 3.5–4.9% faster 3.4–4.0% faster

Full-prover runs used 2 s warm-up, 15 s measurement, 10 samples, with one and
four actions. No runtime CPU dispatch is added here; generic builds remain on
the portable path unless x86_64-asm is explicitly enabled.

@v12-auditor

v12-auditor Bot commented Sep 12, 2026

Copy link
Copy Markdown

Note

Complete: Audit complete. V12 found one issue worth reviewing.

Open the full results here.

FindingSeverityDetails
F-276440 🔵 Low
Debug assertions break constant-time arithmetic

When the x86_64-asm backend is selected, the newly routed addition, subtraction, and ff::Field::double paths execute debug_assert!(is_canonical(...)) before entering the straight-line assembly. The is_canonical helper scans limbs from most significant to least significant and returns at the first limb that differs from the modulus. Canonical field values therefore take different branch counts: values whose high limb is below the modulus exit immediately, while values matching the modulus's high limbs continue through additional comparisons. The assembly kernels themselves are branchless, but the complete field operations are not constant-time in builds where debug assertions are enabled. Builds with debug assertions disabled do not execute these checks.

Analyzed five files, diff 9129811...4c64940.

@ValarDragon
ValarDragon merged commit 66ddff6 into main Sep 13, 2026
68 checks passed
@ValarDragon
ValarDragon deleted the x86-add-sub-asm branch September 13, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant