From 9e671eed0c7e3904458273c32905d29157e052eb Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 11 Aug 2019 11:59:14 -0600 Subject: [PATCH] Add conditional selection for G1/G2. --- src/g1.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/g2.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/src/g1.rs b/src/g1.rs index 6ef4f6bea..c6a64499b 100644 --- a/src/g1.rs +++ b/src/g1.rs @@ -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 + ); +} diff --git a/src/g2.rs b/src/g2.rs index 66c370dc9..d8837b111 100644 --- a/src/g2.rs +++ b/src/g2.rs @@ -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 + ); +}