diff --git a/Cargo.lock b/Cargo.lock index 8a3fd06fe8..483563dde9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3583,7 +3583,7 @@ dependencies = [ [[package]] name = "light-hasher" -version = "1.1.0" +version = "1.1.1" dependencies = [ "ark-bn254", "light-poseidon", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "light-sdk" -version = "0.11.0" +version = "0.11.1" dependencies = [ "account-compression", "aligned-sized", diff --git a/merkle-tree/hasher/Cargo.toml b/merkle-tree/hasher/Cargo.toml index d734b58fb9..b2c3285a4f 100644 --- a/merkle-tree/hasher/Cargo.toml +++ b/merkle-tree/hasher/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-hasher" -version = "1.1.0" +version = "1.1.1" description = "Trait for generic usage of hash functions on Solana" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" diff --git a/merkle-tree/hasher/src/errors.rs b/merkle-tree/hasher/src/errors.rs index 6bcf3f01b0..d8a6c17d2c 100644 --- a/merkle-tree/hasher/src/errors.rs +++ b/merkle-tree/hasher/src/errors.rs @@ -12,6 +12,8 @@ pub enum HasherError { PoseidonSyscall(#[from] PoseidonSyscallError), #[error("Unknown Solana syscall error: {0}")] UnknownSolanaSyscall(u64), + #[error("Input length {0} exceeds maximum of {1} bytes")] + InputTooLarge(usize, usize), } // NOTE(vadorovsky): Unfortunately, we need to do it by hand. `num_derive::ToPrimitive` @@ -23,6 +25,7 @@ impl From for u32 { HasherError::Poseidon(_) => 7002, HasherError::PoseidonSyscall(e) => (u64::from(e)).try_into().unwrap_or(7003), HasherError::UnknownSolanaSyscall(e) => e.try_into().unwrap_or(7004), + HasherError::InputTooLarge(_, _) => 7005, } } } diff --git a/merkle-tree/hasher/src/poseidon.rs b/merkle-tree/hasher/src/poseidon.rs index 9ae42c7003..86172517a7 100644 --- a/merkle-tree/hasher/src/poseidon.rs +++ b/merkle-tree/hasher/src/poseidon.rs @@ -14,6 +14,22 @@ impl Hasher for Poseidon { } fn hashv(vals: &[&[u8]]) -> Result { + // Poseidon syscall requires exactly 32-byte inputs. + // Leading zeros preserve big-endian field element values. + let padded_bufs: Vec<[u8; 32]> = vals + .iter() + .map(|v| { + if v.len() > 32 { + return Err(HasherError::InputTooLarge(v.len(), 32)); + } + let mut buf = [0u8; 32]; + buf[32 - v.len()..].copy_from_slice(v); + Ok(buf) + }) + .collect::, _>>()?; + let vals: Vec<&[u8]> = padded_bufs.iter().map(|b| b.as_slice()).collect(); + let vals: &[&[u8]] = vals.as_slice(); + // Perform the calculation inline, calling this from within a program is // not supported. #[cfg(not(target_os = "solana"))] diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 05f54d1d0c..85b1a671f0 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "light-sdk" -version = "0.11.0" +version = "0.11.1" description = "Rust SDK for ZK Compression on Solana" repository = "https://github.com/Lightprotocol/light-protocol" license = "Apache-2.0" @@ -37,7 +37,7 @@ aligned-sized = { version = "1.1.0", path = "../macros/aligned-sized" } light-macros = { version = "1.1.0", path = "../macros/light" } light-sdk-macros = { version = "0.4.0", path = "../macros/light-sdk-macros" } bytemuck = "1.17" -light-hasher = { version = "1.1.0", path = "../merkle-tree/hasher", features=["solana"] } +light-hasher = { version = "1.1.1", path = "../merkle-tree/hasher", features=["solana"] } light-heap = { version = "1.1.0", path = "../heap", optional = true } light-indexed-merkle-tree = { workspace = true } account-compression = { workspace = true , optional = true }