Skip to content

Commit

Permalink
Make serde optional
Browse files Browse the repository at this point in the history
This change makes the `serde` dependency optional to reduce the total
number of them from 57 to 51 using `--no-default-features` flag.

Also for simpler maintainablity, moved `SerializableProof` into separate
`serializable` modules, so by placing `#[cfg(feature = "serde")]` above
it's declaration the whole implementations and structures became
optional (instead of placing `#[cfg(feature = "serde")]` above each of
them).

Removed usage of `serde` inside tests for more prefered `Debug`
implementations.
  • Loading branch information
Velnbur committed Mar 31, 2024
1 parent 28eab6c commit 7e5fdd7
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 124 deletions.
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ categories = ["cryptography"]
keywords = ["crypto", "bulletproofs", "rangeproofs", "zeroknowledge", "zkp"]
readme = "README.md"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = [ "serde" ]
serde = ["dep:serde_json", "dep:serde"]

[dependencies]
k256 = { version = "0.13.3", features = ["serde"]}
k256 = { version = "0.13.3", features = ["serde"] }
sha2 = "0.10.8"
merlin = "3.0.0"
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"

serde = { version = "1.0.197", features = ["derive"], optional = true }
serde_json = { version = "1.0.114", optional = true }
53 changes: 8 additions & 45 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
///! Definition and implementation of the Bulletproofs++ arithmetic circuit protocol.

use std::ops::{Add, Mul, Sub};
use k256::{AffinePoint, ProjectivePoint, Scalar};
use k256::{ProjectivePoint, Scalar};
use k256::elliptic_curve::rand_core::{CryptoRng, RngCore};
use merlin::Transcript;
use serde::{Deserialize, Serialize};

use crate::util::*;
use crate::{transcript, wnla};
use crate::wnla::WeightNormLinearArgument;

#[cfg(feature = "serde")]
mod serializable;

#[cfg(feature = "serde")]
pub use serializable::SerializableProof;

#[derive(Clone, Debug, Copy, PartialEq)]
pub enum PartitionType {
LO,
Expand All @@ -31,49 +37,6 @@ pub struct Proof {
pub n: Vec<Scalar>,
}

/// Represent serializable version of arithmetic circuit proof (uses AffinePoint instead of ProjectivePoint).
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SerializableProof {
pub c_l: AffinePoint,
pub c_r: AffinePoint,
pub c_o: AffinePoint,
pub c_s: AffinePoint,
pub r: Vec<AffinePoint>,
pub x: Vec<AffinePoint>,
pub l: Vec<Scalar>,
pub n: Vec<Scalar>,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
c_l: ProjectivePoint::from(&value.c_l),
c_r: ProjectivePoint::from(&value.c_r),
c_o: ProjectivePoint::from(&value.c_o),
c_s: ProjectivePoint::from(&value.c_s),
r: value.r.iter().map(|r_val| ProjectivePoint::from(r_val)).collect::<Vec<ProjectivePoint>>(),
x: value.x.iter().map(|x_val| ProjectivePoint::from(x_val)).collect::<Vec<ProjectivePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
c_l: value.c_l.to_affine(),
c_r: value.c_r.to_affine(),
c_o: value.c_o.to_affine(),
c_s: value.c_s.to_affine(),
r: value.r.iter().map(|r_val| r_val.to_affine()).collect::<Vec<AffinePoint>>(),
x: value.x.iter().map(|x_val| x_val.to_affine()).collect::<Vec<AffinePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

/// Represents arithmetic circuit witness.
#[derive(Clone, Debug)]
pub struct Witness {
Expand Down
46 changes: 46 additions & 0 deletions src/circuit/serializable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use k256::{AffinePoint, ProjectivePoint, Scalar};

use super::Proof;

/// Represent serializable version of arithmetic circuit proof (uses AffinePoint instead of ProjectivePoint).
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct SerializableProof {
pub c_l: AffinePoint,
pub c_r: AffinePoint,
pub c_o: AffinePoint,
pub c_s: AffinePoint,
pub r: Vec<AffinePoint>,
pub x: Vec<AffinePoint>,
pub l: Vec<Scalar>,
pub n: Vec<Scalar>,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
c_l: ProjectivePoint::from(&value.c_l),
c_r: ProjectivePoint::from(&value.c_r),
c_o: ProjectivePoint::from(&value.c_o),
c_s: ProjectivePoint::from(&value.c_s),
r: value.r.iter().map(|r_val| ProjectivePoint::from(r_val)).collect::<Vec<ProjectivePoint>>(),
x: value.x.iter().map(|x_val| ProjectivePoint::from(x_val)).collect::<Vec<ProjectivePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
c_l: value.c_l.to_affine(),
c_r: value.c_r.to_affine(),
c_o: value.c_o.to_affine(),
c_s: value.c_s.to_affine(),
r: value.r.iter().map(|r_val| r_val.to_affine()).collect::<Vec<AffinePoint>>(),
x: value.x.iter().map(|x_val| x_val.to_affine()).collect::<Vec<AffinePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}
8 changes: 7 additions & 1 deletion src/range_proof.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
pub mod reciprocal;
pub mod u64_proof;
pub mod u64_proof;

#[cfg(feature = "serde")]
mod serializable;

#[cfg(feature = "serde")]
pub use serializable::SerializableProof;
29 changes: 1 addition & 28 deletions src/range_proof/reciprocal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
///! Definition and implementation of the reciprocal range-proof protocol based on arithmetic circuits protocol.

use std::ops::{Add, Mul};
use k256::{AffinePoint, ProjectivePoint, Scalar};
use k256::{ProjectivePoint, Scalar};
use k256::elliptic_curve::rand_core::{CryptoRng, RngCore};
use merlin::Transcript;
use serde::{Deserialize, Serialize};
use crate::util::*;
use crate::{circuit, transcript};
use crate::circuit::{ArithmeticCircuit, PartitionType};
Expand All @@ -31,32 +30,6 @@ pub struct Proof {
pub r: ProjectivePoint,
}

/// Represent serializable version of reciprocal proof (uses AffinePoint instead of ProjectivePoint
/// and serialized version of circuit proof).
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SerializableProof {
pub circuit_proof: circuit::SerializableProof,
pub r: AffinePoint,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
circuit_proof: circuit::Proof::from(&value.circuit_proof),
r: ProjectivePoint::from(value.r),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
circuit_proof: circuit::SerializableProof::from(&value.circuit_proof),
r: value.r.to_affine(),
};
}
}

/// Represents public reciprocal range proof protocol information. Using this information and challenge
/// both prover and verifier can derive the arithmetic circuit.
#[derive(Clone, Debug)]
Expand Down
32 changes: 32 additions & 0 deletions src/range_proof/serializable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use k256::{AffinePoint, ProjectivePoint};

use crate::circuit;

use super::reciprocal::Proof;


/// Represent serializable version of reciprocal proof (uses AffinePoint instead of ProjectivePoint
/// and serialized version of circuit proof).
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct SerializableProof {
pub circuit_proof: circuit::SerializableProof,
pub r: AffinePoint,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
circuit_proof: circuit::Proof::from(&value.circuit_proof),
r: ProjectivePoint::from(value.r),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
circuit_proof: circuit::SerializableProof::from(&value.circuit_proof),
r: value.r.to_affine(),
};
}
}
32 changes: 19 additions & 13 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ mod tests {
use k256::elliptic_curve::rand_core::OsRng;
use k256::{ProjectivePoint, Scalar};
use crate::circuit::{ArithmeticCircuit, PartitionType, Witness};
use crate::{circuit, range_proof, wnla};
use crate::range_proof::reciprocal;
use crate::{range_proof, wnla};
use crate::range_proof::u64_proof::*;
use crate::util::{minus};
use crate::util::minus;

#[test]
fn u64_proof_works() {
Expand All @@ -36,11 +35,13 @@ mod tests {
let mut pt = merlin::Transcript::new(b"u64 range proof");
let proof = public.prove(x, &s, &mut pt, &mut rand);

println!("Commitment: {}", serde_json::to_string_pretty(&commitment.to_affine()).unwrap());
println!("Proof: {}", serde_json::to_string_pretty(&reciprocal::SerializableProof::from(&proof)).unwrap());

let mut vt = merlin::Transcript::new(b"u64 range proof");
assert!(public.verify(&commitment, proof, &mut vt));

assert!(
public.verify(&commitment, proof.clone(), &mut vt),
"failed to verfiy proof {:?} with commitment {:?}",
commitment, proof,
);
}

#[test]
Expand Down Expand Up @@ -131,10 +132,12 @@ mod tests {
let mut pt = merlin::Transcript::new(b"circuit test");
let proof = circuit.prove::<OsRng>(&v, witness, &mut pt, &mut rand);

println!("{}", serde_json::to_string_pretty(&circuit::SerializableProof::from(&proof)).unwrap());

let mut vt = merlin::Transcript::new(b"circuit test");
assert!(circuit.verify(&v, &mut vt, proof));
assert!(
circuit.verify(&v, &mut vt, proof.clone()),
"failed to verify with proof = {:?}",
proof,
);
}

#[test]
Expand Down Expand Up @@ -166,9 +169,12 @@ mod tests {

let proof = wnla.prove(&commit, &mut pt, l, n);

println!("{}", serde_json::to_string_pretty(&wnla::SerializableProof::from(&proof)).unwrap());

let mut vt = merlin::Transcript::new(b"wnla test");
assert!(wnla.verify(&commit, &mut vt, proof))

assert!(
wnla.verify(&commit, &mut vt, proof.clone()),
"failed to verify WNLA proof = {:?}",
proof,
)
}
}
37 changes: 4 additions & 33 deletions src/wnla.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
///! Definition and implementation of the Bulletproofs++ weight norm linear argument protocol.
use std::ops::{Add, Mul};
use k256::{AffinePoint, ProjectivePoint, Scalar};
use k256::{ProjectivePoint, Scalar};
use merlin::Transcript;
use serde::{Deserialize, Serialize};
use crate::transcript;
use crate::util::*;

#[cfg(feature = "serde")]
mod serializable;

/// Represents public information to be used in weight norm linear argument protocol.
#[derive(Clone, Debug)]
pub struct WeightNormLinearArgument {
Expand All @@ -28,37 +30,6 @@ pub struct Proof {
pub n: Vec<Scalar>,
}

/// Represent serializable version of weight norm linear argument proof (uses AffinePoint instead of ProjectivePoint).
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SerializableProof {
pub r: Vec<AffinePoint>,
pub x: Vec<AffinePoint>,
pub l: Vec<Scalar>,
pub n: Vec<Scalar>,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
r: value.r.iter().map(|r_val| ProjectivePoint::from(r_val)).collect::<Vec<ProjectivePoint>>(),
x: value.x.iter().map(|x_val| ProjectivePoint::from(x_val)).collect::<Vec<ProjectivePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
r: value.r.iter().map(|r_val| r_val.to_affine()).collect::<Vec<AffinePoint>>(),
x: value.x.iter().map(|x_val| x_val.to_affine()).collect::<Vec<AffinePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

impl WeightNormLinearArgument {
/// Creates weight norm linear argument commitment to vectors `l`, `n`:
/// `C = v*g + <h_vec, l> + <g_vec, n>`, where `v = |n|_{mu}^2 + <c, l>`
Expand Down
34 changes: 34 additions & 0 deletions src/wnla/serializable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use k256::{AffinePoint, ProjectivePoint, Scalar};

use super::Proof;

/// Represent serializable version of weight norm linear argument proof (uses AffinePoint instead of ProjectivePoint).
#[derive(Clone, Debug)]
pub struct SerializableProof {
pub r: Vec<AffinePoint>,
pub x: Vec<AffinePoint>,
pub l: Vec<Scalar>,
pub n: Vec<Scalar>,
}

impl From<&SerializableProof> for Proof {
fn from(value: &SerializableProof) -> Self {
return Proof {
r: value.r.iter().map(ProjectivePoint::from).collect::<Vec<ProjectivePoint>>(),
x: value.x.iter().map(ProjectivePoint::from).collect::<Vec<ProjectivePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

impl From<&Proof> for SerializableProof {
fn from(value: &Proof) -> Self {
return SerializableProof {
r: value.r.iter().map(|r_val| r_val.to_affine()).collect::<Vec<AffinePoint>>(),
x: value.x.iter().map(|x_val| x_val.to_affine()).collect::<Vec<AffinePoint>>(),
l: value.l.clone(),
n: value.n.clone(),
};
}
}

0 comments on commit 7e5fdd7

Please sign in to comment.