Skip to content

test: execute the u256 intrinsics against vectors on the OpenVM runner - #2

Merged
maximmenshikov merged 4 commits into
NethermindEth:mainfrom
LukaszRozmej:test/u256-intrinsics
Oct 13, 2026
Merged

maximmenshikov merged 4 commits into
NethermindEth:mainfrom
LukaszRozmej:test/u256-intrinsics

Conversation

@LukaszRozmej

Copy link
Copy Markdown
Member

Changes

The eleven zkvm_u256_* shims in src/openvm_intrinsics/openvm_intrinsics.S are only linked in CI (tests/integration/guest.cs) and never run. A wrong funct7 or register order would link fine and then compute the wrong thing. Nethermind's OpenVM guest is about to call zkvm_u256_mul for EVM MUL (NethermindEth/nethermind branch perf/openvm-bigint-arith), so this PR makes CI execute the shims.

  • tests/integration/u256.cs (new) is a bflat guest that runs every shim against 148 rows of precomputed results: 11 operand pairs for each non-shift op, and 10 shift counts on two values for each shift (counts include 0, 63, 64, 255, 256, 300 and 2^256-1). Each row runs three ways: into a separate buffer, with the result over the first operand, and with the result over the second. The in-place forms are how a caller works on a stack slot, and they only hold if the instruction reads both operands before it writes. The public output is the mismatch count and the check count.
  • build-release.yml:
    • link-guest also links u256.cs and uploads it with guest.
    • The new run-u256-vectors job runs it on the pinned nethermindeth/openvm-runner:v2.1.0-rv64 digest and fails unless the guest reports 0 mismatches over 444 checks.
  • README: one sentence on the new check.

No library or package change, so no version bump.

The vectors pin the extension's semantics on the rv64 line, from extensions/bigint/circuit at OpenVM 56d5e4db:

  • add, sub and mul wrap modulo 2^256;
  • the shifts take their count from the low byte of the second operand, so 256 shifts by 0;
  • slt and sltu write 1 or 0 as a 256-bit word.

Testing

Built locally with the bflat image Nethermind pins (bflat-riscv64-11:2ee8a26) against libopenvm.a from Nethermind.OpenVM.Runtime 1.0.0-preview.1, then run on the pinned runner:

public_values=0000000000000000bc0100000000000000000000000000000000000000000000

That is 0 mismatches over 444 checks. As a negative control, I flipped one expected limb of a mul row: the guest reported 2 mismatches (out of place and in place).

The fork has no Actions run for the new job, so CI on this PR is the first run of run-u256-vectors itself.

Remarks

🤖 AI agent (Claude Code / Opus 5.5) on behalf of @LukaszRozmej

guest.cs only links the zkvm_u256_* shims. u256.cs runs each of the eleven
against precomputed results, out of place and with the result over the first
operand, and CI asserts zero mismatches over 296 checks on the pinned runner.
Also restores the line continuations in the workflow step.
@maximmenshikov
maximmenshikov merged commit ee6e4c6 into NethermindEth:main Oct 13, 2026
7 checks passed
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.

2 participants