-
Notifications
You must be signed in to change notification settings - Fork 36
Description
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:
spongefish/spongefish-poseidon/src/lib.rs
Lines 104 to 109 in 3ded547
| fn new(iv: [u8; 32]) -> Self { | |
| assert!(N >= 1); | |
| let mut sponge = Self::default(); | |
| sponge.state[R] = F::from_be_bytes_mod_order(&iv); | |
| sponge | |
| } |
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