@@ -1939,59 +1939,100 @@ fn the_first_fold_production_chains_cost_what_the_design_derived() {
19391939/// do not depend on the fold.
19401940struct ChainPins {
19411941 grind_perms : usize ,
1942+ opening_perms : usize ,
19421943 perms : usize ,
19431944 words : u32 ,
19441945 lean : ( usize , usize ) ,
19451946 classic : ( usize , usize ) ,
19461947}
19471948
19481949/// ★ THE PRODUCTION DEFAULT CHAIN — what `chain_config` builds with no knob
1949- /// set — is `first6` under the `Auto` cap, at blowup 2^2 and Q = 112 , grinding
1950- /// before its queries alone: P2's `whir_grind=query`, one 20 -bit grind and one
1950+ /// set — is `first6` under the `Auto` cap, at blowup 2^2 and Q = 114 , grinding
1951+ /// before its queries alone: P2's `whir_grind=query`, one 18 -bit grind and one
19511952/// nonce word a round. The legacy chain keeps its own pins above
1952- /// (`the_production_chain_costs…`, 185,509 / 22,828), and the opt-out
1953- /// (`whir_grind=all`) keeps the pins this chain had before P2
1954- /// ([`the_grind_opt_out_chain_keeps_the_pins_from_before_p2`]).
1953+ /// (`the_production_chain_costs…`, 185,509 / 22,828); the same chain at 20
1954+ /// bits (`LAMBDA_VM_ZF_WHIR_GRIND_BITS=20`, Q 112) keeps the pins the default
1955+ /// had before the bits moved ([`the_grind_bits_opt_out_chain_keeps_its_pins`]),
1956+ /// and the opt-out of both (`whir_grind=all` at 20 bits) the pins this chain
1957+ /// had before P2 ([`the_grind_opt_out_chain_keeps_the_pins_from_before_p2`]).
19551958#[ test]
19561959fn the_production_default_chain_is_first6_under_the_auto_cap ( ) {
19571960 let production = crate :: multilinear_prove:: chain_config_under (
19581961 & crate :: zf_format:: ZfFormat :: DEFAULT ,
19591962 & [ ( 1 , 25 ) ] ,
19601963 ) ;
19611964 let want = ChainConfig {
1962- grind : GrindBits :: query_only ( 20 ) ,
1965+ grind : GrindBits :: query_only ( 18 ) ,
19631966 format : ChainFormat {
19641967 cap : CapPolicy :: Auto ,
19651968 folds : WhirFolds :: First ( FirstFold :: new ( 6 ) . expect ( "6" ) ) ,
19661969 stack : multilinear:: whir_chain:: StackVars :: new ( 27 ) . expect ( "27" ) ,
19671970 nonces : NonceLayout :: Spent ,
19681971 argue : multilinear:: whir_chain:: ArgueFormat :: PerTable ,
19691972 } ,
1970- ..config ( 112 , 0 )
1973+ ..config ( 114 , 0 )
19711974 } ;
19721975 assert_eq ! ( production, want, "the production default's chain config" ) ;
19731976 let shape = ChainShape :: new ( & production, 25 ) ;
19741977 for r in 0 ..shape. rounds ( ) {
19751978 assert_eq ! ( shape. carries( r) , [ false , false , true ] , "round {r}" ) ;
19761979 }
19771980 check_production_chain ( "DEFAULT" , & shape, & DEFAULT_CHAIN_PINS ) ;
1978- // Both levers pay: fewer permutations than either alone, and fewer than
1979- // the same chain grinding all three.
1981+ // The two queries the 18-bit grind buys back cost the verifier their
1982+ // openings (2 × 144 permutations, plus the extra queries' schedule terms):
1983+ // the in-circuit price of two fewer grind bits on the prover.
1984+ const {
1985+ assert ! ( DEFAULT_CHAIN_PINS . perms > GRIND_BITS_20_CHAIN_PINS . perms) ;
1986+ assert ! ( DEFAULT_CHAIN_PINS . grind_perms == GRIND_BITS_20_CHAIN_PINS . grind_perms) ;
1987+ } ;
1988+ }
1989+
1990+ /// ★ THE GRIND-BITS OPT-OUT'S CHAIN IS THE DEFAULT'S BEFORE THE BITS MOVED.
1991+ /// `LAMBDA_VM_ZF_WHIR_GRIND_BITS=20` builds P2's chain at 20 bits and Q 112,
1992+ /// with every cost it had then: these pins are the previous default's,
1993+ /// unmoved. P2 and first6 under the auto cap both pay at this Q: fewer
1994+ /// permutations than either alone, and fewer than the same chain grinding all
1995+ /// three.
1996+ #[ test]
1997+ fn the_grind_bits_opt_out_chain_keeps_its_pins ( ) {
1998+ let at20 = crate :: multilinear_prove:: chain_config_under (
1999+ & crate :: zf_format:: ZfFormat {
2000+ whir_grind_bits : crate :: zf_format:: LEGACY_WHIR_GRIND_BITS ,
2001+ ..crate :: zf_format:: ZfFormat :: DEFAULT
2002+ } ,
2003+ & [ ( 1 , 25 ) ] ,
2004+ ) ;
2005+ let want = ChainConfig {
2006+ grind : GrindBits :: query_only ( 20 ) ,
2007+ format : ChainFormat {
2008+ cap : CapPolicy :: Auto ,
2009+ folds : WhirFolds :: First ( FirstFold :: new ( 6 ) . expect ( "6" ) ) ,
2010+ stack : multilinear:: whir_chain:: StackVars :: new ( 27 ) . expect ( "27" ) ,
2011+ nonces : NonceLayout :: Spent ,
2012+ argue : multilinear:: whir_chain:: ArgueFormat :: PerTable ,
2013+ } ,
2014+ ..config ( 112 , 0 )
2015+ } ;
2016+ assert_eq ! ( at20, want, "the 20-bit chain config" ) ;
2017+ let shape = ChainShape :: new ( & at20, 25 ) ;
2018+ check_production_chain ( "GRIND-BITS-20" , & shape, & GRIND_BITS_20_CHAIN_PINS ) ;
19802019 const {
1981- assert ! ( DEFAULT_CHAIN_PINS . perms < 18_729 && DEFAULT_CHAIN_PINS . perms < 19_877 ) ;
1982- assert ! ( DEFAULT_CHAIN_PINS . perms < GRIND_ALL_CHAIN_PINS . perms) ;
2020+ assert ! ( GRIND_BITS_20_CHAIN_PINS . perms < 18_729 && GRIND_BITS_20_CHAIN_PINS . perms < 19_877 ) ;
2021+ assert ! ( GRIND_BITS_20_CHAIN_PINS . perms < GRIND_ALL_CHAIN_PINS . perms) ;
19832022 } ;
19842023}
19852024
1986- /// ★ THE OPT-OUT'S CHAIN IS TODAY'S. `LAMBDA_VM_ZF_WHIR_GRIND=all` builds the
1987- /// production default's chain exactly as it was before P2, 20-bit grinds before
1988- /// all three challenges and three nonce words a round, and every cost it had
1989- /// then: these pins are the pre-P2 default's, unmoved.
2025+ /// ★ THE OPT-OUT'S CHAIN IS TODAY'S. `LAMBDA_VM_ZF_WHIR_GRIND=all` with
2026+ /// `LAMBDA_VM_ZF_WHIR_GRIND_BITS=20` builds the production default's chain
2027+ /// exactly as it was before P2, 20-bit grinds before all three challenges and
2028+ /// three nonce words a round, and every cost it had then: these pins are the
2029+ /// pre-P2 default's, unmoved.
19902030#[ test]
19912031fn the_grind_opt_out_chain_keeps_the_pins_from_before_p2 ( ) {
19922032 let opt_out = crate :: multilinear_prove:: chain_config_under (
19932033 & crate :: zf_format:: ZfFormat {
19942034 whir_grind : crate :: zf_format:: WhirGrind :: All ,
2035+ whir_grind_bits : crate :: zf_format:: LEGACY_WHIR_GRIND_BITS ,
19952036 ..crate :: zf_format:: ZfFormat :: DEFAULT
19962037 } ,
19972038 & [ ( 1 , 25 ) ] ,
@@ -2020,9 +2061,10 @@ fn check_production_chain(label: &str, shape: &ChainShape, pins: &ChainPins) {
20202061 ) ;
20212062 let entry = SpongeEntry :: fresh ( ) ;
20222063 println ! (
2023- "production {label} chain S=25 first6 cap=auto Q=112 grind={:?}: caps {:?}, {} opening \
2064+ "production {label} chain S=25 first6 cap=auto Q={} grind={:?}: caps {:?}, {} opening \
20242065 permutations, {} cap permutations, {} grind permutations, {} permutations, {} words, \
20252066 {} rows ({} shape rows)",
2067+ shape. num_queries,
20262068 shape. grind,
20272069 shape. caps,
20282070 chain_opening_perms( shape) ,
@@ -2040,7 +2082,7 @@ fn check_production_chain(label: &str, shape: &ChainShape, pins: &ChainPins) {
20402082 ) ;
20412083 assert_eq ! (
20422084 chain_opening_perms( shape) ,
2043- 16_166 ,
2085+ pins . opening_perms ,
20442086 "{label}: opening permutations"
20452087 ) ;
20462088 assert_eq ! ( chain_cap_perms( shape) , 38 , "{label}: cap permutations" ) ;
@@ -2080,10 +2122,22 @@ fn check_production_chain(label: &str, shape: &ChainShape, pins: &ChainPins) {
20802122/// The production default chain's pins, derived by the closed forms and
20812123/// checked against the EMITTED program by
20822124/// [`the_production_chains_emit_their_closed_forms`]. P2's: one grind a round
2083- /// (6 × 2 permutations), one nonce word a round.
2125+ /// (6 × 2 permutations), one nonce word a round; Q 114 at 18 grind bits .
20842126const DEFAULT_CHAIN_CAPS : & [ usize ] = & [ 3 , 3 , 3 , 3 , 3 , 2 ] ;
20852127const DEFAULT_CHAIN_PINS : ChainPins = ChainPins {
20862128 grind_perms : 12 ,
2129+ opening_perms : 16_454 ,
2130+ perms : 16_705 ,
2131+ words : 33_170 ,
2132+ lean : ( 152_175 , 152_904 ) ,
2133+ classic : ( 205_730 , 206_459 ) ,
2134+ } ;
2135+
2136+ /// The grind-bits opt-out's pins (20 bits, Q 112), which are the production
2137+ /// default's from before the bits moved.
2138+ const GRIND_BITS_20_CHAIN_PINS : ChainPins = ChainPins {
2139+ grind_perms : 12 ,
2140+ opening_perms : 16_166 ,
20872141 perms : 16_411 ,
20882142 words : 32_590 ,
20892143 lean : ( 149_547 , 150_258 ) ,
@@ -2094,33 +2148,44 @@ const DEFAULT_CHAIN_PINS: ChainPins = ChainPins {
20942148/// `3R − 1 = 17` grinds (34 permutations), three nonce words a round.
20952149const GRIND_ALL_CHAIN_PINS : ChainPins = ChainPins {
20962150 grind_perms : 34 ,
2151+ opening_perms : 16_166 ,
20972152 perms : 16_443 ,
20982153 words : 32_602 ,
20992154 lean : ( 150_075 , 150_811 ) ,
21002155 classic : ( 202_690 , 203_426 ) ,
21012156} ;
21022157
2103- /// ★ The production chains, EMITTED (the F1 of the two tests above), the
2104- /// default and the opt-out , under both fold emissions. `#[ignore]`d like its
2105- /// siblings: production-shape programs; laptop-safe.
2158+ /// ★ The production chains, EMITTED (the F1 of the three tests above), the
2159+ /// default and the two opt-outs , under both fold emissions. `#[ignore]`d like
2160+ /// its siblings: production-shape programs; laptop-safe.
21062161#[ test]
21072162#[ ignore = "builds production-shape chain programs; run with -- --ignored" ]
21082163fn the_production_chains_emit_their_closed_forms ( ) {
2109- for ( label, whir_grind, pins) in [
2164+ use crate :: zf_format:: { LEGACY_WHIR_GRIND_BITS , PRODUCTION_WHIR_GRIND_BITS , WhirGrind } ;
2165+ for ( label, whir_grind, whir_grind_bits, pins) in [
21102166 (
21112167 "DEFAULT" ,
2112- crate :: zf_format:: WhirGrind :: Query ,
2168+ WhirGrind :: Query ,
2169+ PRODUCTION_WHIR_GRIND_BITS ,
21132170 & DEFAULT_CHAIN_PINS ,
21142171 ) ,
2172+ (
2173+ "GRIND-BITS-20" ,
2174+ WhirGrind :: Query ,
2175+ LEGACY_WHIR_GRIND_BITS ,
2176+ & GRIND_BITS_20_CHAIN_PINS ,
2177+ ) ,
21152178 (
21162179 "GRIND-ALL" ,
2117- crate :: zf_format:: WhirGrind :: All ,
2180+ WhirGrind :: All ,
2181+ LEGACY_WHIR_GRIND_BITS ,
21182182 & GRIND_ALL_CHAIN_PINS ,
21192183 ) ,
21202184 ] {
21212185 let production = crate :: multilinear_prove:: chain_config_under (
21222186 & crate :: zf_format:: ZfFormat {
21232187 whir_grind,
2188+ whir_grind_bits,
21242189 ..crate :: zf_format:: ZfFormat :: DEFAULT
21252190 } ,
21262191 & [ ( 1 , 25 ) ] ,
@@ -2151,11 +2216,11 @@ fn the_production_chains_emit_their_closed_forms() {
21512216 "{label}, {fold:?}: every arena word hinted once"
21522217 ) ;
21532218 println ! (
2154- "PRODUCTION {label} chain S=25 first6 cap=auto Q=112 grind={:?}, {fold:?} fold: \
2219+ "PRODUCTION {label} chain S=25 first6 cap=auto Q={} grind={:?}, {fold:?} fold: \
21552220 {measured} rows against {predicted} predicted; {perms} permutations against \
21562221 {predicted_perms} predicted; {consts} constants, {hints} hints, {instructions} \
21572222 instructions",
2158- shape. grind
2223+ shape. num_queries , shape . grind
21592224 ) ;
21602225 assert_eq ! ( measured, predicted, "{label}, {fold:?}: rows" ) ;
21612226 assert_eq ! ( perms, predicted_perms, "{label}, {fold:?}: permutations" ) ;
@@ -2422,7 +2487,7 @@ fn a_query_only_chain_checks_its_query_nonce_in_every_round_on_both_sides() {
24222487 }
24232488}
24242489
2425- /// ★ `LAMBDA_VM_ZF_WHIR_GRIND_BITS=18`'s trade , at a test width: the grind
2490+ /// ★ The default's 18-bit grind (against `LAMBDA_VM_ZF_WHIR_GRIND_BITS=20`) , at a test width: the grind
24262491/// bits and Q are verifier constants. A chain ground at fewer bits and opened
24272492/// at more queries executes on the machine built for its own config, and both
24282493/// the host and the machine refuse it under a stricter grind at the same Q; the
@@ -2628,8 +2693,9 @@ fn proof_digest(proof: &ChainProof<F, E>) -> (usize, String) {
26282693/// programs (instructions, a digest of all of them, arena words), the arenas and
26292694/// the host proofs' rkyv bytes at zero bits (the only width where two proves
26302695/// agree: a search returns any valid nonce), under `Three` with uniform grinds.
2631- /// Also the production chain under the opt-out, `whir_grind=all`, at the stacks
2632- /// the block reaches (25 and 27): the program the pre-P2 default emitted.
2696+ /// Also the production chain under the opt-out, `whir_grind=all` at 20 bits, at
2697+ /// the stacks the block reaches (25 and 27): the program the pre-P2 default
2698+ /// emitted.
26332699#[ test]
26342700fn the_legacy_nonce_layout_reproduces_the_bytes_from_before_p2 ( ) {
26352701 const PROGRAMS : [ ( usize , u8 , usize , u32 , & str ) ; 4 ] = [
@@ -2711,6 +2777,7 @@ fn the_legacy_nonce_layout_reproduces_the_bytes_from_before_p2() {
27112777
27122778 let opt_out = crate :: zf_format:: ZfFormat {
27132779 whir_grind : crate :: zf_format:: WhirGrind :: All ,
2780+ whir_grind_bits : crate :: zf_format:: LEGACY_WHIR_GRIND_BITS ,
27142781 ..crate :: zf_format:: ZfFormat :: DEFAULT
27152782 } ;
27162783 for ( num_vars, instrs, words, digest) in [
@@ -2745,8 +2812,8 @@ fn the_legacy_nonce_layout_reproduces_the_bytes_from_before_p2() {
27452812
27462813/// I-GRIND instrument (not a gate): the emitted chain verifier's real rows per
27472814/// chip at every production height, under the production format at 20 grind
2748- /// bits (Q 112) and at `LAMBDA_VM_ZF_WHIR_GRIND_BITS=18` (Q 114). The per-chain
2749- /// deltas size the recursion's table heights under the arm .
2815+ /// bits (Q 112, the opt-out ) and at the default's 18 (Q 114). The per-chain
2816+ /// deltas size the recursion's table heights under each .
27502817///
27512818/// cargo test -p lambda-vm-prover --lib grind_bits_chain_census -- --ignored --nocapture
27522819#[ test]
0 commit comments