Open martun opened 9 months ago
Examples like this were assigned successfully few weeks ago.
The original issue caused by wrong memory access:
auto begin = layer0.begin();
result = evaluate_root<256>(begin, begin + 256, 256);
begin + 256
- leads invalid getelementptr
, max allowed value is begin + 255
(size - 1
)
Any way need to modify code of example because we don't support dynamic loops
If the final result is hash(hash(hash(0, 1), hash(2, 3)), hash(hash(4, 5), hash(6, 7)))
I suggest to use follow code without dynamic loops:
#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/poseidon.hpp>
#include <nil/crypto3/hash/sha2.hpp>
#include <nil/crypto3/algebra/curves/pallas.hpp>
using namespace nil::crypto3;
using namespace nil::crypto3::algebra::curves;
using value_type = typename hashes::poseidon::block_type;
template<std::size_t size>
value_type evaluate_root(typename std::array<value_type, size>::iterator begin)
{
std::size_t stride = 2;
// stride = 2, 128 iter: hash(0, 1), ..., hash(254, 255)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 4, 64 iter: hash(0, 2), ..., hash(252, 254)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 8, 32 iter: hash(0, 4), ..., hash(248, 252)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 16, 16 iter: hash(0, 8), ..., hash(240, 248)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 32, 8 iter: hash(0, 16), hash(32, 48), hash(64, 80), hash(96, 112), ..., hash(224, 240)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 64, 4 iter: hash(0, 32), hash(64, 96), hash(128, 160), hash(192, 224)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 128, 2 iter: hash(0, 64), hash(64, 128)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
stride *= 2;
// stride = 256, 1 iter: hash(0, 128)
for(std::size_t i = 0; i < size; i += stride) {
begin[i] = hash<hashes::poseidon>(begin[i], begin[i+(stride / 2)]);
}
return *begin;
}
/* parameters summary:
* total number of leaves: 256
* per prover: 256
* total provers: 0
*/
[[circuit]] value_type merkle_tree (
[[private_input]] std::array<value_type, 256> layer0)
{
/* Last layer can be evaluated with one prover */
value_type result;
{
auto begin = layer0.begin();
result = evaluate_root<256>(begin);
}
return result;
}
Yeah, but we have an error even without any loops. We can't use end() iterator at all. Is that right?
#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/poseidon.hpp>
#include <nil/crypto3/hash/sha2.hpp>
#include <nil/crypto3/algebra/curves/pallas.hpp>
using namespace nil::crypto3;
using namespace nil::crypto3::algebra::curves;
using value_type = typename hashes::poseidon::block_type;
value_type evaluate_root(
typename std::array<value_type, 4>::iterator begin,
typename std::array<value_type, 4>::iterator end
)
{
return *begin;
}
/* parameters summary:
* total number of leaves: 4
* per prover: 4
* total provers: 0
*/
[[circuit]] value_type merkle_tree (
[[private_input]] std::array<value_type, 4> layer0)
{
/* Last layer can be evaluated with one prover */
value_type result;
result = evaluate_root(layer0.begin(), layer0.end());
return result;
}
When we remove layer0.end(), this piece assignes well. Is that right, that we can't use end() iterator of array at all?
Solution of @akokoshn works for me, we can close this.
@ETatuzova , we can use end()
iterator, but can't access it: v = *arr.end()
, because it out of memory access.
So @ETatuzova , @martun , can we close issue?
I receive segmentation fault on assigner call like this:
Circuit and inputs.zip