Repository navigation
fix(mamabear): derive the Poseidon2 round numbers for this field - #900
Merged
Merged
Conversation
The mamabear Poseidon2 parameters were inherited from koalabear: 6 full rounds and 21 partial rounds. Only the diagonal and the S-box degree carry over safely. The round numbers do not. Eq. (1) of the Poseidon2 paper (https://eprint.iacr.org/2023/323.pdf) bounds the partial rounds by R_P >= ceil(1.075 * max(R_interp, R_GB)) R_interp = ceil(min{kappa, n}/log2(d)) + ceil(log_d(t)) - 5 with n = ceil(log2(p)). The bound grows with min{kappa, log2(p)}, so a wider field needs MORE rounds, not fewer. koalabear saturates at n = 31 and needs 20; mamabear at n = 49 needs 32, with R_interp = 29 binding. The inherited 21 satisfies Eq. (1) only up to roughly kappa = 33. Set R_F = 8 and R_P = 32 for both the width-16 compression and width-24 sponge parameters. R_F = 8 is the paper's value throughout, and is also the +2 margin over the statistical minimum of 6 that the inherited value had dropped. The S-box degree is unchanged and was already right: d = 3 is the smallest d >= 3 with gcd(d, p-1) = 1, since p-1 = 2^34 * 7 * 31 * 151. The round constants are derived from the round counts by the Grain-style LFSR in initRC, so they regenerate with the new schedule; the known-answer vectors are recomputed accordingly. Those vectors come from this implementation, as the existing ones did, so they guard against regression rather than validating against an independent source. The KAT now builds its permutation from the generated parameters instead of hardcoding the counts, so it cannot drift from the shipped configuration again. The derivation was validated before being applied: the same formula reproduces all six instances of Table 1 of the paper, and all six of Plonky3's shipped constants for babybear (13/21/30 at t = 16/24/32) and koalabear (20/23/31). Only mamabear changes here. Regenerating leaves babybear, koalabear and goldilocks byte for byte unchanged. Note that koalabear ships R_F = 6 against Plonky3's 8, and goldilocks 6/17 against a derived 8/22; both are left alone and are worth a separate look. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
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.
Description
The MamaBear Poseidon2 instance inherited its round numbers from KoalaBear: number of full rounds
R_F = 6, and partial roundsR_P = 21. The diagonal and the S-box degreedcarry over between those two fields safely; the round numbers do not.Eq. (1) of the Poseidon2 paper bounds the partial rounds by
The bound grows with
min{κ, log2(p)}, so a wider field needs more rounds. KoalaBear saturates atn = 31and needsR_P = 20; MamaBear atn = 49needsR_P = 32, withR_interp = 29binding. The inherited 21 satisfies Eq. (1) only up to roughlyκ = 33, i.e. the parameters were sized for a security level far below the intended 128 bits.This PR sets
R_F = 8,R_P = 32for both the width-16 compression and width-24 sponge parameters.R_F = 8is the paper's value throughout, and restores the+2margin over the statistical minimum of 6 that the inherited value had dropped.The S-box degree is unchanged:
d = 3is the smallestd >= 3withgcd(d, p-1) = 1, sincep - 1 = 2^34 * 7 * 31 * 151.Round constants are derived from the round counts by the Grain-style LFSR in
initRC, so they regenerate with the new schedule. The known-answer vectors are recomputed accordingly.Type of change
The permutation output changes, so any digest previously produced by MamaBear Poseidon2 will not reproduce. MamaBear was merged recently (#887) and has no released consumers that we are aware of, so the blast radius should be zero.
How has this been tested?
go test ./field/mamabear/...— all seven packages pass.go test ./field/... ./hash/...— pass, confirming no other field is affected.TestDefaultRoundNumbers(new) pinsR_F = 8,R_P = 32, width,d = 3and the round-key count to the derivation, with the reasoning in the comment, so the numbers cannot be changed silently again.TestPoseidon2Width16/TestPoseidon2Width24known-answer vectors recomputed for the new schedule, and the test now takes its round counts from the generated parameters rather than hardcoding them.TestMulMulInternalInPlaceWidth16/Width24unchanged and passing — the diagonal is untouched.go generate ./...leaves the tree clean, and BabyBear, KoalaBear and Goldilocks regenerate byte for byte unchanged.How has this been benchmarked?
BenchmarkPoseidon2Width16/Width24, benchstat over 10 runs, on MacBook Pro M5, darwin/arm64The permutation gets ~43% slower. S-box count rises 117 → 160 (+36.8%) at width 16 and 165 → 224 (+35.8%) at width 24; the remainder is the two extra full rounds' external layers. This is the cost of the parameters being correct rather than inherited, so the regression is the point of the PR, not a side effect of it.
Not benchmarked on x86 with AVX512-IFMA.
Checklist:
golangci-lintdoes not output errors locally