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::{ConstraintSystem, SynthesisError};
7
8pub mod boolean;
9pub mod uint32;
10pub mod uint64;
11pub mod uint8;
12
13pub trait ToBitsGadget<ConstraintF: Field> {
14 /// Outputs the canonical bit-wise representation of `self`.
15 ///
16 /// This is the correct default for 99% of use cases.
17 fn to_bits<CS: ConstraintSystem<ConstraintF>>(
18 &self,
19 cs: CS,
20 ) -> Result<Vec<Boolean>, SynthesisError>;
21
22 /// Outputs a possibly non-unique bit-wise representation of `self`.
23 ///
24 /// If you're not absolutely certain that your usecase can get away with a
25 /// non-canonical representation, please use `self.to_bits(cs)` instead.
26 fn to_non_unique_bits<CS: ConstraintSystem<ConstraintF>>(
27 &self,
28 cs: CS,
29 ) -> Result<Vec<Boolean>, SynthesisError> {
30 self.to_bits(cs)
31 }
32}
33
34impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for Boolean {
35 fn to_bits<CS: ConstraintSystem<ConstraintF>>(
36 &self,
37 _: CS,
38 ) -> Result<Vec<Boolean>, SynthesisError> {
39 Ok(vec![self.clone()])
40 }
41}
42
43impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for [Boolean] {
44 fn to_bits<CS: ConstraintSystem<ConstraintF>>(
45 &self,
46 _cs: CS,
47 ) -> Result<Vec<Boolean>, SynthesisError> {
48 Ok(self.to_vec())
49 }
50}
51
52impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for Vec<Boolean> {
53 fn to_bits<CS: ConstraintSystem<ConstraintF>>(
54 &self,
55 _cs: CS,
56 ) -> Result<Vec<Boolean>, SynthesisError> {
57 Ok(self.clone())
58 }
59}
60
61impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for [UInt8] {
62 fn to_bits<CS: ConstraintSystem<ConstraintF>>(
63 &self,
64 _cs: CS,
65 ) -> Result<Vec<Boolean>, SynthesisError> {
66 let mut result = Vec::with_capacity(&self.len() * 8);
67 for byte in self {
68 result.extend_from_slice(&byte.into_bits_le());
69 }
70 Ok(result)
71 }
72}
73
74pub trait ToBytesGadget<ConstraintF: Field> {
75 /// Outputs a canonical byte-wise representation of `self`.
76 ///
77 /// This is the correct default for 99% of use cases.
78 fn to_bytes<CS: ConstraintSystem<ConstraintF>>(
79 &self,
80 cs: CS,
81 ) -> Result<Vec<UInt8>, SynthesisError>;
82
83 /// Outputs a possibly non-unique byte decomposition of `self`.
84 ///
85 /// If you're not absolutely certain that your usecase can get away with a
86 /// non-canonical representation, please use `self.to_bytes(cs)` instead.
87 fn to_non_unique_bytes<CS: ConstraintSystem<ConstraintF>>(
88 &self,
89 cs: CS,
90 ) -> Result<Vec<UInt8>, SynthesisError> {
91 self.to_bytes(cs)
92 }
93}
94
95impl<ConstraintF: Field> ToBytesGadget<ConstraintF> for [UInt8] {
96 fn to_bytes<CS: ConstraintSystem<ConstraintF>>(
97 &self,
98 _cs: CS,
99 ) -> Result<Vec<UInt8>, SynthesisError> {
100 Ok(self.to_vec())
101 }
102}
103
104impl<'a, ConstraintF: Field, T: 'a + ToBytesGadget<ConstraintF>> ToBytesGadget<ConstraintF>
105 for &'a T
106{
107 fn to_bytes<CS: ConstraintSystem<ConstraintF>>(
108 &self,
109 cs: CS,
110 ) -> Result<Vec<UInt8>, SynthesisError> {
111 (*self).to_bytes(cs)
112 }
113}
114
115impl<'a, ConstraintF: Field> ToBytesGadget<ConstraintF> for &'a [UInt8] {
116 fn to_bytes<CS: ConstraintSystem<ConstraintF>>(
117 &self,
118 _cs: CS,
119 ) -> Result<Vec<UInt8>, SynthesisError> {
120 Ok(self.to_vec())
121 }
122}