From 4dbf50243be6c65e04d78eb9bfd5ed21056dccd5 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 7 Jul 2022 08:46:11 -0400 Subject: [PATCH] Fix serialization This enabled getting the proof sizes, which are: - ConciseLinear had a proof size of 44607 bytes - CompromiseLinear had a proof size of 48765 bytes - ClassicLinear had a proof size of 56829 bytes - EfficientLinear had a proof size of 65145 byte --- crypto/dleq/src/cross_group/aos.rs | 2 ++ crypto/dleq/src/cross_group/bits.rs | 7 ++++++- crypto/dleq/src/cross_group/mod.rs | 7 +++++-- crypto/dleq/src/tests/cross_group/aos.rs | 1 + crypto/dleq/src/tests/cross_group/mod.rs | 19 ++++++++++++------- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/crypto/dleq/src/cross_group/aos.rs b/crypto/dleq/src/cross_group/aos.rs index 926bcb64..b73cb8b2 100644 --- a/crypto/dleq/src/cross_group/aos.rs +++ b/crypto/dleq/src/cross_group/aos.rs @@ -195,6 +195,7 @@ impl< #[cfg(feature = "serialize")] pub(crate) fn serialize(&self, w: &mut W) -> std::io::Result<()> { + #[allow(non_snake_case)] match self.Re_0 { Re::R(R0, R1) => { w.write_all(R0.to_bytes().as_ref())?; @@ -211,6 +212,7 @@ impl< Ok(()) } + #[allow(non_snake_case)] #[cfg(feature = "serialize")] pub(crate) fn deserialize(r: &mut R, mut Re_0: Re) -> std::io::Result { match Re_0 { diff --git a/crypto/dleq/src/cross_group/bits.rs b/crypto/dleq/src/cross_group/bits.rs index ac77de97..5f55d181 100644 --- a/crypto/dleq/src/cross_group/bits.rs +++ b/crypto/dleq/src/cross_group/bits.rs @@ -165,6 +165,11 @@ impl< #[cfg(feature = "serialize")] pub(crate) fn deserialize(r: &mut R) -> std::io::Result { - Ok(Bits { commitments: (read_point(r)?, read_point(r)?), signature: Aos::deserialize(r)? }) + Ok( + Bits { + commitments: (read_point(r)?, read_point(r)?), + signature: Aos::deserialize(r, BitSignature::from(SIGNATURE).aos_form())? + } + ) } } diff --git a/crypto/dleq/src/cross_group/mod.rs b/crypto/dleq/src/cross_group/mod.rs index 65692585..932f7242 100644 --- a/crypto/dleq/src/cross_group/mod.rs +++ b/crypto/dleq/src/cross_group/mod.rs @@ -63,7 +63,7 @@ pub struct DLEqProof< } macro_rules! dleq { - ($name: ident, $signature: expr, $remainder: expr) => { + ($name: ident, $signature: expr, $remainder: literal) => { pub type $name = DLEqProof< G0, G1, @@ -81,10 +81,12 @@ macro_rules! dleq { // bit and removing a hash while slightly reducing challenge security. This security reduction is // already applied to the scalar being proven for, a result of the requirement it's mutually valid // over both scalar fields, hence its application here as well. This is mainly here as a point of -// reference for the following DLEq proofs, all which use merged challenges +// reference for the following DLEq proofs, all which use merged challenges, and isn't performant +// in comparison to the others dleq!(ClassicLinearDLEq, BitSignature::ClassicLinear, false); // Proves for 2-bits at a time to save 3/7 elements of every other bit +// <9% smaller than CompromiseLinear, yet ~12% slower dleq!(ConciseLinearDLEq, BitSignature::ConciseLinear, true); // Uses AOS signatures of the form R, s, to enable the final step of the ring signature to be @@ -94,6 +96,7 @@ dleq!(EfficientLinearDLEq, BitSignature::EfficientLinear, false); // Proves for 2-bits at a time while using the R, s form. This saves 3/7 elements of every other // bit, while adding 1 element to every bit, and is more efficient than ConciseLinear yet less // efficient than EfficientLinear due to having more ring signature steps which aren't batched +// >25% smaller than EfficientLinear and just 11% slower, making it the recommended option dleq!(CompromiseLinearDLEq, BitSignature::CompromiseLinear, true); impl< diff --git a/crypto/dleq/src/tests/cross_group/aos.rs b/crypto/dleq/src/tests/cross_group/aos.rs index efd37026..0ec83836 100644 --- a/crypto/dleq/src/tests/cross_group/aos.rs +++ b/crypto/dleq/src/tests/cross_group/aos.rs @@ -9,6 +9,7 @@ use crate::{ tests::cross_group::{G0, G1, transcript, generators} }; +#[allow(non_snake_case)] #[cfg(feature = "serialize")] fn test_aos_serialization(proof: Aos, Re_0: Re) { let mut buf = vec![]; diff --git a/crypto/dleq/src/tests/cross_group/mod.rs b/crypto/dleq/src/tests/cross_group/mod.rs index a6cd4f73..c201f497 100644 --- a/crypto/dleq/src/tests/cross_group/mod.rs +++ b/crypto/dleq/src/tests/cross_group/mod.rs @@ -49,7 +49,7 @@ pub(crate) fn generators() -> (Generators, Generators) { } macro_rules! verify_and_deserialize { - ($type: ident, $proof: ident, $generators: ident, $keys: ident) => { + ($type: ty, $proof: ident, $generators: ident, $keys: ident) => { let public_keys = $proof.verify(&mut OsRng, &mut transcript(), $generators).unwrap(); assert_eq!($generators.0.primary * $keys.0, public_keys.0); assert_eq!($generators.1.primary * $keys.1, public_keys.1); @@ -58,14 +58,14 @@ macro_rules! verify_and_deserialize { { let mut buf = vec![]; $proof.serialize(&mut buf).unwrap(); - let deserialized = $type::::deserialize(&mut std::io::Cursor::new(&buf)).unwrap(); - assert_eq!(proof, deserialized); + let deserialized = <$type>::deserialize(&mut std::io::Cursor::new(&buf)).unwrap(); + assert_eq!($proof, deserialized); } } } macro_rules! test_dleq { - ($str: expr, $benchmark: ident, $name: ident, $type: ident) => { + ($str: literal, $benchmark: ident, $name: ident, $type: ident) => { #[ignore] #[test] fn $benchmark() { @@ -93,7 +93,7 @@ macro_rules! test_dleq { #[cfg(feature = "serialize")] { let mut buf = vec![]; - proofs[0].serialize(&mut buf); + proofs[0].serialize(&mut buf).unwrap(); println!("{} had a proof size of {} bytes", $str, buf.len()); } } @@ -126,7 +126,7 @@ macro_rules! test_dleq { res }; - verify_and_deserialize!($type, proof, generators, keys); + verify_and_deserialize!($type::, proof, generators, keys); } } } @@ -183,5 +183,10 @@ fn test_remainder() { ).unwrap(); assert_eq!(keys, res); - verify_and_deserialize!(ConciseLinearDLEq, proof, generators, keys); + verify_and_deserialize!( + ConciseLinearDLEq::, + proof, + generators, + keys + ); }