Browse Source

better bounds

reuse ark-error
main
kilic 9 months ago
parent
commit
1e696264a9
3 changed files with 89 additions and 76 deletions
  1. +52
    -42
      src/eddsa.rs
  2. +21
    -12
      src/lib.rs
  3. +16
    -22
      src/signature.rs

+ 52
- 42
src/eddsa.rs

@ -3,7 +3,10 @@ use ark_crypto_primitives::sponge::{
poseidon::{PoseidonConfig, PoseidonSponge},
Absorb, CryptographicSponge,
};
use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr, CurveGroup};
use ark_ec::{
twisted_edwards::{Affine, TECurveConfig},
AffineRepr,
};
use ark_ff::PrimeField;
use digest::Digest;
use digest::OutputSizeUser;
@ -41,41 +44,48 @@ impl SecretKey {
#[derive(Copy, Clone, Debug)]
/// `PublicKey` is EdDSA signature verification key
pub struct PublicKey<A: AffineRepr>(A)
where
A::Config: TECurveConfig;
pub struct PublicKey<TE: TECurveConfig>(Affine<TE>);
impl<A: AffineRepr> PublicKey<A>
where
A::Config: TECurveConfig,
{
pub fn xy(&self) -> (&A::BaseField, &A::BaseField) {
self.0.xy().unwrap()
impl<TE: TECurveConfig> PublicKey<TE> {
pub fn point(&self) -> &Affine<TE> {
&self.0
}
pub fn xy(&self) -> (&TE::BaseField, &TE::BaseField) {
self.as_ref().xy().unwrap()
}
}
impl<TE: TECurveConfig> From<Affine<TE>> for PublicKey<TE> {
fn from(affine: Affine<TE>) -> Self {
Self(affine)
}
}
impl<TE: TECurveConfig> AsRef<Affine<TE>> for PublicKey<TE> {
fn as_ref(&self) -> &Affine<TE> {
&self.0
}
}
#[derive(Copy, Clone, Debug)]
/// `SigningKey` produces EdDSA signatures for given message
pub struct SigningKey<A: AffineRepr>
where
A::Config: TECurveConfig,
{
pub struct SigningKey<TE: TECurveConfig> {
secret_key: SecretKey,
public_key: PublicKey<A>,
public_key: PublicKey<TE>,
}
impl<A: AffineRepr> SigningKey<A>
impl<TE: TECurveConfig> SigningKey<TE>
where
A::Config: TECurveConfig,
A::BaseField: PrimeField + Absorb,
TE::BaseField: PrimeField + Absorb,
{
pub fn new<D: Digest>(secret_key: &SecretKey) -> Result<Self, Error> {
(<D as OutputSizeUser>::output_size() == 64)
.then_some(())
.ok_or(Error::BadOutputSize)?;
.ok_or(Error::BadDigestOutput)?;
let (x, _) = secret_key.expand::<A::ScalarField, D>();
let public_key: A = (A::generator() * x).into_affine();
let (x, _) = secret_key.expand::<TE::ScalarField, D>();
let public_key: Affine<TE> = (Affine::<TE>::generator() * x).into();
let signing_key = Self {
secret_key: *secret_key,
public_key: PublicKey(public_key),
@ -90,35 +100,36 @@ where
Self::new::<D>(&secret_key)
}
pub fn public_key(&self) -> &PublicKey<A> {
pub fn public_key(&self) -> &PublicKey<TE> {
&self.public_key
}
pub fn sign<D: Digest, E: Absorb>(
&self,
poseidon: &PoseidonConfig<A::BaseField>,
poseidon: &PoseidonConfig<TE::BaseField>,
message: &[E],
) -> Signature<A> {
let (x, prefix) = self.secret_key.expand::<A::ScalarField, D>();
) -> Signature<TE> {
let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>();
let mut h = D::new();
h.update(prefix);
message
.iter()
.for_each(|m| h.update(m.to_sponge_bytes_as_vec()));
let r: A::ScalarField = crate::from_digest(h);
let sig_r = (A::generator() * r).into_affine();
let r: TE::ScalarField = crate::from_digest(h);
let sig_r: Affine<TE> = (Affine::<TE>::generator() * r).into();
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = sig_r.xy().unwrap();
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
let (vk_x, vk_y) = self.public_key.0.xy().unwrap();
poseidon.absorb(vk_x);
poseidon.absorb(vk_y);
let (pk_x, pk_y) = self.public_key.0.xy().unwrap();
poseidon.absorb(pk_x);
poseidon.absorb(pk_y);
message.iter().for_each(|m| poseidon.absorb(m));
let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
let k = poseidon.squeeze_field_elements::<TE::ScalarField>(1);
let k = k.first().unwrap();
let sig_s = (x * k) + r;
@ -127,33 +138,32 @@ where
}
}
impl<A: AffineRepr> PublicKey<A>
impl<TE: TECurveConfig> PublicKey<TE>
where
A::Config: TECurveConfig,
A::BaseField: PrimeField + Absorb,
TE::BaseField: PrimeField + Absorb,
{
pub fn verify<E: Absorb>(
&self,
poseidon: &PoseidonConfig<A::BaseField>,
poseidon: &PoseidonConfig<TE::BaseField>,
message: &[E],
signature: &Signature<A>,
signature: &Signature<TE>,
) -> Result<(), Error> {
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = signature.r().xy().unwrap();
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
let (vk_x, vk_y) = self.0.xy().unwrap();
poseidon.absorb(vk_x);
poseidon.absorb(vk_y);
let (pk_x, pk_y) = self.0.xy().unwrap();
poseidon.absorb(pk_x);
poseidon.absorb(pk_y);
message.iter().for_each(|m| poseidon.absorb(m));
let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
let k = poseidon.squeeze_field_elements::<TE::ScalarField>(1);
let k = k.first().unwrap();
let kx_b = self.0 * k;
let s_b = A::generator() * signature.s();
let r_rec: A = (s_b - kx_b).into();
let s_b = Affine::<TE>::generator() * signature.s();
let r_rec: Affine<TE> = (s_b - kx_b).into();
(signature.r() == &r_rec).then_some(()).ok_or(Error::Verify)
}

+ 21
- 12
src/lib.rs

@ -14,17 +14,27 @@ pub(crate) fn from_digest(digest: D) -> F {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error {
Verify,
BadOutputSize,
InvalidData,
BadDigestOutput,
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match *self {
Error::Verify => write!(f, "Signature verification failed"),
Error::BadDigestOutput => write!(f, "Bad digest output size"),
}
}
}
impl ark_std::error::Error for Error {}
#[cfg(test)]
mod test {
use crate::SigningKey;
use ark_crypto_primitives::sponge::poseidon::{find_poseidon_ark_and_mds, PoseidonConfig};
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr};
use ark_ec::twisted_edwards::TECurveConfig;
use ark_ff::PrimeField;
use digest::Digest;
use rand_core::OsRng;
@ -46,13 +56,12 @@ mod test {
PoseidonConfig::new(full_rounds, partial_rounds, 5, mds, ark, rate, 1)
}
fn run_test<A: AffineRepr, D: Digest>()
fn run_test<TE: TECurveConfig, D: Digest>()
where
A::BaseField: Absorb + PrimeField,
A::Config: TECurveConfig,
TE::BaseField: Absorb + PrimeField,
{
let poseidon = poseidon_config(4, 8, 55);
let signing_key = SigningKey::<A>::generate::<D>(&mut OsRng).unwrap();
let signing_key = SigningKey::<TE>::generate::<D>(&mut OsRng).unwrap();
let message = b"xxx yyy <<< zzz >>> bunny";
let signature = signing_key.sign::<D, _>(&poseidon, &message[..]);
let public_key = signing_key.public_key();
@ -63,10 +72,10 @@ mod test {
#[test]
fn test_eddsa() {
run_test::<ark_ed_on_bn254::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsAffine, blake2::Blake2b512>();
run_test::<crate::ed_on_bn254_twist::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsConfig, blake2::Blake2b512>();
run_test::<crate::ed_on_bn254_twist::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsConfig, sha2::Sha512>();
}
}

+ 16
- 22
src/signature.rs

@ -1,22 +1,18 @@
use crate::Error;
use ark_ec::twisted_edwards::Affine;
use ark_ec::twisted_edwards::TECurveConfig;
use ark_ec::AffineRepr;
use ark_serialize::CanonicalDeserialize;
use ark_serialize::CanonicalSerialize;
#[derive(Clone, Copy, Debug)]
/// `SignatureComponents` contains the realized parts of a signature
pub struct Signature<A: AffineRepr> {
r: A,
s: A::ScalarField,
pub struct Signature<TE: TECurveConfig> {
r: Affine<TE>,
s: TE::ScalarField,
}
impl<A: AffineRepr> Signature<A>
where
A::Config: TECurveConfig,
{
impl<TE: TECurveConfig> Signature<TE> {
/// Serializes the signature components to bytes as uncompressed.
/// Expect output size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)`
/// Expect output size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)`
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.r.serialize_uncompressed(&mut bytes).unwrap();
@ -25,32 +21,30 @@ where
}
/// Checked deserialization of the signature components from bytes.
/// Expects input size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)`
pub fn from_bytes(bytes: &[u8]) -> Result<Signature<A>, Error> {
let point_size = A::Config::serialized_size(ark_serialize::Compress::No);
(bytes.len() == 32 + A::Config::serialized_size(ark_serialize::Compress::No))
/// Expects input size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)`
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn ark_std::error::Error>> {
let point_size = TE::serialized_size(ark_serialize::Compress::No);
(bytes.len() == 32 + TE::serialized_size(ark_serialize::Compress::No))
.then_some(true)
.ok_or(Error::InvalidData)?;
.ok_or(ark_serialize::SerializationError::InvalidData)?;
let off1 = point_size;
let off2 = off1 + 32;
let r =
A::deserialize_uncompressed(&bytes[00..off1]).map_err(|_| crate::Error::InvalidData)?;
let s = A::ScalarField::deserialize_uncompressed(&bytes[off1..off2])
.map_err(|_| crate::Error::InvalidData)?;
let r = Affine::<TE>::deserialize_uncompressed(&bytes[00..off1])?;
let s = TE::ScalarField::deserialize_uncompressed(&bytes[off1..off2])?;
Ok(Signature { r, s })
}
pub fn new(r: A, s: A::ScalarField) -> Self {
pub fn new(r: Affine<TE>, s: TE::ScalarField) -> Self {
Self { r, s }
}
pub(crate) fn r(&self) -> &A {
pub fn r(&self) -> &Affine<TE> {
&self.r
}
pub(crate) fn s(&self) -> &A::ScalarField {
pub fn s(&self) -> &TE::ScalarField {
&self.s
}
}

Loading…
Cancel
Save