Merge pull request #26 from zkcrypto/bls12-381-scalar
Replace Fq implementation with bls12_381::Scalar
This commit is contained in:
commit
e83f7d2bd1
|
@ -11,7 +11,7 @@ jobs:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.33.0
|
toolchain: 1.36.0
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
# Ensure all code has been formatted with rustfmt
|
# Ensure all code has been formatted with rustfmt
|
||||||
|
@ -33,7 +33,7 @@ jobs:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.33.0
|
toolchain: 1.36.0
|
||||||
override: true
|
override: true
|
||||||
- name: cargo fetch
|
- name: cargo fetch
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -58,7 +58,7 @@ jobs:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.33.0
|
toolchain: 1.36.0
|
||||||
override: true
|
override: true
|
||||||
- run: rustup target add thumbv6m-none-eabi
|
- run: rustup target add thumbv6m-none-eabi
|
||||||
- name: cargo fetch
|
- name: cargo fetch
|
||||||
|
|
|
@ -13,8 +13,8 @@ repository = "https://github.com/zkcrypto/jubjub"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies.byteorder]
|
[dependencies.bls12_381]
|
||||||
version = "1"
|
version = "0.1"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dependencies.subtle]
|
[dependencies.subtle]
|
||||||
|
@ -22,11 +22,11 @@ version = "^2.2.1"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dev-dependencies.rand_core]
|
[dev-dependencies.rand_core]
|
||||||
version = "0.4"
|
version = "0.5"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dev-dependencies.rand_xorshift]
|
[dev-dependencies.rand_xorshift]
|
||||||
version = "0.1"
|
version = "0.2"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
This is a pure Rust implementation of the Jubjub elliptic curve group and its associated fields.
|
This is a pure Rust implementation of the Jubjub elliptic curve group and its associated fields.
|
||||||
|
|
||||||
* **This implementation has not been reviewed or audited. Use at your own risk.**
|
* **This implementation has not been reviewed or audited. Use at your own risk.**
|
||||||
* This implementation targets Rust `1.33` or later.
|
* This implementation targets Rust `1.36` or later.
|
||||||
* All operations are constant time unless explicitly noted.
|
* All operations are constant time unless explicitly noted.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
35
src/fr.rs
35
src/fr.rs
|
@ -1,7 +1,7 @@
|
||||||
|
use core::convert::TryInto;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||||
|
|
||||||
use crate::util::{adc, mac, sbb};
|
use crate::util::{adc, mac, sbb};
|
||||||
|
@ -107,6 +107,7 @@ impl<'a, 'b> Sub<&'b Fr> for &'a Fr {
|
||||||
impl<'a, 'b> Add<&'b Fr> for &'a Fr {
|
impl<'a, 'b> Add<&'b Fr> for &'a Fr {
|
||||||
type Output = Fr;
|
type Output = Fr;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, rhs: &'b Fr) -> Fr {
|
fn add(self, rhs: &'b Fr) -> Fr {
|
||||||
let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
|
let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
|
||||||
|
@ -192,10 +193,10 @@ impl Fr {
|
||||||
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Fr> {
|
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Fr> {
|
||||||
let mut tmp = Fr([0, 0, 0, 0]);
|
let mut tmp = Fr([0, 0, 0, 0]);
|
||||||
|
|
||||||
tmp.0[0] = LittleEndian::read_u64(&bytes[0..8]);
|
tmp.0[0] = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
|
||||||
tmp.0[1] = LittleEndian::read_u64(&bytes[8..16]);
|
tmp.0[1] = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
|
||||||
tmp.0[2] = LittleEndian::read_u64(&bytes[16..24]);
|
tmp.0[2] = u64::from_le_bytes(bytes[16..24].try_into().unwrap());
|
||||||
tmp.0[3] = LittleEndian::read_u64(&bytes[24..32]);
|
tmp.0[3] = u64::from_le_bytes(bytes[24..32].try_into().unwrap());
|
||||||
|
|
||||||
// Try to subtract the modulus
|
// Try to subtract the modulus
|
||||||
let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
|
let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
|
||||||
|
@ -223,10 +224,10 @@ impl Fr {
|
||||||
let tmp = Fr::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
|
let tmp = Fr::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
|
||||||
|
|
||||||
let mut res = [0; 32];
|
let mut res = [0; 32];
|
||||||
LittleEndian::write_u64(&mut res[0..8], tmp.0[0]);
|
res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
|
||||||
LittleEndian::write_u64(&mut res[8..16], tmp.0[1]);
|
res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
|
||||||
LittleEndian::write_u64(&mut res[16..24], tmp.0[2]);
|
res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
|
||||||
LittleEndian::write_u64(&mut res[24..32], tmp.0[3]);
|
res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -235,14 +236,14 @@ impl Fr {
|
||||||
/// an element of Fr by reducing modulo r.
|
/// an element of Fr by reducing modulo r.
|
||||||
pub fn from_bytes_wide(bytes: &[u8; 64]) -> Fr {
|
pub fn from_bytes_wide(bytes: &[u8; 64]) -> Fr {
|
||||||
Fr::from_u512([
|
Fr::from_u512([
|
||||||
LittleEndian::read_u64(&bytes[0..8]),
|
u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[8..16]),
|
u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[16..24]),
|
u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[24..32]),
|
u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[32..40]),
|
u64::from_le_bytes(bytes[32..40].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[40..48]),
|
u64::from_le_bytes(bytes[40..48].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[48..56]),
|
u64::from_le_bytes(bytes[48..56].try_into().unwrap()),
|
||||||
LittleEndian::read_u64(&bytes[56..64]),
|
u64::from_le_bytes(bytes[56..64].try_into().unwrap()),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
73
src/lib.rs
73
src/lib.rs
|
@ -33,9 +33,8 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
mod fq;
|
|
||||||
mod fr;
|
mod fr;
|
||||||
pub use fq::Fq;
|
pub use bls12_381::Scalar as Fq;
|
||||||
pub use fr::Fr;
|
pub use fr::Fr;
|
||||||
|
|
||||||
const FR_MODULUS_BYTES: [u8; 32] = [
|
const FR_MODULUS_BYTES: [u8; 32] = [
|
||||||
|
@ -453,9 +452,9 @@ impl AffinePoint {
|
||||||
/// for use in multiple additions.
|
/// for use in multiple additions.
|
||||||
pub const fn to_niels(&self) -> AffineNielsPoint {
|
pub const fn to_niels(&self) -> AffineNielsPoint {
|
||||||
AffineNielsPoint {
|
AffineNielsPoint {
|
||||||
v_plus_u: self.v.field_add(&self.u),
|
v_plus_u: Fq::add(&self.v, &self.u),
|
||||||
v_minus_u: self.v.subtract(&self.u),
|
v_minus_u: Fq::sub(&self.v, &self.u),
|
||||||
t2d: self.u.multiply(&self.v).multiply(&EDWARDS_D2),
|
t2d: Fq::mul(&Fq::mul(&self.u, &self.v), &EDWARDS_D2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,6 +659,7 @@ impl_binops_multiplicative!(ExtendedPoint, Fr);
|
||||||
impl<'a, 'b> Add<&'b ExtendedNielsPoint> for &'a ExtendedPoint {
|
impl<'a, 'b> Add<&'b ExtendedNielsPoint> for &'a ExtendedPoint {
|
||||||
type Output = ExtendedPoint;
|
type Output = ExtendedPoint;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
fn add(self, other: &'b ExtendedNielsPoint) -> ExtendedPoint {
|
fn add(self, other: &'b ExtendedNielsPoint) -> ExtendedPoint {
|
||||||
// We perform addition in the extended coordinates. Here we use
|
// We perform addition in the extended coordinates. Here we use
|
||||||
// a formula presented by Hisil, Wong, Carter and Dawson in
|
// a formula presented by Hisil, Wong, Carter and Dawson in
|
||||||
|
@ -698,6 +698,7 @@ impl<'a, 'b> Add<&'b ExtendedNielsPoint> for &'a ExtendedPoint {
|
||||||
impl<'a, 'b> Sub<&'b ExtendedNielsPoint> for &'a ExtendedPoint {
|
impl<'a, 'b> Sub<&'b ExtendedNielsPoint> for &'a ExtendedPoint {
|
||||||
type Output = ExtendedPoint;
|
type Output = ExtendedPoint;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
fn sub(self, other: &'b ExtendedNielsPoint) -> ExtendedPoint {
|
fn sub(self, other: &'b ExtendedNielsPoint) -> ExtendedPoint {
|
||||||
let a = (&self.v - &self.u) * &other.v_plus_u;
|
let a = (&self.v - &self.u) * &other.v_plus_u;
|
||||||
let b = (&self.v + &self.u) * &other.v_minus_u;
|
let b = (&self.v + &self.u) * &other.v_minus_u;
|
||||||
|
@ -719,6 +720,7 @@ impl_binops_additive!(ExtendedPoint, ExtendedNielsPoint);
|
||||||
impl<'a, 'b> Add<&'b AffineNielsPoint> for &'a ExtendedPoint {
|
impl<'a, 'b> Add<&'b AffineNielsPoint> for &'a ExtendedPoint {
|
||||||
type Output = ExtendedPoint;
|
type Output = ExtendedPoint;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
fn add(self, other: &'b AffineNielsPoint) -> ExtendedPoint {
|
fn add(self, other: &'b AffineNielsPoint) -> ExtendedPoint {
|
||||||
// This is identical to the addition formula for `ExtendedNielsPoint`,
|
// This is identical to the addition formula for `ExtendedNielsPoint`,
|
||||||
// except we can assume that `other.z` is one, so that we perform
|
// except we can assume that `other.z` is one, so that we perform
|
||||||
|
@ -744,6 +746,7 @@ impl<'a, 'b> Add<&'b AffineNielsPoint> for &'a ExtendedPoint {
|
||||||
impl<'a, 'b> Sub<&'b AffineNielsPoint> for &'a ExtendedPoint {
|
impl<'a, 'b> Sub<&'b AffineNielsPoint> for &'a ExtendedPoint {
|
||||||
type Output = ExtendedPoint;
|
type Output = ExtendedPoint;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
fn sub(self, other: &'b AffineNielsPoint) -> ExtendedPoint {
|
fn sub(self, other: &'b AffineNielsPoint) -> ExtendedPoint {
|
||||||
let a = (&self.v - &self.u) * &other.v_plus_u;
|
let a = (&self.v - &self.u) * &other.v_plus_u;
|
||||||
let b = (&self.v + &self.u) * &other.v_minus_u;
|
let b = (&self.v + &self.u) * &other.v_minus_u;
|
||||||
|
@ -943,17 +946,17 @@ fn test_extended_niels_point_identity() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_assoc() {
|
fn test_assoc() {
|
||||||
let p = ExtendedPoint::from(AffinePoint {
|
let p = ExtendedPoint::from(AffinePoint {
|
||||||
u: Fq([
|
u: Fq::from_raw([
|
||||||
0xc0115cb656ae4839,
|
0x81c571e5d883cfb0,
|
||||||
0x623dc3ff81d64c26,
|
0x049f7a686f147029,
|
||||||
0x5868e739b5794f2c,
|
0xf539c860bc3ea21f,
|
||||||
0x23bd4fbb18d39c9c,
|
0x4284715b7ccc8162,
|
||||||
]),
|
]),
|
||||||
v: Fq([
|
v: Fq::from_raw([
|
||||||
0x7588ee6d6dd40deb,
|
0xbf096275684bb8ca,
|
||||||
0x9d6d7a23ebdb7c4c,
|
0xc7ba245890af256d,
|
||||||
0x46462e26d4edb8c7,
|
0x59119f3e86380eb0,
|
||||||
0x10b4c1517ca82e9b,
|
0x3793de182f9fb1d2,
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
.mul_by_cofactor();
|
.mul_by_cofactor();
|
||||||
|
@ -969,17 +972,17 @@ fn test_assoc() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_batch_normalize() {
|
fn test_batch_normalize() {
|
||||||
let mut p = ExtendedPoint::from(AffinePoint {
|
let mut p = ExtendedPoint::from(AffinePoint {
|
||||||
u: Fq([
|
u: Fq::from_raw([
|
||||||
0xc0115cb656ae4839,
|
0x81c571e5d883cfb0,
|
||||||
0x623dc3ff81d64c26,
|
0x049f7a686f147029,
|
||||||
0x5868e739b5794f2c,
|
0xf539c860bc3ea21f,
|
||||||
0x23bd4fbb18d39c9c,
|
0x4284715b7ccc8162,
|
||||||
]),
|
]),
|
||||||
v: Fq([
|
v: Fq::from_raw([
|
||||||
0x7588ee6d6dd40deb,
|
0xbf096275684bb8ca,
|
||||||
0x9d6d7a23ebdb7c4c,
|
0xc7ba245890af256d,
|
||||||
0x46462e26d4edb8c7,
|
0x59119f3e86380eb0,
|
||||||
0x10b4c1517ca82e9b,
|
0x3793de182f9fb1d2,
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
.mul_by_cofactor();
|
.mul_by_cofactor();
|
||||||
|
@ -1204,17 +1207,17 @@ fn test_mul_consistency() {
|
||||||
]);
|
]);
|
||||||
assert_eq!(a * b, c);
|
assert_eq!(a * b, c);
|
||||||
let p = ExtendedPoint::from(AffinePoint {
|
let p = ExtendedPoint::from(AffinePoint {
|
||||||
u: Fq([
|
u: Fq::from_raw([
|
||||||
0xc0115cb656ae4839,
|
0x81c571e5d883cfb0,
|
||||||
0x623dc3ff81d64c26,
|
0x049f7a686f147029,
|
||||||
0x5868e739b5794f2c,
|
0xf539c860bc3ea21f,
|
||||||
0x23bd4fbb18d39c9c,
|
0x4284715b7ccc8162,
|
||||||
]),
|
]),
|
||||||
v: Fq([
|
v: Fq::from_raw([
|
||||||
0x7588ee6d6dd40deb,
|
0xbf096275684bb8ca,
|
||||||
0x9d6d7a23ebdb7c4c,
|
0xc7ba245890af256d,
|
||||||
0x46462e26d4edb8c7,
|
0x59119f3e86380eb0,
|
||||||
0x10b4c1517ca82e9b,
|
0x3793de182f9fb1d2,
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
.mul_by_cofactor();
|
.mul_by_cofactor();
|
||||||
|
|
Loading…
Reference in New Issue