Browse Source

rm unwraps inside methods, return params to private

main^2
arnaucube 4 months ago
parent
commit
15158474ab
5 changed files with 39 additions and 35 deletions
  1. +2
    -1
      .gitignore
  2. +21
    -20
      src/constraints.rs
  3. +11
    -11
      src/eddsa.rs
  4. +3
    -1
      src/lib.rs
  5. +2
    -2
      src/signature.rs

+ 2
- 1
.gitignore

@ -1,2 +1,3 @@
/target /target
*.py
*.py
Cargo.lock

+ 21
- 20
src/constraints.rs

@ -5,14 +5,11 @@ use ark_crypto_primitives::sponge::{
}; };
use ark_ec::CurveGroup; use ark_ec::CurveGroup;
use ark_ff::Field; use ark_ff::Field;
use ark_relations::r1cs::ConstraintSystemRef;
use ark_r1cs_std::{ use ark_r1cs_std::{
boolean::Boolean, fields::fp::FpVar, fields::nonnative::NonNativeFieldVar, groups::CurveVar, boolean::Boolean, fields::fp::FpVar, fields::nonnative::NonNativeFieldVar, groups::CurveVar,
ToBitsGadget, ToConstraintFieldGadget, ToBitsGadget, ToConstraintFieldGadget,
}; };
use crate::Error;
use ark_relations::r1cs::ConstraintSystemRef;
/// CF stands for ConstraintField /// CF stands for ConstraintField
pub type CF<C> = <<C as CurveGroup>::BaseField as Field>::BasePrimeField; pub type CF<C> = <<C as CurveGroup>::BaseField as Field>::BasePrimeField;
@ -24,29 +21,31 @@ pub fn verify(
pk: GC, pk: GC,
sig: (GC, NonNativeFieldVar<C::ScalarField, CF<C>>), sig: (GC, NonNativeFieldVar<C::ScalarField, CF<C>>),
msg: FpVar<CF<C>>, msg: FpVar<CF<C>>,
) -> Result<Boolean<CF<C>>, Error>
) -> ark_relations::r1cs::Result<Boolean<CF<C>>>
where where
C: CurveGroup, C: CurveGroup,
GC: CurveVar<C, CF<C>> + ToConstraintFieldGadget<CF<C>>, GC: CurveVar<C, CF<C>> + ToConstraintFieldGadget<CF<C>>,
{ {
let (r, s): (GC, NonNativeFieldVar<C::ScalarField, CF<C>>) = sig; let (r, s): (GC, NonNativeFieldVar<C::ScalarField, CF<C>>) = sig;
let r_xy = r.to_constraint_field().unwrap();
let pk_xy = pk.to_constraint_field().unwrap();
let r_xy = r.to_constraint_field()?;
let pk_xy = pk.to_constraint_field()?;
let mut poseidon = PoseidonSpongeVar::new(cs.clone(), &poseidon_config); let mut poseidon = PoseidonSpongeVar::new(cs.clone(), &poseidon_config);
poseidon.absorb(&r_xy).unwrap();
poseidon.absorb(&pk_xy).unwrap();
poseidon.absorb(&msg).unwrap();
let k = poseidon.squeeze_field_elements(1).unwrap();
let k = k.first().unwrap();
poseidon.absorb(&r_xy)?;
poseidon.absorb(&pk_xy)?;
poseidon.absorb(&msg)?;
let k = poseidon.squeeze_field_elements(1)?;
let k = k
.first()
.ok_or(ark_relations::r1cs::SynthesisError::Unsatisfiable)?;
let kx_b = pk.scalar_mul_le(k.to_bits_le().unwrap().iter()).unwrap();
let kx_b = pk.scalar_mul_le(k.to_bits_le()?.iter())?;
let g = GC::new_constant(cs.clone(), C::generator()).unwrap();
let s_b = g.scalar_mul_le(s.to_bits_le().unwrap().iter()).unwrap();
let g = GC::new_constant(cs.clone(), C::generator())?;
let s_b = g.scalar_mul_le(s.to_bits_le()?.iter())?;
let r_rec: GC = s_b - kx_b; let r_rec: GC = s_b - kx_b;
Ok(r_rec.is_eq(&r).unwrap())
Ok(r_rec.is_eq(&r)?)
} }
#[cfg(test)] #[cfg(test)]
@ -69,14 +68,16 @@ mod tests {
let sk = SigningKey::<EdwardsConfig>::generate::<blake2::Blake2b512>(&mut OsRng).unwrap(); let sk = SigningKey::<EdwardsConfig>::generate::<blake2::Blake2b512>(&mut OsRng).unwrap();
let msg_raw = b"xxx yyy <<< zzz >>> bunny"; let msg_raw = b"xxx yyy <<< zzz >>> bunny";
let msg = Fq::from_le_bytes_mod_order(msg_raw); let msg = Fq::from_le_bytes_mod_order(msg_raw);
let sig = sk.sign::<blake2::Blake2b512>(&poseidon_config, &msg);
let sig = sk
.sign::<blake2::Blake2b512>(&poseidon_config, &msg)
.unwrap();
let pk = sk.public_key(); let pk = sk.public_key();
pk.verify(&poseidon_config, &msg, &sig).unwrap(); pk.verify(&poseidon_config, &msg, &sig).unwrap();
let cs = ConstraintSystem::<Fq>::new_ref(); let cs = ConstraintSystem::<Fq>::new_ref();
let pk_var: GVar = GVar::new_witness(cs.clone(), || Ok(pk.0)).unwrap();
let r_var: GVar = GVar::new_witness(cs.clone(), || Ok(sig.r)).unwrap();
let s_var = NonNativeFieldVar::<Fr, Fq>::new_witness(cs.clone(), || Ok(sig.s)).unwrap();
let pk_var: GVar = GVar::new_witness(cs.clone(), || Ok(*pk.as_ref())).unwrap();
let r_var: GVar = GVar::new_witness(cs.clone(), || Ok(*sig.r())).unwrap();
let s_var = NonNativeFieldVar::<Fr, Fq>::new_witness(cs.clone(), || Ok(sig.s())).unwrap();
let msg_var = FpVar::<Fq>::new_witness(cs.clone(), || Ok(msg)).unwrap(); let msg_var = FpVar::<Fq>::new_witness(cs.clone(), || Ok(msg)).unwrap();
let res = verify::<G, GVar>(cs.clone(), poseidon_config, pk_var, (r_var, s_var), msg_var) let res = verify::<G, GVar>(cs.clone(), poseidon_config, pk_var, (r_var, s_var), msg_var)

+ 11
- 11
src/eddsa.rs

@ -45,11 +45,11 @@ impl SecretKey {
/// `PublicKey` is EdDSA signature verification key /// `PublicKey` is EdDSA signature verification key
#[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] #[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct PublicKey<TE: TECurveConfig>(pub Affine<TE>);
pub struct PublicKey<TE: TECurveConfig>(Affine<TE>);
impl<TE: TECurveConfig> PublicKey<TE> { impl<TE: TECurveConfig> PublicKey<TE> {
pub fn xy(&self) -> (&TE::BaseField, &TE::BaseField) {
self.as_ref().xy().unwrap()
pub fn xy(&self) -> Result<(&TE::BaseField, &TE::BaseField), Error> {
self.as_ref().xy().ok_or(Error::Coordinates)
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -125,7 +125,7 @@ where
&self, &self,
poseidon: &PoseidonConfig<TE::BaseField>, poseidon: &PoseidonConfig<TE::BaseField>,
message: &TE::BaseField, message: &TE::BaseField,
) -> Signature<TE> {
) -> Result<Signature<TE>, Error> {
let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>(); let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>();
let mut h = D::new(); let mut h = D::new();
@ -140,22 +140,22 @@ where
let mut poseidon = PoseidonSponge::new(poseidon); let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = sig_r.xy().unwrap();
let (sig_r_x, sig_r_y) = sig_r.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(sig_r_x); poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y); poseidon.absorb(sig_r_y);
let (pk_x, pk_y) = self.public_key.0.xy().unwrap();
let (pk_x, pk_y) = self.public_key.0.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(pk_x); poseidon.absorb(pk_x);
poseidon.absorb(pk_y); poseidon.absorb(pk_y);
poseidon.absorb(message); poseidon.absorb(message);
// use poseidon over Fq, so that it can be done too in-circuit // use poseidon over Fq, so that it can be done too in-circuit
let k = poseidon.squeeze_field_elements::<TE::BaseField>(1); let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
let k = k.first().unwrap();
let k = k.first().ok_or(Error::BadDigestOutput)?;
let k = TE::ScalarField::from_le_bytes_mod_order(&k.into_bigint().to_bytes_le()); let k = TE::ScalarField::from_le_bytes_mod_order(&k.into_bigint().to_bytes_le());
let sig_s = (x * k) + r; let sig_s = (x * k) + r;
Signature::new(sig_r, sig_s)
Ok(Signature::new(sig_r, sig_s))
} }
} }
@ -181,17 +181,17 @@ where
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut poseidon = PoseidonSponge::new(poseidon); let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = signature.r().xy().unwrap();
let (sig_r_x, sig_r_y) = signature.r().xy().ok_or(Error::Coordinates)?;
poseidon.absorb(sig_r_x); poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y); poseidon.absorb(sig_r_y);
let (pk_x, pk_y) = self.0.xy().unwrap();
let (pk_x, pk_y) = self.0.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(pk_x); poseidon.absorb(pk_x);
poseidon.absorb(pk_y); poseidon.absorb(pk_y);
poseidon.absorb(message); poseidon.absorb(message);
// use poseidon over Fq, so that it can be done too in-circuit // use poseidon over Fq, so that it can be done too in-circuit
let k = poseidon.squeeze_field_elements::<TE::BaseField>(1); let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
let k = k.first().unwrap();
let k = k.first().ok_or(Error::BadDigestOutput)?;
let kx_b = self.0.mul_bigint(k.into_bigint()); let kx_b = self.0.mul_bigint(k.into_bigint());
let s_b = Affine::<TE>::generator() * signature.s(); let s_b = Affine::<TE>::generator() * signature.s();

+ 3
- 1
src/lib.rs

@ -19,6 +19,7 @@ pub(crate) fn from_digest(digest: D) -> F {
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error { pub enum Error {
Coordinates,
Verify, Verify,
BadDigestOutput, BadDigestOutput,
} }
@ -26,6 +27,7 @@ pub enum Error {
impl core::fmt::Display for Error { impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match *self { match *self {
Error::Coordinates => write!(f, "Could not obtain the coordinates of a point"),
Error::Verify => write!(f, "Signature verification failed"), Error::Verify => write!(f, "Signature verification failed"),
Error::BadDigestOutput => write!(f, "Bad digest output size"), Error::BadDigestOutput => write!(f, "Bad digest output size"),
} }
@ -68,7 +70,7 @@ mod test {
let signing_key = SigningKey::<TE>::generate::<D>(&mut OsRng).unwrap(); let signing_key = SigningKey::<TE>::generate::<D>(&mut OsRng).unwrap();
let message_raw = b"xxx yyy <<< zzz >>> bunny"; let message_raw = b"xxx yyy <<< zzz >>> bunny";
let message = TE::BaseField::from_le_bytes_mod_order(message_raw); let message = TE::BaseField::from_le_bytes_mod_order(message_raw);
let signature = signing_key.sign::<D>(&poseidon, &message);
let signature = signing_key.sign::<D>(&poseidon, &message).unwrap();
let public_key = signing_key.public_key(); let public_key = signing_key.public_key();
public_key.verify(&poseidon, &message, &signature).unwrap(); public_key.verify(&poseidon, &message, &signature).unwrap();
} }

+ 2
- 2
src/signature.rs

@ -6,8 +6,8 @@ use ark_serialize::CanonicalSerialize;
/// `SignatureComponents` contains the realized parts of a signature /// `SignatureComponents` contains the realized parts of a signature
#[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] #[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct Signature<TE: TECurveConfig + Clone> { pub struct Signature<TE: TECurveConfig + Clone> {
pub r: Affine<TE>,
pub s: TE::ScalarField,
r: Affine<TE>,
s: TE::ScalarField,
} }
impl<TE: TECurveConfig + Clone> Signature<TE> { impl<TE: TECurveConfig + Clone> Signature<TE> {

Loading…
Cancel
Save