Skip to content

Commit

Permalink
Introduce ristretto255 crate feature (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Dec 23, 2021
1 parent 140f9e0 commit 6669a0c
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 158 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ jobs:
backend_feature:
- ristretto255_u64
- ristretto255_u32
# skip doc tests
- p256 --lib
- p256
- ristretto255_u64,p256
frontend_feature:
-
Expand Down
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ version = "0.3.0"
danger = []
default = ["ristretto255_u64", "serde"]
p256 = ["num-bigint", "num-integer", "num-traits", "once_cell", "p256_"]
ristretto255_fiat_u32 = ["curve25519-dalek/fiat_u32_backend"]
ristretto255_fiat_u64 = ["curve25519-dalek/fiat_u64_backend"]
ristretto255_simd = ["curve25519-dalek/simd_backend"]
ristretto255_u32 = ["curve25519-dalek/u32_backend"]
ristretto255_u64 = ["curve25519-dalek/u64_backend"]
ristretto255 = []
ristretto255_fiat_u32 = ["curve25519-dalek/fiat_u32_backend", "ristretto255"]
ristretto255_fiat_u64 = ["curve25519-dalek/fiat_u64_backend", "ristretto255"]
ristretto255_simd = ["curve25519-dalek/simd_backend", "ristretto255"]
ristretto255_u32 = ["curve25519-dalek/u32_backend", "ristretto255"]
ristretto255_u64 = ["curve25519-dalek/u64_backend", "ristretto255"]
std = []

[dependencies]
Expand Down
14 changes: 3 additions & 11 deletions src/group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@

//! Defines the Group trait to specify the underlying prime order group

#[cfg(any(
feature = "ristretto255_u64",
feature = "ristretto255_u32",
feature = "ristretto255_fiat_u64",
feature = "ristretto255_fiat_u32",
feature = "ristretto255_simd",
feature = "p256",
))]
#[cfg(any(feature = "ristretto255", feature = "p256",))]
mod expand;
#[cfg(feature = "p256")]
mod p256;
cfg_ristretto! {
mod ristretto;
}
#[cfg(feature = "ristretto255")]
mod ristretto;

use core::ops::{Add, Mul, Sub};

Expand Down
208 changes: 102 additions & 106 deletions src/group/ristretto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,127 +5,123 @@
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree.

use super::Group;
use crate::errors::InternalError;
use core::convert::TryInto;
use core::ops::Add;
use curve25519_dalek::{
constants::RISTRETTO_BASEPOINT_POINT,
ristretto::{CompressedRistretto, RistrettoPoint},
scalar::Scalar,
traits::Identity,
};

use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint};
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::Identity;
use digest::{BlockInput, Digest};
use generic_array::{
typenum::{U1, U32, U64},
ArrayLength, GenericArray,
};
use generic_array::typenum::{U1, U32, U64};
use generic_array::{ArrayLength, GenericArray};
use rand_core::{CryptoRng, RngCore};

// `cfg` here is only needed because of a bug in Rust's crate feature documentation. See:
// https://github.com/rust-lang/rust/issues/83428
cfg_ristretto! {
/// The implementation of such a subgroup for Ristretto
impl Group for RistrettoPoint {
const SUITE_ID: usize = 0x0001;

// Implements the `hash_to_ristretto255()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.txt
fn hash_to_curve<H: BlockInput + Digest, D: ArrayLength<u8> + Add<U1>>(
msg: &[u8],
dst: GenericArray<u8, D>,
) -> Result<Self, InternalError>
where
<D as Add<U1>>::Output: ArrayLength<u8>,
{
let uniform_bytes = super::expand::expand_message_xmd::<H, U64, _, _>(Some(msg), dst)?;

Ok(RistrettoPoint::from_uniform_bytes(
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalError::HashToCurveError)?,
))
}
use super::Group;
use crate::errors::InternalError;

// Implements the `HashToScalar()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-07.html#section-4.1
fn hash_to_scalar<
'a,
H: BlockInput + Digest,
D: ArrayLength<u8> + Add<U1>,
I: IntoIterator<Item = &'a [u8]>,
>(
input: I,
dst: GenericArray<u8, D>,
) -> Result<Self::Scalar, InternalError>
where
<D as Add<U1>>::Output: ArrayLength<u8>,
{
let uniform_bytes = super::expand::expand_message_xmd::<H, U64, _, _>(input, dst)?;

Ok(Scalar::from_bytes_mod_order_wide(
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalError::HashToCurveError)?,
))
}
// `cfg` here is only needed because of a bug in Rust's crate feature documentation. See: https://github.com/rust-lang/rust/issues/83428
#[cfg(feature = "ristretto255")]
/// The implementation of such a subgroup for Ristretto
impl Group for RistrettoPoint {
const SUITE_ID: usize = 0x0001;

type Scalar = Scalar;
type ScalarLen = U32;
fn from_scalar_slice_unchecked(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalError> {
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
}
// Implements the `hash_to_ristretto255()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-10.txt
fn hash_to_curve<H: BlockInput + Digest, D: ArrayLength<u8> + Add<U1>>(
msg: &[u8],
dst: GenericArray<u8, D>,
) -> Result<Self, InternalError>
where
<D as Add<U1>>::Output: ArrayLength<u8>,
{
let uniform_bytes = super::expand::expand_message_xmd::<H, U64, _, _>(Some(msg), dst)?;

Ok(RistrettoPoint::from_uniform_bytes(
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalError::HashToCurveError)?,
))
}

// Implements the `HashToScalar()` function from
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-07.html#section-4.1
fn hash_to_scalar<
'a,
H: BlockInput + Digest,
D: ArrayLength<u8> + Add<U1>,
I: IntoIterator<Item = &'a [u8]>,
>(
input: I,
dst: GenericArray<u8, D>,
) -> Result<Self::Scalar, InternalError>
where
<D as Add<U1>>::Output: ArrayLength<u8>,
{
let uniform_bytes = super::expand::expand_message_xmd::<H, U64, _, _>(input, dst)?;

Ok(Scalar::from_bytes_mod_order_wide(
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalError::HashToCurveError)?,
))
}

type Scalar = Scalar;
type ScalarLen = U32;
fn from_scalar_slice_unchecked(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalError> {
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
}

fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
loop {
let scalar = {
let mut scalar_bytes = [0u8; 64];
rng.fill_bytes(&mut scalar_bytes);
Scalar::from_bytes_mod_order_wide(&scalar_bytes)
};

if scalar != Scalar::zero() {
break scalar;
}
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
loop {
let scalar = {
let mut scalar_bytes = [0u8; 64];
rng.fill_bytes(&mut scalar_bytes);
Scalar::from_bytes_mod_order_wide(&scalar_bytes)
};

if scalar != Scalar::zero() {
break scalar;
}
}
}

fn scalar_as_bytes(scalar: Self::Scalar) -> GenericArray<u8, Self::ScalarLen> {
scalar.to_bytes().into()
}
fn scalar_as_bytes(scalar: Self::Scalar) -> GenericArray<u8, Self::ScalarLen> {
scalar.to_bytes().into()
}

fn scalar_invert(scalar: &Self::Scalar) -> Self::Scalar {
scalar.invert()
}
fn scalar_invert(scalar: &Self::Scalar) -> Self::Scalar {
scalar.invert()
}

// The byte length necessary to represent group elements
type ElemLen = U32;
fn from_element_slice_unchecked(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalError> {
CompressedRistretto::from_slice(element_bits)
.decompress()
.ok_or(InternalError::PointError)
}
// serialization of a group element
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
self.compress().to_bytes().into()
}
// The byte length necessary to represent group elements
type ElemLen = U32;
fn from_element_slice_unchecked(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalError> {
CompressedRistretto::from_slice(element_bits)
.decompress()
.ok_or(InternalError::PointError)
}
// serialization of a group element
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
self.compress().to_bytes().into()
}

fn base_point() -> Self {
RISTRETTO_BASEPOINT_POINT
}
fn base_point() -> Self {
RISTRETTO_BASEPOINT_POINT
}

fn identity() -> Self {
<Self as Identity>::identity()
}
fn identity() -> Self {
<Self as Identity>::identity()
}

fn scalar_zero() -> Self::Scalar {
Self::Scalar::zero()
}
fn scalar_zero() -> Self::Scalar {
Self::Scalar::zero()
}
}
5 changes: 3 additions & 2 deletions src/group/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ use crate::group::Group;

#[test]
fn test_group_properties() -> Result<(), InternalError> {
cfg_ristretto! { {
#[cfg(feature = "ristretto255")]
{
use curve25519_dalek::ristretto::RistrettoPoint;

test_identity_element_error::<RistrettoPoint>()?;
test_zero_scalar_error::<RistrettoPoint>()?;
} }
}

#[cfg(feature = "p256")]
{
Expand Down
Loading

0 comments on commit 6669a0c

Please sign in to comment.