Browse Source

added new field Fl instead of Fr for suborder instead of order

pull/8/head
Nanak Nihal Singh Khalsa 1 year ago
parent
commit
a6946a16f9
2 changed files with 43 additions and 13 deletions
  1. +2
    -1
      Cargo.toml
  2. +41
    -12
      src/lib.rs

+ 2
- 1
Cargo.toml

@ -10,7 +10,8 @@ readme = "README.md"
[dependencies] [dependencies]
ff = {package="ff_ce", version= "0.11", features = ["derive"]} ff = {package="ff_ce", version= "0.11", features = ["derive"]}
rand = "0.8"
rand_new = {package="rand", version="0.8"}
rand = "0.4.6"
num = "0.4" num = "0.4"
num-bigint = {version = "0.4", features = ["rand"]} num-bigint = {version = "0.4", features = ["rand"]}
num-traits = "0.2.8" num-traits = "0.2.8"

+ 41
- 12
src/lib.rs

@ -9,6 +9,17 @@ use bytes::{BytesMut, BufMut};
use poseidon_rs::Poseidon; use poseidon_rs::Poseidon;
pub type Fr = poseidon_rs::Fr; // alias pub type Fr = poseidon_rs::Fr; // alias
extern crate rand_new;
extern crate rand;
#[macro_use]
extern crate ff;
// Create a new primefield for the subgroup defined by the base point, order Fl:
#[derive(PrimeField)]
#[PrimeFieldModulus = "2736030358979909402780800718157159386076813972158567259200215660948447373041"]
#[PrimeFieldGenerator = "7"] // TODO: double check this is a valid generator!!!
pub struct Fl(FpRepr);
use arrayref::array_ref; use arrayref::array_ref;
// #[cfg(not(feature = "aarch64"))] // #[cfg(not(feature = "aarch64"))]
@ -54,7 +65,7 @@ lazy_static! {
.unwrap(); .unwrap();
// SUBORDER = ORDER >> 3 // SUBORDER = ORDER >> 3
static ref SUBORDER: BigInt = &BigInt::parse_bytes(
pub static ref SUBORDER: BigInt = &BigInt::parse_bytes(
b"21888242871839275222246405745257275088614511777268538073601725287587578984328", b"21888242871839275222246405745257275088614511777268538073601725287587578984328",
10, 10,
) )
@ -69,8 +80,8 @@ lazy_static! {
.unwrap() .unwrap()
>> 10; >> 10;
// An arbitrary number for Koblitz method of encoding string to point. 1024 is convenient compared to original 1000 to do bitshifts instead of multiplications/divisions // An arbitrary number for Koblitz method of encoding string to point. 1024 is convenient compared to original 1000 to do bitshifts instead of multiplications/divisions
pub static ref KOBLITZ_NUMBER: Fr = Fr::from_str("1024").unwrap();
pub static ref KOBLITZ_NUMBER_INV: Fr = Fr::from_str("1024").unwrap().inverse().unwrap();
// pub static ref KOBLITZ_NUMBER: Fr = Fr::from_str("1024").unwrap();
// pub static ref KOBLITZ_NUMBER_INV: Fr = Fr::from_str("1024").unwrap().inverse().unwrap();
} }
@ -162,12 +173,20 @@ impl ToDecimalString for Fr {
BigInt::from_str_radix(&hex_str, 16).unwrap().to_string() BigInt::from_str_radix(&hex_str, 16).unwrap().to_string()
} }
} }
pub trait FrBigIntConversion {
fn from_bigint(bi: &BigInt) -> Fr;
impl ToDecimalString for Fl {
fn to_dec_string(&self) -> String {
let mut s = self.to_string();
let hex_str = s[5..s.len()-1].to_string();
BigInt::from_str_radix(&hex_str, 16).unwrap().to_string()
}
}
pub trait FrBigIntConversion<T> {
fn from_bigint(bi: &BigInt) -> T;
fn to_bigint(&self) -> BigInt; fn to_bigint(&self) -> BigInt;
} }
impl FrBigIntConversion for Fr {
impl FrBigIntConversion<Fr> for Fr {
// Note: this could probably be more efficient by converting bigint to raw repr to Fr // Note: this could probably be more efficient by converting bigint to raw repr to Fr
fn from_bigint(bi: &BigInt) -> Fr { fn from_bigint(bi: &BigInt) -> Fr {
Fr::from_str(&bi.to_string()).unwrap() Fr::from_str(&bi.to_string()).unwrap()
@ -177,6 +196,16 @@ impl FrBigIntConversion for Fr {
} }
} }
impl FrBigIntConversion<Fl> for Fl {
// Note: this could probably be more efficient by converting bigint to raw repr to Fr
fn from_bigint(bi: &BigInt) -> Fl {
Fl::from_str(&bi.to_string()).unwrap()
}
fn to_bigint(&self) -> BigInt {
BigInt::from_str(&self.to_dec_string()).unwrap()
}
}
pub struct FrWrapper { pub struct FrWrapper {
pub fr: Fr pub fr: Fr
} }
@ -525,7 +554,7 @@ impl PrivateKey {
#[allow(clippy::many_single_char_names)] #[allow(clippy::many_single_char_names)]
pub fn sign_schnorr(&self, m: BigInt) -> Result<(Point, BigInt), String> { pub fn sign_schnorr(&self, m: BigInt) -> Result<(Point, BigInt), String> {
// random r // random r
let mut rng = rand::thread_rng();
let mut rng = rand_new::thread_rng();
let k = rng.gen_biguint(1024).to_bigint().unwrap(); let k = rng.gen_biguint(1024).to_bigint().unwrap();
// r = k·G // r = k·G
@ -589,7 +618,7 @@ pub fn verify_schnorr(pk: Point, m: BigInt, r: Point, s: BigInt) -> Result
pub fn new_key() -> PrivateKey { pub fn new_key() -> PrivateKey {
// https://tools.ietf.org/html/rfc8032#section-5.1.5 // https://tools.ietf.org/html/rfc8032#section-5.1.5
let mut rng = rand::thread_rng();
let mut rng = rand_new::thread_rng();
let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap(); let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
let (_, sk_raw_bytes) = sk_raw.to_bytes_be(); let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
PrivateKey::import(sk_raw_bytes[..32].to_vec()).unwrap() PrivateKey::import(sk_raw_bytes[..32].to_vec()).unwrap()
@ -617,7 +646,7 @@ pub fn verify(pk: Point, sig: Signature, msg: BigInt) -> bool {
mod tests { mod tests {
use super::*; use super::*;
use ::hex; use ::hex;
use rand::Rng;
use rand_new::Rng;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
#[test] #[test]
@ -635,7 +664,7 @@ mod tests {
// Try with some more random numbers -- it's extremely unlikely to get lucky will with valid points 20 times in a row if it's not always producing valid points // Try with some more random numbers -- it's extremely unlikely to get lucky will with valid points 20 times in a row if it's not always producing valid points
for n in 0..20 { for n in 0..20 {
let m = rand::thread_rng().gen_bigint_range(&0.to_bigint().unwrap() , &MAX_MSG);
let m = rand_new::thread_rng().gen_bigint_range(&0.to_bigint().unwrap() , &MAX_MSG);
assert!(Point::from_msg_vartime(&m).on_curve()); assert!(Point::from_msg_vartime(&m).on_curve());
} }
@ -654,7 +683,7 @@ mod tests {
// Try with some more random numbers -- it's extremely unlikely to get lucky will with valid points 20 times in a row if it's not always producing valid points // Try with some more random numbers -- it's extremely unlikely to get lucky will with valid points 20 times in a row if it's not always producing valid points
for n in 0..20 { for n in 0..20 {
let m = rand::thread_rng().gen_bigint_range(&0.to_bigint().unwrap() , &MAX_MSG);
let m = rand_new::thread_rng().gen_bigint_range(&0.to_bigint().unwrap() , &MAX_MSG);
assert!( assert!(
Point::from_msg_vartime(&m).to_msg() Point::from_msg_vartime(&m).to_msg()
.eq( .eq(
@ -907,7 +936,7 @@ mod tests {
#[test] #[test]
fn test_point_decompress_loop() { fn test_point_decompress_loop() {
for _ in 0..5 { for _ in 0..5 {
let random_bytes = rand::thread_rng().gen::<[u8; 32]>();
let random_bytes = rand_new::thread_rng().gen::<[u8; 32]>();
let sk_raw: BigInt = BigInt::from_bytes_le(Sign::Plus, &random_bytes[..]); let sk_raw: BigInt = BigInt::from_bytes_le(Sign::Plus, &random_bytes[..]);
let (_, sk_raw_bytes) = sk_raw.to_bytes_be(); let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
let mut h: Vec<u8> = blh(&sk_raw_bytes); let mut h: Vec<u8> = blh(&sk_raw_bytes);

Loading…
Cancel
Save