Skip to content

Commit

Permalink
Add support for hex, octal, and binary input in BigInt and MontFp
Browse files Browse the repository at this point in the history
… macros (arkworks-rs#635)

* Add support for hex, octal, and binary input in `BigInt` and `MontFp` macros

* Fix re-exports

* Format
  • Loading branch information
Pratyush authored and mmagician committed Nov 3, 2023
1 parent 6f309fa commit f853bda
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 28 deletions.
8 changes: 4 additions & 4 deletions ec/src/hashing/map_to_curve_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ where
})
}

// Produce a hash of the message, using the hash to field and map to curve
// traits. This uses the IETF hash to curve's specification for Random
// oracle encoding (hash_to_curve) defined by combining these components.
// See https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-3
/// Produce a hash of the message, using the hash to field and map to curve
/// traits. This uses the IETF hash to curve's specification for Random
/// oracle encoding (hash_to_curve) defined by combining these components.
/// See <https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-3>
fn hash(&self, msg: &[u8]) -> Result<T::Affine, HashToCurveError> {
// IETF spec of hash_to_curve, from hash_to_field and map_to_curve
// sub-components
Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/bls12/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub type G2Projective<P> = Projective<<P as Bls12Config>::G2Config>;
Eq(bound = "P: Bls12Config")
)]
pub struct G2Prepared<P: Bls12Config> {
// Stores the coefficients of the line evaluations as calculated in
// https://eprint.iacr.org/2013/722.pdf
/// Stores the coefficients of the line evaluations as calculated in
/// <https://eprint.iacr.org/2013/722.pdf>
pub ell_coeffs: Vec<EllCoeff<P>>,
pub infinity: bool,
}
Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/bn/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub type G2Projective<P> = Projective<<P as BnConfig>::G2Config>;
Eq(bound = "P: BnConfig")
)]
pub struct G2Prepared<P: BnConfig> {
// Stores the coefficients of the line evaluations as calculated in
// https://eprint.iacr.org/2013/722.pdf
/// Stores the coefficients of the line evaluations as calculated in
/// <https://eprint.iacr.org/2013/722.pdf>
pub ell_coeffs: Vec<EllCoeff<P>>,
pub infinity: bool,
}
Expand Down
7 changes: 4 additions & 3 deletions ec/src/models/bw6/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ pub type G2Projective<P> = Projective<<P as BW6Config>::G2Config>;
Eq(bound = "P: BW6Config")
)]
pub struct G2Prepared<P: BW6Config> {
// Stores the coefficients of the line evaluations as calculated in
// https://eprint.iacr.org/2013/722.pdf
/// Stores the coefficients of the line evaluations as calculated in
/// <https://eprint.iacr.org/2013/722.pdf>
pub ell_coeffs_1: Vec<(P::Fp, P::Fp, P::Fp)>,
pub ell_coeffs_2: Vec<(P::Fp, P::Fp, P::Fp)>,
pub infinity: bool,
Expand Down Expand Up @@ -127,7 +127,8 @@ impl<P: BW6Config> G2Prepared<P> {
impl<P: BW6Config> G2HomProjective<P> {
fn double_in_place(&mut self) -> (P::Fp, P::Fp, P::Fp) {
// Formula for line function when working with
// homogeneous projective coordinates, as described in https://eprint.iacr.org/2013/722.pdf.
// homogeneous projective coordinates, as described in
// <https://eprint.iacr.org/2013/722.pdf>.

let a = self.x * &self.y;
let b = self.y.square();
Expand Down
2 changes: 1 addition & 1 deletion ec/src/models/short_weierstrass/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl<P: SWCurveConfig> Neg for Projective<P> {
}

impl<P: SWCurveConfig, T: Borrow<Affine<P>>> AddAssign<T> for Projective<P> {
/// Using http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
/// Using <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl>
fn add_assign(&mut self, other: T) {
let other = other.borrow();
if let Some((&other_x, &other_y)) = other.xy() {
Expand Down
41 changes: 41 additions & 0 deletions ff-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,47 @@ fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option<String> {

#[test]
fn test_str_to_limbs() {
use num_bigint::Sign::*;
for i in 0..100 {
for sign in [Plus, Minus] {
let number = 1i128 << i;
let signed_number = match sign {
Minus => -number,
Plus | _ => number,
};
for base in [2, 8, 16, 10] {
let mut string = match base {
2 => format!("{:#b}", number),
8 => format!("{:#o}", number),
16 => format!("{:#x}", number),
10 => format!("{}", number),
_ => unreachable!(),
};
if sign == Minus {
string.insert(0, '-');
}
let (is_positive, limbs) = utils::str_to_limbs(&format!("{}", string));
assert_eq!(
limbs[0],
format!("{}u64", signed_number.abs() as u64),
"{signed_number}, {i}"
);
if i > 63 {
assert_eq!(
limbs[1],
format!("{}u64", (signed_number.abs() >> 64) as u64),
"{signed_number}, {i}"
);
}

assert_eq!(is_positive, sign == Plus);
}
}
}
let (is_positive, limbs) = utils::str_to_limbs("0");
assert!(is_positive);
assert_eq!(&limbs, &["0u64".to_string()]);

let (is_positive, limbs) = utils::str_to_limbs("-5");
assert!(!is_positive);
assert_eq!(&limbs, &["5u64".to_string()]);
Expand Down
23 changes: 20 additions & 3 deletions ff-macros/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::str::FromStr;

use num_bigint::{BigInt, Sign};
use num_traits::Num;
use proc_macro::TokenStream;
use syn::{Expr, Lit};

Expand All @@ -26,9 +27,25 @@ pub fn str_to_limbs(num: &str) -> (bool, Vec<String>) {
}

pub fn str_to_limbs_u64(num: &str) -> (bool, Vec<u64>) {
let (sign, digits) = BigInt::from_str(num)
.expect("could not parse to bigint")
.to_radix_le(16);
let is_negative = num.starts_with('-');
let num = if is_negative { &num[1..] } else { num };
let number = if num.starts_with("0x") || num.starts_with("0X") {
// We are in hexadecimal
BigInt::from_str_radix(&num[2..], 16)
} else if num.starts_with("0o") || num.starts_with("0O") {
// We are in octal
BigInt::from_str_radix(&num[2..], 8)
} else if num.starts_with("0b") || num.starts_with("0B") {
// We are in binary
BigInt::from_str_radix(&num[2..], 2)
} else {
// We are in decimal
BigInt::from_str(num)
}
.expect("could not parse to bigint");
let number = if is_negative { -number } else { number };
let (sign, digits) = number.to_radix_le(16);

let limbs = digits
.chunks(16)
.map(|chunk| {
Expand Down
6 changes: 3 additions & 3 deletions ff/src/fields/field_hashers/expander/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ impl<T: DynDigest + Clone> Expander for ExpanderXmd<T> {

let dst_prime = self.construct_dst_prime();
let z_pad: Vec<u8> = vec![0; self.block_size];
// // Represent `len_in_bytes` as a 2-byte array.
// // As per I2OSP method outlined in https://tools.ietf.org/pdf/rfc8017.pdf,
// // The program should abort if integer that we're trying to convert is too large.
// Represent `len_in_bytes` as a 2-byte array.
// As per I2OSP method outlined in https://tools.ietf.org/pdf/rfc8017.pdf,
// The program should abort if integer that we're trying to convert is too large.
assert!(n < (1 << 16), "Length should be smaller than 2^16");
let lib_str: [u8; 2] = (n as u16).to_be_bytes();

Expand Down
7 changes: 5 additions & 2 deletions ff/src/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,10 @@ mod no_std_tests {
// TODO: only Fr & FrConfig should need to be imported.
// The rest of imports are caused by cargo not resolving the deps properly
// from this crate and from ark_test_curves
use ark_test_curves::{batch_inversion, batch_inversion_and_mul, bls12_381::Fr, PrimeField};
use ark_test_curves::{
ark_ff::{batch_inversion, batch_inversion_and_mul, PrimeField},
bls12_381::Fr,
};

#[test]
fn test_batch_inversion() {
Expand Down Expand Up @@ -457,7 +460,7 @@ mod no_std_tests {
// TODO: Eventually generate all the test vector bytes via computation with the
// modulus
use ark_std::{rand::Rng, string::ToString};
use ark_test_curves::BigInteger;
use ark_test_curves::ark_ff::BigInteger;
use num_bigint::BigUint;

let ref_modulus = BigUint::from_bytes_be(&Fr::MODULUS.to_bytes_be());
Expand Down
2 changes: 1 addition & 1 deletion ff/src/fields/models/cubic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,9 @@ mod cube_ext_tests {
use super::*;
use ark_std::test_rng;
use ark_test_curves::{
ark_ff::Field,
bls12_381::{Fq, Fq2, Fq6},
mnt6_753::Fq3,
Field,
};

#[test]
Expand Down
4 changes: 2 additions & 2 deletions ff/src/fields/models/fp/montgomery_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,9 @@ pub const fn sqrt_precomputation<const N: usize, T: MontConfig<N>>(
/// # Usage
///
/// ```rust
/// # use ark_test_curves::{MontFp, One};
/// # use ark_test_curves::MontFp;
/// # use ark_test_curves::bls12_381 as ark_bls12_381;
/// # use ark_std::str::FromStr;
/// # use ark_std::{One, str::FromStr};
/// use ark_bls12_381::Fq;
/// const ONE: Fq = MontFp!("1");
/// const NEG_ONE: Fq = MontFp!("-1");
Expand Down
2 changes: 1 addition & 1 deletion ff/src/fields/models/quadratic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,8 +772,8 @@ mod quad_ext_tests {
use super::*;
use ark_std::test_rng;
use ark_test_curves::{
ark_ff::Field,
bls12_381::{Fq, Fq2},
Field,
};

#[test]
Expand Down
5 changes: 4 additions & 1 deletion ff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ extern crate derivative;

#[macro_use]
pub mod biginteger;
pub use self::biginteger::*;
pub use biginteger::{
signed_mod_reduction, BigInt, BigInteger, BigInteger128, BigInteger256, BigInteger320,
BigInteger384, BigInteger448, BigInteger64, BigInteger768, BigInteger832,
};

#[macro_use]
pub mod fields;
Expand Down
6 changes: 3 additions & 3 deletions test-curves/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![no_std]

extern crate ark_ff;
pub use ark_ff::*;
pub use ark_ff;
pub use ark_ff::{fields::models::*, FftField, Field, LegendreSymbol, MontFp, PrimeField};

extern crate ark_ec;
pub use ark_ec;
pub use ark_ec::*;

#[cfg(any(feature = "bls12_381_scalar_field", feature = "bls12_381_curve"))]
Expand Down

0 comments on commit f853bda

Please sign in to comment.