Merge pull request #31 from zkcrypto/release-0.1.1

Release 0.1.1
This commit is contained in:
ebfull 2020-01-28 13:33:10 -07:00 committed by GitHub
commit 24aa1a4052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 10 deletions

View File

@ -43,8 +43,18 @@ jobs:
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: build command: build
args: --verbose --release --tests args: --verbose --release --tests --features endo
- name: Run tests - name: Run tests
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --release --features endo
- name: Build tests (no endomorphism)
uses: actions-rs/cargo@v1
with:
command: build
args: --verbose --release --tests
- name: Run tests (no endomorphism)
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: test command: test

View File

@ -6,7 +6,7 @@ homepage = "https://github.com/zkcrypto/bls12_381"
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
name = "bls12_381" name = "bls12_381"
repository = "https://github.com/zkcrypto/bls12_381" repository = "https://github.com/zkcrypto/bls12_381"
version = "0.1.0" version = "0.1.1"
edition = "2018" edition = "2018"
[package.metadata.docs.rs] [package.metadata.docs.rs]
@ -30,3 +30,6 @@ groups = []
pairings = ["groups"] pairings = ["groups"]
alloc = [] alloc = []
nightly = ["subtle/nightly"] nightly = ["subtle/nightly"]
# GLV patents US7110538B2 and US7995752B2 expire in September 2020.
endo = []

View File

@ -13,6 +13,7 @@ This crate provides an implementation of the BLS12-381 pairing-friendly elliptic
* `pairings` (on by default): Enables some APIs for performing pairings. * `pairings` (on by default): Enables some APIs for performing pairings.
* `alloc` (on by default): Enables APIs that require an allocator; these include pairing optimizations. * `alloc` (on by default): Enables APIs that require an allocator; these include pairing optimizations.
* `nightly`: Enables `subtle/nightly` which tries to prevent compiler optimizations that could jeopardize constant time operations. Requires the nightly Rust compiler. * `nightly`: Enables `subtle/nightly` which tries to prevent compiler optimizations that could jeopardize constant time operations. Requires the nightly Rust compiler.
* `endo`: Enables optimizations that leverage curve endomorphisms, which may run foul of patents US7110538B2 and US7995752B2 set to expire in September 2020.
## [Documentation](https://docs.rs/bls12_381) ## [Documentation](https://docs.rs/bls12_381)

View File

@ -1,3 +1,12 @@
# 0.1.1
Added `clear_cofactor` methods to `G1Projective` and `G2Projective`. If the crate feature `endo`
is enabled the G2 cofactor clearing will use the curve endomorphism technique described by
[Budroni-Pintore](https://ia.cr/2017/419). If the crate feature `endo` is _not_ enabled then
the code will simulate the effects of the Budroni-Pintore cofactor clearing in order to keep
the API consistent. In September 2020, when patents US7110538B2 and US7995752B2 expire, the
endo feature will be made default. However, for now it must be explicitly enabled.
# 0.1.0 # 0.1.0
Initial release. Initial release.

View File

@ -805,7 +805,7 @@ impl G2Projective {
G2Projective::conditional_select(&res, &tmp, (!f1) & (!f2) & (!f3)) G2Projective::conditional_select(&res, &tmp, (!f1) & (!f2) & (!f3))
} }
fn multiply(&self, by: &[u8; 32]) -> G2Projective { fn multiply(&self, by: &[u8]) -> G2Projective {
let mut acc = G2Projective::identity(); let mut acc = G2Projective::identity();
// This is a simple double-and-add implementation of point // This is a simple double-and-add implementation of point
@ -827,6 +827,7 @@ impl G2Projective {
acc acc
} }
#[cfg(feature = "endo")]
fn psi(&self) -> G2Projective { fn psi(&self) -> G2Projective {
// 1 / ((u+1) ^ ((q-1)/3)) // 1 / ((u+1) ^ ((q-1)/3))
let psi_coeff_x = Fp2 { let psi_coeff_x = Fp2 {
@ -870,6 +871,7 @@ impl G2Projective {
} }
} }
#[cfg(feature = "endo")]
fn psi2(&self) -> G2Projective { fn psi2(&self) -> G2Projective {
// 1 / 2 ^ ((q-1)/3) // 1 / 2 ^ ((q-1)/3)
let psi2_coeff_x = Fp2 { let psi2_coeff_x = Fp2 {
@ -895,6 +897,7 @@ impl G2Projective {
} }
/// Multiply `self` by `crate::BLS_X`, using double and add. /// Multiply `self` by `crate::BLS_X`, using double and add.
#[cfg(feature = "endo")]
fn mul_by_x(&self) -> G2Projective { fn mul_by_x(&self) -> G2Projective {
let mut xself = G2Projective::identity(); let mut xself = G2Projective::identity();
// NOTE: in BLS12-381 we can just skip the first bit. // NOTE: in BLS12-381 we can just skip the first bit.
@ -918,15 +921,36 @@ impl G2Projective {
/// This is equivalent to multiplying by $h\_\textrm{eff} = 3(z^2 - 1) \cdot /// This is equivalent to multiplying by $h\_\textrm{eff} = 3(z^2 - 1) \cdot
/// h_2$, where $h_2$ is the cofactor of $\mathbb{G}\_2$ and $z$ is the /// h_2$, where $h_2$ is the cofactor of $\mathbb{G}\_2$ and $z$ is the
/// parameter of BLS12-381. /// parameter of BLS12-381.
///
/// The endomorphism is only actually used if the crate feature `endo` is
/// enabled, and it is disabled by default to mitigate potential patent
/// issues.
pub fn clear_cofactor(&self) -> G2Projective { pub fn clear_cofactor(&self) -> G2Projective {
let t1 = self.mul_by_x(); // [x] P #[cfg(feature = "endo")]
let t2 = self.psi(); // psi(P) fn clear_cofactor(this: &G2Projective) -> G2Projective {
let t1 = this.mul_by_x(); // [x] P
let t2 = this.psi(); // psi(P)
self.double().psi2() // psi^2(2P) this.double().psi2() // psi^2(2P)
+ (t1 + t2).mul_by_x() // psi^2(2P) + [x^2] P + [x] psi(P) + (t1 + t2).mul_by_x() // psi^2(2P) + [x^2] P + [x] psi(P)
- t1 // psi^2(2P) + [x^2 - x] P + [x] psi(P) - t1 // psi^2(2P) + [x^2 - x] P + [x] psi(P)
- t2 // psi^2(2P) + [x^2 - x] P + [x - 1] psi(P) - t2 // psi^2(2P) + [x^2 - x] P + [x - 1] psi(P)
- self // psi^2(2P) + [x^2 - x - 1] P + [x - 1] psi(P) - this // psi^2(2P) + [x^2 - x - 1] P + [x - 1] psi(P)
}
#[cfg(not(feature = "endo"))]
fn clear_cofactor(this: &G2Projective) -> G2Projective {
this.multiply(&[
0x51, 0x55, 0xa9, 0xaa, 0x5, 0x0, 0x2, 0xe8, 0xb4, 0xf6, 0xbb, 0xde, 0xa, 0x4c,
0x89, 0x59, 0xa3, 0xf6, 0x89, 0x66, 0xc0, 0xcb, 0x54, 0xe9, 0x1a, 0x7c, 0x47, 0xd7,
0x69, 0xec, 0xc0, 0x2e, 0xb0, 0x12, 0x12, 0x5d, 0x1, 0xbf, 0x82, 0x6d, 0x95, 0xdb,
0x31, 0x87, 0x17, 0x2f, 0x9c, 0x32, 0xe1, 0xff, 0x8, 0x15, 0x3, 0xff, 0x86, 0x99,
0x68, 0xd7, 0x5a, 0x14, 0xe9, 0xa8, 0xe2, 0x88, 0x28, 0x35, 0x1b, 0xa9, 0xe, 0x6a,
0x4c, 0x58, 0xb3, 0x75, 0xee, 0xf2, 0x8, 0x9f, 0xc6, 0xb,
])
}
clear_cofactor(self)
} }
/// Converts a batch of `G2Projective` elements into `G2Affine` elements. This /// Converts a batch of `G2Projective` elements into `G2Affine` elements. This
@ -1653,6 +1677,7 @@ fn test_is_torsion_free() {
assert!(bool::from(G2Affine::generator().is_torsion_free())); assert!(bool::from(G2Affine::generator().is_torsion_free()));
} }
#[cfg(feature = "endo")]
#[test] #[test]
fn test_mul_by_x() { fn test_mul_by_x() {
// multiplying by `x` a point in G2 is the same as multiplying by // multiplying by `x` a point in G2 is the same as multiplying by
@ -1669,6 +1694,7 @@ fn test_mul_by_x() {
assert_eq!(point.mul_by_x(), point * x); assert_eq!(point.mul_by_x(), point * x);
} }
#[cfg(feature = "endo")]
#[test] #[test]
fn test_psi() { fn test_psi() {
let generator = G2Projective::generator(); let generator = G2Projective::generator();