Add support for Ristretto

Replaces P-256 as the curve used for testing FROST.
This commit is contained in:
Luke Parker
2022-06-06 04:22:49 -04:00
parent e0ce6e5c12
commit 301634dd8e
12 changed files with 477 additions and 412 deletions

View File

@@ -16,88 +16,123 @@ use dalek::{
traits::Identity,
scalar::Scalar as DScalar,
edwards::{
EdwardsPoint as DPoint,
EdwardsBasepointTable as DTable,
CompressedEdwardsY as DCompressed
EdwardsPoint as DEdwardsPoint,
EdwardsBasepointTable as DEdwardsBasepointTable,
CompressedEdwardsY as DCompressedEdwards
},
ristretto::{
RistrettoPoint as DRistrettoPoint,
RistrettoBasepointTable as DRistrettoBasepointTable,
CompressedRistretto as DCompressedRistretto
}
};
use group::{ff::{Field, PrimeField}, Group};
macro_rules! deref_borrow {
($Source: ident, $Target: ident) => {
impl Deref for $Source {
type Target = $Target;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Borrow<$Target> for $Source {
fn borrow(&self) -> &$Target {
&self.0
}
}
impl Borrow<$Target> for &$Source {
fn borrow(&self) -> &$Target {
&self.0
}
}
}
}
macro_rules! math {
($Value: ident, $Factor: ident, $Product: ident) => {
impl Add<$Value> for $Value {
type Output = Self;
fn add(self, other: $Value) -> Self::Output { Self(self.0 + other.0) }
}
impl AddAssign for $Value {
fn add_assign(&mut self, other: $Value) { self.0 += other.0 }
}
impl<'a> Add<&'a $Value> for $Value {
type Output = Self;
fn add(self, other: &'a $Value) -> Self::Output { Self(self.0 + other.0) }
}
impl<'a> AddAssign<&'a $Value> for $Value {
fn add_assign(&mut self, other: &'a $Value) { self.0 += other.0 }
}
impl Sub<$Value> for $Value {
type Output = Self;
fn sub(self, other: $Value) -> Self::Output { Self(self.0 - other.0) }
}
impl SubAssign for $Value {
fn sub_assign(&mut self, other: $Value) { self.0 -= other.0 }
}
impl<'a> Sub<&'a $Value> for $Value {
type Output = Self;
fn sub(self, other: &'a $Value) -> Self::Output { Self(self.0 - other.0) }
}
impl<'a> SubAssign<&'a $Value> for $Value {
fn sub_assign(&mut self, other: &'a $Value) { self.0 -= other.0 }
}
impl Neg for $Value {
type Output = Self;
fn neg(self) -> Self::Output { Self(-self.0) }
}
impl Mul<$Factor> for $Value {
type Output = $Product;
fn mul(self, other: $Factor) -> Self::Output { Self(self.0 * other.0) }
}
impl MulAssign<$Factor> for $Value {
fn mul_assign(&mut self, other: $Factor) { self.0 *= other.0 }
}
impl<'a> Mul<&'a $Factor> for $Value {
type Output = Self;
fn mul(self, b: &'a $Factor) -> $Product { Self(b.0 * self.0) }
}
impl<'a> MulAssign<&'a $Factor> for $Value {
fn mul_assign(&mut self, other: &'a $Factor) { self.0 *= other.0 }
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub struct Scalar(pub DScalar);
deref_borrow!(Scalar, DScalar);
math!(Scalar, Scalar, Scalar);
impl Deref for Scalar {
type Target = DScalar;
fn deref(&self) -> &Self::Target {
&self.0
impl Scalar {
pub fn from_canonical_bytes(bytes: [u8; 32]) -> Option<Scalar> {
DScalar::from_canonical_bytes(bytes).map(|x| Self(x))
}
}
impl Borrow<DScalar> for Scalar {
fn borrow(&self) -> &DScalar {
&self.0
pub fn from_bytes_mod_order(bytes: [u8; 32]) -> Scalar {
Self(DScalar::from_bytes_mod_order(bytes))
}
}
impl Borrow<DScalar> for &Scalar {
fn borrow(&self) -> &DScalar {
&self.0
pub fn from_bytes_mod_order_wide(bytes: &[u8; 64]) -> Scalar {
Self(DScalar::from_bytes_mod_order_wide(bytes))
}
}
impl Add<Scalar> for Scalar {
type Output = Self;
fn add(self, other: Scalar) -> Scalar { Self(self.0 + other.0) }
}
impl AddAssign for Scalar {
fn add_assign(&mut self, other: Scalar) { self.0 += other.0 }
}
impl<'a> Add<&'a Scalar> for Scalar {
type Output = Self;
fn add(self, other: &'a Scalar) -> Scalar { Self(self.0 + other.0) }
}
impl<'a> AddAssign<&'a Scalar> for Scalar {
fn add_assign(&mut self, other: &'a Scalar) { self.0 += other.0 }
}
impl Sub<Scalar> for Scalar {
type Output = Self;
fn sub(self, other: Scalar) -> Scalar { Self(self.0 - other.0) }
}
impl SubAssign for Scalar {
fn sub_assign(&mut self, other: Scalar) { self.0 -= other.0 }
}
impl<'a> Sub<&'a Scalar> for Scalar {
type Output = Self;
fn sub(self, other: &'a Scalar) -> Scalar { Self(self.0 - other.0) }
}
impl<'a> SubAssign<&'a Scalar> for Scalar {
fn sub_assign(&mut self, other: &'a Scalar) { self.0 -= other.0 }
}
impl Neg for Scalar {
type Output = Self;
fn neg(self) -> Scalar { Self(-self.0) }
}
impl Mul<Scalar> for Scalar {
type Output = Self;
fn mul(self, other: Scalar) -> Scalar { Self(self.0 * other.0) }
}
impl MulAssign for Scalar {
fn mul_assign(&mut self, other: Scalar) { self.0 *= other.0 }
}
impl<'a> Mul<&'a Scalar> for Scalar {
type Output = Self;
fn mul(self, other: &'a Scalar) -> Scalar { Self(self.0 * other.0) }
}
impl<'a> MulAssign<&'a Scalar> for Scalar {
fn mul_assign(&mut self, other: &'a Scalar) { self.0 *= other.0 }
pub fn from_hash<D: Digest<OutputSize = U64>>(hash: D) -> Scalar {
let mut output = [0u8; 64];
output.copy_from_slice(&hash.finalize());
Scalar(DScalar::from_bytes_mod_order_wide(&output))
}
}
impl ConstantTimeEq for Scalar {
@@ -153,163 +188,106 @@ impl PrimeField for Scalar {
fn root_of_unity() -> Self { unimplemented!() }
}
impl Scalar {
pub fn from_hash<D: Digest<OutputSize = U64>>(hash: D) -> Scalar {
let mut output = [0u8; 64];
output.copy_from_slice(&hash.finalize());
Scalar(DScalar::from_bytes_mod_order_wide(&output))
}
}
macro_rules! dalek_group {
(
$Point: ident,
$DPoint: ident,
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct EdwardsPoint(pub DPoint);
pub const ED25519_BASEPOINT_POINT: EdwardsPoint = EdwardsPoint(constants::ED25519_BASEPOINT_POINT);
$Table: ident,
$DTable: ident,
impl Deref for EdwardsPoint {
type Target = DPoint;
$Compressed: ident,
$DCompressed: ident,
fn deref(&self) -> &Self::Target {
&self.0
$BASEPOINT_POINT: ident,
$BASEPOINT_TABLE: ident
) => {
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct $Point(pub $DPoint);
deref_borrow!($Point, $DPoint);
math!($Point, Scalar, $Point);
pub const $BASEPOINT_POINT: $Point = $Point(constants::$BASEPOINT_POINT);
impl Sum<$Point> for $Point {
fn sum<I: Iterator<Item = $Point>>(iter: I) -> $Point { Self($DPoint::sum(iter)) }
}
impl<'a> Sum<&'a $Point> for $Point {
fn sum<I: Iterator<Item = &'a $Point>>(iter: I) -> $Point { Self($DPoint::sum(iter)) }
}
impl Group for $Point {
type Scalar = Scalar;
fn random(rng: impl RngCore) -> Self { &$BASEPOINT_TABLE * Scalar::random(rng) }
fn identity() -> Self { Self($DPoint::identity()) }
fn generator() -> Self { $BASEPOINT_POINT }
fn is_identity(&self) -> Choice { self.0.ct_eq(&$DPoint::identity()) }
fn double(&self) -> Self { *self + self }
}
pub struct $Compressed(pub $DCompressed);
deref_borrow!($Compressed, $DCompressed);
impl $Compressed {
pub fn new(y: [u8; 32]) -> $Compressed {
Self($DCompressed(y))
}
pub fn decompress(&self) -> Option<$Point> {
self.0.decompress().map(|x| $Point(x))
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
}
impl $Point {
pub fn compress(&self) -> $Compressed {
$Compressed(self.0.compress())
}
}
pub struct $Table(pub $DTable);
deref_borrow!($Table, $DTable);
pub const $BASEPOINT_TABLE: $Table = $Table(constants::$BASEPOINT_TABLE);
impl Mul<Scalar> for &$Table {
type Output = $Point;
fn mul(self, b: Scalar) -> $Point { $Point(&b.0 * &self.0) }
}
};
}
impl Borrow<DPoint> for EdwardsPoint {
fn borrow(&self) -> &DPoint {
&self.0
}
}
dalek_group!(
EdwardsPoint,
DEdwardsPoint,
impl Borrow<DPoint> for &EdwardsPoint {
fn borrow(&self) -> &DPoint {
&self.0
}
}
EdwardsBasepointTable,
DEdwardsBasepointTable,
impl Add<EdwardsPoint> for EdwardsPoint {
type Output = Self;
fn add(self, b: EdwardsPoint) -> EdwardsPoint { Self(self.0 + b.0) }
}
impl AddAssign<EdwardsPoint> for EdwardsPoint {
fn add_assign(&mut self, other: EdwardsPoint) { self.0 += other.0 }
}
impl Sum<EdwardsPoint> for EdwardsPoint {
fn sum<I: Iterator<Item = EdwardsPoint>>(iter: I) -> EdwardsPoint { Self(DPoint::sum(iter)) }
}
CompressedEdwardsY,
DCompressedEdwards,
impl<'a> Add<&'a EdwardsPoint> for EdwardsPoint {
type Output = Self;
fn add(self, b: &'a EdwardsPoint) -> EdwardsPoint { Self(self.0 + b.0) }
}
impl<'a> AddAssign<&'a EdwardsPoint> for EdwardsPoint {
fn add_assign(&mut self, other: &'a EdwardsPoint) { self.0 += other.0 }
}
impl<'a> Sum<&'a EdwardsPoint> for EdwardsPoint {
fn sum<I: Iterator<Item = &'a EdwardsPoint>>(iter: I) -> EdwardsPoint { Self(DPoint::sum(iter)) }
}
impl Sub<EdwardsPoint> for EdwardsPoint {
type Output = Self;
fn sub(self, b: EdwardsPoint) -> EdwardsPoint { Self(self.0 - b.0) }
}
impl SubAssign<EdwardsPoint> for EdwardsPoint {
fn sub_assign(&mut self, other: EdwardsPoint) { self.0 -= other.0 }
}
impl<'a> Sub<&'a EdwardsPoint> for EdwardsPoint {
type Output = Self;
fn sub(self, b: &'a EdwardsPoint) -> EdwardsPoint { Self(self.0 - b.0) }
}
impl<'a> SubAssign<&'a EdwardsPoint> for EdwardsPoint {
fn sub_assign(&mut self, other: &'a EdwardsPoint) { self.0 -= other.0 }
}
impl Neg for EdwardsPoint {
type Output = Self;
fn neg(self) -> EdwardsPoint { Self(-self.0) }
}
impl Mul<Scalar> for EdwardsPoint {
type Output = Self;
fn mul(self, b: Scalar) -> EdwardsPoint { Self(b.0 * self.0) }
}
impl MulAssign<Scalar> for EdwardsPoint {
fn mul_assign(&mut self, other: Scalar) { self.0 *= other.0 }
}
impl<'a> Mul<&'a Scalar> for EdwardsPoint {
type Output = Self;
fn mul(self, b: &'a Scalar) -> EdwardsPoint { Self(b.0 * self.0) }
}
impl<'a> MulAssign<&'a Scalar> for EdwardsPoint {
fn mul_assign(&mut self, other: &'a Scalar) { self.0 *= other.0 }
}
impl Group for EdwardsPoint {
type Scalar = Scalar;
fn random(rng: impl RngCore) -> Self { &ED25519_BASEPOINT_TABLE * Scalar::random(rng) }
fn identity() -> Self { Self(DPoint::identity()) }
fn generator() -> Self { ED25519_BASEPOINT_POINT }
fn is_identity(&self) -> Choice { self.0.ct_eq(&DPoint::identity()) }
fn double(&self) -> Self { *self + self }
}
impl Scalar {
pub fn from_canonical_bytes(bytes: [u8; 32]) -> Option<Scalar> {
DScalar::from_canonical_bytes(bytes).map(|x| Self(x))
}
pub fn from_bytes_mod_order(bytes: [u8; 32]) -> Scalar {
Self(DScalar::from_bytes_mod_order(bytes))
}
pub fn from_bytes_mod_order_wide(bytes: &[u8; 64]) -> Scalar {
Self(DScalar::from_bytes_mod_order_wide(bytes))
}
}
pub struct CompressedEdwardsY(pub DCompressed);
impl CompressedEdwardsY {
pub fn new(y: [u8; 32]) -> CompressedEdwardsY {
Self(DCompressed(y))
}
pub fn decompress(&self) -> Option<EdwardsPoint> {
self.0.decompress().map(|x| EdwardsPoint(x))
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
}
ED25519_BASEPOINT_POINT,
ED25519_BASEPOINT_TABLE
);
impl EdwardsPoint {
pub fn is_torsion_free(&self) -> bool {
self.0.is_torsion_free()
}
pub fn compress(&self) -> CompressedEdwardsY {
CompressedEdwardsY(self.0.compress())
}
}
pub struct EdwardsBasepointTable(pub DTable);
pub const ED25519_BASEPOINT_TABLE: EdwardsBasepointTable = EdwardsBasepointTable(
constants::ED25519_BASEPOINT_TABLE
dalek_group!(
RistrettoPoint,
DRistrettoPoint,
RistrettoBasepointTable,
DRistrettoBasepointTable,
CompressedRistretto,
DCompressedRistretto,
RISTRETTO_BASEPOINT_POINT,
RISTRETTO_BASEPOINT_TABLE
);
impl Deref for EdwardsBasepointTable {
type Target = DTable;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Borrow<DTable> for &EdwardsBasepointTable {
fn borrow(&self) -> &DTable {
&self.0
}
}
impl Mul<Scalar> for &EdwardsBasepointTable {
type Output = EdwardsPoint;
fn mul(self, b: Scalar) -> EdwardsPoint { EdwardsPoint(&b.0 * &self.0) }
}