nimue icon indicating copy to clipboard operation
nimue copied to clipboard

Permutation iv design

Open alxiong opened this issue 7 months ago • 0 comments

I ran into a use case where the Sponge is over >256 bits field, and I want to initialize the sponge state with a field element (think keyed hash, but algebraic with fields rather than bytes).

If I use DuplexSponge::new(f.into_bigint().to_bytes_be()[..32]), then i'm basically truncating some of the bytes, which is not ideal. Ideally, I want a DuplexSponge::new_from(iv: U) where U: Permutation::U. Ultimately I'm proposing an additional method on trait Permutation called: ::new_from(iv: U) or ::new_from_unit(iv: U).

(a somewhat related topic, the choice to use big-endian for PoseidonPermutation implementation is little inconvenient imo: https://github.com/arkworks-rs/spongefish/blob/3ded547f7f56d7f8a1fc4c9a5c0ce965310bba5f/spongefish-poseidon/src/lib.rs#L104-L109

because if my field size is <32 bytes, and I want the "keyed iv" behavior, then i have to do this:

        let key_bigint_bytes = key.into_bigint().to_bytes_be();
        let mut key_bytes_be = [0u8; 32];
        let copy_len = usize::min(32, key_bigint_bytes.len());
        key_bytes_be[32 - copy_len..]
            .copy_from_slice(&key_bigint_bytes[key_bigint_bytes.len() - copy_len..]);

        let mut perm = PoseidonPermutation::new(key_bytes_be);

whereas if we use little-endian then it's eye-friendly:

        let mut key_bytes_le = [0u8; 32];
        key_bytes_le.copy_from_slice(&key.into_bigint().to_bytes_le());

        let mut perm = PoseidonPermutation::new(key_bytes_le);

But this is super nit-picky, and doesn't hurt either way. Just pointing out its small implication on the consumer side.

cc @mmaker

alxiong avatar Sep 09 '25 07:09 alxiong