|
barretenberg
|
Public Types | |
| typedef std::vector< field_t< Builder > > | bytes_t |
Public Member Functions | |
| byte_array (Builder *parent_context=nullptr) | |
| byte_array (Builder *parent_context, size_t const n) | |
| byte_array (Builder *parent_context, std::string const &input) | |
| byte_array (Builder *parent_context, std::vector< uint8_t > const &input) | |
| Create a byte array out of a vector of uint8_t bytes. | |
| byte_array (Builder *parent_context, bytes_t const &input) | |
| byte_array (Builder *parent_context, bytes_t &&input) | |
| byte_array (const field_t< Builder > &input, const size_t num_bytes=32) | |
| Create a byte_array out of a field element. | |
| byte_array (const safe_uint_t< Builder > &input, const size_t num_bytes=32) | |
| template<typename ItBegin , typename ItEnd > | |
| byte_array (Builder *parent_context, ItBegin const &begin, ItEnd const &end) | |
| byte_array (const byte_array &other) | |
| byte_array (byte_array &&other) | |
| byte_array & | operator= (const byte_array &other) |
| byte_array & | operator= (byte_array &&other) |
| operator field_t< Builder > () const | |
| Convert a byte array into a field element. | |
| field_t< Builder > | operator[] (const size_t index) const |
| byte_array & | write (byte_array const &other) |
| byte_array & | write_at (byte_array const &other, size_t index) |
| byte_array | slice (size_t offset) const |
| byte_array | slice (size_t offset, size_t length) const |
Slice length bytes from the byte array, starting at offset. Does not add any constraints. | |
| byte_array | reverse () const |
| Reverse the bytes in the byte array. | |
| size_t | size () const |
| bytes_t const & | bytes () const |
| bool_t< Builder > | get_bit (size_t index) const |
| Extract a bit from the byte array. | |
| void | set_bit (size_t index, bool_t< Builder > const &value) |
| Set a bit in the byte array. | |
| void | set_byte (size_t index, const field_t< Builder > &byte_val) |
| void | set_context (Builder *ctx) |
| Builder * | get_context () const |
| std::vector< uint8_t > | get_value () const |
| std::string | get_string () const |
| proof_system::plonk::stdlib::byte_array< Builder >::byte_array | ( | Builder * | parent_context, |
| std::vector< uint8_t > const & | input | ||
| ) |
Create a byte array out of a vector of uint8_t bytes.
| proof_system::plonk::stdlib::byte_array< Builder >::byte_array | ( | const field_t< Builder > & | input, |
| const size_t | num_bytes = 32 |
||
| ) |
Create a byte_array out of a field element.
The length of the byte array will default to 32 bytes, but shorter lengths can be specified. If a shorter length is used, the circuit will NOT truncate the input to fit the reduced length. Instead, the circuit adds constraints that VALIDATE the input is smaller than the specified length
e.g. if this constructor is used on a 16-bit input witness, where num_bytes is 1, the resulting proof will fail.
Our field element is input. Say the byte vector provided by the prover consists of bits b0,...,b255. These bits are used to construct the corresponding uint256_t validator := \sum_{i=0}^{8num_bytes-1} 2^{i}b_{i}, and validator is copy constrained to be equal to input. However, more constraints are needed in general.
Let r = barretenberg::fr::modulus. For later applications, we want to ensure that the prover must pass the bit decomposition of the standard representative of the mod r residue class containing input, which is to say that we want to show validator lies in [0, ..., r-1]. By the formula for validator, we do not have to worry about it wrapping the modulus if num_bytes < 32 or, in the default case, if the input fits into 31 bytes.
Suppose now that num_bytes is 32. We would like to show that r - validator lies > 0 as integers, but this cannot be done inside of uint256_t since validator can be any uint256_t, hence its negative is not constrained to lie in any proper subset. We therefore split it and r-1 into two smaller limbs and make comparisons using range constraints in uint256_t (shifting r to turn a > into a >=).
By the construction of validator, it is easy to extract its top 16 bytes shifted_high_limb = 2^{128}v_hi, so that one gets a decomposition by computing v_lo := validator - 2^{128}v_hi. We separate the problem of imposing that validator <= r - 1 into two cases.
Case 0: When s_lo < v_lo, we must impose that v_hi < s_hi, i.e., s_hi - v_hi - 1 >= 0. Case 1: >= =< s_hi - v_hi >= 0.
To unify these cases, we need a predicate that distinguishes them, and we need to use this to effect a shift of 1 or 0 in v_hi, as the case may be. We build this now. Consider the expression s_lo - v_lo. As an integer, this lies in [-2^128+1, 2^128-1], with Case 0 corresponding to the numbers < 0. Shifting to y_lo := s_lo - v_lo + 2^128, Case 0 corresponds to the range [1, 2^128-1]. We see that the 129th bit of y_lo exactly indicates the case. Extracting this (and the 130th bit, which is always 0, for convenience) and adding it to v_hi, we have a uniform constraint to apply. Namely, setting y_overlap := 1 - (top quad of y_lo regarded as a 130-bit integer) and y_hi := s_hi - v_hi - y_overlap, range constrianing y_hi to 128 bits imposes validator < r.
| bool_t< Builder > proof_system::plonk::stdlib::byte_array< Builder >::get_bit | ( | size_t | index_reversed | ) | const |
Extract a bit from the byte array.
get_bit treats the array as a little-endian integer e.g. get_bit(1) corresponds to the second bit in the last, 'least significant' byte in the array.
|
explicit |
Convert a byte array into a field element.
The byte array is represented as a big integer, that is then converted into a field element. The transformation is only injective if the byte array is < 32 bytes. Larger byte arrays can still be cast to a single field element, but the value will wrap around the circuit modulus
| void proof_system::plonk::stdlib::byte_array< Builder >::set_bit | ( | size_t | index_reversed, |
| bool_t< Builder > const & | new_bit | ||
| ) |
Set a bit in the byte array.
set_bit treats the array as a little-endian integer e.g. set_bit(0) will set the first bit in the last, 'least significant' byte in the array
For example, if we have a 64-byte array filled with zeroes, set_bit(0, true) will set values[63] to 1, and set_bit(511, true) will set values[0] to 128
Previously we did not reverse the bit index, but we have modified the behavior to be consistent with get_bit
The rationale behind reversing the bit index is so that we can more naturally contain integers inside byte arrays and perform bit manipulation
| byte_array< Builder > proof_system::plonk::stdlib::byte_array< Builder >::slice | ( | size_t | offset, |
| size_t | length | ||
| ) | const |
Slice length bytes from the byte array, starting at offset. Does not add any constraints.
Note that the syntax here differs for the syntax used for slicing uint256_t's.