Skip to content

Commit

Permalink
Make it possible to use poseidon hash function in transcript
Browse files Browse the repository at this point in the history
  • Loading branch information
martun committed Dec 13, 2023
1 parent d8bd4e1 commit 33d33a6
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 224 deletions.
123 changes: 120 additions & 3 deletions include/nil/crypto3/zk/transcript/fiat_shamir.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,23 @@
#include <nil/marshalling/algorithms/pack.hpp>
#include <nil/crypto3/marshalling/algebra/types/field_element.hpp>

#include <nil/crypto3/hash/type_traits.hpp>
#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>
#include <nil/crypto3/hash/keccak.hpp>

#include <nil/crypto3/multiprecision/cpp_int.hpp>
#include <nil/crypto3/algebra/curves/pallas.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>
#include <nil/crypto3/hash/poseidon.hpp>

#include <nil/crypto3/hash/detail/poseidon/kimchi_constants.hpp>
#include <nil/crypto3/hash/detail/poseidon/original_constants.hpp>
#include <nil/crypto3/hash/detail/poseidon/poseidon_policy.hpp>
#include <nil/crypto3/hash/detail/poseidon/poseidon_permutation.hpp>
#include <nil/crypto3/hash/detail/poseidon/poseidon_sponge.hpp>
#include <nil/crypto3/hash/detail/block_stream_processor.hpp>

#include <nil/crypto3/multiprecision/cpp_int.hpp>
namespace nil {
namespace crypto3 {
namespace zk {
Expand Down Expand Up @@ -116,8 +127,9 @@ namespace nil {
}
};

template<typename Hash>
struct fiat_shamir_heuristic_sequential {
template<typename Hash, typename Enable = void>
struct fiat_shamir_heuristic_sequential
{
typedef Hash hash_type;

fiat_shamir_heuristic_sequential() : state(hash<hash_type>({0})) {
Expand Down Expand Up @@ -184,6 +196,111 @@ namespace nil {
private:
typename hash_type::digest_type state;
};

// Specialize for posseidon.
template<typename Hash>
struct fiat_shamir_heuristic_sequential<
Hash,
typename std::enable_if_t<crypto3::hashes::is_poseidon<Hash>::value>> {

typedef Hash hash_type;
using field_type = nil::crypto3::algebra::curves::pallas::base_field_type;
using poseidon_policy = nil::crypto3::hashes::detail::mina_poseidon_policy<field_type>;
using permutation_type = nil::crypto3::hashes::detail::poseidon_permutation<poseidon_policy>;
using state_type = typename permutation_type::state_type;

fiat_shamir_heuristic_sequential() : state({0,0,0}), cur(1) {
}

template<typename InputRange>
fiat_shamir_heuristic_sequential(const InputRange &r)
: state({hash<hash_type>(r), 0, 0})
, cur(1) {
}

template<typename InputIterator>
fiat_shamir_heuristic_sequential(InputIterator first, InputIterator last)
: state({hash<hash_type>(first, last), 0, 0})
, cur(1) {
}

void operator()(const typename hash_type::digest_type input) {
state[cur] = input;
if (cur == 2) {
state_type poseidon_state;
std::copy(state.begin(), state.end(), poseidon_state.begin());
permutation_type::permute(poseidon_state);

state[0] = poseidon_state[2];
state[1] = 0;
state[2] = 0;
cur = 1;
} else {
cur++;
}
}

template<typename InputRange>
void operator()(const InputRange &r) {
// Used for initilization code, where we pass a marshalled structure to transcript.
state = {hash<hash_type>(r, hash<hash_type>(state)), 0, 0};
cur = 1;
}

template<typename InputIterator>
void operator()(InputIterator first, InputIterator last) {
state = {hash<hash_type>(first, last, hash<hash_type>(state)), 0, 0};
cur = 1;
}

template<typename Field>
typename Field::value_type challenge() {
// TODO(martun): use sponge here.
// state[0] = hash<hash_type>(state);
state_type poseidon_state;
std::copy(state.begin(), state.end(), poseidon_state.begin());
permutation_type::permute(poseidon_state);

state[0] = poseidon_state[2];
state[1] = 0;
state[2] = 0;
cur = 1;

return state[0];
}

template<typename Integral>
Integral int_challenge() {
auto c = challenge<field_type>();
nil::marshalling::status_type status;

nil::crypto3::multiprecision::cpp_int intermediate_result = nil::marshalling::pack(c, status);
Integral result = 0;
Integral factor = 1;
while (intermediate_result > 0) {
result += factor * (Integral)(intermediate_result % 0x100);
factor *= 0x100;
intermediate_result = intermediate_result / 0x100;
}
return result;
}

template<typename Field, std::size_t N>
std::array<typename Field::value_type, N> challenges() {

std::array<typename Field::value_type, N> result;
for (auto &ch : result) {
ch = challenge<Field>();
}

return result;
}

private:
std::vector<typename hash_type::digest_type> state;
std::size_t cur = 1;
};

} // namespace transcript
} // namespace zk
} // namespace crypto3
Expand Down
13 changes: 6 additions & 7 deletions test/systems/plonk/placeholder/circuits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,8 @@ namespace nil {

typedef placeholder_circuit_params<FieldType, arithmetization_params_4> circuit_params;

circuit_description<FieldType, circuit_params, rows_log, permutation> test_circuit;
circuit_description<FieldType, circuit_params, 3, permutation> test_circuit;
test_circuit.table_rows = 1 << rows_log;

std::array<std::vector<typename FieldType::value_type>, table_columns> table;
for (std::size_t j = 0; j < table_columns; j++) {
Expand Down Expand Up @@ -534,17 +535,14 @@ namespace nil {
std::array<plonk_column<FieldType>, public_columns> public_input_assignment = {};
std::array<plonk_column<FieldType>, constant_columns> constant_assignment;

std::vector<typename FieldType::value_type> sel_lookup(test_circuit.table_rows);
sel_lookup ={1, 1, 0, 1, 1, 0, 0, 0};
std::vector<typename FieldType::value_type> sel_lookup = {1, 1, 0, 1, 1, 0, 0, 0};
selectors_assignment[0] = sel_lookup;

std::vector<typename FieldType::value_type> sel_gate0(test_circuit.table_rows);
sel_gate0 = {1, 1, 1, 1, 1, 0, 0, 0};
std::vector<typename FieldType::value_type> sel_gate0 = {1, 1, 1, 1, 1, 0, 0, 0};
selectors_assignment[1] = sel_gate0;


std::vector<typename FieldType::value_type> sel_lookup_table(test_circuit.table_rows);
sel_lookup_table = {0, 1, 1, 1, 1, 0, 0, 0};
std::vector<typename FieldType::value_type> sel_lookup_table = {0, 1, 1, 1, 1, 0, 0, 0};
selectors_assignment[2] = sel_lookup_table;

for (std::size_t i = 0; i < constant_columns; i++) {
Expand All @@ -555,6 +553,7 @@ namespace nil {
plonk_public_assignment_table<FieldType, arithmetization_params_4>(
public_input_assignment, constant_assignment, selectors_assignment));


plonk_variable<assignment_type> w0(0, 0, true, plonk_variable<assignment_type>::column_type::witness);
plonk_variable<assignment_type> w1(1, 0, true, plonk_variable<assignment_type>::column_type::witness);
plonk_variable<assignment_type> w2(2, 0, true, plonk_variable<assignment_type>::column_type::witness);
Expand Down
Loading

0 comments on commit 33d33a6

Please sign in to comment.