Skip to content

Commit

Permalink
k256+p256: impl LinearCombination trait
Browse files Browse the repository at this point in the history
Adds impls of traits for linear combinations added in
RustCrypto/traits#833:

- `k256` uses an optimized implementation.
- `p256` uses the default unoptimized implementation.
  • Loading branch information
tarcieri committed Dec 4, 2021
1 parent 79c0963 commit 3dabeec
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 29 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion k256/Cargo.toml
Expand Up @@ -19,7 +19,7 @@ rust-version = "1.56"

[dependencies]
cfg-if = "1.0"
elliptic-curve = { version = "0.11.3", default-features = false, features = ["hazmat", "sec1"] }
elliptic-curve = { version = "0.11.4", default-features = false, features = ["hazmat", "sec1"] }
sec1 = { version = "0.2", default-features = false }

# optional dependencies
Expand Down
1 change: 0 additions & 1 deletion k256/src/arithmetic.rs
Expand Up @@ -10,7 +10,6 @@ pub(crate) mod scalar;
mod dev;

pub use field::FieldElement;
pub use mul::lincomb;

use affine::AffinePoint;
use projective::ProjectivePoint;
Expand Down
38 changes: 22 additions & 16 deletions k256/src/arithmetic/mul.rs
Expand Up @@ -65,12 +65,16 @@
//! In experiments, I was not able to detect any case where they would go outside the 128 bit bound,
//! but I cannot be sure that it cannot happen.

use crate::arithmetic::{
scalar::{Scalar, WideScalar},
ProjectivePoint,
use crate::{
arithmetic::{
scalar::{Scalar, WideScalar},
ProjectivePoint,
},
Secp256k1,
};
use core::ops::{Mul, MulAssign};
use elliptic_curve::{
ops::LinearCombination,
subtle::{Choice, ConditionallySelectable, ConstantTimeEq},
IsHigh,
};
Expand Down Expand Up @@ -301,14 +305,15 @@ fn mul(x: &ProjectivePoint, k: &Scalar) -> ProjectivePoint {
lincomb_generic(&[*x], &[*k])
}

/// Calculates `x * k + y * l`.
pub fn lincomb(
x: &ProjectivePoint,
k: &Scalar,
y: &ProjectivePoint,
l: &Scalar,
) -> ProjectivePoint {
lincomb_generic(&[*x, *y], &[*k, *l])
impl LinearCombination for Secp256k1 {
fn lincomb(
x: &ProjectivePoint,
k: &Scalar,
y: &ProjectivePoint,
l: &Scalar,
) -> ProjectivePoint {
lincomb_generic(&[*x, *y], &[*k, *l])
}
}

impl Mul<Scalar> for ProjectivePoint {
Expand Down Expand Up @@ -349,10 +354,11 @@ impl MulAssign<&Scalar> for ProjectivePoint {

#[cfg(test)]
mod tests {
use super::lincomb;
use crate::arithmetic::{ProjectivePoint, Scalar};
use elliptic_curve::rand_core::OsRng;
use elliptic_curve::{Field, Group};
use crate::{
arithmetic::{ProjectivePoint, Scalar},
Secp256k1,
};
use elliptic_curve::{ops::LinearCombination, rand_core::OsRng, Field, Group};

#[test]
fn test_lincomb() {
Expand All @@ -362,7 +368,7 @@ mod tests {
let l = Scalar::random(&mut OsRng);

let reference = &x * &k + &y * &l;
let test = lincomb(&x, &k, &y, &l);
let test = Secp256k1::lincomb(&x, &k, &y, &l);
assert_eq!(reference, test);
}
}
6 changes: 3 additions & 3 deletions k256/src/ecdsa/recoverable.rs
Expand Up @@ -48,10 +48,10 @@ use crate::{
elliptic_curve::{
bigint::U256,
consts::U32,
ops::{Invert, Reduce},
ops::{Invert, LinearCombination, Reduce},
DecompressPoint,
},
lincomb, AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar,
AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar, Secp256k1,
};

#[cfg(feature = "keccak256")]
Expand Down Expand Up @@ -181,7 +181,7 @@ impl Signature {
let r_inv = r.invert().unwrap();
let u1 = -(r_inv * z);
let u2 = r_inv * *s;
let pk = lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine();
let pk = Secp256k1::lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine();

// TODO(tarcieri): ensure the signature verifies?
Ok(VerifyingKey::from(&pk))
Expand Down
7 changes: 3 additions & 4 deletions k256/src/ecdsa/verify.rs
Expand Up @@ -2,14 +2,13 @@

use super::{recoverable, Error, Signature};
use crate::{
lincomb, AffinePoint, CompressedPoint, EncodedPoint, ProjectivePoint, PublicKey, Scalar,
Secp256k1,
AffinePoint, CompressedPoint, EncodedPoint, ProjectivePoint, PublicKey, Scalar, Secp256k1,
};
use ecdsa_core::{hazmat::VerifyPrimitive, signature};
use elliptic_curve::{
bigint::U256,
consts::U32,
ops::{Invert, Reduce},
ops::{Invert, LinearCombination, Reduce},
sec1::ToEncodedPoint,
IsHigh,
};
Expand Down Expand Up @@ -111,7 +110,7 @@ impl VerifyPrimitive<Secp256k1> for AffinePoint {
let u1 = z * s_inv;
let u2 = *r * s_inv;

let x = lincomb(
let x = Secp256k1::lincomb(
&ProjectivePoint::generator(),
&u1,
&ProjectivePoint::from(*self),
Expand Down
2 changes: 1 addition & 1 deletion k256/src/lib.rs
Expand Up @@ -39,7 +39,7 @@ pub mod test_vectors;
pub use elliptic_curve::{self, bigint::U256};

#[cfg(feature = "arithmetic")]
pub use arithmetic::{affine::AffinePoint, lincomb, projective::ProjectivePoint, scalar::Scalar};
pub use arithmetic::{affine::AffinePoint, projective::ProjectivePoint, scalar::Scalar};

#[cfg(feature = "expose-field")]
pub use arithmetic::FieldElement;
Expand Down
6 changes: 5 additions & 1 deletion p256/src/arithmetic.rs
@@ -1,12 +1,14 @@
//! A pure-Rust implementation of group operations on secp256r1.
//! Pure Rust implementation of group operations on secp256r1.

pub(crate) mod affine;
mod field;
pub(crate) mod projective;
pub(crate) mod scalar;
pub(crate) mod util;

use crate::NistP256;
use affine::AffinePoint;
use elliptic_curve::ops::LinearCombination;
use field::{FieldElement, MODULUS};
use projective::ProjectivePoint;
use scalar::Scalar;
Expand All @@ -25,6 +27,8 @@ const CURVE_EQUATION_B: FieldElement = FieldElement([
0xdc30_061d_0487_4834,
]);

impl LinearCombination for NistP256 {}

#[cfg(test)]
mod tests {
use super::{CURVE_EQUATION_A, CURVE_EQUATION_B};
Expand Down

0 comments on commit 3dabeec

Please sign in to comment.