Add conditional selection for G1/G2.

This commit is contained in:
Sean Bowe 2019-08-11 11:59:14 -06:00
parent e836a7ab5c
commit 9e671eed0c
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
2 changed files with 90 additions and 2 deletions

View File

@ -1,7 +1,7 @@
//! This module provides an implementation of the $\mathbb{G}_1$ group of BLS12-381.
use crate::fp::Fp;
use subtle::{Choice, ConstantTimeEq};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
/// This is an element of $\mathbb{G}_1$ represented in the affine coordinate space.
/// It is ideal to keep elements in this representation to reduce memory usage and
@ -30,6 +30,16 @@ impl ConstantTimeEq for G1Affine {
}
}
impl ConditionallySelectable for G1Affine {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
G1Affine {
x: Fp::conditional_select(&a.x, &b.x, choice),
y: Fp::conditional_select(&a.y, &b.y, choice),
infinity: Choice::conditional_select(&a.infinity, &b.infinity, choice),
}
}
}
impl Eq for G1Affine {}
impl PartialEq for G1Affine {
#[inline]
@ -118,6 +128,16 @@ impl ConstantTimeEq for G1Projective {
}
}
impl ConditionallySelectable for G1Projective {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
G1Projective {
x: Fp::conditional_select(&a.x, &b.x, choice),
y: Fp::conditional_select(&a.y, &b.y, choice),
z: Fp::conditional_select(&a.z, &b.z, choice),
}
}
}
impl Eq for G1Projective {}
impl PartialEq for G1Projective {
#[inline]
@ -257,3 +277,27 @@ fn test_projective_point_equality() {
assert!(a != c);
assert!(b != c);
}
#[test]
fn test_conditionally_select_affine() {
let a = G1Affine::generator();
let b = G1Affine::identity();
assert_eq!(G1Affine::conditional_select(&a, &b, Choice::from(0u8)), a);
assert_eq!(G1Affine::conditional_select(&a, &b, Choice::from(1u8)), b);
}
#[test]
fn test_conditionally_select_projective() {
let a = G1Projective::generator();
let b = G1Projective::identity();
assert_eq!(
G1Projective::conditional_select(&a, &b, Choice::from(0u8)),
a
);
assert_eq!(
G1Projective::conditional_select(&a, &b, Choice::from(1u8)),
b
);
}

View File

@ -2,7 +2,7 @@
use crate::fp::Fp;
use crate::fp2::Fp2;
use subtle::{Choice, ConstantTimeEq};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
/// This is an element of $\mathbb{G}_2$ represented in the affine coordinate space.
/// It is ideal to keep elements in this representation to reduce memory usage and
@ -31,6 +31,16 @@ impl ConstantTimeEq for G2Affine {
}
}
impl ConditionallySelectable for G2Affine {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
G2Affine {
x: Fp2::conditional_select(&a.x, &b.x, choice),
y: Fp2::conditional_select(&a.y, &b.y, choice),
infinity: Choice::conditional_select(&a.infinity, &b.infinity, choice),
}
}
}
impl Eq for G2Affine {}
impl PartialEq for G2Affine {
#[inline]
@ -149,6 +159,16 @@ impl ConstantTimeEq for G2Projective {
}
}
impl ConditionallySelectable for G2Projective {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
G2Projective {
x: Fp2::conditional_select(&a.x, &b.x, choice),
y: Fp2::conditional_select(&a.y, &b.y, choice),
z: Fp2::conditional_select(&a.z, &b.z, choice),
}
}
}
impl Eq for G2Projective {}
impl PartialEq for G2Projective {
#[inline]
@ -328,3 +348,27 @@ fn test_projective_point_equality() {
assert!(a != c);
assert!(b != c);
}
#[test]
fn test_conditionally_select_affine() {
let a = G2Affine::generator();
let b = G2Affine::identity();
assert_eq!(G2Affine::conditional_select(&a, &b, Choice::from(0u8)), a);
assert_eq!(G2Affine::conditional_select(&a, &b, Choice::from(1u8)), b);
}
#[test]
fn test_conditionally_select_projective() {
let a = G2Projective::generator();
let b = G2Projective::identity();
assert_eq!(
G2Projective::conditional_select(&a, &b, Choice::from(0u8)),
a
);
assert_eq!(
G2Projective::conditional_select(&a, &b, Choice::from(1u8)),
b
);
}