barretenberg
Loading...
Searching...
No Matches
uint.hpp
1#pragma once
2#include "../../bool/bool.hpp"
3#include "../../byte_array/byte_array.hpp"
4#include "../../circuit_builders/circuit_builders_fwd.hpp"
5#include "../../field/field.hpp"
6#include "../../plookup/plookup.hpp"
7
8namespace proof_system::plonk {
9namespace stdlib {
10
11template <typename Builder, typename Native> class uint_plookup {
12 public:
13 using FF = typename Builder::FF;
14 static constexpr size_t width = sizeof(Native) * 8;
15
16 uint_plookup(const witness_t<Builder>& other);
17 uint_plookup(const field_t<Builder>& other);
18 uint_plookup(const uint256_t& value = 0);
19 uint_plookup(Builder* builder, const uint256_t& value = 0);
21 uint_plookup(Builder* parent_context, const std::vector<bool_t<Builder>>& wires);
22 uint_plookup(Builder* parent_context, const std::array<bool_t<Builder>, width>& wires);
23
24 uint_plookup(const Native v)
25 : uint_plookup(static_cast<uint256_t>(v))
26 {}
27
28 std::vector<uint32_t> constrain_accumulators(Builder* ctx, const uint32_t witness_index) const;
29
30 static constexpr size_t bits_per_limb = 12;
31 static constexpr size_t num_accumulators() { return (width + bits_per_limb - 1) / bits_per_limb; }
32
33 uint_plookup(const uint_plookup& other);
35
36 uint_plookup& operator=(const uint_plookup& other);
37 uint_plookup& operator=(uint_plookup&& other);
38
39 explicit operator byte_array<Builder>() const;
40 explicit operator field_t<Builder>() const;
41
42 uint_plookup operator+(const uint_plookup& other) const;
43 uint_plookup operator-(const uint_plookup& other) const;
44 uint_plookup operator*(const uint_plookup& other) const;
45 uint_plookup operator/(const uint_plookup& other) const;
46 uint_plookup operator%(const uint_plookup& other) const;
47
48 uint_plookup operator&(const uint_plookup& other) const;
49 uint_plookup operator^(const uint_plookup& other) const;
50 uint_plookup operator|(const uint_plookup& other) const;
51 uint_plookup operator~() const;
52
53 uint_plookup operator>>(const size_t shift) const;
54 uint_plookup operator<<(const size_t shift) const;
55
56 uint_plookup ror(const size_t target_rotation) const;
57 uint_plookup rol(const size_t target_rotation) const;
58 uint_plookup ror(const uint256_t target_rotation) const
59 {
60 return ror(static_cast<size_t>(target_rotation.data[0]));
61 }
62 uint_plookup rol(const uint256_t target_rotation) const
63 {
64 return rol(static_cast<size_t>(target_rotation.data[0]));
65 }
66
67 bool_t<Builder> operator>(const uint_plookup& other) const;
68 bool_t<Builder> operator<(const uint_plookup& other) const;
69 bool_t<Builder> operator>=(const uint_plookup& other) const;
70 bool_t<Builder> operator<=(const uint_plookup& other) const;
71 bool_t<Builder> operator==(const uint_plookup& other) const;
72 bool_t<Builder> operator!=(const uint_plookup& other) const;
73 bool_t<Builder> operator!() const;
74
75 uint_plookup operator+=(const uint_plookup& other)
76 {
77 *this = operator+(other);
78 return *this;
79 }
80 uint_plookup operator-=(const uint_plookup& other)
81 {
82 *this = operator-(other);
83 return *this;
84 }
85 uint_plookup operator*=(const uint_plookup& other)
86 {
87 *this = operator*(other);
88 return *this;
89 }
90 uint_plookup operator/=(const uint_plookup& other)
91 {
92 *this = operator/(other);
93 return *this;
94 }
95 uint_plookup operator%=(const uint_plookup& other)
96 {
97 *this = operator%(other);
98 return *this;
99 }
100
101 uint_plookup operator&=(const uint_plookup& other)
102 {
103 *this = operator&(other);
104 return *this;
105 }
106 uint_plookup operator^=(const uint_plookup& other)
107 {
108 *this = operator^(other);
109 return *this;
110 }
111 uint_plookup operator|=(const uint_plookup& other)
112 {
113 *this = operator|(other);
114 return *this;
115 }
116
117 uint_plookup operator>>=(const size_t shift)
118 {
119 *this = operator>>(shift);
120 return *this;
121 }
122 uint_plookup operator<<=(const size_t shift)
123 {
124 *this = operator<<(shift);
125 return *this;
126 }
127
128 uint_plookup normalize() const;
129
130 uint256_t get_value() const;
131
132 bool is_constant() const { return witness_index == IS_CONSTANT; }
133 Builder* get_context() const { return context; }
134
135 bool_t<Builder> at(const size_t bit_index) const;
136
137 size_t get_width() const { return width; }
138
139 uint32_t get_witness_index() const { return witness_index; }
140
141 uint256_t get_additive_constant() const { return additive_constant; }
142
143 std::vector<uint32_t> get_accumulators() const { return accumulators; }
144 uint256_t get_unbounded_value() const;
145
146 protected:
147 Builder* context;
148
149 enum WitnessStatus { OK, NOT_NORMALIZED, WEAK_NORMALIZED };
150
151 mutable uint256_t additive_constant;
152 mutable WitnessStatus witness_status;
153
154 // N.B. Not an accumulator! Contains 6-bit slices of input
155 mutable std::vector<uint32_t> accumulators;
156 mutable uint32_t witness_index;
157
158 static constexpr uint256_t CIRCUIT_UINT_MAX_PLUS_ONE = (uint256_t(1) << width);
159 static constexpr uint256_t MASK = CIRCUIT_UINT_MAX_PLUS_ONE - 1;
160
161 private:
162 enum LogicOp {
163 AND,
164 XOR,
165 };
166
167 std::pair<uint_plookup, uint_plookup> divmod(const uint_plookup& other) const;
168 uint_plookup logic_operator(const uint_plookup& other, const LogicOp op_type) const;
169};
170
171template <typename T, typename w> inline std::ostream& operator<<(std::ostream& os, uint_plookup<T, w> const& v)
172{
173 return os << v.get_value();
174}
175
176EXTERN_STDLIB_ULTRA_TYPE_VA(uint_plookup, uint8_t);
177EXTERN_STDLIB_ULTRA_TYPE_VA(uint_plookup, uint16_t);
178EXTERN_STDLIB_ULTRA_TYPE_VA(uint_plookup, uint32_t);
179EXTERN_STDLIB_ULTRA_TYPE_VA(uint_plookup, uint64_t);
180
181} // namespace stdlib
182} // namespace proof_system::plonk
Definition: uint256.hpp:25
Definition: standard_circuit_builder.hpp:12
Definition: byte_array.hpp:9
Definition: field.hpp:10
bool_t< Builder > operator>(const uint_plookup &other) const
Definition: comparison.cpp:10
Definition: witness.hpp:10
Definition: widget.bench.cpp:13