sparse.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_ACCUMULATORS_ZK_SPARSE_HPP
27 #define CRYPTO3_ACCUMULATORS_ZK_SPARSE_HPP
28 
29 #include <boost/container/static_vector.hpp>
30 
31 #include <boost/parameter/value_type.hpp>
32 
33 #include <boost/accumulators/framework/accumulator_base.hpp>
34 #include <boost/accumulators/framework/extractor.hpp>
35 #include <boost/accumulators/framework/depends_on.hpp>
36 #include <boost/accumulators/framework/parameters/sample.hpp>
37 
39 
41 
42 namespace nil {
43  namespace crypto3 {
44  namespace accumulators {
45  namespace detail {
46  template<typename T>
47  struct sparse_impl : boost::accumulators::accumulator_base {
48  typedef typename T::value_type value_type;
49  typedef std::vector<std::size_t> indicies_type;
50 
51  typedef std::pair<value_type, std::pair<indicies_type, std::vector<T>>> result_type;
52 
53  template<typename Args>
54  sparse_impl(const Args &args) : in_block(false), accumulated_value(value_type::zero()) {
55  }
56 
57  template<typename ArgumentPack>
58  inline void operator()(const ArgumentPack &args) {
59  resolve_type(args[boost::accumulators::sample], args[::nil::crypto3::accumulators::offset]);
60  }
61 
62  inline result_type result(boost::accumulators::dont_care) const {
63  }
64 
65  protected:
66  template<typename SinglePassRange>
67  inline result_type resolve_type(const SinglePassRange r, std::size_t offset) {
68  const std::size_t chunks = 1;
69 
70  std::pair<indicies_type, std::vector<T>> resulting_vector;
71  resulting_vector.domain_size_ = domain_size_;
72 
73  const std::size_t range_len = r.size();
74  std::size_t first_pos = -1, last_pos = -1;
75  for (std::size_t i = 0; i < indices.size(); ++i) {
76  const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len);
77  bool copy_over;
78 
79  if (in_block) {
80  if (matching_pos && last_pos == i - 1) {
81  // block can be extended, do it
82  last_pos = i;
83  copy_over = false;
84  } else {
85  // block has ended here
86  in_block = false;
87  copy_over = true;
88 
91  algebra::multiexp<algebra::policies::multiexp_method_bos_coster>(
92  values.begin() + first_pos, values.begin() + last_pos + 1,
93  std::begin(r) + (indices[first_pos] - offset),
94  std::begin(r) + (indices[last_pos] - offset) + 1, chunks);
95  }
96  } else {
97  if (matching_pos) {
98  // block can be started
99  first_pos = i;
100  last_pos = i;
101  in_block = true;
102  copy_over = false;
103  } else {
104  copy_over = true;
105  }
106  }
107 
108  if (copy_over) {
109  resulting_vector.first.emplace_back(indices[i]);
110  resulting_vector.second.emplace_back(values[i]);
111  }
112  }
113 
114  if (in_block) {
116  accumulated_value + algebra::multiexp<algebra::policies::multiexp_method_bos_coster>(
117  values.begin() + first_pos,
118  values.begin() + last_pos + 1,
119  std::begin(r) + (indices[first_pos] - offset),
120  std::begin(r) + (indices[last_pos] - offset) + 1,
121  chunks);
122  }
123 
124  return std::make_pair(accumulated_value, resulting_vector);
125  }
126 
127  bool in_block;
128 
130 
132  std::vector<value_type> values;
133  std::size_t domain_size_;
134  };
135  } // namespace detail
136 
137  namespace tag {
138  template<typename T>
139  struct sparse : boost::accumulators::depends_on<> {
140  typedef T value_type;
141 
144 
145  typedef boost::mpl::always<accumulators::detail::sparse_impl<value_type>> impl;
146  };
147  } // namespace tag
148 
149  namespace extract {
150  template<typename Mode, typename AccumulatorSet>
151  typename boost::mpl::apply<AccumulatorSet, tag::sparse<Mode>>::type::result_type
152  sparse(const AccumulatorSet &acc) {
153  return boost::accumulators::extract_result<tag::sparse<Mode>>(acc);
154  }
155  } // namespace extract
156  } // namespace accumulators
157  } // namespace crypto3
158 } // namespace nil
159 
160 #endif // CRYPTO3_ACCUMULATORS_SNARK_HPP
boost::mpl::apply< AccumulatorSet, tag::sparse< Mode > >::type::result_type sparse(const AccumulatorSet &acc)
Definition: sparse.hpp:152
Definition: pair.hpp:31
bool in_block
Definition: sparse.hpp:127
result_type result(boost::accumulators::dont_care) const
Definition: sparse.hpp:62
T::value_type value_type
Definition: sparse.hpp:48
std::pair< value_type, std::pair< indicies_type, std::vector< T > > > result_type
Definition: sparse.hpp:51
std::vector< std::size_t > indicies_type
Definition: sparse.hpp:49
indicies_type indices
Definition: sparse.hpp:131
sparse_impl(const Args &args)
Definition: sparse.hpp:54
void operator()(const ArgumentPack &args)
Definition: sparse.hpp:58
value_type accumulated_value
Definition: sparse.hpp:129
result_type resolve_type(const SinglePassRange r, std::size_t offset)
Definition: sparse.hpp:67
std::size_t domain_size_
Definition: sparse.hpp:133
std::vector< value_type > values
Definition: sparse.hpp:132
Definition: sparse.hpp:139
T value_type
Definition: sparse.hpp:140
boost::mpl::always< accumulators::detail::sparse_impl< value_type > > impl
Definition: sparse.hpp:145