github.com/ledgerwatch/erigon-lib@v1.0.0/pedersen_hash/pedersen_hash.cc (about)

     1  #include "pedersen_hash.h"
     2  
     3  #include <vector>
     4  
     5  #include "elliptic_curve.h"
     6  #include "fraction_field_element.h"
     7  #include "elliptic_curve_constants.h"
     8  #include "error_handling.h"
     9  
    10  namespace starkware {
    11  
    12  namespace {
    13  
    14  EcPoint<FractionFieldElement<PrimeFieldElement>> EcSubsetSumHash(
    15      const EcPoint<FractionFieldElement<PrimeFieldElement>>& shift_point,
    16      gsl::span<const EcPoint<PrimeFieldElement>> points, const PrimeFieldElement& selector_value) {
    17    using FractionFieldElementT = FractionFieldElement<PrimeFieldElement>;
    18    const auto selector_value_as_big_int = selector_value.ToStandardForm();
    19    const std::vector<bool> selector_bits = selector_value_as_big_int.ToBoolVector();
    20    ASSERT(points.size() <= selector_bits.size(), "Too many points.");
    21  
    22    auto partial_sum = shift_point;
    23    for (size_t j = 0; j < points.size(); j++) {
    24      const auto point = points[j].template ConvertTo<FractionFieldElementT>();
    25      ASSERT(partial_sum.x != point.x, "Adding a point to itself or to its inverse point.");
    26      if (selector_bits[j]) {
    27        partial_sum = partial_sum + point;
    28      }
    29    }
    30    for (size_t j = points.size(); j < selector_bits.size(); j++) {
    31      ASSERT(selector_bits[j] == 0, "Given selector is too big.");
    32    }
    33    return partial_sum;
    34  }
    35  
    36  }  // namespace
    37  
    38  PrimeFieldElement PedersenHash(const PrimeFieldElement& x, const PrimeFieldElement& y) {
    39    const size_t n_element_bits = 252;
    40    const auto& consts = GetEcConstants();
    41    const auto& shift_point = consts.k_points[0];
    42    const auto points_span = gsl::make_span(consts.k_points).subspan(2);
    43  
    44    auto cur_sum = shift_point.template ConvertTo<FractionFieldElement<PrimeFieldElement>>();
    45    cur_sum = EcSubsetSumHash(cur_sum, points_span.subspan(0, n_element_bits), x);
    46    cur_sum = EcSubsetSumHash(cur_sum, points_span.subspan(n_element_bits, n_element_bits), y);
    47  
    48    const EcPoint<PrimeFieldElement> res = cur_sum.template ConvertTo<PrimeFieldElement>();
    49    return res.x;
    50  }
    51  
    52  }  // namespace starkware