From 2835d706b32769f70edbaac42cc9fc8a50c02f81 Mon Sep 17 00:00:00 2001 From: Lucas Meier Date: Mon, 29 Jan 2024 13:59:31 -0800 Subject: [PATCH] Implement FromStr for all the fields --- proptest-regressions/fields/fr/arkworks.txt | 1 + src/fields/fp/arkworks.rs | 29 +++++++++++++++++--- src/fields/fq/arkworks.rs | 29 +++++++++++++++++--- src/fields/fr/arkworks.rs | 30 ++++++++++++++++++--- 4 files changed, 80 insertions(+), 9 deletions(-) diff --git a/proptest-regressions/fields/fr/arkworks.txt b/proptest-regressions/fields/fr/arkworks.txt index a3a12f5..9a0ff67 100644 --- a/proptest-regressions/fields/fr/arkworks.txt +++ b/proptest-regressions/fields/fr/arkworks.txt @@ -5,3 +5,4 @@ # It is recommended to check this file in to source control so that # everyone who runs the test benefits from these saved cases. cc 77fe8cd73668f517c0ddfd13999e303d1121ad67db8c896f6d7f33195288d791 # shrinks to a = Fr(0x0000000000000001000000000000000000000000000000000000000000000000) +cc 82d116306befe522f9442271ef7cf8675f016da4d94c21e2fb631fd544187bf6 # shrinks to a = Fr(0x0000000000000000000000000000000000000000000000000000000000000000) diff --git a/src/fields/fp/arkworks.rs b/src/fields/fp/arkworks.rs index 143f1f1..5453a64 100644 --- a/src/fields/fp/arkworks.rs +++ b/src/fields/fp/arkworks.rs @@ -309,8 +309,23 @@ impl ark_std::rand::distributions::Distribution for ark_std::rand::distribut impl FromStr for Fp { type Err = (); - fn from_str(_s: &str) -> Result { - unimplemented!() + fn from_str(s: &str) -> Result { + // CANDO: a more efficient method accumulating into 64 bits first. + let mut acc = Self::zero(); + + let ten = Self::from(10u8); + + for c in s.chars() { + match c.to_digit(10) { + Some(c) => { + acc = ten * acc + Self::from(u64::from(c)); + } + None => { + return Err(()); + } + } + } + Ok(acc) } } @@ -354,7 +369,7 @@ impl Display for Fp { mod tests { use super::*; extern crate alloc; - use alloc::vec::Vec; + use alloc::{format, vec::Vec}; use ark_bls12_377::Fq as ArkFp; use proptest::prelude::*; @@ -587,6 +602,14 @@ mod tests { } } + proptest! { + #[test] + fn test_from_str(a in arb_fp()) { + let x = ::BigInt::from(a); + assert_eq!(Ok(a), Fp::from_str(&format!("{}", x))); + } + } + #[test] fn test_from_le_bytes_mod_order_examples() { let p_plus_1_bytes: [u8; 48] = [ diff --git a/src/fields/fq/arkworks.rs b/src/fields/fq/arkworks.rs index 92962bd..be2321b 100644 --- a/src/fields/fq/arkworks.rs +++ b/src/fields/fq/arkworks.rs @@ -316,8 +316,23 @@ impl Display for Fq { impl FromStr for Fq { type Err = (); - fn from_str(_s: &str) -> Result { - unimplemented!() + fn from_str(s: &str) -> Result { + // CANDO: a more efficient method accumulating into 64 bits first. + let mut acc = Self::zero(); + + let ten = Self::from(10u8); + + for c in s.chars() { + match c.to_digit(10) { + Some(c) => { + acc = ten * acc + Self::from(u64::from(c)); + } + None => { + return Err(()); + } + } + } + Ok(acc) } } @@ -354,7 +369,7 @@ impl From> for Fq { mod tests { use super::*; extern crate alloc; - use alloc::vec::Vec; + use alloc::{format, vec::Vec}; use ark_bls12_377::Fr as ArkFq; use proptest::prelude::*; @@ -585,6 +600,14 @@ mod tests { } } + proptest! { + #[test] + fn test_from_str(a in arb_fq()) { + let x = ::BigInt::from(a); + assert_eq!(Ok(a), Fq::from_str(&format!("{}", x))); + } + } + #[test] fn test_from_le_bytes_mod_order_examples() { let p_plus_1_bytes: [u8; 32] = [ diff --git a/src/fields/fr/arkworks.rs b/src/fields/fr/arkworks.rs index e48094d..4cd6c65 100644 --- a/src/fields/fr/arkworks.rs +++ b/src/fields/fr/arkworks.rs @@ -318,8 +318,24 @@ impl Display for Fr { impl FromStr for Fr { type Err = (); - fn from_str(_s: &str) -> Result { - unimplemented!() + fn from_str(s: &str) -> Result { + ark_std::dbg!(&s); + // CANDO: a more efficient method accumulating into 64 bits first. + let mut acc = Self::zero(); + + let ten = Self::from(10u8); + + for c in s.chars() { + match c.to_digit(10) { + Some(c) => { + acc = ten * acc + Self::from(u64::from(c)); + } + None => { + return Err(()); + } + } + } + Ok(acc) } } @@ -356,7 +372,7 @@ impl From> for Fr { mod tests { use super::*; extern crate alloc; - use alloc::vec::Vec; + use alloc::{format, vec::Vec}; use proptest::prelude::*; prop_compose! { @@ -570,6 +586,14 @@ mod tests { } } + proptest! { + #[test] + fn test_from_str(a in arb_fr()) { + let x = ::BigInt::from(a); + assert_eq!(Ok(a), Fr::from_str(&format!("{}", x))); + } + } + #[test] fn test_from_le_bytes_mod_order_examples() { let p_plus_1_bytes: [u8; 32] = [