Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: do not differentiate variable vs fixed length for Poseidon2 #11740

Merged
merged 10 commits into from
Feb 7, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace bb::crypto {
template <typename Params>
typename Poseidon2<Params>::FF Poseidon2<Params>::hash(const std::vector<typename Poseidon2<Params>::FF>& input)
{
return Sponge::hash_fixed_length(input);
return Sponge::hash_internal(input);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,10 @@ template <typename FF, size_t rate, size_t capacity, size_t t, typename Permutat
* @brief Use the sponge to hash an input string
*
* @tparam out_len
* @tparam is_variable_length. Distinguishes between hashes where the preimage length is constant/not constant
* @param input
* @return std::array<FF, out_len>
*/
template <size_t out_len, bool is_variable_length>
static std::array<FF, out_len> hash_internal(std::span<const FF> input)
template <size_t out_len> static std::array<FF, out_len> hash_internal(std::span<const FF> input)
{
size_t in_len = input.size();
const uint256_t iv = (static_cast<uint256_t>(in_len) << 64) + out_len - 1;
Expand All @@ -140,30 +138,13 @@ template <typename FF, size_t rate, size_t capacity, size_t t, typename Permutat
sponge.absorb(input[i]);
}

// In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish
// from fixed-length hashes. (the combination of this additional field element + the hash IV ensures
// fixed-length and variable-length hashes do not collide)
if constexpr (is_variable_length) {
sponge.absorb(1);
}

std::array<FF, out_len> output;
for (size_t i = 0; i < out_len; ++i) {
output[i] = sponge.squeeze();
}
return output;
}

template <size_t out_len> static std::array<FF, out_len> hash_fixed_length(std::span<const FF> input)
{
return hash_internal<out_len, false>(input);
}
static FF hash_fixed_length(std::span<const FF> input) { return hash_fixed_length<1>(input)[0]; }

template <size_t out_len> static std::array<FF, out_len> hash_variable_length(std::span<FF> input)
{
return hash_internal<out_len, true>(input);
}
static FF hash_variable_length(std::span<FF> input) { return hash_variable_length<1>(input)[0]; }
static FF hash_internal(std::span<const FF> input) { return hash_internal<1>(input)[0]; }
};
} // namespace bb::crypto
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ template <typename C> field_t<C> poseidon2<C>::hash(C& builder, const std::vecto
* This should just call the sponge variable length hash function
*
*/
return Sponge::hash_fixed_length(builder, inputs);
return Sponge::hash_internal(builder, inputs);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ template <size_t rate, size_t capacity, size_t t, typename Permutation, typename
* @param input
* @return std::array<field_t, out_len>
*/
template <size_t out_len, bool is_variable_length>
template <size_t out_len>
static std::array<field_t, out_len> hash_internal(Builder& builder, std::span<const field_t> input)
{
size_t in_len = input.size();
Expand All @@ -145,38 +145,16 @@ template <size_t rate, size_t capacity, size_t t, typename Permutation, typename
sponge.absorb(input[i]);
}

// In the case where the hash preimage is variable-length, we append `1` to the end of the input, to distinguish
// from fixed-length hashes. (the combination of this additional field element + the hash IV ensures
// fixed-length and variable-length hashes do not collide)
if constexpr (is_variable_length) {
sponge.absorb(1);
}

std::array<field_t, out_len> output;
for (size_t i = 0; i < out_len; ++i) {
output[i] = sponge.squeeze();
}
return output;
}

template <size_t out_len>
static std::array<field_t, out_len> hash_fixed_length(Builder& builder, std::span<const field_t> input)
{
return hash_internal<out_len, false>(builder, input);
}
static field_t hash_fixed_length(Builder& builder, std::span<const field_t> input)
{
return hash_fixed_length<1>(builder, input)[0];
}

template <size_t out_len>
static std::array<field_t, out_len> hash_variable_length(Builder& builder, std::span<field_t> input)
{
return hash_internal<out_len, true>(builder, input);
}
static field_t hash_variable_length(Builder& builder, std::span<field_t> input)
static field_t hash_internal(Builder& builder, std::span<const field_t> input)
{
return hash_variable_length<1>(builder, input)[0];
return hash_internal<1>(builder, input)[0];
}
};
} // namespace bb::stdlib