20 #include <libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp>
21 #include <libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp>
22 #include <libff/algebra/curves/alt_bn128/alt_bn128_pairing.hpp>
23 #include <libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
24 #include <libff/common/profiling.hpp>
38 void initLibSnark() noexcept
40 static bool s_initialized = []() noexcept
42 libff::inhibit_profiling_info =
true;
43 libff::inhibit_profiling_counters =
true;
44 libff::alt_bn128_pp::init_public_params();
50 libff::bigint<libff::alt_bn128_q_limbs> toLibsnarkBigint(
h256 const& _x)
52 libff::bigint<libff::alt_bn128_q_limbs> b;
54 constexpr
size_t L =
sizeof(b.data[0]);
55 static_assert(
sizeof(mp_limb_t) == L,
"Unexpected limb size in libff::bigint.");
56 for (
size_t i = 0; i < N; i++)
57 for (
size_t j = 0; j < L; j++)
58 b.data[N - 1 - i] |= mp_limb_t(_x[i * L + j]) << (8 * (L - 1 - j));
62 h256 fromLibsnarkBigint(libff::bigint<libff::alt_bn128_q_limbs>
const& _b)
64 static size_t const N =
static_cast<size_t>(_b.N);
65 static size_t const L =
sizeof(_b.data[0]);
66 static_assert(
sizeof(mp_limb_t) == L,
"Unexpected limb size in libff::bigint.");
68 for (
size_t i = 0; i < N; i++)
69 for (
size_t j = 0; j < L; j++)
70 x[i * L + j] = uint8_t(_b.data[N - 1 - i] >> (8 * (L - 1 - j)));
78 h256 xbin(_data, h256::AlignLeft);
80 if (
u256(xbin) >=
u256(fromLibsnarkBigint(libff::alt_bn128_Fq::mod)))
81 BOOST_THROW_EXCEPTION(InvalidEncoding());
82 return toLibsnarkBigint(xbin);
87 libff::alt_bn128_Fq x = decodeFqElement(_data.
cropped(0));
88 libff::alt_bn128_Fq y = decodeFqElement(_data.
cropped(32));
89 if (x == libff::alt_bn128_Fq::zero() && y == libff::alt_bn128_Fq::zero())
90 return libff::alt_bn128_G1::zero();
91 libff::alt_bn128_G1 p(x, y, libff::alt_bn128_Fq::one());
92 if (!p.is_well_formed())
93 BOOST_THROW_EXCEPTION(InvalidEncoding());
97 bytes encodePointG1(libff::alt_bn128_G1 _p)
101 _p.to_affine_coordinates();
103 fromLibsnarkBigint(_p.X.as_bigint()).asBytes() +
104 fromLibsnarkBigint(_p.Y.as_bigint()).asBytes();
111 return libff::alt_bn128_Fq2(
112 decodeFqElement(_data.
cropped(32)),
113 decodeFqElement(_data.
cropped(0))
119 libff::alt_bn128_Fq2
const x = decodeFq2Element(_data);
120 libff::alt_bn128_Fq2
const y = decodeFq2Element(_data.
cropped(64));
121 if (x == libff::alt_bn128_Fq2::zero() && y == libff::alt_bn128_Fq2::zero())
122 return libff::alt_bn128_G2::zero();
123 libff::alt_bn128_G2 p(x, y, libff::alt_bn128_Fq2::one());
124 if (!p.is_well_formed())
125 BOOST_THROW_EXCEPTION(InvalidEncoding());
136 size_t constexpr pairSize = 2 * 32 + 2 * 64;
137 size_t const pairs = _in.
size() / pairSize;
138 if (pairs * pairSize != _in.
size())
140 return {
false,
bytes{}};
145 libff::alt_bn128_Fq12 x = libff::alt_bn128_Fq12::one();
146 for (
size_t i = 0; i < pairs; ++i)
149 libff::alt_bn128_G1
const g1 = decodePointG1(pair);
150 libff::alt_bn128_G2
const p = decodePointG2(pair.
cropped(2 * 32));
151 if (-libff::alt_bn128_G2::scalar_field::one() * p + p != libff::alt_bn128_G2::zero())
153 return {
false,
bytes()};
154 if (p.is_zero() || g1.is_zero())
156 x = x * libff::alt_bn128_miller_loop(
157 libff::alt_bn128_precompute_G1(g1),
158 libff::alt_bn128_precompute_G2(p)
161 bool const result = libff::alt_bn128_final_exponentiation(x) == libff::alt_bn128_GT::one();
164 catch (InvalidEncoding
const&)
167 return {
false,
bytes{}};
176 libff::alt_bn128_G1
const p1 = decodePointG1(_in);
177 libff::alt_bn128_G1
const p2 = decodePointG1(_in.
cropped(32 * 2));
178 return {
true, encodePointG1(p1 + p2)};
180 catch (InvalidEncoding
const&)
183 return {
false,
bytes{}};
192 libff::alt_bn128_G1
const p = decodePointG1(_in.
cropped(0));
193 libff::alt_bn128_G1
const result = toLibsnarkBigint(
h256(_in.
cropped(64), h256::AlignLeft)) * p;
194 return {
true, encodePointG1(result)};
196 catch (InvalidEncoding
const&)
199 return {
false,
bytes{}};