From 712434de7030866e360954ad88120dac11b44219 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 14:41:51 -0700 Subject: [PATCH] elliptic-curve: make `NonZeroScalar::invert` infallible Because `NonZeroScalar` means we'll never divide by 0, it's possible to make the implementation infallible. To accomplish this, `CtOption` is removed from the `Invert` trait's signature, and used as the result type for scalars that are potentially zero as part of the blanket impl of `Invert`. Fixes RustCrypto/elliptic-curves#499 --- elliptic-curve/src/ops.rs | 7 +++---- elliptic-curve/src/scalar/nonzero.rs | 10 ++++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index d6a215490..64a0eb3c6 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -3,10 +3,9 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; -use subtle::CtOption; #[cfg(feature = "arithmetic")] -use group::Group; +use {group::Group, subtle::CtOption}; #[cfg(feature = "digest")] use digest::{core_api::BlockSizeUser, Digest, FixedOutput, Reset}; @@ -17,12 +16,12 @@ pub trait Invert { type Output; /// Invert a field element. - fn invert(&self) -> CtOption; + fn invert(&self) -> Self::Output; } #[cfg(feature = "arithmetic")] impl Invert for F { - type Output = F; + type Output = CtOption; fn invert(&self) -> CtOption { ff::Field::invert(self) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 224c26603..7450537a9 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -170,11 +170,13 @@ impl Invert for NonZeroScalar where C: Curve + ScalarArithmetic, { - type Output = Scalar; + type Output = Self; - /// Perform a scalar inversion - fn invert(&self) -> CtOption { - ff::Field::invert(&self.scalar) + fn invert(&self) -> Self { + Self { + // This will always succeed since `scalar` will never be 0 + scalar: ff::Field::invert(&self.scalar).unwrap(), + } } }