diff --git a/crypto-primitives/src/sponge/absorb.rs b/crypto-primitives/src/sponge/absorb.rs index 3dea6b46..ed98bf1d 100644 --- a/crypto-primitives/src/sponge/absorb.rs +++ b/crypto-primitives/src/sponge/absorb.rs @@ -7,6 +7,7 @@ use ark_ec::{ use ark_ff::models::{Fp, FpConfig}; use ark_ff::{BigInteger, Field, PrimeField, ToConstraintField}; use ark_serialize::CanonicalSerialize; +use ark_std::string::String; use ark_std::vec::Vec; pub use ark_crypto_primitives_macros::*; @@ -229,6 +230,17 @@ impl Absorb for isize { } } +impl Absorb for String { + fn to_sponge_bytes(&self, dest: &mut Vec) { + self.len().to_sponge_bytes(dest); + dest.extend_from_slice(self.as_bytes()) + } + + fn to_sponge_field_elements(&self, dest: &mut Vec) { + self.as_bytes().to_sponge_field_elements(dest) + } +} + impl Absorb for TEAffine

where P::BaseField: ToConstraintField<::BasePrimeField>, @@ -456,4 +468,31 @@ mod tests { let out_manual = sponge.squeeze_bytes(32); assert_eq!(out_derived, out_manual); } + + #[test] + fn test_string_absort() { + // absorbing two strings should not be the same as absorbing the concatenated string + let s1 = "hello".to_string(); + let s2 = "world".to_string(); + + let mut dest1 = Vec::new(); + s1.to_sponge_bytes(&mut dest1); + s2.to_sponge_bytes(&mut dest1); + + let mut dest2 = Vec::new(); + let s3 = "helloworld".to_string(); + s3.to_sponge_bytes(&mut dest2); + + assert_ne!(dest1, dest2); + + // Same for converting to sponge field elements + let mut dest1: Vec = Vec::new(); + s1.to_sponge_field_elements(&mut dest1); + s2.to_sponge_field_elements(&mut dest1); + + let mut dest2 = Vec::new(); + s3.to_sponge_field_elements(&mut dest2); + + assert_ne!(dest1, dest2); + } }