#transcript #sha-3 #hash #shake

no-std ark-transcript

Arkworks friendly transcripts for proofs using Fiat-Shamir

3 releases

new 0.0.3 Dec 4, 2024
0.0.2 Sep 27, 2024
0.0.1 Apr 13, 2023

#209 in Cryptography

Download history 1/week @ 2024-08-25 316/week @ 2024-09-22 936/week @ 2024-09-29 1010/week @ 2024-10-06 1006/week @ 2024-10-13 861/week @ 2024-10-20 807/week @ 2024-10-27 823/week @ 2024-11-03 566/week @ 2024-11-10 835/week @ 2024-11-17 954/week @ 2024-11-24 924/week @ 2024-12-01

3,314 downloads per month
Used in 2 crates (via dleq_vrf)

MIT/Apache

29KB
408 lines

Arkworks friendly transcripts for proofs using Fiat-Shamir

A simple wrapper around shake128 which provides transcript aka tuple-hash style hashing for simple safe domain seperation, but compatible with an io::Write interface for simple idomatic integration into arkworks.

We do basic domain seperation using postfix writes of the lengths of written data, as opposed to the prefix writes done by merlin, TupleHash from SP 800-185, since postfix writes simplify polymorphic code.

Why not merlin?

A trascript flavored hash like merlin (docs) simplifies protocol development by somewhat abstracting away domain seperation.

Although merlin works fine in the dalek ecosystem, we discovered its prefix length convention fits poorly with ecosystems like arkworks or other zcash derivatives, which serialize and hash via the io::Write trait or similar.

An io::Write instance should treat h.write(xs); exactly like for x in xs { h.write(x); } so write cannot directly wrape merlin's append_bytes. In principle, one could still provide merlin extension traits which serialize fully monomorphized arkworks types into buffers, and then appends those to the merlin transcript. Arkworks strives for polymorphism however, which while complex when doing cryptography, brings many advantages.

Idiomatic rust should minimize allocations. Also, zeroing secrets appears easier or more natrual on the stack. Those buffers should thus live on the stack, not the heap. Yet, rust still lacks dynamic stack allocations ala alloca in C!

We know several hacky solutions of course, with diverse annoyances. Yet, there is no good reason why a trascript style hasher should not support io::Write natively, but doing this directly demands a postfix length convention.

As a minor cost for us, any users whose hashing involves multiple code paths should ensure they invoke label between arkworks types and user data with possibly zero length.

Aside from postfix lengths..

There do exist people who feel STROBE maybe overkill, unfamiliar, or not widely available. Almost all sha3 implementations provide shake128, making this transcript simple, portable, etc.

We also "correct" merlin's excessively opinionated requirement of &'static [u8]s for labels, which complicates some key management practices.

Accumulation

We support accumulating hashed data in a Vec<u8>, which users could then transport to a remote signer for actual signing or proving. Although possible in principle, we do not reparse this accumulated data, but regardless the accumulation should not break any domain seperation that occurs inside the remore signer.

Ideally, accumulations should've applications specific labels both prefixed inside the accumulations and postfixed by the remote signer. A remote signer could check this prefix of course, but applying a postfix label should suffice given we use Shake128.

We have a debug-transcript feature similar to merlin as well.

Dependencies

~4.5MB
~74K SLoC