Skip to content

Commit

Permalink
Change BigInt::{to_bits, from_bytes} to have big endian/ little endia…
Browse files Browse the repository at this point in the history
…n variants, and add to_bytes_{be,le} (arkworks-rs#166)

* Add to_bytes to bigint

* Switch to *_be, *_le API

Co-authored-by: Pratyush Mishra <[email protected]>
  • Loading branch information
ValarDragon and Pratyush authored Jan 7, 2021
1 parent 210f35b commit 33508d6
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The main features of this release are:
a default value.
Downstream users other than `ark-curves` should not see breakage unless they rely on these methods/traits explicitly.
- #165 (ark-ff) Add `from_base_field_elements` as a method to the `Field` trait.
- #166 (ark-ff) Change `BigInt::{from_bytes, to_bits}` to `from_bytes_le, from_bytes_be, to_bits_le, to_bits_be`.

### Features
- #20 (ark-poly) Add structs/traits for multivariate polynomials
Expand Down Expand Up @@ -69,6 +70,7 @@ The main features of this release are:
- #153 (ark-serialize) Add an impl of `CanonicalSerialize/Deserialize` for `Rc<T>`.
- #157 (ark-ec) Speed up `variable_base_msm` by not relying on unnecessary normalization.
- #158 (ark-serialize) Add an impl of `CanonicalSerialize/Deserialize` for `()`.
- #166 (ark-ff) Add a `to_bytes_be()` and `to_bytes_le` methods to `BigInt`.

### Bug fixes
- #36 (ark-ec) In Short-Weierstrass curves, include an infinity bit in `ToConstraintField`.
Expand Down
3 changes: 1 addition & 2 deletions ec/src/msm/fixed_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ impl FixedBaseMSM {
scalar: &T::ScalarField,
) -> T {
let modulus_size = <T::ScalarField as PrimeField>::Params::MODULUS_BITS as usize;
let mut scalar_val = scalar.into_repr().to_bits();
scalar_val.reverse();
let scalar_val = scalar.into_repr().to_bits_le();

let mut res = multiples_of_g[0][0].into_projective();
for outer in 0..outerc {
Expand Down
34 changes: 29 additions & 5 deletions ff/src/biginteger/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ macro_rules! bigint_impl {
}

#[inline]
fn from_bits(bits: &[bool]) -> Self {
fn from_bits_be(bits: &[bool]) -> Self {
let mut res = Self::default();
let mut acc: u64 = 0;

Expand All @@ -166,11 +166,35 @@ macro_rules! bigint_impl {
res
}

fn from_bits_le(bits: &[bool]) -> Self {
let mut res = Self::default();
let mut acc: u64 = 0;

let bits = bits.to_vec();
for (i, bits64) in bits.chunks(64).enumerate() {
for bit in bits64.iter().rev() {
acc <<= 1;
acc += *bit as u64;
}
res.0[i] = acc;
acc = 0;
}
res
}

#[inline]
fn to_bytes_be(&self) -> Vec<u8> {
let mut le_bytes = self.to_bytes_le();
le_bytes.reverse();
le_bytes
}

#[inline]
fn to_bits(&self) -> Vec<bool> {
let mut res = Vec::with_capacity(256);
for b in BitIteratorBE::new(self.0) {
res.push(b);
fn to_bytes_le(&self) -> Vec<u8> {
let array_map = self.0.iter().map(|limb| limb.to_le_bytes());
let mut res = Vec::<u8>::with_capacity($num_limbs * 8);
for limb in array_map {
res.extend_from_slice(&limb);
}
res
}
Expand Down
30 changes: 25 additions & 5 deletions ff/src/biginteger/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
bytes::{FromBytes, ToBytes},
fields::BitIteratorBE,
fields::{BitIteratorBE, BitIteratorLE},
UniformRand,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
Expand Down Expand Up @@ -96,11 +96,31 @@ pub trait BigInteger:

/// Returns the big integer representation of a given big endian boolean
/// array.
fn from_bits(bits: &[bool]) -> Self;
fn from_bits_be(bits: &[bool]) -> Self;

/// Returns the bit representation in a big endian boolean array, without
/// leading zeros.
fn to_bits(&self) -> Vec<bool>;
/// Returns the big integer representation of a given little endian boolean
/// array.
fn from_bits_le(bits: &[bool]) -> Self;

/// Returns the bit representation in a big endian boolean array,
/// with leading zeroes.
fn to_bits_be(&self) -> Vec<bool> {
BitIteratorBE::new(self).collect::<Vec<_>>()
}

/// Returns the bit representation in a little endian boolean array,
/// with trailing zeroes.
fn to_bits_le(&self) -> Vec<bool> {
BitIteratorLE::new(self).collect::<Vec<_>>()
}

/// Returns the byte representation in a big endian byte array,
/// with leading zeros.
fn to_bytes_be(&self) -> Vec<u8>;

/// Returns the byte representation in a little endian byte array,
/// with trailing zeros.
fn to_bytes_le(&self) -> Vec<u8>;

/// Returns a vector for wnaf.
fn find_wnaf(&self) -> Vec<i64>;
Expand Down

0 comments on commit 33508d6

Please sign in to comment.