ecdsa: use NonZeroScalar arguments to sign_prehashed (#794)

Provides type-level enforcement that these parameters are non-zero
This commit is contained in:
Tony Arcieri
2024-01-18 02:07:59 +00:00
committed by GitHub
parent 3ed9867409
commit ff9a2058bd
3 changed files with 13 additions and 18 deletions
+3 -3
View File
@@ -43,14 +43,14 @@ macro_rules! new_signing_test {
array::{typenum::Unsigned, Array},
bigint::Encoding,
group::ff::PrimeField,
Curve, CurveArithmetic, FieldBytes, Scalar,
Curve, CurveArithmetic, FieldBytes, NonZeroScalar, Scalar,
},
hazmat::sign_prehashed,
};
fn decode_scalar(bytes: &[u8]) -> Option<Scalar<$curve>> {
fn decode_scalar(bytes: &[u8]) -> Option<NonZeroScalar<$curve>> {
if bytes.len() == <$curve as Curve>::FieldBytesSize::USIZE {
Scalar::<$curve>::from_repr(bytes.try_into().unwrap()).into()
NonZeroScalar::<$curve>::from_repr(bytes.try_into().unwrap()).into()
} else {
None
}
+8 -13
View File
@@ -18,12 +18,12 @@ use elliptic_curve::{array::typenum::Unsigned, FieldBytes};
use {
crate::{RecoveryId, SignatureSize},
elliptic_curve::{
ff::{Field, PrimeField},
ff::PrimeField,
group::{Curve as _, Group},
ops::{Invert, LinearCombination, MulByGenerator, Reduce},
point::AffineCoordinates,
scalar::IsHigh,
CurveArithmetic, ProjectivePoint, Scalar,
CurveArithmetic, NonZeroScalar, ProjectivePoint, Scalar,
},
};
@@ -121,23 +121,18 @@ pub fn bits2field<C: EcdsaCurve>(bits: &[u8]) -> Result<FieldBytes<C>> {
#[cfg(feature = "arithmetic")]
#[allow(non_snake_case)]
pub fn sign_prehashed<C>(
d: &Scalar<C>,
k: &Scalar<C>,
d: &NonZeroScalar<C>,
k: &NonZeroScalar<C>,
z: &FieldBytes<C>,
) -> Result<(Signature<C>, RecoveryId)>
where
C: EcdsaCurve + CurveArithmetic,
SignatureSize<C>: ArraySize,
{
// TODO(tarcieri): use `NonZeroScalar<C>` for `k`.
if k.is_zero().into() {
return Err(Error::new());
}
let z = <Scalar<C> as Reduce<C::Uint>>::reduce_bytes(z);
// Compute scalar inversion of 𝑘
let k_inv = Option::<Scalar<C>>::from(Invert::invert(k)).ok_or_else(Error::new)?;
let k_inv = k.invert();
// Compute 𝑹 = 𝑘×𝑮
let R = ProjectivePoint::<C>::mul_by_generator(k).to_affine();
@@ -148,7 +143,7 @@ where
let x_is_reduced = r.to_repr() != R.x();
// Compute 𝒔 as a signature over 𝒓 and 𝒛.
let s = k_inv * (z + (r * d));
let s = *k_inv * (z + (r * d.as_ref()));
// NOTE: `Signature::from_scalars` checks that both `r` and `s` are non-zero.
let mut signature = Signature::from_scalars(r, s)?;
@@ -174,7 +169,7 @@ where
/// [RFC6979]: https://datatracker.ietf.org/doc/html/rfc6979
#[cfg(feature = "rfc6979")]
pub fn sign_prehashed_rfc6979<C, D>(
d: &Scalar<C>,
d: &NonZeroScalar<C>,
z: &FieldBytes<C>,
ad: &[u8],
) -> Result<(Signature<C>, RecoveryId)>
@@ -191,7 +186,7 @@ where
// h = bits2int(H(m)) mod q
let z2 = <Scalar<C> as Reduce<C::Uint>>::reduce_bytes(z);
let k = Scalar::<C>::from_repr(rfc6979::generate_k::<D, _>(
let k = NonZeroScalar::<C>::from_repr(rfc6979::generate_k::<D, _>(
&d.to_repr(),
&C::ORDER.encode_field_bytes(),
&z2.to_repr(),
+2 -2
View File
@@ -157,7 +157,7 @@ where
{
fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature<C>> {
let z = bits2field::<C>(prehash)?;
Ok(sign_prehashed_rfc6979::<C, C::Digest>(self.secret_scalar.as_ref(), &z, &[])?.0)
Ok(sign_prehashed_rfc6979::<C, C::Digest>(&self.secret_scalar, &z, &[])?.0)
}
}
@@ -206,7 +206,7 @@ where
let z = bits2field::<C>(prehash)?;
let mut ad = FieldBytes::<C>::default();
rng.fill_bytes(&mut ad);
Ok(sign_prehashed_rfc6979::<C, C::Digest>(self.secret_scalar.as_ref(), &z, &ad)?.0)
Ok(sign_prehashed_rfc6979::<C, C::Digest>(&self.secret_scalar, &z, &ad)?.0)
}
}