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

feat: new Poseidon2 relations #3406

Merged
merged 28 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e1c732d
initial commit
zac-williamson Oct 27, 2023
ea12f99
mmmmm constexpr
zac-williamson Oct 27, 2023
95e6572
wip
zac-williamson Oct 27, 2023
8c30828
basic poseidon hash working
zac-williamson Oct 27, 2023
86cf018
added tests + comments
zac-williamson Oct 30, 2023
6dd2511
comments
zac-williamson Oct 30, 2023
3dbd8df
removed string_view constructors
zac-williamson Oct 30, 2023
3631294
poseidon2 parameters now consistent with definition in paper
zac-williamson Oct 31, 2023
910b303
fixed bug where constructing uint from a string that is too big!
zac-williamson Oct 31, 2023
c7b4157
added cast to fix build error
lucasxia01 Nov 7, 2023
7bcee20
benchmarking file for native impl
lucasxia01 Nov 7, 2023
752bd14
Merge branch 'master' into zw/poseidon2
lucasxia01 Nov 7, 2023
7d0fe79
Merge branch 'master' into zw/poseidon2
lucasxia01 Nov 20, 2023
20a7eb2
Merge branch 'master' into zw/poseidon2
lucasxia01 Nov 22, 2023
f09ed91
external poseidon2 round relation
lucasxia01 Nov 20, 2023
d679581
added ARC and SBox rounds to external
lucasxia01 Nov 20, 2023
35ab7d9
created internal round relation
lucasxia01 Nov 20, 2023
5e94698
naming update
lucasxia01 Nov 22, 2023
14157c1
external relation consistency test
lucasxia01 Nov 22, 2023
e04037e
internal round consistency test
lucasxia01 Nov 22, 2023
6da3335
initial manual relation tests
lucasxia01 Nov 22, 2023
0c961b1
variable renaming
lucasxia01 Nov 24, 2023
8ef04db
added manual tests for internal
lucasxia01 Nov 24, 2023
b144cce
Merge branch 'master' into lx/poseidon2-relations
lucasxia01 Nov 28, 2023
80958c5
updated based on review
lucasxia01 Nov 30, 2023
a3c8eed
naming update
lucasxia01 Nov 30, 2023
52d260b
comment and scoping update
lucasxia01 Dec 1, 2023
a53e861
Merge branch 'master' into lx/poseidon2-relations
lucasxia01 Dec 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1 @@
barretenberg_module(crypto_poseidon2 ecc numeric)
barretenberg_module(crypto_poseidon2 ecc)
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ template <typename Params> class Poseidon2Permutation {
auto t5 = t0 + t0;
t5 += t5;
t5 += t2; // 4A + 6B + C + D
auto t6 = t3 + t5; // 5A + 7B + 3C + D
auto t7 = t2 + t4; // A + 3B + 5D + 7C
auto t6 = t3 + t5; // 5A + 7B + C + 3D
auto t7 = t2 + t4; // A + 3B + 5C + 7D
input[0] = t6;
input[1] = t5;
input[2] = t7;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#pragma once
#include "barretenberg/relations/relation_types.hpp"
namespace proof_system {

template <typename FF_> class Poseidon2ExternalRelationImpl {
public:
using FF = FF_;

static constexpr std::array<size_t, 4> SUBRELATION_PARTIAL_LENGTHS{
7, // external poseidon2 round sub-relation for first value
7, // external poseidon2 round sub-relation for second value
7, // external poseidon2 round sub-relation for third value
7, // external poseidon2 round sub-relation for fourth value
};

/**
* @brief Expression for the poseidon2 external round relation, based on E_i in Section 6 of
* https://eprint.iacr.org/2023/323.pdf.
* @details This relation is defined as:
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
* q_poseidon2_external * ( (v1 - w_1_shift) + \alpha * (v2 - w_2_shift) +
* \alpha^2 * (v3 - w_3_shift) + \alpha^3 * (v4 - w_4_shift) ) = 0 where:
* u1 := (w_1 + q_1)^5
* u2 := (w_2 + q_2)^5
* u3 := (w_3 + q_3)^5
* u4 := (w_4 + q_4)^5
* t0 := u1 + u2 (1, 1, 0, 0)
* t1 := u3 + u4 (0, 0, 1, 1)
* t2 := 2 * u2 + t1 = 2 * u2 + u3 + u4 (0, 2, 1, 1)
* t3 := 2 * u4 + t0 = u1 + u2 + 2 * u4 (1, 1, 0, 2)
* v4 := 4 * t1 + t3 = u1 + u2 + 4 * u3 + 6 * u4 (1, 1, 4, 6)
* v2 := 4 * t0 + t2 = 4 * u1 + 6 * u2 + u3 + u4 (4, 6, 1, 1)
* v1 := t3 + v2 = 5 * u1 + 7 * u2 + 1 * u3 + 3 * u4 (5, 7, 1, 3)
* v3 := t2 + v4 (1, 3, 5, 7)
*
* @param evals transformed to `evals + C(in(X)...)*scaling_factor`
* @param in an std::array containing the fully extended Univariate edges.
* @param parameters contains beta, gamma, and public_input_delta, ....
* @param scaling_factor optional term to scale the evaluation before adding to evals.
*/
template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
void static accumulate(ContainerOverSubrelations& evals,
const AllEntities& in,
const Parameters&,
const FF& scaling_factor)
{
using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>;
using View = typename Accumulator::View;
auto w_l = View(in.w_l);
auto w_r = View(in.w_r);
auto w_o = View(in.w_o);
auto w_4 = View(in.w_4);
auto w_l_shift = View(in.w_l_shift);
auto w_r_shift = View(in.w_r_shift);
auto w_o_shift = View(in.w_o_shift);
auto w_4_shift = View(in.w_4_shift);
auto q_l = View(in.q_l);
auto q_r = View(in.q_r);
auto q_o = View(in.q_o);
auto q_4 = View(in.q_4);
auto q_poseidon2_external = View(in.q_poseidon2_external);

// add round constants which are loaded in selectors
auto s1 = w_l + q_l;
auto s2 = w_r + q_r;
auto s3 = w_o + q_o;
auto s4 = w_4 + q_4;

// apply s-box round
auto u1 = s1 * s1;
u1 *= u1;
u1 *= s1;
auto u2 = s2 * s2;
u2 *= u2;
u2 *= s2;
auto u3 = s3 * s3;
u3 *= u3;
u3 *= s3;
auto u4 = s4 * s4;
u4 *= u4;
u4 *= s4;

// matrix mul v = M_E * u with 14 additions
auto t0 = u1 + u2; // A + B
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
auto t1 = u3 + u4; // C + D
auto t2 = u2 + u2; // 2B
t2 += t1; // 2B + C + D
auto t3 = u4 + u4; // 2D
t3 += t0; // 2D + A + B
auto v4 = t1 + t1;
v4 += v4;
v4 += t3; // A + B + 4C + 6D
auto v2 = t0 + t0;
v2 += v2;
v2 += t2; // 4A + 6B + C + D
auto v1 = t3 + v2; // 5A + 7B + C + 3D
auto v3 = t2 + v4; // A + 3B + 5C + 7D

{
auto tmp = q_poseidon2_external * (v1 - w_l_shift);
tmp *= scaling_factor;
std::get<0>(evals) += tmp;
}
{
auto tmp = q_poseidon2_external * (v2 - w_r_shift);
tmp *= scaling_factor;
std::get<1>(evals) += tmp;
}
{
auto tmp = q_poseidon2_external * (v3 - w_o_shift);
tmp *= scaling_factor;
std::get<2>(evals) += tmp;
}
{
auto tmp = q_poseidon2_external * (v4 - w_4_shift);
tmp *= scaling_factor;
std::get<3>(evals) += tmp;
}
};
};

template <typename FF> using Poseidon2ExternalRelation = Relation<Poseidon2ExternalRelationImpl<FF>>;
} // namespace proof_system
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma once
#include "barretenberg/crypto/poseidon2/poseidon2_params.hpp"
#include "relation_types.hpp"

namespace proof_system {

template <typename FF_> class Poseidon2InternalRelationImpl {
public:
using FF = FF_;

static constexpr std::array<size_t, 4> SUBRELATION_PARTIAL_LENGTHS{
7, // internal poseidon2 round sub-relation for first value
7, // internal poseidon2 round sub-relation for second value
7, // internal poseidon2 round sub-relation for third value
7, // internal poseidon2 round sub-relation for fourth value
};

/**
* @brief Expression for the poseidon2 internal round relation, based on I_i in Section 6 of
* https://eprint.iacr.org/2023/323.pdf.
* @details This relation is defined as:
* q_poseidon2_internal * ( (v1 - w_1_shift) + \alpha * (v2 - w_2_shift) +
* \alpha^2 * (v3 - w_3_shift) + \alpha^3 * (v4 - w_4_shift) ) = 0 where:
* u1 := (w_1 + q_1)^5
* sum := u1 + w_2 + w_3 + w_4
* v1 := u1 * D1 + sum
* v2 := w_2 * D2 + sum
* v3 := w_3 * D3 + sum
* v4 := w_4 * D4 + sum
* Di is the ith internal diagonal value - 1 of the internal matrix M_I
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param evals transformed to `evals + C(in(X)...)*scaling_factor`
* @param in an std::array containing the fully extended Univariate edges.
* @param parameters contains beta, gamma, and public_input_delta, ....
* @param scaling_factor optional term to scale the evaluation before adding to evals.
*/
template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
void static accumulate(ContainerOverSubrelations& evals,
const AllEntities& in,
const Parameters&,
const FF& scaling_factor)
{
using Accumulator = std::tuple_element_t<0, ContainerOverSubrelations>;
using View = typename Accumulator::View;
auto w_l = View(in.w_l);
auto w_r = View(in.w_r);
auto w_o = View(in.w_o);
auto w_4 = View(in.w_4);
auto w_l_shift = View(in.w_l_shift);
auto w_r_shift = View(in.w_r_shift);
auto w_o_shift = View(in.w_o_shift);
auto w_4_shift = View(in.w_4_shift);
auto q_l = View(in.q_l);
auto q_poseidon2_internal = View(in.q_poseidon2_internal);

// add round constants
auto s1 = w_l + q_l;

// apply s-box round
auto u1 = s1 * s1;
u1 *= u1;
u1 *= s1;
auto u2 = w_r;
auto u3 = w_o;
auto u4 = w_4;

// matrix mul with v = M_I * u 4 muls and 7 additions
auto sum = u1 + u2 + u3 + u4;
{
lucasxia01 marked this conversation as resolved.
Show resolved Hide resolved
auto v1 = u1 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[0];
v1 += sum;
auto tmp = q_poseidon2_internal * (v1 - w_l_shift);
tmp *= scaling_factor;
std::get<0>(evals) += tmp;
}
{
auto v2 = u2 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[1];
v2 += sum;
auto tmp = q_poseidon2_internal * (v2 - w_r_shift);
tmp *= scaling_factor;
std::get<1>(evals) += tmp;
}
{
auto v3 = u3 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[2];
v3 += sum;
auto tmp = q_poseidon2_internal * (v3 - w_o_shift);
tmp *= scaling_factor;
std::get<2>(evals) += tmp;
}
{
auto v4 = u4 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[3];
v4 += sum;
auto tmp = q_poseidon2_internal * (v4 - w_4_shift);
tmp *= scaling_factor;
std::get<3>(evals) += tmp;
}
};
}; // namespace proof_system

template <typename FF> using Poseidon2InternalRelation = Relation<Poseidon2InternalRelationImpl<FF>>;
} // namespace proof_system
Loading