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
8pub mod boolean;
9pub mod uint8;
10#[macro_use]
11pub mod uint;
12
13make_uint!(UInt16, 16, u16, uint16);
14make_uint!(UInt32, 32, u32, uint32);
15make_uint!(UInt64, 64, u64, uint64);
16
17pub trait ToBitsGadget<F: Field> {
18 /// Outputs the canonical little-endian bit-wise representation of `self`.
19 ///
20 /// This is the correct default for 99% of use cases.
21 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError>;
22
23 /// Outputs a possibly non-unique bit-wise representation of `self`.
24 ///
25 /// If you're not absolutely certain that your usecase can get away with a
26 /// non-canonical representation, please use `self.to_bits(cs)` instead.
27 fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
28 self.to_bits_le()
29 }
30}
31
32impl<F: Field> ToBitsGadget<F> for Boolean<F> {
33 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
34 Ok(vec![self.clone()])
35 }
36}
37
38impl<F: Field> ToBitsGadget<F> for [Boolean<F>] {
39 /// Outputs `self`.
40 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
41 Ok(self.to_vec())
42 }
43}
44
45impl<F: Field> ToBitsGadget<F> for UInt8<F> {
46 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
47 Ok(self.bits.to_vec())
48 }
49}
50
51impl<F: Field> ToBitsGadget<F> for [UInt8<F>] {
52 /// Interprets `self` as an integer, and outputs the little-endian
53 /// bit-wise decomposition of that integer.
54 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
55 let bits = self.iter().flat_map(|b| &b.bits).cloned().collect();
56 Ok(bits)
57 }
58}
59
60impl<F: Field, T> ToBitsGadget<F> for Vec<T>
61where
62 [T]: ToBitsGadget<F>,
63{
64 fn to_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
65 self.as_slice().to_bits_le().map(|v| v.to_vec())
66 }
67
68 fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
69 self.as_slice().to_non_unique_bits_le().map(|v| v.to_vec())
70 }
71}
72
73pub trait ToBytesGadget<F: Field> {
74 /// Outputs a canonical, little-endian, byte decomposition of `self`.
75 ///
76 /// This is the correct default for 99% of use cases.
77 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
78
79 /// Outputs a possibly non-unique byte decomposition of `self`.
80 ///
81 /// If you're not absolutely certain that your usecase can get away with a
82 /// non-canonical representation, please use `self.to_bytes(cs)` instead.
83 fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
84 self.to_bytes()
85 }
86}
87
88impl<F: Field> ToBytesGadget<F> for [UInt8<F>] {
89 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
90 Ok(self.to_vec())
91 }
92}
93
94impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
95 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
96 (*self).to_bytes()
97 }
98}
99
100impl<'a, F: Field> ToBytesGadget<F> for &'a [UInt8<F>] {
101 fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
102 Ok(self.to_vec())
103 }
104}