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

Reduce use of magic numbers #33

Merged
merged 4 commits into from
Nov 23, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions graviola/src/high/curve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl PrivateKey<P256> for p256::PrivateKey {
}

fn public_key_encode_uncompressed<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], Error> {
if let Some(out) = out.get_mut(0..65) {
if let Some(out) = out.get_mut(0..p256::PublicKey::BYTES) {
out.copy_from_slice(&self.public_key_uncompressed());
Ok(out)
} else {
Expand All @@ -180,7 +180,7 @@ impl PrivateKey<P256> for p256::PrivateKey {
}

impl PublicKey<P256> for p256::PublicKey {
const LEN_BYTES: usize = 65;
const LEN_BYTES: usize = Self::BYTES;

fn from_x962_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
Self::from_x962_uncompressed(bytes)
Expand All @@ -197,7 +197,7 @@ impl PublicKey<P256> for p256::PublicKey {
}

impl Scalar<P256> for p256::Scalar {
const LEN_BYTES: usize = 32;
const LEN_BYTES: usize = Self::BYTES;

fn from_bytes_checked(bytes: &[u8]) -> Result<Self, Error> {
Self::from_bytes_checked(bytes)
Expand Down Expand Up @@ -258,7 +258,7 @@ impl PrivateKey<P384> for p384::PrivateKey {
}

fn public_key_encode_uncompressed<'a>(&self, out: &'a mut [u8]) -> Result<&'a [u8], Error> {
if let Some(out) = out.get_mut(0..97) {
if let Some(out) = out.get_mut(0..p384::PublicKey::BYTES) {
out.copy_from_slice(&self.public_key_uncompressed());
Ok(out)
} else {
Expand All @@ -272,7 +272,7 @@ impl PrivateKey<P384> for p384::PrivateKey {
}

impl PublicKey<P384> for p384::PublicKey {
const LEN_BYTES: usize = 97;
const LEN_BYTES: usize = Self::BYTES;

fn from_x962_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
Self::from_x962_uncompressed(bytes)
Expand All @@ -289,7 +289,7 @@ impl PublicKey<P384> for p384::PublicKey {
}

impl Scalar<P384> for p384::Scalar {
const LEN_BYTES: usize = 48;
const LEN_BYTES: usize = Self::BYTES;

fn from_bytes_checked(bytes: &[u8]) -> Result<Self, Error> {
Self::from_bytes_checked(bytes)
Expand Down
12 changes: 6 additions & 6 deletions graviola/src/high/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use core::ops::{Deref, DerefMut};
#[derive(Clone, Debug)]
pub enum HashOutput {
/// Output from SHA256
Sha256([u8; 32]),
Sha256([u8; Sha256Context::OUTPUT_SZ]),
/// Output from SHA384
Sha384([u8; 48]),
Sha384([u8; Sha384Context::OUTPUT_SZ]),
/// Output from SHA512
Sha512([u8; 64]),
Sha512([u8; Sha512Context::OUTPUT_SZ]),
}

impl HashOutput {
Expand Down Expand Up @@ -160,7 +160,7 @@ impl Hash for Sha256 {
}

fn zeroed_output() -> HashOutput {
HashOutput::Sha256([0u8; 32])
HashOutput::Sha256([0u8; Sha256Context::OUTPUT_SZ])
}
}

Expand Down Expand Up @@ -198,7 +198,7 @@ impl Hash for Sha384 {
}

fn zeroed_output() -> HashOutput {
HashOutput::Sha384([0u8; 48])
HashOutput::Sha384([0u8; Sha384Context::OUTPUT_SZ])
}
}

Expand Down Expand Up @@ -235,7 +235,7 @@ impl Hash for Sha512 {
}

fn zeroed_output() -> HashOutput {
HashOutput::Sha512([0u8; 64])
HashOutput::Sha512([0u8; Sha512Context::OUTPUT_SZ])
}
}

Expand Down
76 changes: 47 additions & 29 deletions graviola/src/mid/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::mid::rng::{RandomSource, SystemRandom};
use crate::Error;

use core::fmt;
use core::ops::Range;

mod precomp;

Expand All @@ -18,6 +19,8 @@ pub struct PublicKey {
}

impl PublicKey {
pub(crate) const BYTES: usize = 1 + FieldElement::BYTES + FieldElement::BYTES;

/// Create an P-256 [`PublicKey`] from a byte slice.
///
/// This must be exactly 65 bytes in length, using the X9.62
Expand All @@ -30,7 +33,7 @@ impl PublicKey {
}

/// Encodes this public key using the X9.62 uncompressed encoding.
pub fn as_bytes_uncompressed(&self) -> [u8; 65] {
pub fn as_bytes_uncompressed(&self) -> [u8; Self::BYTES] {
let _ = low::Entry::new_public();
self.point.as_bytes_uncompressed()
}
Expand Down Expand Up @@ -102,14 +105,14 @@ impl PrivateKey {
}

/// Return a fixed-length encoding of this private key's value.
pub fn as_bytes(&self) -> [u8; 32] {
pub fn as_bytes(&self) -> [u8; Scalar::BYTES] {
let _ = low::Entry::new_secret();
self.scalar.as_bytes()
}

/// Derive the corresponding public key, and return it in
/// X9.62 uncompressed encoding.
pub fn public_key_uncompressed(&self) -> [u8; 65] {
pub fn public_key_uncompressed(&self) -> [u8; PublicKey::BYTES] {
let _ = low::Entry::new_secret();
self.public_point().as_bytes_uncompressed()
}
Expand Down Expand Up @@ -148,7 +151,7 @@ impl PrivateKey {
pub(crate) fn generate(rng: &mut dyn RandomSource) -> Result<Self, Error> {
let _ = low::Entry::new_secret();
for _ in 0..64 {
let mut r = [0u8; 32];
let mut r = [0u8; Scalar::BYTES];
rng.fill(&mut r)?;
if let Ok(p) = Self::from_bytes(&r) {
return Ok(p);
Expand Down Expand Up @@ -178,7 +181,7 @@ impl fmt::Debug for PrivateKey {
}

/// A shared secret output from a P-256 Diffie-Hellman operation.
pub struct SharedSecret(pub [u8; 32]);
pub struct SharedSecret(pub [u8; FieldElement::BYTES]);

impl Drop for SharedSecret {
fn drop(&mut self) {
Expand All @@ -192,19 +195,22 @@ struct AffineMontPoint {
}

impl AffineMontPoint {
const X: Range<usize> = 0..4;
const Y: Range<usize> = 4..8;

fn from_x962_uncompressed(bytes: &[u8]) -> Result<Self, Error> {
match bytes.first() {
Some(&0x04) => (),
Some(_) => return Err(Error::NotUncompressed),
None => return Err(Error::WrongLength),
}

if bytes.len() != 1 + 64 {
if bytes.len() != PublicKey::BYTES {
return Err(Error::WrongLength);
}

let x = &bytes[1..33];
let y = &bytes[33..65];
let (_, xy) = bytes.split_at(1);
let (x, y) = xy.split_at(FieldElement::BYTES);

let point = Self::from_xy(
FieldElement(util::big_endian_slice_to_u64x4(x).unwrap()).as_mont(),
Expand All @@ -220,22 +226,22 @@ impl AffineMontPoint {

fn x_scalar(&self) -> Scalar {
let bytes = self.as_bytes_uncompressed();
Scalar::from_bytes_reduced(&bytes[1..33]).unwrap()
Scalar::from_bytes_reduced(&bytes[1..1 + Scalar::BYTES]).unwrap()
}

fn from_xy(x: FieldElement, y: FieldElement) -> Self {
let mut r = Self::default();
r.xy[0..4].copy_from_slice(&x.0[..]);
r.xy[4..8].copy_from_slice(&y.0[..]);
r.xy[Self::X].copy_from_slice(&x.0[..]);
r.xy[Self::Y].copy_from_slice(&y.0[..]);
r
}

fn x(&self) -> FieldElement {
FieldElement(self.xy[0..4].try_into().unwrap())
FieldElement(self.xy[Self::X].try_into().unwrap())
}

fn y(&self) -> FieldElement {
FieldElement(self.xy[4..8].try_into().unwrap())
FieldElement(self.xy[Self::Y].try_into().unwrap())
}

fn on_curve(&self) -> bool {
Expand All @@ -257,11 +263,14 @@ impl AffineMontPoint {
lhs.public_eq(&rhs)
}

fn as_bytes_uncompressed(&self) -> [u8; 65] {
let mut r = [0u8; 65];
r[0] = 0x04;
r[1..33].copy_from_slice(&util::u64x4_to_big_endian(&self.x().demont().0));
r[33..65].copy_from_slice(&util::u64x4_to_big_endian(&self.y().demont().0));
fn as_bytes_uncompressed(&self) -> [u8; PublicKey::BYTES] {
let mut r = [0u8; PublicKey::BYTES];
let (indicator, xy) = r.split_at_mut(1);
let (x, y) = xy.split_at_mut(FieldElement::BYTES);

indicator[0] = 0x04;
x.copy_from_slice(&util::u64x4_to_big_endian(&self.x().demont().0));
y.copy_from_slice(&util::u64x4_to_big_endian(&self.y().demont().0));
r
}

Expand All @@ -282,14 +291,14 @@ impl AffineMontPoint {

fn negate_y(&mut self) {
let neg_y = self.y().negate_mod_p();
self.xy[4..8].copy_from_slice(&neg_y.0);
self.xy[Self::Y].copy_from_slice(&neg_y.0);
}

fn maybe_negate_y(&mut self, sign: u8) {
let y = self.y();
let neg_y = y.negate_mod_p();
let result = FieldElement::select(&y, &neg_y, sign);
self.xy[4..8].copy_from_slice(&result.0);
self.xy[Self::Y].copy_from_slice(&result.0);
}

/// Precomputes wNAF form (with 𝑤=6) for the point `self`
Expand Down Expand Up @@ -396,6 +405,11 @@ struct JacobianMontPoint {
}

impl JacobianMontPoint {
const X: Range<usize> = 0..4;
const Y: Range<usize> = 4..8;
const XY: Range<usize> = 0..8;
const Z: Range<usize> = 8..12;

fn infinity() -> Self {
Self {
xyz: [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
Expand All @@ -411,19 +425,19 @@ impl JacobianMontPoint {
}

fn x(&self) -> FieldElement {
FieldElement(self.xyz[0..4].try_into().unwrap())
FieldElement(self.xyz[Self::X].try_into().unwrap())
}

fn y(&self) -> FieldElement {
FieldElement(self.xyz[4..8].try_into().unwrap())
FieldElement(self.xyz[Self::Y].try_into().unwrap())
}

fn z(&self) -> FieldElement {
FieldElement(self.xyz[8..12].try_into().unwrap())
FieldElement(self.xyz[Self::Z].try_into().unwrap())
}

fn set_z(&mut self, fe: &FieldElement) {
self.xyz[8..12].copy_from_slice(&fe.0);
self.xyz[Self::Z].copy_from_slice(&fe.0);
}

fn base_multiply(scalar: &Scalar) -> Self {
Expand Down Expand Up @@ -527,8 +541,8 @@ impl JacobianMontPoint {

fn from_affine(p: &AffineMontPoint) -> Self {
let mut xyz: [u64; 12] = Default::default();
xyz[..8].copy_from_slice(&p.xy);
xyz[8..12].copy_from_slice(&CURVE_ONE_MONT.0);
xyz[Self::XY].copy_from_slice(&p.xy);
xyz[Self::Z].copy_from_slice(&CURVE_ONE_MONT.0);
Self { xyz }
}

Expand Down Expand Up @@ -635,21 +649,23 @@ impl JacobianMontPoint {

fn negate_y(&mut self) {
let neg_y = self.y().negate_mod_p();
self.xyz[4..8].copy_from_slice(&neg_y.0);
self.xyz[Self::Y].copy_from_slice(&neg_y.0);
}

fn maybe_negate_y(&mut self, sign: u8) {
let y = self.y();
let neg_y = y.negate_mod_p();
let result = FieldElement::select(&y, &neg_y, sign);
self.xyz[4..8].copy_from_slice(&result.0);
self.xyz[Self::Y].copy_from_slice(&result.0);
}
}

#[derive(Clone, Copy, Debug, Default)]
struct FieldElement([u64; 4]);

impl FieldElement {
const BYTES: usize = 32;

fn inv(&self) -> Self {
let mut r = Self::default();
low::bignum_inv_p256(&mut r.0, &self.0);
Expand Down Expand Up @@ -715,6 +731,8 @@ impl FieldElement {
pub struct Scalar([u64; 4]);

impl Scalar {
pub(crate) const BYTES: usize = 32;

/// Create a scalar from the given slice, which can be any size.
///
/// If it is larger than 32 bytes, the leading bytes must be
Expand Down Expand Up @@ -745,7 +763,7 @@ impl Scalar {
}
}

pub(crate) fn as_bytes(&self) -> [u8; 32] {
pub(crate) fn as_bytes(&self) -> [u8; Self::BYTES] {
util::u64x4_to_big_endian(&self.0)
}

Expand Down
Loading