Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

k256+p256: impl LinearCombination trait #476

Merged
merged 1 commit into from Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
8 changes: 5 additions & 3 deletions k256/bench/scalar.rs
Expand Up @@ -5,8 +5,8 @@ use criterion::{
};
use hex_literal::hex;
use k256::{
elliptic_curve::{generic_array::arr, group::ff::PrimeField},
lincomb, ProjectivePoint, Scalar,
elliptic_curve::{generic_array::arr, group::ff::PrimeField, ops::LinearCombination},
ProjectivePoint, Scalar, Secp256k1,
};

fn test_scalar_x() -> Scalar {
Expand Down Expand Up @@ -39,7 +39,9 @@ fn bench_point_lincomb<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) {
let m = hex!("AA5E28D6A97A2479A65527F7290311A3624D4CC0FA1578598EE3C2613BF99522");
let s = Scalar::from_repr(m.into()).unwrap();
group.bench_function("lincomb via mul+add", |b| b.iter(|| &p * &s + &p * &s));
group.bench_function("lincomb()", |b| b.iter(|| lincomb(&p, &s, &p, &s)));
group.bench_function("lincomb()", |b| {
b.iter(|| Secp256k1::lincomb(&p, &s, &p, &s))
});
}

fn bench_high_level(c: &mut Criterion) {
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