Skip to content

Commit ab6e3b5

Browse files
authored
elliptic-curve: add ctutils traits to arithmetic bounds (#2166)
Makes it possible to use the `CtEq` and `CtSelect` traits on the `CurveArithmetic::{AffinePoint, ProjectivePoint, Scalar}` associated types.
1 parent 443d4ee commit ab6e3b5

3 files changed

Lines changed: 91 additions & 7 deletions

File tree

elliptic-curve/src/arithmetic.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::{
44
Curve, CurveGroup, Error, FieldBytes, Group, NonZeroScalar, PrimeCurve, ScalarValue,
5+
ctutils::{CtEq, CtSelect},
56
ops::{Invert, LinearCombination, Mul, Reduce},
67
point::{AffineCoordinates, NonIdentity},
78
scalar::{FromUintUnchecked, IsHigh},
@@ -18,6 +19,8 @@ pub trait CurveArithmetic: Curve {
1819
+ Copy
1920
+ ConditionallySelectable
2021
+ ConstantTimeEq
22+
+ CtEq
23+
+ CtSelect
2124
+ Debug
2225
+ Default
2326
+ DefaultIsZeroes
@@ -42,6 +45,8 @@ pub trait CurveArithmetic: Curve {
4245
/// - [`Sync`]
4346
type ProjectivePoint: ConditionallySelectable
4447
+ ConstantTimeEq
48+
+ CtEq
49+
+ CtSelect
4550
+ Default
4651
+ DefaultIsZeroes
4752
+ From<Self::AffinePoint>
@@ -66,6 +71,8 @@ pub trait CurveArithmetic: Curve {
6671
/// - [`Send`]
6772
/// - [`Sync`]
6873
type Scalar: AsRef<Self::Scalar>
74+
+ CtEq
75+
+ CtSelect
6976
+ DefaultIsZeroes
7077
+ From<NonZeroScalar<Self>>
7178
+ From<ScalarValue<Self>>

elliptic-curve/src/dev.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ impl ConstantTimeEq for Scalar {
194194
}
195195
}
196196

197+
impl ctutils::CtEq for Scalar {
198+
fn ct_eq(&self, other: &Self) -> ctutils::Choice {
199+
ctutils::CtEq::ct_eq(&self.0, &other.0)
200+
}
201+
}
202+
203+
impl ctutils::CtSelect for Scalar {
204+
fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
205+
Self(self.0.ct_select(&other.0, choice))
206+
}
207+
}
208+
197209
impl DefaultIsZeroes for Scalar {}
198210

199211
impl Add<Scalar> for Scalar {
@@ -503,8 +515,20 @@ impl ConstantTimeEq for AffinePoint {
503515

504516
impl ConditionallySelectable for AffinePoint {
505517
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
518+
ctutils::CtSelect::ct_select(a, b, choice.into())
519+
}
520+
}
521+
522+
impl ctutils::CtEq for AffinePoint {
523+
fn ct_eq(&self, other: &Self) -> ctutils::Choice {
524+
ConstantTimeEq::ct_eq(self, other).into()
525+
}
526+
}
527+
528+
impl ctutils::CtSelect for AffinePoint {
529+
fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
506530
// Not really constant time, but this is dev code
507-
if choice.into() { *b } else { *a }
531+
if choice.to_bool() { *other } else { *self }
508532
}
509533
}
510534

@@ -613,7 +637,19 @@ impl ConstantTimeEq for ProjectivePoint {
613637

614638
impl ConditionallySelectable for ProjectivePoint {
615639
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
616-
if choice.into() { *b } else { *a }
640+
ctutils::CtSelect::ct_select(a, b, choice.into())
641+
}
642+
}
643+
644+
impl ctutils::CtEq for ProjectivePoint {
645+
fn ct_eq(&self, other: &Self) -> ctutils::Choice {
646+
ConstantTimeEq::ct_eq(self, other).into()
647+
}
648+
}
649+
650+
impl ctutils::CtSelect for ProjectivePoint {
651+
fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
652+
if choice.to_bool() { *other } else { *self }
617653
}
618654
}
619655

elliptic-curve/src/scalar/value.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
use crate::{
44
Curve, Error, FieldBytes, FieldBytesEncoding, Result,
55
array::Array,
6-
bigint::{Limb, Odd, prelude::*},
7-
scalar::FromUintUnchecked,
8-
scalar::IsHigh,
6+
bigint::{AddMod, ConstOne, ConstZero, Integer, Limb, NegMod, Odd, RandomMod, SubMod, Zero},
7+
ctutils::{self, CtEq, CtGt, CtLt, CtSelect},
8+
scalar::{FromUintUnchecked, IsHigh},
99
};
1010
use base16ct::HexDisplay;
1111
use core::{
@@ -72,7 +72,10 @@ where
7272

7373
/// Create a new scalar from [`Curve::Uint`].
7474
pub fn new(uint: C::Uint) -> CtOption<Self> {
75-
CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS).into())
75+
CtOption::new(
76+
Self { inner: uint },
77+
CtLt::ct_lt(&uint, &Self::MODULUS).into(),
78+
)
7679
}
7780

7881
/// Decode [`ScalarValue`] from a serialized field element
@@ -192,6 +195,44 @@ where
192195
}
193196
}
194197

198+
impl<C> CtSelect for ScalarValue<C>
199+
where
200+
C: Curve,
201+
{
202+
fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
203+
Self {
204+
inner: C::Uint::ct_select(&self.inner, &other.inner, choice),
205+
}
206+
}
207+
}
208+
209+
impl<C> CtEq for ScalarValue<C>
210+
where
211+
C: Curve,
212+
{
213+
fn ct_eq(&self, other: &Self) -> ctutils::Choice {
214+
self.inner.ct_eq(&other.inner)
215+
}
216+
}
217+
218+
impl<C> CtGt for ScalarValue<C>
219+
where
220+
C: Curve,
221+
{
222+
fn ct_gt(&self, other: &Self) -> ctutils::Choice {
223+
self.inner.ct_gt(&other.inner)
224+
}
225+
}
226+
227+
impl<C> CtLt for ScalarValue<C>
228+
where
229+
C: Curve,
230+
{
231+
fn ct_lt(&self, other: &Self) -> ctutils::Choice {
232+
self.inner.ct_lt(&other.inner)
233+
}
234+
}
235+
195236
impl<C: Curve> DefaultIsZeroes for ScalarValue<C> {}
196237

197238
impl<C: Curve> Eq for ScalarValue<C> {}
@@ -201,7 +242,7 @@ where
201242
C: Curve,
202243
{
203244
fn eq(&self, other: &Self) -> bool {
204-
self.ct_eq(other).into()
245+
CtEq::ct_eq(self, other).to_bool()
205246
}
206247
}
207248

0 commit comments

Comments
 (0)