2022-11-10 22:35:09 -05:00
|
|
|
use core::ops::Deref;
|
|
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
use hex_literal::hex;
|
2022-11-10 22:35:09 -05:00
|
|
|
|
|
|
|
|
use zeroize::Zeroizing;
|
2022-07-07 07:30:10 -04:00
|
|
|
use rand_core::{RngCore, OsRng};
|
2022-06-30 05:42:29 -04:00
|
|
|
|
2022-07-02 02:46:40 -04:00
|
|
|
use ff::{Field, PrimeField};
|
2022-06-30 05:42:29 -04:00
|
|
|
use group::{Group, GroupEncoding};
|
|
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
use blake2::{Digest, Blake2b512};
|
|
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
use k256::{Scalar, ProjectivePoint};
|
2022-07-12 03:38:59 -04:00
|
|
|
use dalek_ff_group::{self as dfg, EdwardsPoint};
|
2022-07-02 02:46:40 -04:00
|
|
|
|
2022-07-12 03:38:59 -04:00
|
|
|
use transcript::{Transcript, RecommendedTranscript};
|
2022-06-30 05:42:29 -04:00
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
use crate::{
|
2022-07-07 08:26:59 -04:00
|
|
|
cross_group::{
|
2022-07-15 01:26:07 -04:00
|
|
|
scalar::mutual_scalar_from_bytes, Generators, ClassicLinearDLEq, EfficientLinearDLEq,
|
|
|
|
|
ConciseLinearDLEq, CompromiseLinearDLEq,
|
|
|
|
|
},
|
2022-07-07 07:30:10 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mod scalar;
|
|
|
|
|
mod aos;
|
2022-07-05 19:10:30 -04:00
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
type G0 = ProjectivePoint;
|
|
|
|
|
type G1 = EdwardsPoint;
|
2022-06-30 05:42:29 -04:00
|
|
|
|
2022-07-05 19:10:30 -04:00
|
|
|
pub(crate) fn transcript() -> RecommendedTranscript {
|
2022-07-02 02:46:40 -04:00
|
|
|
RecommendedTranscript::new(b"Cross-Group DLEq Proof Test")
|
|
|
|
|
}
|
2022-06-30 05:42:29 -04:00
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
pub(crate) fn generators() -> (Generators<G0>, Generators<G1>) {
|
2022-07-02 02:46:40 -04:00
|
|
|
(
|
2022-06-30 05:42:29 -04:00
|
|
|
Generators::new(
|
|
|
|
|
ProjectivePoint::GENERATOR,
|
|
|
|
|
ProjectivePoint::from_bytes(
|
2022-07-15 01:26:07 -04:00
|
|
|
&(hex!("0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0").into()),
|
|
|
|
|
)
|
|
|
|
|
.unwrap(),
|
2022-06-30 05:42:29 -04:00
|
|
|
),
|
|
|
|
|
Generators::new(
|
|
|
|
|
EdwardsPoint::generator(),
|
2022-07-15 01:26:07 -04:00
|
|
|
EdwardsPoint::from_bytes(&hex!(
|
|
|
|
|
"8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94"
|
|
|
|
|
))
|
|
|
|
|
.unwrap(),
|
|
|
|
|
),
|
2022-07-02 02:46:40 -04:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
macro_rules! verify_and_deserialize {
|
2022-07-07 08:46:11 -04:00
|
|
|
($type: ty, $proof: ident, $generators: ident, $keys: ident) => {
|
2022-07-07 07:30:10 -04:00
|
|
|
let public_keys = $proof.verify(&mut OsRng, &mut transcript(), $generators).unwrap();
|
2022-11-10 22:35:09 -05:00
|
|
|
assert_eq!($generators.0.primary * $keys.0.deref(), public_keys.0);
|
|
|
|
|
assert_eq!($generators.1.primary * $keys.1.deref(), public_keys.1);
|
2022-07-07 07:30:10 -04:00
|
|
|
|
|
|
|
|
#[cfg(feature = "serialize")]
|
|
|
|
|
{
|
|
|
|
|
let mut buf = vec![];
|
2023-01-01 01:54:18 -05:00
|
|
|
$proof.write(&mut buf).unwrap();
|
|
|
|
|
let deserialized = <$type>::read::<&[u8]>(&mut buf.as_ref()).unwrap();
|
2022-07-07 08:46:11 -04:00
|
|
|
assert_eq!($proof, deserialized);
|
2022-07-07 07:30:10 -04:00
|
|
|
}
|
2022-07-15 01:26:07 -04:00
|
|
|
};
|
2022-07-07 07:30:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! test_dleq {
|
2022-07-07 08:46:11 -04:00
|
|
|
($str: literal, $benchmark: ident, $name: ident, $type: ident) => {
|
2022-07-07 08:26:59 -04:00
|
|
|
#[ignore]
|
|
|
|
|
#[test]
|
|
|
|
|
fn $benchmark() {
|
|
|
|
|
println!("Benchmarking with Secp256k1/Ed25519");
|
|
|
|
|
let generators = generators();
|
|
|
|
|
|
|
|
|
|
let mut seed = [0; 32];
|
|
|
|
|
OsRng.fill_bytes(&mut seed);
|
|
|
|
|
let key = Blake2b512::new().chain_update(seed);
|
|
|
|
|
|
|
|
|
|
let runs = 200;
|
|
|
|
|
let mut proofs = Vec::with_capacity(usize::try_from(runs).unwrap());
|
|
|
|
|
let time = std::time::Instant::now();
|
|
|
|
|
for _ in 0 .. runs {
|
|
|
|
|
proofs.push($type::prove(&mut OsRng, &mut transcript(), generators, key.clone()).0);
|
|
|
|
|
}
|
|
|
|
|
println!("{} had a average prove time of {}ms", $str, time.elapsed().as_millis() / runs);
|
|
|
|
|
|
|
|
|
|
let time = std::time::Instant::now();
|
|
|
|
|
for proof in &proofs {
|
|
|
|
|
proof.verify(&mut OsRng, &mut transcript(), generators).unwrap();
|
|
|
|
|
}
|
|
|
|
|
println!("{} had a average verify time of {}ms", $str, time.elapsed().as_millis() / runs);
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "serialize")]
|
|
|
|
|
{
|
|
|
|
|
let mut buf = vec![];
|
2023-01-01 01:54:18 -05:00
|
|
|
proofs[0].write(&mut buf).unwrap();
|
2022-07-07 08:26:59 -04:00
|
|
|
println!("{} had a proof size of {} bytes", $str, buf.len());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 07:30:10 -04:00
|
|
|
#[test]
|
|
|
|
|
fn $name() {
|
|
|
|
|
let generators = generators();
|
|
|
|
|
|
|
|
|
|
for i in 0 .. 1 {
|
|
|
|
|
let (proof, keys) = if i == 0 {
|
|
|
|
|
let mut seed = [0; 32];
|
|
|
|
|
OsRng.fill_bytes(&mut seed);
|
|
|
|
|
|
|
|
|
|
$type::prove(
|
|
|
|
|
&mut OsRng,
|
|
|
|
|
&mut transcript(),
|
|
|
|
|
generators,
|
2022-07-15 01:26:07 -04:00
|
|
|
Blake2b512::new().chain_update(seed),
|
2022-07-07 07:30:10 -04:00
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
let mut key;
|
|
|
|
|
let mut res;
|
|
|
|
|
while {
|
2022-11-10 22:35:09 -05:00
|
|
|
key = Zeroizing::new(Scalar::random(&mut OsRng));
|
|
|
|
|
res = $type::prove_without_bias(&mut OsRng, &mut transcript(), generators, key.clone());
|
2022-07-07 07:30:10 -04:00
|
|
|
res.is_none()
|
|
|
|
|
} {}
|
|
|
|
|
let res = res.unwrap();
|
2022-07-15 01:26:07 -04:00
|
|
|
assert_eq!(key, res.1 .0);
|
2022-07-07 07:30:10 -04:00
|
|
|
res
|
|
|
|
|
};
|
|
|
|
|
|
2022-07-07 08:46:11 -04:00
|
|
|
verify_and_deserialize!($type::<G0, G1>, proof, generators, keys);
|
2022-07-07 07:30:10 -04:00
|
|
|
}
|
|
|
|
|
}
|
2022-07-15 01:26:07 -04:00
|
|
|
};
|
2022-07-07 07:30:10 -04:00
|
|
|
}
|
|
|
|
|
|
2022-07-07 08:26:59 -04:00
|
|
|
test_dleq!("ClassicLinear", benchmark_classic_linear, test_classic_linear, ClassicLinearDLEq);
|
|
|
|
|
test_dleq!("ConciseLinear", benchmark_concise_linear, test_concise_linear, ConciseLinearDLEq);
|
|
|
|
|
test_dleq!(
|
|
|
|
|
"EfficientLinear",
|
|
|
|
|
benchmark_efficient_linear,
|
|
|
|
|
test_efficient_linear,
|
|
|
|
|
EfficientLinearDLEq
|
|
|
|
|
);
|
|
|
|
|
test_dleq!(
|
|
|
|
|
"CompromiseLinear",
|
|
|
|
|
benchmark_compromise_linear,
|
|
|
|
|
test_compromise_linear,
|
|
|
|
|
CompromiseLinearDLEq
|
|
|
|
|
);
|
2022-07-07 07:30:10 -04:00
|
|
|
|
2022-07-02 02:46:40 -04:00
|
|
|
#[test]
|
|
|
|
|
fn test_rejection_sampling() {
|
|
|
|
|
let mut pow_2 = Scalar::one();
|
|
|
|
|
for _ in 0 .. dfg::Scalar::CAPACITY {
|
|
|
|
|
pow_2 = pow_2.double();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert!(
|
2022-07-07 07:30:10 -04:00
|
|
|
// Either would work
|
2022-11-10 22:35:09 -05:00
|
|
|
EfficientLinearDLEq::prove_without_bias(
|
|
|
|
|
&mut OsRng,
|
|
|
|
|
&mut transcript(),
|
|
|
|
|
generators(),
|
|
|
|
|
Zeroizing::new(pow_2)
|
|
|
|
|
)
|
|
|
|
|
.is_none()
|
2022-06-30 05:42:29 -04:00
|
|
|
);
|
2022-07-02 02:46:40 -04:00
|
|
|
}
|
2022-07-07 07:30:10 -04:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_remainder() {
|
|
|
|
|
// Uses Secp256k1 for both to achieve an odd capacity of 255
|
|
|
|
|
assert_eq!(Scalar::CAPACITY, 255);
|
|
|
|
|
let generators = (generators().0, generators().0);
|
|
|
|
|
// This will ignore any unused bits, ensuring every remaining one is set
|
2022-11-10 22:35:09 -05:00
|
|
|
let keys = mutual_scalar_from_bytes::<Scalar, Scalar>(&[0xFF; 32]);
|
|
|
|
|
let keys = (Zeroizing::new(keys.0), Zeroizing::new(keys.1));
|
|
|
|
|
assert_eq!(Scalar::one() + keys.0.deref(), Scalar::from(2u64).pow_vartime(&[255]));
|
2022-07-07 07:30:10 -04:00
|
|
|
assert_eq!(keys.0, keys.1);
|
|
|
|
|
|
2022-11-10 22:35:09 -05:00
|
|
|
let (proof, res) = ConciseLinearDLEq::prove_without_bias(
|
|
|
|
|
&mut OsRng,
|
|
|
|
|
&mut transcript(),
|
|
|
|
|
generators,
|
|
|
|
|
keys.0.clone(),
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2022-07-07 07:30:10 -04:00
|
|
|
assert_eq!(keys, res);
|
|
|
|
|
|
2022-07-07 08:46:11 -04:00
|
|
|
verify_and_deserialize!(
|
|
|
|
|
ConciseLinearDLEq::<ProjectivePoint, ProjectivePoint>,
|
|
|
|
|
proof,
|
|
|
|
|
generators,
|
|
|
|
|
keys
|
|
|
|
|
);
|
2022-07-07 07:30:10 -04:00
|
|
|
}
|