Add spongefish-dsfs: Duplex-Sponge Fiat-Shamir compiler#153
Add spongefish-dsfs: Duplex-Sponge Fiat-Shamir compiler#153ricardo-perello wants to merge 10 commits into
Conversation
Move DSFS compiler implementation under spongefish::dsfs and re-export Argus-owned codec traits through spongefish for compatibility with existing derive outputs and paths.
Make p3-* features enable ia-core's p3 codecs and keep only the local Unit impls to avoid orphan impls.
Address clippy warnings and minor API polish in the new spongefish::dsfs module and related code.
…urn to spongefish
Splits the April 2026 codec inversion into three cleanly-stacked crates:
- spongefish: transcript + codecs (Encoding/Decoding/NargSerialize/NargDeserialize/
Deserialize) + foreign-type drivers. No ia-core dependency.
- ia-core (Argus): IA/IR/NIA/NIR protocol abstractions, depends on spongefish for
codec traits.
- spongefish-dsfs: DSFS bridge crate (Dsfs/DsfsReduction wrappers + free fns) that
depends on both spongefish and ia-core.
This reverses the prior arrangement where spongefish had a backwards dep on ia-core
just to see the codec traits. Codec impls for ark_ff/ark_ec/bls12_381/curve25519-
dalek/p256/k256/p3 fields are merged into spongefish/src/drivers/<type>.rs alongside
the existing Unit impls. SmallFp codec impls are not yet ported (ia-core did not
have them).
[patch.crates-io] spongefish = { path = "spongefish" } added to the spongefish
workspace so transitive deps (ia-core) see the local copy instead of the stale
crates.io 0.7.0 publish.
The free-fn DSFS surface (prove/verify/*_with_*) stays pub for now; it will be
flipped to pub(crate) in a follow-up after Argus call sites are swept onto the
Dsfs::new(...) wrapper.
cargo test --workspace --all-features passes.
The `Dsfs::new(...).prove(...)` / `DsfsReduction::new(...).prove(...)` wrappers are now the only public DSFS surface. Internal helper free fns kept (called by the wrapper): - `prove_with_sponge_and_salt` - `verify_with_sponge_and_salt` - `prove_reduction_with_sponge_and_salt_full` (private) - `verify_reduction_with_sponge_and_salt` Deleted (13 fns, no public callers and not needed internally since the wrapper parametrizes `Dsfs<IA, S, H, SALT_LEN>` over sponge + salt-length): - `prove`, `prove_with_salt`, `prove_with_sponge` - `verify`, `verify_with_salt`, `verify_with_sponge` - `prove_reduction`, `prove_reduction_with_salt`, `prove_reduction_with_sponge`, `prove_reduction_with_sponge_and_salt` - `verify_reduction`, `verify_reduction_with_salt`, `verify_reduction_with_sponge` The `Dsfs::new` const-generic salt + explicit sponge field already cover every variant the deleted free fns expressed. Custom-salt example: `Dsfs::<_, _, _, 16>::new(ia, sponge)`. Custom-sponge example: `Dsfs::<_, _, StdHash, 0>::new(ia, StdHash::default())`. Argus workspace tests pass (except 3 pre-existing sigma-bridge golden_vectors).
The ia-core → spongefish → ia-core → spongefish round trip left cosmetic
reformatting (doc-comment rewrites, import reordering, comment deletions) in
files that are otherwise upstream's own and functionally unchanged. Reverted
to `upstream/main` exact content:
- spongefish/src/{codecs,io,error}.rs
- spongefish/src/drivers/{ark_ec_impl,ark_ff_impl,bls12_381_impl,
curve25519_dalek_impl,p256_impl,secp256k1_impl,p3_baby_bear,p3_koala_bear,
p3_mersenne31,tests}.rs
Also reverted spongefish/src/domain_separator.rs to PR arkworks-rs#114's exact version
(dropped a stray blank line, two `#[allow(dead_code)]`, and a `const fn
instance` tweak that don't belong in this PR — that file is PR arkworks-rs#114's).
Net result: this PR's spongefish/ diff vs upstream is now only:
- spongefish/src/deserialize.rs — new channel-side `Deserialize` shim
- ~5 lines of spongefish/src/lib.rs (declare/export `deserialize`, drop the
moved-out `pub mod dsfs`)
- domain_separator.rs / narg_prover.rs / narg_verifier.rs / tests.rs /
lib.rs-macro — byte-identical to PR arkworks-rs#114 (arkworks-rs#153 stacks on arkworks-rs#114; this part
of the diff disappears once arkworks-rs#114 merges to main)
cargo test --workspace --all-features still passes.
|
|
sorry, but this is an insanely large PR with a description that is AI generated, jargon that is internal to argus/ai core, new dependencies without justification. This library is meant to be used externally, this is maybe a good PoC but doesn't meet the bar of the rest of the project. |
Summary
Adds a new sibling crate
spongefish-dsfsimplementing the Duplex-Sponge Fiat-Shamir (DSFS) transformation of [Chiesa–Orrù 2025], Construction 4.3. The compiler takes a public-coin interactive argument or reduction and produces a non-interactive proof using spongefish's existing duplex sponge transcript machinery.DSFS is the transformation that makes spongefish useful end-to-end: a typed protocol → a transcript → a byte string the verifier checks. Today spongefish stops at the transcript; this PR adds the missing top layer.
What's new
spongefish-dsfs(new workspace crate)The compiler:
Public surface:
Dsfs<IA, S, H = Keccak, const SALT_LEN: usize = 0>— wraps anInteractiveArgument, implementsNonInteractiveArgument. Const-generic salt length, explicit sponge parameter.DsfsReduction<IR, S, H, SALT_LEN>— symmetric forInteractiveReduction(verifiers output a reduced target instance instead of accept/reject).SpongeProver/SpongeVerifier— adapters that viewspongefish::ProverState/VerifierStateas a typed prover/verifier channel.TranscriptSponge— initialization trait.Keccakusesdomsep.to_prover();StdHash(SHAKE128) usesdomsep.std_prover()so DSFS output is byte-compatible with spongefish's existing standard-hash transcript path (and σ-proofsNizk).NargSecurity+security_for_concrete_instance/security_for_instance_boundand reduction variants — applies the bounds of [CO25], Theorems 6.1, 6.2, 7.1 to derive concrete NARG soundness / knowledge-soundness / zero-knowledge errors from the IA's per-round metadata plus the sponge's(alphabet_size, capacity, rate, delta)parameters.Transcript invariants the compiler maintains:
Companion crate:
ia-coreThe DSFS compiler needs a vocabulary for "what's an interactive argument" and "what's a non-interactive argument". That vocabulary lives in a small
ia-corecrate thatspongefish-dsfsdepends on:Plus analogous
InteractiveReduction/NonInteractiveReductionfor reduction-style protocols, the channel traitsProverChannel/VerifierChannel, and a security-metadata module.ia-coreitself is pure-no_std, has no transcript / sponge knowledge, and re-exportsspongefish's codec traits (Encoding,Decoding,NargSerialize,NargDeserialize,Deserialize) for protocol authors.Hosted at https://github.com/ricardo-perello/argus (path dep here; will be published when the IA/IR API stabilizes).
Workspace plumbing
spongefish-dsfsworkspace member; standardversion.workspace = true/ lints inheritance.[patch.crates-io] spongefish = { path = "spongefish" }so transitive deps (ia-coreresolved throughspongefish-dsfs) see the local copy instead of the registry version during development.What's not in this PR
spongefishcore. Transcript layer,DomainSeparator, sponge instantiations (Keccak,StdHash, all ofinstantiations::*), and codec traits (Encoding,Decoding,NargSerialize,NargDeserialize) are exactly where they were.spongefish-dsfsconsumes them through their existing public API.examples/schnorr.rs,examples/bulletproof.rs, the bench harness, the drivers' Unit impls, thederive_genericstests — all untouched.SHA-512-padded protocol-id derivation, instance binding, etc., is whatDomainSeparator::derivealready does upstream.Verification
cargo tree -p spongefish | grep ia-coreis empty —spongefishcore has no upward dependency. The arrows are strictly:Reference
draft-irtf-cfrg-fiat-shamir.Follow-ups (separate PRs)
Nizkbyte-compat fixtures land in the consumer (Argus) — not needed here.ia-coreis published to crates.io, drop the path dep in favor of a versioned one.Optional tweaks you might want: