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

feat: adds fedl vuf #2

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions proof-essentials/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ starknet-curve = { path = "../starknet-curve" }
thiserror = "1.0.30"
blake2 = { version = "0.9", default-features = false }
digest = { version = "0.9" }
tiny-keccak = { version = "2.0.2", features = [ "shake" ] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
Expand Down
3 changes: 3 additions & 0 deletions proof-essentials/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub enum CryptoError {

#[error("IoError: {0}")]
IoError(String),

#[error("Cannot hash to curve")]
CannotHashToCurve,
}

impl From<std::io::Error> for CryptoError {
Expand Down
1 change: 1 addition & 0 deletions proof-essentials/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pub mod error;
pub mod homomorphic_encryption;
pub mod utils;
pub mod vector_commitment;
pub mod vuf;
pub mod zkp;
128 changes: 128 additions & 0 deletions proof-essentials/src/vuf/fedl/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
mod test;

use crate::{
error::CryptoError,
vuf::VerifiableUnpredictableFunction,
zkp::{
proofs::chaum_pedersen_dl_equality::{
proof::Proof, DLEquality, Parameters as ChaumPedersenParameters, Statement,
},
ArgumentOfKnowledge,
},
};
use ark_ec::{AffineCurve, ProjectiveCurve};
use ark_ff::UniformRand;
use ark_marlin::rng::FiatShamirRng;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
use ark_std::{
io::{Read, Write},
marker::PhantomData,
rand::Rng,
};
use blake2::Blake2s;
use tiny_keccak::{Hasher, Shake, Xof};

const FS_RNG_SEED: &'static [u8] = b"FEDL";

/// Unique signature scheme based on [EDL](with a change to fix the randmoness), with fixed randomness, henced Fixed EDL
pub struct FEDL<'a, C: ProjectiveCurve> {
_group: PhantomData<C>,
_message_lifetime: PhantomData<&'a ()>,
}

#[derive(Copy, Clone, CanonicalSerialize, CanonicalDeserialize)]
pub struct Parameters<C: ProjectiveCurve> {
pub g: C::Affine,
}

fn try_and_increment<C: ProjectiveCurve>(msg: &[u8]) -> Result<C::Affine, CryptoError> {
for nonce in 0u8..=255 {
let mut h = Shake::v128();
h.update(&[nonce]);
h.update(msg.as_ref());
let output_size = C::zero().serialized_size();
let mut output = vec![0u8; output_size];
h.squeeze(&mut output);

if let Some(p) = C::Affine::from_random_bytes(&output) {
return Ok(p);
}
}

Err(CryptoError::CannotHashToCurve)
}

#[derive(Copy, Clone, CanonicalSerialize, CanonicalDeserialize)]
pub struct Signature<C: ProjectiveCurve> {
pub proof: Proof<C>,
pub b: C::Affine,
}

impl<'a, C: ProjectiveCurve> VerifiableUnpredictableFunction for FEDL<'a, C> {
type Message = &'a [u8];
type Parameters = Parameters<C>;
type PublicKey = <C as ProjectiveCurve>::Affine;
type SecretKey = <C as ProjectiveCurve>::ScalarField;
type Signature = Signature<C>;
type UniqueToken = <C as ProjectiveCurve>::Affine;

fn keygen<R: Rng>(
pp: &Self::Parameters,
rng: &mut R,
) -> Result<(Self::PublicKey, Self::SecretKey), CryptoError> {
let secret_key = Self::SecretKey::rand(rng).into();
let public_key = pp.g.mul(secret_key).into();
Ok((public_key, secret_key))
}

fn sign<R: Rng>(
pp: &Self::Parameters,
rng: &mut R,
keypair: (&Self::PublicKey, &Self::SecretKey),
message: Self::Message,
) -> Result<Self::Signature, CryptoError> {
let hash_of_message: C::Affine = try_and_increment::<C>(message)?;
let chaum_pedersen_parameters = ChaumPedersenParameters {
g: &pp.g,
h: &hash_of_message,
};
let b = hash_of_message.mul(*keypair.1).into();
let statement = Statement::new(keypair.0, &b);

let mut fs_rng = FiatShamirRng::<Blake2s>::from_seed(&FS_RNG_SEED);
let proof = DLEquality::prove(
rng,
&chaum_pedersen_parameters,
&statement,
keypair.1,
&mut fs_rng,
)?;
Ok(Signature { proof, b })
}

fn extract_token(signature: &Self::Signature) -> Result<Self::UniqueToken, CryptoError> {
Ok(signature.b)
}

fn verify(
pp: &Self::Parameters,
pk: &Self::PublicKey,
message: Self::Message,
signature: &Self::Signature,
) -> Result<(), CryptoError> {
let hash_of_message: C::Affine = try_and_increment::<C>(message)?;
let chaum_pedersen_parameters = ChaumPedersenParameters {
g: &pp.g,
h: &hash_of_message,
};

let statement = Statement::new(pk, &signature.b);
let mut fs_rng = FiatShamirRng::<Blake2s>::from_seed(&FS_RNG_SEED);
DLEquality::verify(
&chaum_pedersen_parameters,
&statement,
&signature.proof,
&mut fs_rng,
)
}
}
66 changes: 66 additions & 0 deletions proof-essentials/src/vuf/fedl/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#[cfg(test)]
mod test {

use crate::vuf::{
fedl::{self, FEDL},
VerifiableUnpredictableFunction,
};
use ark_ec::ProjectiveCurve;
use ark_std::{rand::thread_rng, UniformRand};
use rand::{prelude::ThreadRng, Rng};
use starknet_curve;

type AffinePoint = starknet_curve::Affine;
type Curve = starknet_curve::Projective;
type Parameters = fedl::Parameters<Curve>;

fn setup<R: Rng>(rng: &mut R) -> AffinePoint {
Curve::rand(rng).into_affine()
}

fn test_template() -> (ThreadRng, AffinePoint) {
let mut rng = thread_rng();
let g = setup(&mut rng);

(rng, g)
}

#[test]
fn test_signing_and_uniqueness() {
let (mut rng, g) = test_template();

let pp = Parameters { g };

let keypair = FEDL::keygen(&pp, &mut rng).unwrap();

let message = b"MESSAGE!!!";

let signature =
FEDL::sign(&pp, &mut rng, (&keypair.0, &keypair.1), message.as_slice()).unwrap();
FEDL::verify(&pp, &keypair.0, message.as_slice(), &signature).unwrap();
let signature2 =
FEDL::sign(&pp, &mut rng, (&keypair.0, &keypair.1), message.as_slice()).unwrap();
FEDL::verify(&pp, &keypair.0, message.as_slice(), &signature2).unwrap();
assert_eq!(
FEDL::extract_token(&signature),
FEDL::extract_token(&signature2),
);
}

#[test]
#[should_panic]
fn test_bad_signing() {
let (mut rng, g) = test_template();

let pp = Parameters { g };

let keypair = FEDL::keygen(&pp, &mut rng).unwrap();
let keypair2 = FEDL::keygen(&pp, &mut rng).unwrap();

let message = b"MESSAGE!!!";

let signature =
FEDL::sign(&pp, &mut rng, (&keypair.0, &keypair.1), message.as_slice()).unwrap();
FEDL::verify(&pp, &keypair2.0, message.as_slice(), &signature).unwrap();
}
}
40 changes: 40 additions & 0 deletions proof-essentials/src/vuf/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::error::CryptoError;
use ark_ff::ToBytes;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::rand::Rng;

pub mod fedl;

pub trait VerifiableUnpredictableFunction {
type Parameters: CanonicalSerialize + CanonicalDeserialize;
type PublicKey: CanonicalSerialize + CanonicalDeserialize;
type SecretKey: CanonicalSerialize + CanonicalDeserialize;
type Signature: CanonicalSerialize + CanonicalDeserialize;
type UniqueToken: CanonicalSerialize + CanonicalDeserialize;
type Message: ToBytes;

/// Generate a public key and a private key.
fn keygen<R: Rng>(
pp: &Self::Parameters,
rng: &mut R,
) -> Result<(Self::PublicKey, Self::SecretKey), CryptoError>;

/// Sign a message.
fn sign<R: Rng>(
pp: &Self::Parameters,
rng: &mut R,
keypair: (&Self::PublicKey, &Self::SecretKey),
message: Self::Message,
) -> Result<Self::Signature, CryptoError>;

/// Extract a unique token from a signature.
fn extract_token(signature: &Self::Signature) -> Result<Self::UniqueToken, CryptoError>;

/// Verify a signature.
fn verify(
pp: &Self::Parameters,
pk: &Self::PublicKey,
message: Self::Message,
signature: &Self::Signature,
) -> Result<(), CryptoError>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use ark_std::io::{Read, Write};
use ark_std::UniformRand;
use digest::Digest;

#[derive(CanonicalDeserialize, CanonicalSerialize)]
#[derive(Copy, Clone, CanonicalDeserialize, CanonicalSerialize)]
pub struct Proof<C>
where
C: ProjectiveCurve,
Expand Down
4 changes: 2 additions & 2 deletions starknet-curve/src/fields/fr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ impl FpParameters for FrParameters {
0x07fffffffffff9b1,
]);

const MODULUS_BITS: u32 = 251;
const MODULUS_BITS: u32 = 252;

const CAPACITY: u32 = Self::MODULUS_BITS - 1;

const REPR_SHAVE_BITS: u32 = 5;
const REPR_SHAVE_BITS: u32 = 4;

// INV = -q^{-1} (mod 2^64)
const INV: u64 = 13504954208620504625;
Expand Down