ark-r1cs-std/r1cs-std/src/bits/mod.rs
r1cs-std/src/bits/mod.rsRaw
1use crate::{
2 bits::{boolean::Boolean, uint8::UInt8},
3 Vec,
4};
5use algebra::Field;
6use r1cs_core::SynthesisError;
7
8/// This module contains `Boolean`, a R1CS equivalent of the `bool` type.
9pub mod boolean;
10/// This module contains `UInt8`, a R1CS equivalent of the `u8` type.
11pub mod uint8;
12/// This module contains a macro for generating `UIntN` types, which are R1CS equivalents of
13/// `N`-bit unsigned integers.
14#[macro_use]
15pub mod uint;
16
17make_uint!(UInt16, 16, u16, uint16, "16");
18make_uint!(UInt32, 32, u32, uint32, "32");
19make_uint!(UInt64, 64, u64, uint64, "64");
20
21/// Specifies constraints for conversion to a little-endian bit representation of `self`.
22pub trait ToBitsGadget<F: Field> {
23 /// Outputs the canonical little-endian bit-wise representation of `self`.
24 ///
25 /// This is the correct default for 99% of use cases.
26 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
27
28 /// Outputs a possibly non-unique little-endian bit-wise representation of `self`.
29 ///
30 /// If you're not absolutely certain that your usecase can get away with a
31 /// non-canonical representation, please use `self.to_bits()` instead.
32 fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
33 self.to_bits_le()
34 }
35
36 /// Outputs the canonical big-endian bit-wise representation of `self`.
37 fn to_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
38 let mut res = self.to_bits_le()?;
39 res.reverse();
40 Ok(res)
41 }
42
43 /// Outputs a possibly non-unique big-endian bit-wise representation of `self`.
44 fn to_non_unique_bits_be(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
45 let mut res = self.to_non_unique_bits_le()?;
46 res.reverse();
47 Ok(res)
48 }
49}
50
51impl<F: Field> ToBitsGadget<F> for Boolean<F> {
52 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
53 Ok(vec![self.clone()])
54 }
55}
56
57impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
58 /// Outputs `self`.
59 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
60 Ok(self.to_vec())
61 }
62}
63
64impl<F: Field> ToBitsGadget<F> for UInt8<F> {
65 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
66 Ok(self.bits.to_vec())
67 }
68}
69
70impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
71 /// Interprets `self` as an integer, and outputs the little-endian
72 /// bit-wise decomposition of that integer.
73 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
74 let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
75 Ok(bits)
76 }
77}
78
79impl<F: Field, T> ToBitsGadget<F> for Vec<T>
80where
81 [T]: ToBitsGadget<F>,
82{
83 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
84 self.as_slice().to_bits_le().map(|v| v.to_vec())
85 }
86
87 fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
88 self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
89 }
90}
91
92/// Specifies constraints for conversion to a little-endian byte representation of `self`.
93pub trait ToBytesGadget<F: Field> {
94 /// Outputs a canonical, little-endian, byte decomposition of `self`.
95 ///
96 /// This is the correct default for 99% of use cases.
97 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
98
99 /// Outputs a possibly non-unique byte decomposition of `self`.
100 ///
101 /// If you're not absolutely certain that your usecase can get away with a
102 /// non-canonical representation, please use `self.to_bytes(cs)` instead.
103 fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
104 self.to_bytes()
105 }
106}
107
108impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
109 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
110 Ok(self.to_vec())
111 }
112}
113
114impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
115 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
116 (*self).to_bytes()
117 }
118}
119
120impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
121 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
122 Ok(self.to_vec())
123 }
124}