Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require using Schnorr proofs from signature proof for predicates #42

Merged
merged 2 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/knox/accumulator/vb20/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,14 @@ impl MembershipProofCommitting {
/// A ZKP membership proof
#[derive(Debug, Default, Copy, Clone, Deserialize, Serialize)]
pub struct MembershipProof {
e_c: G1Projective,
t_sigma: G1Projective,
t_rho: G1Projective,
s_sigma: Scalar,
s_rho: Scalar,
s_delta_sigma: Scalar,
s_delta_rho: Scalar,
s_y: Scalar,
pub(crate) e_c: G1Projective,
pub(crate) t_sigma: G1Projective,
pub(crate) t_rho: G1Projective,
pub(crate) s_sigma: Scalar,
pub(crate) s_rho: Scalar,
pub(crate) s_delta_sigma: Scalar,
pub(crate) s_delta_rho: Scalar,
pub(crate) s_y: Scalar,
mikelodder7 marked this conversation as resolved.
Show resolved Hide resolved
}

impl core::fmt::Display for MembershipProof {
Expand Down
47 changes: 19 additions & 28 deletions src/knox/bbs/pok_signature.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::error::Error;
use crate::knox::bbs::{PokSignatureProof, PublicKey, Signature};
use crate::knox::short_group_sig_core::{
short_group_traits::ProofOfSignatureKnowledgeContribution, *,
};
use crate::CredxResult;
use blsful::inner_types::{G1Affine, G1Projective, Scalar};
use elliptic_curve::{group::Curve, Field};
use elliptic_curve::Field;
use merlin::Transcript;
use rand_core::*;

Expand All @@ -14,7 +15,6 @@ pub struct PokSignature {
proof: ProofCommittedBuilder<G1Projective, G1Affine, Scalar>,
a_bar: G1Projective,
b_bar: G1Projective,
commitment: G1Projective,
hidden_messages: Vec<Scalar>,
}

Expand All @@ -31,57 +31,48 @@ impl ProofOfSignatureKnowledgeContribution for PokSignature {
) -> CredxResult<Self> {
let msgs = messages.iter().map(|m| m.get_message()).collect::<Vec<_>>();

let signature_randomizer = Scalar::random(&mut rng);
let r = Scalar::random(&mut rng);
let r_inv = Option::from((-r).invert()).ok_or(Error::InvalidPresentationData)?;
let r_inv_e = r_inv * signature.e;

let b = G1Projective::GENERATOR + G1Projective::sum_of_products(&public_key.y, &msgs);

let a_bar = signature.a * signature_randomizer;
let b_bar = b * signature_randomizer - a_bar * signature.e;
let a_bar = signature.a * r;
let b_bar = b * r - a_bar * signature.e;

let mut proof = ProofCommittedBuilder::new(G1Projective::sum_of_products);
let mut points = Vec::with_capacity(msgs.len());
let mut hidden_messages = Vec::with_capacity(msgs.len());
let mut revealed_messages = Vec::with_capacity(msgs.len());
let mut hidden_messages = Vec::with_capacity(msgs.len() + 2);

for (i, m) in messages.iter().enumerate() {
match m {
ProofMessage::Hidden(HiddenMessage::ProofSpecificBlinding(msg)) => {
proof.commit_random(public_key.y[i], &mut rng);
hidden_messages.push(*msg * signature_randomizer);
hidden_messages.push(*msg);
}
ProofMessage::Hidden(HiddenMessage::ExternalBlinding(msg, n)) => {
proof.commit(public_key.y[i], *n);
hidden_messages.push(*msg * signature_randomizer);
}
ProofMessage::Revealed(msg) => {
points.push(public_key.y[i]);
revealed_messages.push(*msg);
hidden_messages.push(*msg);
}
ProofMessage::Revealed(_) => {}
}
}
let commitment =
G1Projective::GENERATOR + G1Projective::sum_of_products(&points, &revealed_messages);
proof.commit_random(commitment, &mut rng);
hidden_messages.push(signature_randomizer);
proof.commit_random(a_bar, &mut rng);
hidden_messages.push(-signature.e);
hidden_messages.push(r_inv_e);
proof.commit_random(b_bar, &mut rng);
hidden_messages.push(r_inv);
Ok(Self {
proof,
a_bar,
b_bar,
commitment,
hidden_messages,
})
}

fn add_proof_contribution(&self, transcript: &mut Transcript) {
transcript.append_message(b"a_bar", self.a_bar.to_affine().to_compressed().as_ref());
transcript.append_message(b"b_bar", self.b_bar.to_affine().to_compressed().as_ref());
transcript.append_message(
b"random commitment",
self.commitment.to_affine().to_compressed().as_ref(),
);
transcript.append_message(b"a_bar", self.a_bar.to_compressed().as_ref());
transcript.append_message(b"b_bar", self.b_bar.to_compressed().as_ref());
self.proof
.add_challenge_contribution(b"blind commitment", transcript);
.add_challenge_contribution(b"commitment", transcript);
}

fn generate_proof(self, challenge: Scalar) -> CredxResult<Self::ProofOfKnowledge> {
Expand All @@ -91,7 +82,7 @@ impl ProofOfSignatureKnowledgeContribution for PokSignature {
Ok(PokSignatureProof {
a_bar: self.a_bar,
b_bar: self.b_bar,
commitment: self.commitment,
t: self.proof.commitment(),
proof,
})
}
Expand Down
83 changes: 40 additions & 43 deletions src/knox/bbs/pok_signature_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::collections::{BTreeMap, BTreeSet};
pub struct PokSignatureProof {
pub(crate) a_bar: G1Projective,
pub(crate) b_bar: G1Projective,
pub(crate) commitment: G1Projective,
pub(crate) t: G1Projective,
pub(crate) proof: Vec<Scalar>,
}

Expand All @@ -26,64 +26,58 @@ impl ProofOfSignatureKnowledge for PokSignatureProof {

fn add_proof_contribution(
&self,
public_key: &Self::PublicKey,
revealed_messages: &[(usize, Scalar)],
challenge: Scalar,
_public_key: &Self::PublicKey,
_revealed_messages: &[(usize, Scalar)],
_challenge: Scalar,
transcript: &mut Transcript,
) {
transcript.append_message(b"a_bar", self.a_bar.to_affine().to_compressed().as_ref());
transcript.append_message(b"b_bar", self.b_bar.to_affine().to_compressed().as_ref());
transcript.append_message(
b"random commitment",
self.commitment.to_affine().to_compressed().as_ref(),
);
let mut known = BTreeSet::new();
for (idx, _) in revealed_messages {
known.insert(*idx);
}

let mut points = Vec::with_capacity(public_key.y.len() + 2);
for (idx, _) in public_key.y.iter().enumerate() {
if known.contains(&idx) {
continue;
}
points.push(public_key.y[idx]);
}
points.push(self.commitment);
points.push(self.a_bar);
points.push(self.b_bar);
let mut scalars = self.proof.clone();
scalars.push(-challenge);
let commitment = G1Projective::sum_of_products(&points, &scalars);
transcript.append_message(
b"blind commitment",
commitment.to_affine().to_compressed().as_ref(),
);
transcript.append_message(b"a_bar", self.a_bar.to_compressed().as_ref());
transcript.append_message(b"b_bar", self.b_bar.to_compressed().as_ref());
transcript.append_message(b"commitment", self.t.to_compressed().as_ref());
}

fn verify(
&self,
revealed_messages: &[(usize, Scalar)],
public_key: &Self::PublicKey,
revealed_messages: &[(usize, Scalar)],
challenge: Scalar,
) -> CredxResult<()> {
if (self.a_bar.is_identity() | self.b_bar.is_identity()).into() {
if (self.a_bar.is_identity() | self.b_bar.is_identity() | self.t.is_identity()).into() {
return Err(Error::General("Invalid proof - identity"));
}
if public_key.is_invalid().into() {
return Err(Error::General("Invalid public key"));
}
let mut points = Vec::with_capacity(public_key.y.len() + 2);
let mut points = Vec::with_capacity(public_key.y.len() + 3);
let mut msgs = Vec::with_capacity(revealed_messages.len());
let mut known = BTreeSet::new();
for (idx, msg) in revealed_messages {
if *idx >= public_key.y.len() {
continue;
}
known.insert(*idx);
points.push(public_key.y[*idx]);
msgs.push(*msg);
}
let commitment = G1Projective::GENERATOR + G1Projective::sum_of_products(&points, &msgs);
if self.commitment != commitment {
return Err(Error::General("Invalid proof - commitment"));
let lhs = -G1Projective::sum_of_products(&points, &msgs) - G1Projective::GENERATOR;
points.clear();
msgs.clear();

for (idx, y) in public_key.y.iter().enumerate() {
if known.contains(&idx) {
continue;
}
points.push(*y);
}

points.push(self.a_bar);
points.push(self.b_bar);
points.push(lhs);
let mut scalars = self.proof.clone();
scalars.push(-challenge);
let commitment = G1Projective::sum_of_products(&points, &scalars);
if self.t != commitment {
return Err(Error::General("Invalid proof - invalid messages"));
}

let res = multi_miller_loop(&[
Expand Down Expand Up @@ -127,7 +121,10 @@ impl ProofOfSignatureKnowledge for PokSignatureProof {
j += 1;
continue;
}
let message = self.proof.get(i).ok_or(Error::General("invalid proof"))?;
let message = self
.proof
.get(i - j)
.ok_or(Error::General("invalid proof"))?;
hidden.insert(i, *message);
}

Expand All @@ -140,9 +137,9 @@ impl PokSignatureProof {
pub fn to_bytes(&self) -> Vec<u8> {
let mut buffer = Vec::with_capacity(48 * 3 + 32 * self.proof.len());

buffer.extend_from_slice(&self.a_bar.to_affine().to_compressed());
buffer.extend_from_slice(&self.b_bar.to_affine().to_compressed());
buffer.extend_from_slice(&self.commitment.to_affine().to_compressed());
buffer.extend_from_slice(&self.a_bar.to_compressed());
buffer.extend_from_slice(&self.b_bar.to_compressed());
buffer.extend_from_slice(&self.t.to_compressed());
for scalar in &self.proof {
buffer.extend_from_slice(scalar.to_repr().as_ref());
}
Expand Down Expand Up @@ -194,7 +191,7 @@ impl PokSignatureProof {
Some(Self {
a_bar: a_bar.unwrap(),
b_bar: b_bar.unwrap(),
commitment: commitment.unwrap(),
t: commitment.unwrap(),
proof,
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/knox/bbs/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ impl ShortGroupSignatureScheme for BbsScheme {
transcript.challenge_bytes(b"signature proof of knowledge", &mut res);
let v_challenge = Scalar::from_bytes_wide(&res);

proof.verify(revealed_msgs, public_key).is_ok() && challenge == v_challenge
proof.verify(public_key, revealed_msgs, challenge).is_ok() && challenge == v_challenge
}
}
11 changes: 8 additions & 3 deletions src/knox/ps/pok_signature_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ impl ProofOfSignatureKnowledge for PokSignatureProof {
/// Validate the proof, only checks the signature proof
/// the selective disclosure proof is checked by verifying
/// self.challenge == computed_challenge
fn verify(&self, rvl_msgs: &[(usize, Scalar)], public_key: &PublicKey) -> CredxResult<()> {
fn verify(
&self,
public_key: &Self::PublicKey,
revealed_messages: &[(usize, Scalar)],
_challenge: Scalar,
) -> CredxResult<()> {
// check the signature proof
if self
.sigma_1
Expand All @@ -84,7 +89,7 @@ impl ProofOfSignatureKnowledge for PokSignatureProof {
return Err(Error::General("Invalid proof - identity"));
}

if public_key.y.len() < rvl_msgs.len() {
if public_key.y.len() < revealed_messages.len() {
return Err(Error::General(
"Invalid key - revealed messages length is bigger than the public key",
));
Expand All @@ -96,7 +101,7 @@ impl ProofOfSignatureKnowledge for PokSignatureProof {
let mut points = Vec::new();
let mut scalars = Vec::new();

for (idx, msg) in rvl_msgs {
for (idx, msg) in revealed_messages {
if *idx > public_key.y.len() {
return Err(Error::General("Invalid proof - revealed message index"));
}
Expand Down
2 changes: 1 addition & 1 deletion src/knox/ps/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,6 @@ impl ShortGroupSignatureScheme for PsScheme {
transcript.challenge_bytes(b"signature proof of knowledge", &mut res);
let v_challenge = Scalar::from_bytes_wide(&res);

proof.verify(revealed_msgs, public_key).is_ok() && challenge == v_challenge
proof.verify(public_key, revealed_msgs, challenge).is_ok() && challenge == v_challenge
}
}
8 changes: 6 additions & 2 deletions src/knox/short_group_sig_core/proof_committed_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@ where

/// Convert the committed values to bytes for the fiat-shamir challenge
pub fn add_challenge_contribution(&self, label: &'static [u8], transcript: &mut Transcript) {
let mut scalars = self.scalars.clone();
let commitment = (self.sum_of_products)(self.points.as_ref(), scalars.as_mut());
let commitment = self.commitment();
transcript.append_message(label, commitment.to_affine().to_bytes().as_ref());
}

pub fn commitment(&self) -> B {
let mut scalars = self.scalars.clone();
(self.sum_of_products)(self.points.as_ref(), scalars.as_mut())
}

/// Generate the Schnorr challenges given the specified secrets
/// by computing p = r + c * s
pub fn generate_proof(&self, challenge: S, secrets: &[S]) -> CredxResult<Vec<S>> {
Expand Down
3 changes: 2 additions & 1 deletion src/knox/short_group_sig_core/short_group_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ pub trait ProofOfSignatureKnowledge:
/// Verify the signature proof of knowledge
fn verify(
&self,
revealed_messages: &[(usize, Scalar)],
public_key: &Self::PublicKey,
revealed_messages: &[(usize, Scalar)],
challenge: Scalar,
) -> CredxResult<()>;

/// Get the hidden message proofs
Expand Down
7 changes: 0 additions & 7 deletions src/presentation/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ use serde::{Deserialize, Serialize};
pub(crate) struct CommitmentBuilder<'a> {
pub(crate) commitment: G1Projective,
pub(crate) statement: &'a CommitmentStatement<G1Projective>,
pub(crate) message: Scalar,
pub(crate) b: Scalar,
pub(crate) r: Scalar,
}

impl<S: ShortGroupSignatureScheme> PresentationBuilder<S> for CommitmentBuilder<'_> {
fn gen_proof(self, challenge: Scalar) -> PresentationProofs<S> {
let message_proof = self.b + challenge * self.message;
let blinder_proof = self.r + challenge * self.b;
CommitmentProof {
id: self.statement.id.clone(),
commitment: self.commitment,
message_proof,
blinder_proof,
}
.into()
Expand All @@ -41,7 +38,6 @@ impl<'a> CommitmentBuilder<'a> {
transcript: &mut Transcript,
) -> CredxResult<Self> {
let r = Scalar::random(&mut rng);

let commitment = statement.message_generator * message + statement.blinder_generator * b;
let blind_commitment = statement.message_generator * b + statement.blinder_generator * r;

Expand All @@ -57,7 +53,6 @@ impl<'a> CommitmentBuilder<'a> {
Ok(Self {
commitment,
statement,
message,
b,
r,
})
Expand All @@ -71,8 +66,6 @@ pub struct CommitmentProof {
pub id: String,
/// The commitment
pub commitment: G1Projective,
/// The schnorr message proof
pub message_proof: Scalar,
/// The schnorr blinder proof
pub blinder_proof: Scalar,
}
Loading
Loading