Skip to content

fix: negation of MIN_VALUE wraps to match sigma-state#870

Open
mwaddip wants to merge 1 commit into
ergoplatform:developfrom
mwaddip:fix/negation-min-value-wrap
Open

fix: negation of MIN_VALUE wraps to match sigma-state#870
mwaddip wants to merge 1 commit into
ergoplatform:developfrom
mwaddip:fix/negation-min-value-wrap

Conversation

@mwaddip
Copy link
Copy Markdown

@mwaddip mwaddip commented Jun 1, 2026

Negation ran every numeric width through checked_neg, erroring when negating a fixed-width MIN_VALUE. sigma-state 6.0.3 negates fixed-width ints unchecked (ast/trees.scala Negation.eval), so -MIN == MIN (two's-complement wrap, no error) — a script negating a MIN is accepted by the JVM but rejected here: a latent consensus fork (not seen on mainnet).

Fix: wrapping_neg for Byte/Short/Int/Long; BigInt256 stays checked (its 256-bit MIN overflows on the JVM too).

Verified against JVM-blessed v5 vectors (LanguageSpecificationV5 Numeric_Negation); new negation_of_min_value_wraps_to_self test asserts the 4 widths wrap and BigInt256 still errors.

…/Long)

sigma-rust's `Negation` eval ran every numeric width through
`checked_neg`, erroring when negating a fixed-width MIN_VALUE
(`-(i8::MIN)` … `-(i64::MIN)`). sigma-state 6.0.3 negates fixed-width
ints with the unchecked numeric `negate` (`ast/trees.scala`
Negation.eval), so `-MIN == MIN` via two's-complement wrap, no error.
A script that negates a context-/register-derived MIN is therefore
accepted by the JVM but rejected by sigma-rust -- a latent consensus
fork (never observed on mainnet, since live scripts don't negate MIN).

Negate Byte/Short/Int/Long with `wrapping_neg`; keep `BigInt256` on
`checked_neg` -- sigma-state's 256-bit BigInt also overflows negating
its MIN (`-(2^255)`), so both sides error there.

Verified against SANTA's JVM-blessed v5 vectors
(`Numeric_Negation_equivalence.json`: `-128#0`, `-32768#9`,
`-2147483648#18`, `-9223372036854775808#26` -> MIN with `error:null`).
New test `negation_of_min_value_wraps_to_self` asserts the four widths
wrap and `BigInt256::min_value()` still errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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