Add (not particularly efficient) from_str to PrimeField.
This commit is contained in:
parent
dcca363d1b
commit
40ec989184
@ -1766,6 +1766,7 @@ fn fq_field_tests() {
|
||||
::tests::field::random_field_tests::<Fq>();
|
||||
::tests::field::random_sqrt_tests::<Fq>();
|
||||
::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
|
||||
::tests::field::from_str_tests::<Fq>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1478,6 +1478,7 @@ fn fr_field_tests() {
|
||||
::tests::field::random_field_tests::<Fr>();
|
||||
::tests::field::random_sqrt_tests::<Fr>();
|
||||
::tests::field::random_frobenius_tests::<Fr, _>(Fr::char(), 13);
|
||||
::tests::field::from_str_tests::<Fr>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
40
src/lib.rs
40
src/lib.rs
@ -477,6 +477,46 @@ pub trait PrimeField: Field
|
||||
/// representation.
|
||||
type Repr: PrimeFieldRepr + From<Self>;
|
||||
|
||||
/// Interpret a string of numbers as a (congruent) prime field element.
|
||||
/// Does not accept unnecessary leading zeroes or a blank string.
|
||||
fn from_str(s: &str) -> Option<Self> {
|
||||
if s.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
if s == "0" {
|
||||
return Some(Self::zero());
|
||||
}
|
||||
|
||||
let mut res = Self::zero();
|
||||
|
||||
let ten = Self::from_repr(Self::Repr::from(10)).unwrap();
|
||||
|
||||
let mut first_digit = true;
|
||||
|
||||
for c in s.chars() {
|
||||
match c.to_digit(10) {
|
||||
Some(c) => {
|
||||
if first_digit {
|
||||
if c == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
first_digit = false;
|
||||
}
|
||||
|
||||
res.mul_assign(&ten);
|
||||
res.add_assign(&Self::from_repr(Self::Repr::from(c as u64)).unwrap());
|
||||
},
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(res)
|
||||
}
|
||||
|
||||
/// Convert this prime field element into a biginteger representation.
|
||||
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rand::{Rng, SeedableRng, XorShiftRng};
|
||||
use ::{SqrtField, Field};
|
||||
use ::{SqrtField, Field, PrimeField};
|
||||
|
||||
pub fn random_frobenius_tests<F: Field, C: AsRef<[u64]>>(characteristic: C, maxpower: usize) {
|
||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
@ -87,6 +87,40 @@ pub fn random_field_tests<F: Field>() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str_tests<F: PrimeField>() {
|
||||
{
|
||||
let a = "84395729384759238745923745892374598234705297301958723458712394587103249587213984572934750213947582345792304758273458972349582734958273495872304598234";
|
||||
let b = "38495729084572938457298347502349857029384609283450692834058293405982304598230458230495820394850293845098234059823049582309485203948502938452093482039";
|
||||
let c = "3248875134290623212325429203829831876024364170316860259933542844758450336418538569901990710701240661702808867062612075657861768196242274635305077449545396068598317421057721935408562373834079015873933065667961469731886739181625866970316226171512545167081793907058686908697431878454091011239990119126";
|
||||
|
||||
let mut a = F::from_str(a).unwrap();
|
||||
let b = F::from_str(b).unwrap();
|
||||
let c = F::from_str(c).unwrap();
|
||||
|
||||
a.mul_assign(&b);
|
||||
|
||||
assert_eq!(a, c);
|
||||
}
|
||||
|
||||
{
|
||||
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let n: u64 = rng.gen();
|
||||
|
||||
let a = F::from_str(&format!("{}", n)).unwrap();
|
||||
let b = F::from_repr(n.into()).unwrap();
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
assert!(F::from_str("").is_none());
|
||||
assert!(F::from_str("0").unwrap().is_zero());
|
||||
assert!(F::from_str("00").is_none());
|
||||
assert!(F::from_str("00000000000").is_none());
|
||||
}
|
||||
|
||||
fn random_multiplication_tests<F: Field, R: Rng>(rng: &mut R) {
|
||||
for _ in 0..10000 {
|
||||
let a = F::rand(rng);
|
||||
|
Loading…
Reference in New Issue
Block a user