Skip to content

Commit

Permalink
work in progress on v2 #300
Browse files Browse the repository at this point in the history
  • Loading branch information
vo-nil committed Feb 29, 2024
1 parent 3768893 commit c7fc15a
Show file tree
Hide file tree
Showing 2 changed files with 383 additions and 1 deletion.
220 changes: 220 additions & 0 deletions include/nil/crypto3/zk/commitments/polynomial/kzg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,226 @@ namespace nil {
}

};

// Placeholder-friendly class
template<typename KZGScheme, typename PolynomialType = typename math::polynomial_dfs<typename KZGScheme::field_type::value_type>>
class kzg_commitment_scheme_v2 : public polys_evaluator<typename KZGScheme::params_type, typename KZGScheme::commitment_type, PolynomialType>{
public:
using curve_type = typename KZGScheme::curve_type;
using field_type = typename KZGScheme::field_type;
using params_type = typename KZGScheme::params_type;

// This should be marshallable and transcriptable type
using commitment_type = typename KZGScheme::commitment_type;
using transcript_type = typename KZGScheme::transcript_type;
using transcript_hash_type = typename KZGScheme::transcript_hash_type;
using poly_type = PolynomialType;
using proof_type = typename KZGScheme::proof_type;
using endianness = nil::marshalling::option::big_endian;
private:
params_type _params;
std::map<std::size_t, commitment_type> _commitments;
std::map<std::size_t, std::vector<typename KZGScheme::single_commitment_type>> _ind_commitments;
std::vector<typename KZGScheme::scalar_value_type> _merged_points;
protected:
typename KZGScheme::verification_key_type commit_g2(typename math::polynomial<typename KZGScheme::scalar_value_type> poly) {
BOOST_ASSERT(poly.size() <= _params.verification_key.size());
auto result = algebra::multiexp<typename KZGScheme::multiexp_method>(_params.verification_key.begin(),
_params.verification_key.begin() + poly.size(), poly.begin(), poly.end(), 1);
return result;
}

// Differs from static one by input parameters
void merge_eval_points(){
std::set<typename KZGScheme::scalar_value_type> set;
for( auto const &it:this->_points){
auto k = it.first;
for (std::size_t i = 0; i < this->_points[k].size(); ++i) {
set.insert(this->_points[k][i].begin(), this->_points[k][i].end());
}
}
_merged_points = std::vector<typename KZGScheme::scalar_value_type>(set.begin(), set.end());
}

typename math::polynomial<typename KZGScheme::scalar_value_type>
set_difference_polynom(
std::vector<typename KZGScheme::scalar_value_type> merged_points,
std::vector<typename KZGScheme::scalar_value_type> points
) {
std::sort(merged_points.begin(), merged_points.end());
std::sort(points.begin(), points.end());
std::vector<typename KZGScheme::scalar_value_type> result;
std::set_difference(merged_points.begin(), merged_points.end(), points.begin(), points.end(), std::back_inserter(result));
if (result.size() == 0) {
return typename math::polynomial<typename KZGScheme::scalar_value_type>({{1}});
}
BOOST_ASSERT(this->get_V(result) * this->get_V(points) == this->get_V(merged_points));
return this->get_V(result);
}

void update_transcript(std::size_t batch_ind, typename KZGScheme::transcript_type &transcript) {
/* The procedure of updating the transcript is subject to review and change
* #295 */

// Push commitments to transcript
transcript(_commitments[batch_ind]);

// Push evaluation points to transcript
for( std::size_t i = 0; i < this->_z.get_batch_size(batch_ind); i++){
for( std::size_t j = 0; j < this->_z.get_poly_points_number(batch_ind, i); j++ ) {
nil::marshalling::status_type status;
std::vector<uint8_t> byteblob =
nil::marshalling::pack<endianness>(this->_z.get(batch_ind, i, j), status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(byteblob);
}
}

// Push U polynomials to transcript
for (std::size_t i = 0; i < this->_points[batch_ind].size(); i++) {
auto poly = this->get_U(batch_ind, i);
for (std::size_t j = 0; j < poly.size(); ++j) {
nil::marshalling::status_type status;
std::vector<uint8_t> byteblob =
nil::marshalling::pack<endianness>(poly[j], status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
transcript(byteblob);
}
}
}
public:
// Interface function. Isn't useful here.
void mark_batch_as_fixed(std::size_t index) {
}

kzg_commitment_scheme_v2(params_type kzg_params) : _params(kzg_params) {}

// Differs from static, because we pack the result into byte blob.
commitment_type commit(std::size_t index){
this->_ind_commitments[index] = {};
this->state_commited(index);

std::vector<std::uint8_t> result = {};
for (std::size_t i = 0; i < this->_polys[index].size(); ++i) {
BOOST_ASSERT(this->_polys[index][i].degree() <= _params.commitment_key.size());
auto single_commitment = nil::crypto3::zk::algorithms::commit_one<KZGScheme>(_params, this->_polys[index][i]);
this->_ind_commitments[index].push_back(single_commitment);
nil::marshalling::status_type status;
std::vector<uint8_t> single_commitment_bytes =
nil::marshalling::pack<endianness>(single_commitment, status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
result.insert(result.end(), single_commitment_bytes.begin(), single_commitment_bytes.end());
}
_commitments[index] = result;
return result;
}

using preprocessed_data_type = bool;
preprocessed_data_type preprocess(transcript_type& transcript) const{
return true;
}

void setup(transcript_type& transcript, preprocessed_data_type b = true) {
// Nothing to be done here.
}

proof_type proof_eval(transcript_type &transcript){
this->eval_polys();
this->merge_eval_points();

for( auto const &it: this->_commitments ){
auto k = it.first;
update_transcript(k, transcript);
}

auto gamma = transcript.template challenge<typename KZGScheme::curve_type::scalar_field_type>();
auto factor = KZGScheme::scalar_value_type::one();
typename math::polynomial<typename KZGScheme::scalar_value_type> accum = {0};

for( auto const &it: this->_polys ){
auto k = it.first;
for (std::size_t i = 0; i < this->_z.get_batch_size(k); ++i) {
accum += factor * ( math::polynomial<typename KZGScheme::scalar_value_type>( this->_polys[k][i].coefficients()) - this->get_U(k, i)) / this->get_V(this->_points[k][i]);
factor *= gamma;
}
}

//verify without pairing. It's only for debug
//if something goes wrong, it may be useful to place here verification with pairings
/*
{
typename math::polynomial<typename KZGScheme::scalar_value_type> right_side({{0}});
factor = KZGScheme::scalar_value_type::one();
for( auto const &it: this->_polys ){
auto k = it.first;
for (std::size_t i = 0; i < this->_points[k].size(); ++i) {
right_side = right_side + (factor * (math::polynomial<typename KZGScheme::scalar_value_type>(this->_polys[k][i].coefficients()) - this->get_U(k, i)) *
set_difference_polynom(this->_merged_points, this->_points[k][i]));
factor = factor * gamma;
}
}
assert(accum * this->get_V(this->_merged_points) == right_side);
}*/
return {this->_z, nil::crypto3::zk::algorithms::commit_one<KZGScheme>(_params, accum)};
}

bool verify_eval(
const proof_type &proof,
const std::map<std::size_t, commitment_type> &commitments,
transcript_type &transcript
) {
this->merge_eval_points();
this->_commitments = commitments;
this->_z = proof.z;

for (auto const &it: this->_commitments) {
auto k = it.first;
update_transcript(k, transcript);
}

auto gamma = transcript.template challenge<typename KZGScheme::curve_type::scalar_field_type>();
auto factor = KZGScheme::scalar_value_type::one();
auto left_side_accum = KZGScheme::gt_value_type::one();

for (const auto &it: this->_commitments) {
auto k = it.first;
for (std::size_t i = 0; i < this->_points.at(k).size(); ++i) {
std::size_t blob_size = this->_commitments.at(k).size() / this->_points.at(k).size();
std::vector<std::uint8_t> byteblob(blob_size);

for (std::size_t j = 0; j < blob_size; j++) {
byteblob[j] = this->_commitments.at(k)[i * blob_size + j];
}
nil::marshalling::status_type status;
typename curve_type::template g1_type<>::value_type
i_th_commitment = nil::marshalling::pack(byteblob, status);
BOOST_ASSERT(status == nil::marshalling::status_type::success);
auto U_commit = nil::crypto3::zk::algorithms::commit_one<KZGScheme>(_params, this->get_U(k,i));

auto diffpoly = set_difference_polynom(_merged_points, this->_points.at(k)[i]);
auto diffpoly_commitment = commit_g2(diffpoly);

auto left_side_pairing = nil::crypto3::algebra::pair_reduced<curve_type>(
factor*(i_th_commitment - U_commit), diffpoly_commitment);

left_side_accum = left_side_accum * left_side_pairing;
factor *= gamma;
}
}

auto right_side_pairing = algebra::pair_reduced<typename KZGScheme::curve_type>(
proof.kzg_proof,
commit_g2(this->get_V(this->_merged_points))
);

return left_side_accum == right_side_pairing;
}

const params_type& get_commitment_params() const {
return _params;
}

};
} // namespace commitments
} // namespace zk
} // namespace crypto3
Expand Down
Loading

0 comments on commit c7fc15a

Please sign in to comment.