feat: update to Noir 1.0.0-beta.25 - #311
Open
TomAFrench wants to merge 10 commits into
Open
Conversation
Describes every place the targeted Noir version is referenced, the update procedure, and the testing steps that validate an update.
Bumps the pinned noir-lang/noir rev (previously the beta.19 release commit) to the v1.0.0-beta.25 tag and ports the extractor to the new noirc APIs: - DependencyId::Struct is now DependencyId::DataType. - Type::Constant carries a comptime Integer instead of a (FieldElement, Kind) pair, and Type::Array's element/size order flipped to Array(E, N). - HirLiteral::Integer holds a BigInt and HirLiteral::Str holds bytes. - Attributes::get_deprecated_note was replaced by get_deprecated, and SecondaryAttributeKind::Deprecated gained a deny flag. - QuotedType::Location and HirStatement::TraitAssociatedConstant are new; the latter also surfaces as placeholder globals which are now skipped. - activate_lsp_mode and report_all grew parameters; u1 is gone. - Builtin/foreign trait impl methods no longer have elaborated bodies, so a body forwarding to the intrinsic is synthesized instead. - Trait default methods materialize per impl with Self bound to itself; Self is now resolved to the impl's concrete type (and excluded from generic patterns) while generating an impl, and identity type-variable bindings no longer recurse forever. The in-crate Noir test fixtures are updated for language changes (as_slice -> as_vector, signed type-level constants need suffixed literals).
Replaces stdlib/src with noir_stdlib/src from the pinned rev and bumps the package version that names the extracted std package. Notable upstream changes: collections/map.nr and collections/vec.nr are gone, integer.nr, internal/ and meta/location.nr are new, and slices have become vectors.
- The versioned stdlib struct names baked into the embedded curve builtins move to std-1.0.0-beta.25. - The new stdlib poseidon2_config_state_size foreign builtin is modeled as the constant 4, matching the width-4 (BN254) Poseidon2 configuration Lampe formalizes. - The eDSL gains a dedicated token for the unitEq builtin: beta.25's stdlib exercises Eq for the unit type, and the generic builtin call syntax cannot parse it because maximal munch tokenizes #_unitEq as the #_unit literal followed by Eq.
Noir's bit decompositions now produce bool arrays instead of u1 arrays: - toLeBits/toBeBits/modulusLeBits/modulusBeBits move to .bool, with Bool.toDigit / Digit.toBool conversions (and roundtrip simp lemmas) in Lampe.Data.Digits. - The corresponding Hoare intro rules are restated accordingly. - Struct gains cross-member indexTpl/replaceTuple' simp lemmas, needed now that BoundedVec methods read and write through references.
Replaces the extracted std-1.0.0-beta.14 package with std-1.0.0-beta.25 and updates the handwritten theorem layer for the upstream changes: - u1 is gone: its Eq/arith/bit specs are deleted. - Bit decompositions return bool arrays: the to_le/be_bits, pow_32 and sgn0 proofs are converted (with Mathlib's lex List.LE' locally erased, since Bool is a LinearOrder and it would shadow the core list order the proofs use). bytes32_to_field was removed upstream, so its spec goes too. - Tuple Ord impls end in a value-if; the tuple3/4/5 proofs are restructured. - BoundedVec::get/get_unchecked/len take &self now: their specs are restated in the reference style. pop no longer zeroes the popped slot, from_parts lost its zeroing loop, from_parts_unchecked is deprecated (and excluded from the extracted env, so its spec is deleted), and extend_from_bounded_vec bounds its loop with cmp::min (covered by a new min_u32_spec). - The larger extracted env pushes some proofs over the default heartbeat/recursion limits; those files raise them explicitly. - Collections/Map is gone upstream. Known remaining work (previously masked by upstream build failures): Stdlib/Array/CheckShuffle.lean, Stdlib/Hash/Poseidon2.lean and Stdlib/Option.lean still fail against the beta.25 extraction (the same by-reference migration); tracked in PROOF_REPAIRS.md.
Completes the stdlib proof repairs so `stdlib/lampe` builds green: - BoundedVec map/mapi/for_each/for_eachi and array higher-order methods (map/mapi/for_each/for_eachi/fold/reduce/all/any/concat/sort_via/sort) restated ref-style for the by-reference &self migration - BoundedVec Eq re-proved against the new element-wise active-prefix comparison; check_shuffle restated over &[T; N] operands - Poseidon2: the sponge struct is gone upstream; model the new chunked finish_ref absorption directly (addToState/chunkState/finishDigest) and re-prove finish/finish_ref/write/RATE/CAPACITY/POSEIDON2_CONFIG_STATE_SIZE - Option: is_some/is_none restated ref-style; expect re-proved - EmbeddedCurvePoint lost is_infinite: infinity is canonically (0, 0); reshape the Lampe curve model and re-prove the point/scalar/MSM specs (round-trip lemmas now require [Bn254.Prime p] so (0,0) is off-curve) - Pedersen: bridge the removed hash::from_field_unsafe via EmbeddedCurveScalar::from_field's safe decomposition - Lampe: implement Builtin.mkFormatString (was an unprovable stub; beta.25's poseidon2_permutation builds a format string for its static assert)
The Merkle projects' vendored deps/hasher-0.0.0 snapshots are replaced by direct path requires on ../../hasher/lampe: the extractor no longer vendors dependencies that ship their own lampe directory, so the stale snapshots could never be regenerated. Merkle also gains a clean.sh (matching Base64's) so generated extraction output is refreshed on every test run. MerkleFromScratch's sgn0 spec is restated for beta.25's bool bit decomposition, and Sort's handwritten env-inclusion proof plus the checked-in lakefiles/manifests now reference std-1.0.0-beta.25.
The beta.25 elaborator recurses deeply enough to overflow the default 2MiB test-thread stack in debug builds, so the test helpers now run extraction on a 16MiB thread. Also adds a #[must_use] clippy had started asking for.
TomAFrench
marked this pull request as ready for review
July 29, 2026 10:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Updates Lampe's targeted Noir version from 1.0.0-beta.19 (with the stdlib still extracted at beta.14) to 1.0.0-beta.25: the extractor is ported to the new
noircAPIs, the vendored stdlib is re-vendored and re-extracted at beta.25, and the handwritten stdlib theorem layer plus the testing projects are repaired so everything builds green. A new doc describes the version-update process end to end.Extractor (
src/)Ports to the beta.25
noircAPIs:DependencyId::DataType, comptime-integerType::Constant, flippedType::Array(E, N)argument order,BigInt/byte literals, the reworked deprecation attributes, and the newQuotedType::Location/HirStatement::TraitAssociatedConstant(the latter's placeholder globals are skipped). Two behavioural changes were needed:Selfbound to itself;Selfis now resolved to the impl's concrete type while generating an impl, and identity type-variable bindings no longer recurse forever.Lampe library (
Lampe/)boolarrays instead ofu1arrays.toLeBits/toBeBits/modulusLeBits/modulusBeBitsmove to.boolwithBool.toDigit/Digit.toBoolconversions and roundtrip simp lemmas inLampe.Data.Digits; the Hoare intro rules are restated accordingly.poseidon2_config_state_sizeforeign builtin is modeled as the constant 4, matching the width-4 (BN254) Poseidon2 configuration Lampe formalizes.Builtin.mkFormatStringis now implemented (it was an unprovable stub; beta.25'sposeidon2_permutationbuilds a format string for its static assert).unitEqbuiltin (beta.25's stdlib exercisesEqfor unit, and maximal munch tokenizes#_unitEqas the#_unitliteral followed byEq).Structgains cross-memberindexTpl/replaceTuple'simp lemmas, needed now thatBoundedVecmethods read and write through references.Stdlib spec (
stdlib/)stdlib/srcis re-vendored from the pinned rev (collections/map.nrandcollections/vec.nrare gone,integer.nr,internal/andmeta/location.nrare new, slices have become vectors), the extractedstd-1.0.0-beta.14package is replaced bystd-1.0.0-beta.25, and the theorem layer is repaired:&selfmigration:BoundedVec::get/get_unchecked/len, theBoundedVecand array higher-order methods (map/mapi/for_each/for_eachi/fold/reduce/all/any/concat/sort_via/sort),Option::is_some/is_none, andcheck_shuffle(now over&[T; N]operands) are all restated in the by-reference style and re-proved.u1removal / bool bits: theu1Eq/arith/bit specs are deleted;to_le_bits/to_be_bits,pow_32andsgn0proofs are converted to the bool-array decomposition (with Mathlib's lexList.LE'locally erased, sinceBoolis aLinearOrderand it would shadow the core list order the proofs use).bytes32_to_fieldwas removed upstream, so its spec goes too.BoundedVecsemantics:popno longer zeroes the popped slot,from_partslost its zeroing loop,from_parts_uncheckedis deprecated (excluded from the extracted env, spec deleted), andextend_from_bounded_vecbounds its loop withcmp::min(covered by a newmin_u32_spec).Eqis re-proved against the new element-wise active-prefix comparison.finish_refabsorption is modeled directly (addToState/chunkState/finishDigest) andfinish/finish_ref/write/RATE/CAPACITY/POSEIDON2_CONFIG_STATE_SIZEare re-proved.EmbeddedCurvePointlostis_infinite; infinity is canonically(0, 0). The Lampe curve model is reshaped and the point/scalar/MSM specs re-proved — the round-trip lemmas now require[Bn254.Prime p]so that(0, 0)is off-curve.hash::from_field_unsafeis bridged viaEmbeddedCurveScalar::from_field's safe decomposition.Ordimpls now end in a value-if, so the tuple3/4/5 proofs are restructured;Collections/Mapspecs are gone with the upstream module; some files explicitly raise heartbeat/recursion limits, as the larger extracted env pushes them over the defaults.Testing projects (
testing/)Re-extracted at beta.25 with proofs repaired. The Merkle projects' vendored
deps/hasher-0.0.0snapshots are replaced by direct path requires on../../hasher/lampe(the extractor no longer vendors dependencies that ship their ownlampedirectory, so the snapshots could never be regenerated), and Merkle gains aclean.shmatching Base64's. The Rust extraction tests now run on a 16MiB thread, as the beta.25 elaborator overflows the default 2MiB test-thread stack in debug builds.Docs
docs/gains a guide to the Noir version update process: every place the targeted version is referenced, the update procedure, and the testing steps that validate an update.