Skip to content

Commit

Permalink
algebra: Refactor implementation to be generic over curve choice
Browse files Browse the repository at this point in the history
  • Loading branch information
joeykraut committed Oct 9, 2023
1 parent 9137ca0 commit 6cd97f9
Show file tree
Hide file tree
Showing 9 changed files with 1,114 additions and 1,201 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ tracing = { version = "0.1", features = ["log"] }
zeroize = "1.3"

[dev-dependencies]
ark-curve25519 = "0.4"
clap = { version = "3.2.8", features = ["derive"] }
colored = "2"
criterion = { version = "0.5", features = ["async", "async_tokio"] }
Expand All @@ -104,5 +105,3 @@ dns-lookup = "1.0"
env_logger = "0.10"
gperftools = { version = "0.2", features = ["heap"] }
inventory = "0.3"
starknet = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "655af56" }
starknet-curve = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "655af56" }

Large diffs are not rendered by default.

395 changes: 202 additions & 193 deletions src/algebra/authenticated_scalar.rs

Large diffs are not rendered by default.

541 changes: 259 additions & 282 deletions src/algebra/stark_curve.rs → src/algebra/curve.rs

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions src/algebra/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
/// implements the same arithmetic on the owned and partially-owned variants
macro_rules! impl_borrow_variants {
// Single type trait
($target:ty, $trait:ident, $fn_name:ident, $op:tt) => {
($target:ty, $trait:ident, $fn_name:ident, $op:tt, $($gen:ident: $gen_ty:ty),*) => {
// Single implementation, owned target type
impl $trait for $target {
impl<$($gen),*> $trait for $target {
type Output = $target;

fn $fn_name(self) -> Self::Output {
Expand All @@ -16,14 +16,14 @@ macro_rules! impl_borrow_variants {
};

// Output type same as left hand side
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty) => {
impl_borrow_variants!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs);
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, $($gen:ident: $gen_ty:ty),*) => {
impl_borrow_variants!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs, $($gen: $gen_ty),*);
};

// Output type specified
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty) => {
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty, $($gen:ident: $gen_ty:ty),*) => {
/// lhs borrowed, rhs owned
impl<'a> $trait<$rhs> for &'a $lhs {
impl<'a, $($gen),*> $trait<$rhs> for &'a $lhs {
type Output = $out_type;

fn $fn_name(self, rhs: $rhs) -> Self::Output {
Expand All @@ -32,7 +32,7 @@ macro_rules! impl_borrow_variants {
}

/// lhs owned, rhs borrowed
impl<'a> $trait<&'a $rhs> for $lhs {
impl<'a, $($gen),*> $trait<&'a $rhs> for $lhs {
type Output = $out_type;

fn $fn_name(self, rhs: &'a $rhs) -> Self::Output {
Expand All @@ -41,7 +41,7 @@ macro_rules! impl_borrow_variants {
}

/// lhs owned, rhs owned
impl $trait<$rhs> for $lhs {
impl<$($gen),*> $trait<$rhs> for $lhs {
type Output = $out_type;

fn $fn_name(self, rhs: $rhs) -> Self::Output {
Expand All @@ -53,13 +53,13 @@ macro_rules! impl_borrow_variants {

/// A macro to implement commutative variants of a binary operation
macro_rules! impl_commutative {
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty) => {
impl_commutative!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs);
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, $($gen:ident: $gen_ty:ty),*) => {
impl_commutative!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs, $($gen: $gen_ty),*);
};

($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty) => {
($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty, $($gen:ident: $gen_ty:ty),*) => {
/// lhs borrowed, rhs borrowed
impl<'a> $trait<&'a $lhs> for &'a $rhs {
impl<'a, $($gen),*> $trait<&'a $lhs> for &'a $rhs {
type Output = $out_type;

fn $fn_name(self, rhs: &'a $lhs) -> Self::Output {
Expand All @@ -68,7 +68,7 @@ macro_rules! impl_commutative {
}

/// lhs borrowed, rhs owned
impl<'a> $trait<$lhs> for &'a $rhs
impl<'a, $($gen),*> $trait<$lhs> for &'a $rhs
{
type Output = $out_type;

Expand All @@ -78,7 +78,7 @@ macro_rules! impl_commutative {
}

/// lhs owned, rhs borrowed
impl<'a> $trait<&'a $lhs> for $rhs
impl<'a, $($gen),*> $trait<&'a $lhs> for $rhs
{
type Output = $out_type;

Expand All @@ -88,7 +88,7 @@ macro_rules! impl_commutative {
}

/// lhs owned, rhs owned
impl $trait<$lhs> for $rhs
impl<$($gen),*> $trait<$lhs> for $rhs
{
type Output = $out_type;

Expand Down
87 changes: 10 additions & 77 deletions src/algebra/mod.rs
Original file line number Diff line number Diff line change
@@ -1,110 +1,43 @@
//! Defines algebraic MPC types and operations on them
pub mod authenticated_curve;
pub mod authenticated_scalar;
pub mod authenticated_stark_point;
pub mod curve;
pub mod macros;
pub mod mpc_curve;
pub mod mpc_scalar;
pub mod mpc_stark_point;
pub mod scalar;
pub mod stark_curve;

/// Helpers useful for testing throughout the `algebra` module
#[cfg(test)]
pub(crate) mod test_helper {
use std::iter;

use super::{scalar::Scalar, stark_curve::StarkPoint};
use super::scalar::Scalar;

use ark_curve25519::EdwardsProjective as Curve25519Projective;
use ark_ec::CurveGroup;
use ark_ff::PrimeField;
use num_bigint::BigUint;
use rand::thread_rng;
use starknet::core::types::FieldElement as StarknetFelt;
use starknet_curve::{AffinePoint, ProjectivePoint};

// -----------
// | Helpers |
// -----------

/// A curve used for testing algebra implementations, set to curve25519
pub type TestCurve = Curve25519Projective;

/// Generate a random point, by multiplying the basepoint with a random scalar
pub fn random_point() -> StarkPoint {
pub fn random_point() -> TestCurve {
let mut rng = thread_rng();
let scalar = Scalar::random(&mut rng);
let point = StarkPoint::generator() * scalar;
let point = TestCurve::generator() * scalar;
point * scalar
}

/// Convert a starknet felt to a BigUint
pub fn starknet_felt_to_biguint(felt: &StarknetFelt) -> BigUint {
BigUint::from_bytes_be(&felt.to_bytes_be())
}

/// Convert a `BigUint` to a starknet felt
pub fn biguint_to_starknet_felt(biguint: &BigUint) -> StarknetFelt {
// Pad the bytes up to 32 by prepending zeros
let bytes = biguint.to_bytes_be();
let padded_bytes = iter::repeat(0u8)
.take(32 - bytes.len())
.chain(bytes.iter().cloned())
.collect::<Vec<_>>();

StarknetFelt::from_bytes_be(&padded_bytes.try_into().unwrap()).unwrap()
}

/// Convert a prime field element to a `BigUint`
pub fn prime_field_to_biguint<F: PrimeField>(val: &F) -> BigUint {
(*val).into()
}

/// Convert a `Scalar` to a `StarknetFelt`
pub fn prime_field_to_starknet_felt<F: PrimeField>(scalar: &F) -> StarknetFelt {
biguint_to_starknet_felt(&prime_field_to_biguint(scalar))
}

/// Convert a point in the arkworks representation to a point in the starknet representation
pub fn arkworks_point_to_starknet(point: &StarkPoint) -> ProjectivePoint {
let affine = point.0.into_affine();
let x = prime_field_to_starknet_felt(&affine.x);
let y = prime_field_to_starknet_felt(&affine.y);

ProjectivePoint::from_affine_point(&AffinePoint {
x,
y,
infinity: false,
})
}

/// Multiply a point in the starknet-rs `ProjectivePoint` representation with a scalar
///
/// Multiplication is only implemented for a point and `&[bool]`, so this method essentially
/// provides the bit decomposition
pub fn starknet_rs_scalar_mul(
scalar: &StarknetFelt,
point: &ProjectivePoint,
) -> ProjectivePoint {
let bits = scalar.to_bits_le();
point * &bits
}

/// Compare scalars from the two curve implementations
pub fn compare_scalars<F: PrimeField>(s1: &F, s2: &StarknetFelt) -> bool {
let s1_biguint = prime_field_to_biguint(s1);
let s2_biguint = starknet_felt_to_biguint(s2);

s1_biguint == s2_biguint
}

/// Compare curve points between the two implementation
pub fn compare_points(p1: &StarkPoint, p2: &ProjectivePoint) -> bool {
// Convert the points to affine coordinates
let p1_affine = p1.0.into_affine();
let x_1 = p1_affine.x;
let y_1 = p1_affine.y;

let z_inv = p2.z.invert().unwrap();
let x_2 = p2.x * z_inv;
let y_2 = p2.y * z_inv;

compare_scalars(&x_1, &x_2) && compare_scalars(&y_1, &y_2)
}
}
Loading

0 comments on commit 6cd97f9

Please sign in to comment.