Skip to content

Commit a124995

Browse files
authored
Add back ToBytesGadget and ToBitsGadget to prelude (arkworks-rs#136)
1 parent d011859 commit a124995

26 files changed

+874
-231
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@
44

55
### Breaking changes
66

7+
- [\#121](https://github.com/arkworks-rs/r1cs-std/pull/121)
8+
- Refactor `UInt{8,16,64,128}` into one struct `UInt`.
9+
- Remove `bits` module.
10+
- Use `std::ops` traits for `UInt` and `Boolean`.
711
- [\#134](https://github.com/arkworks-rs/r1cs-std/pull/134) Add `Mul<NonnativeFieldVar>` bounds and impls for `CurveVar`.
812
- [\#135](https://github.com/arkworks-rs/r1cs-std/pull/135)
913
- Rename `NonNativeFieldVar` to `EmulatedFpVar`.
1014
- Rename `fields::nonnative` to `fields::emulated_fp`.
1115
- Rename `fields::nonnative::{Allocated}NonNativeMulResultVar` to `fields::emulated_fp::{Allocated}MulResultVar`.
16+
- [\#136](https://github.com/arkworks-rs/r1cs-std/pull/136)
17+
- Rename `ToBytesGadget::to_{non_unique_}bytes``ToBytesGadget::to_{non_unique_}bytes_in_le`.
1218

1319
### Features
1420

21+
- [\#136](https://github.com/arkworks-rs/r1cs-std/pull/136)
22+
- Add `{BitAnd,BitOr,BitXor,BitAndAssign,BitOrAssign,BitXorAssign}<T> for UInt<N, T, F>`.
23+
- Add `UInt::rotate_{left,right}_in_place`.
24+
- Add `{Boolean,UInt}::not_in_place`.
25+
- Add `UInt::{from_bytes_le, from_bytes_be, to_bytes_be}`.
26+
1527
### Improvements
1628

1729
### Bug Fixes

src/boolean/convert.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::convert::{ToBytesGadget, ToConstraintFieldGadget};
44
impl<F: Field> ToBytesGadget<F> for Boolean<F> {
55
/// Outputs `1u8` if `self` is true, and `0u8` otherwise.
66
#[tracing::instrument(target = "r1cs")]
7-
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
7+
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
88
let value = self.value().map(u8::from).ok();
99
let mut bits = [Boolean::FALSE; 8];
1010
bits[0] = self.clone();

src/boolean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ mod test {
215215
for val in [true, false].iter() {
216216
let cs = ConstraintSystem::<Fr>::new_ref();
217217
let a = Boolean::new_witness(cs.clone(), || Ok(*val))?;
218-
let bytes = a.to_bytes()?;
218+
let bytes = a.to_bytes_le()?;
219219
assert_eq!(bytes.len(), 1);
220220
let byte = &bytes[0];
221221
assert_eq!(byte.value()?, *val as u8);

src/boolean/not.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@ use super::Boolean;
66

77
impl<F: Field> Boolean<F> {
88
fn _not(&self) -> Result<Self, SynthesisError> {
9+
let mut result = self.clone();
10+
result.not_in_place()?;
11+
Ok(result)
12+
}
13+
14+
pub fn not_in_place(&mut self) -> Result<(), SynthesisError> {
915
match *self {
10-
Boolean::Constant(c) => Ok(Boolean::Constant(!c)),
11-
Boolean::Var(ref v) => Ok(Boolean::Var(v.not().unwrap())),
16+
Boolean::Constant(ref mut c) => *c = !*c,
17+
Boolean::Var(ref mut v) => *v = v.not()?,
1218
}
19+
Ok(())
1320
}
1421
}
1522

src/cmp.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use ark_ff::Field;
22
use ark_relations::r1cs::SynthesisError;
33

4-
use crate::boolean::Boolean;
4+
use crate::{boolean::Boolean, R1CSVar};
55

66
/// Specifies how to generate constraints for comparing two variables.
7-
pub trait CmpGadget<F: Field> {
7+
pub trait CmpGadget<F: Field>: R1CSVar<F> {
88
fn is_gt(&self, other: &Self) -> Result<Boolean<F>, SynthesisError> {
99
other.is_lt(self)
1010
}

src/convert.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,24 @@ pub trait ToBytesGadget<F: Field> {
6969
/// Outputs a canonical, little-endian, byte decomposition of `self`.
7070
///
7171
/// This is the correct default for 99% of use cases.
72-
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
72+
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError>;
7373

7474
/// Outputs a possibly non-unique byte decomposition of `self`.
7575
///
7676
/// If you're not absolutely certain that your usecase can get away with a
77-
/// non-canonical representation, please use `self.to_bytes(cs)` instead.
78-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
79-
self.to_bytes()
77+
/// non-canonical representation, please use `self.to_bytes_le(cs)` instead.
78+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
79+
self.to_bytes_le()
8080
}
8181
}
8282

8383
impl<'a, F: Field, T: 'a + ToBytesGadget<F>> ToBytesGadget<F> for &'a T {
84-
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
85-
(*self).to_bytes()
84+
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
85+
(*self).to_bytes_le()
86+
}
87+
88+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
89+
(*self).to_non_unique_bytes_le()
8690
}
8791
}
8892

src/fields/cubic_extension.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -435,21 +435,21 @@ where
435435
P: CubicExtVarConfig<BF>,
436436
{
437437
#[tracing::instrument(target = "r1cs")]
438-
fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
439-
let mut c0 = self.c0.to_bytes()?;
440-
let mut c1 = self.c1.to_bytes()?;
441-
let mut c2 = self.c2.to_bytes()?;
438+
fn to_bytes_le(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
439+
let mut c0 = self.c0.to_bytes_le()?;
440+
let mut c1 = self.c1.to_bytes_le()?;
441+
let mut c2 = self.c2.to_bytes_le()?;
442442
c0.append(&mut c1);
443443
c0.append(&mut c2);
444444

445445
Ok(c0)
446446
}
447447

448448
#[tracing::instrument(target = "r1cs")]
449-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
450-
let mut c0 = self.c0.to_non_unique_bytes()?;
451-
let mut c1 = self.c1.to_non_unique_bytes()?;
452-
let mut c2 = self.c2.to_non_unique_bytes()?;
449+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
450+
let mut c0 = self.c0.to_non_unique_bytes_le()?;
451+
let mut c1 = self.c1.to_non_unique_bytes_le()?;
452+
let mut c2 = self.c2.to_non_unique_bytes_le()?;
453453

454454
c0.append(&mut c1);
455455
c0.append(&mut c2);

src/fields/emulated_fp/allocated_field_var.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ impl<TargetF: PrimeField, BaseF: PrimeField> ToBytesGadget<BaseF>
681681
for AllocatedEmulatedFpVar<TargetF, BaseF>
682682
{
683683
#[tracing::instrument(target = "r1cs")]
684-
fn to_bytes(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
684+
fn to_bytes_le(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
685685
let mut bits = self.to_bits_le()?;
686686

687687
let num_bits = TargetF::BigInt::NUM_LIMBS * 64;

src/fields/emulated_fp/field_var.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -297,23 +297,23 @@ impl<TargetF: PrimeField, BaseF: PrimeField> ToBytesGadget<BaseF>
297297
/// Outputs the unique byte decomposition of `self` in *little-endian*
298298
/// form.
299299
#[tracing::instrument(target = "r1cs")]
300-
fn to_bytes(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
300+
fn to_bytes_le(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
301301
match self {
302302
Self::Constant(c) => Ok(UInt8::constant_vec(
303303
c.into_bigint().to_bytes_le().as_slice(),
304304
)),
305305

306-
Self::Var(v) => v.to_bytes(),
306+
Self::Var(v) => v.to_bytes_le(),
307307
}
308308
}
309309

310310
#[tracing::instrument(target = "r1cs")]
311-
fn to_non_unique_bytes(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
311+
fn to_non_unique_bytes_le(&self) -> R1CSResult<Vec<UInt8<BaseF>>> {
312312
match self {
313313
Self::Constant(c) => Ok(UInt8::constant_vec(
314314
c.into_bigint().to_bytes_le().as_slice(),
315315
)),
316-
Self::Var(v) => v.to_non_unique_bytes(),
316+
Self::Var(v) => v.to_non_unique_bytes_le(),
317317
}
318318
}
319319
}

src/fields/fp/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ impl<F: PrimeField> ToBytesGadget<F> for AllocatedFp<F> {
552552
/// This method enforces that the decomposition represents
553553
/// an integer that is less than `F::MODULUS`.
554554
#[tracing::instrument(target = "r1cs")]
555-
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
555+
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
556556
let num_bits = F::BigInt::NUM_LIMBS * 64;
557557
let mut bits = self.to_bits_le()?;
558558
let remainder = core::iter::repeat(Boolean::constant(false)).take(num_bits - bits.len());
@@ -565,7 +565,7 @@ impl<F: PrimeField> ToBytesGadget<F> for AllocatedFp<F> {
565565
}
566566

567567
#[tracing::instrument(target = "r1cs")]
568-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
568+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
569569
let num_bits = F::BigInt::NUM_LIMBS * 64;
570570
let mut bits = self.to_non_unique_bits_le()?;
571571
let remainder = core::iter::repeat(Boolean::constant(false)).take(num_bits - bits.len());
@@ -957,22 +957,22 @@ impl<F: PrimeField> ToBytesGadget<F> for FpVar<F> {
957957
/// Outputs the unique byte decomposition of `self` in *little-endian*
958958
/// form.
959959
#[tracing::instrument(target = "r1cs")]
960-
fn to_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
960+
fn to_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
961961
match self {
962962
Self::Constant(c) => Ok(UInt8::constant_vec(
963963
c.into_bigint().to_bytes_le().as_slice(),
964964
)),
965-
Self::Var(v) => v.to_bytes(),
965+
Self::Var(v) => v.to_bytes_le(),
966966
}
967967
}
968968

969969
#[tracing::instrument(target = "r1cs")]
970-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
970+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<F>>, SynthesisError> {
971971
match self {
972972
Self::Constant(c) => Ok(UInt8::constant_vec(
973973
c.into_bigint().to_bytes_le().as_slice(),
974974
)),
975-
Self::Var(v) => v.to_non_unique_bytes(),
975+
Self::Var(v) => v.to_non_unique_bytes_le(),
976976
}
977977
}
978978
}

src/fields/quadratic_extension.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -435,17 +435,17 @@ where
435435
P: QuadExtVarConfig<BF>,
436436
{
437437
#[tracing::instrument(target = "r1cs")]
438-
fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
439-
let mut c0 = self.c0.to_bytes()?;
440-
let mut c1 = self.c1.to_bytes()?;
438+
fn to_bytes_le(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
439+
let mut c0 = self.c0.to_bytes_le()?;
440+
let mut c1 = self.c1.to_bytes_le()?;
441441
c0.append(&mut c1);
442442
Ok(c0)
443443
}
444444

445445
#[tracing::instrument(target = "r1cs")]
446-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
447-
let mut c0 = self.c0.to_non_unique_bytes()?;
448-
let mut c1 = self.c1.to_non_unique_bytes()?;
446+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
447+
let mut c0 = self.c0.to_non_unique_bytes_le()?;
448+
let mut c1 = self.c1.to_non_unique_bytes_le()?;
449449
c0.append(&mut c1);
450450
Ok(c0)
451451
}

src/groups/curves/short_weierstrass/bls12/mod.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,20 @@ impl<P: Bls12Config> AllocVar<G1Prepared<P>, P::Fp> for G1PreparedVar<P> {
7979
impl<P: Bls12Config> ToBytesGadget<P::Fp> for G1PreparedVar<P> {
8080
#[inline]
8181
#[tracing::instrument(target = "r1cs")]
82-
fn to_bytes(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
83-
let mut bytes = self.0.x.to_bytes()?;
84-
let y_bytes = self.0.y.to_bytes()?;
85-
let inf_bytes = self.0.infinity.to_bytes()?;
82+
fn to_bytes_le(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
83+
let mut bytes = self.0.x.to_bytes_le()?;
84+
let y_bytes = self.0.y.to_bytes_le()?;
85+
let inf_bytes = self.0.infinity.to_bytes_le()?;
8686
bytes.extend_from_slice(&y_bytes);
8787
bytes.extend_from_slice(&inf_bytes);
8888
Ok(bytes)
8989
}
9090

9191
#[tracing::instrument(target = "r1cs")]
92-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
93-
let mut bytes = self.0.x.to_non_unique_bytes()?;
94-
let y_bytes = self.0.y.to_non_unique_bytes()?;
95-
let inf_bytes = self.0.infinity.to_non_unique_bytes()?;
92+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
93+
let mut bytes = self.0.x.to_non_unique_bytes_le()?;
94+
let y_bytes = self.0.y.to_non_unique_bytes_le()?;
95+
let inf_bytes = self.0.infinity.to_non_unique_bytes_le()?;
9696
bytes.extend_from_slice(&y_bytes);
9797
bytes.extend_from_slice(&inf_bytes);
9898
Ok(bytes)
@@ -174,21 +174,21 @@ impl<P: Bls12Config> AllocVar<G2Prepared<P>, P::Fp> for G2PreparedVar<P> {
174174
impl<P: Bls12Config> ToBytesGadget<P::Fp> for G2PreparedVar<P> {
175175
#[inline]
176176
#[tracing::instrument(target = "r1cs")]
177-
fn to_bytes(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
177+
fn to_bytes_le(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
178178
let mut bytes = Vec::new();
179179
for coeffs in &self.ell_coeffs {
180-
bytes.extend_from_slice(&coeffs.0.to_bytes()?);
181-
bytes.extend_from_slice(&coeffs.1.to_bytes()?);
180+
bytes.extend_from_slice(&coeffs.0.to_bytes_le()?);
181+
bytes.extend_from_slice(&coeffs.1.to_bytes_le()?);
182182
}
183183
Ok(bytes)
184184
}
185185

186186
#[tracing::instrument(target = "r1cs")]
187-
fn to_non_unique_bytes(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
187+
fn to_non_unique_bytes_le(&self) -> Result<Vec<UInt8<P::Fp>>, SynthesisError> {
188188
let mut bytes = Vec::new();
189189
for coeffs in &self.ell_coeffs {
190-
bytes.extend_from_slice(&coeffs.0.to_non_unique_bytes()?);
191-
bytes.extend_from_slice(&coeffs.1.to_non_unique_bytes()?);
190+
bytes.extend_from_slice(&coeffs.0.to_non_unique_bytes_le()?);
191+
bytes.extend_from_slice(&coeffs.1.to_non_unique_bytes_le()?);
192192
}
193193
Ok(bytes)
194194
}

0 commit comments

Comments
 (0)