Skip to content

Commit 8e752c1

Browse files
committed
Fix bug that occurs when public point is the identity
1 parent 26ee455 commit 8e752c1

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ macro_rules! define_proof {
292292

293293
let public_vars = PublicVars {
294294
$(
295-
$instance_var: verifier.allocate_point(
295+
$instance_var: verifier.allocate_public_point(
296296
TRANSCRIPT_LABELS.$instance_var.as_bytes(),
297297
*assignments.$instance_var,
298298
)?,

src/toolbox/verifier.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ impl<'a> Verifier<'a> {
6262
ScalarVar(self.num_scalars - 1)
6363
}
6464

65+
/// Attempt to allocate a public point variable, or fail verification if
66+
/// the assignment is invalid. This function allows for public points being the identity.
67+
pub fn allocate_public_point(
68+
&mut self,
69+
label: &'static [u8],
70+
assignment: CompressedRistretto,
71+
) -> Result<PointVar, ProofError> {
72+
let encoding = assignment.decompress();
73+
self.transcript
74+
.append_point_var(label, &encoding.unwrap());
75+
self.points.push(assignment);
76+
self.point_labels.push(label);
77+
Ok(PointVar(self.points.len() - 1))
78+
}
79+
6580
/// Attempt to allocate a point variable, or fail verification if
6681
/// the assignment is invalid.
6782
pub fn allocate_point(

tests/vrf_public_zero.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// We really want points to be capital letters and scalars to be
2+
// lowercase letters
3+
#![allow(non_snake_case)]
4+
5+
#[macro_use]
6+
extern crate zkp;
7+
8+
use curve25519_dalek::constants as dalek_constants;
9+
use curve25519_dalek::ristretto::RistrettoPoint;
10+
use curve25519_dalek::scalar::Scalar;
11+
12+
use zkp::Transcript;
13+
14+
define_proof! {
15+
testproof,
16+
"Test Proof",
17+
(s, a, b, c),
18+
(W, X, Y, Z),
19+
(B):
20+
Z = (s*B + a*W + b*X + c*Y)
21+
}
22+
23+
// Test the generation and verification of the proof where (W,X,Y) =
24+
// (w*B, x*B, y*B) and B is the Ristretto generator. This situation
25+
// comes up in the issuing protocol of CMZ14 credentials, where w, x,
26+
// and y are the (public) attributes on the credential being issued.
27+
pub fn test_issue(w: &Scalar, x: &Scalar, y: &Scalar) {
28+
let B: RistrettoPoint = dalek_constants::RISTRETTO_BASEPOINT_POINT;
29+
30+
// Public points based on the public attributes
31+
let (W, X, Y) = (w*B, x*B, y*B);
32+
33+
let mut rng = rand::thread_rng();
34+
// Private coefficients (the prover's MAC key)
35+
let a = Scalar::random(&mut rng);
36+
let b = Scalar::random(&mut rng);
37+
let c = Scalar::random(&mut rng);
38+
let s = Scalar::random(&mut rng);
39+
40+
// (Part of the) public MAC
41+
let Z = s*B + a*W + b*X + c*Y;
42+
43+
// Construct the proof
44+
let mut prv_transcript = Transcript::new(b"test transcript");
45+
let pi = testproof::prove_compact(
46+
&mut prv_transcript,
47+
testproof::ProveAssignments {
48+
B: &B,
49+
W: &W,
50+
X: &X,
51+
Y: &Y,
52+
Z: &Z,
53+
a: &a,
54+
b: &b,
55+
c: &c,
56+
s: &s,
57+
},
58+
)
59+
.0;
60+
61+
// Send (Z, pi) to the verifier
62+
63+
// The verifier will recompute W, Y, Z as above and then verify:
64+
65+
let mut vrf_transcript = Transcript::new(b"test transcript");
66+
let result = testproof::verify_compact(
67+
&pi,
68+
&mut vrf_transcript,
69+
testproof::VerifyAssignments {
70+
B: &B.compress(),
71+
W: &W.compress(),
72+
X: &X.compress(),
73+
Y: &Y.compress(),
74+
Z: &Z.compress(),
75+
},
76+
);
77+
78+
assert!(result.is_ok());
79+
}
80+
81+
#[test]
82+
fn test_nozero() {
83+
let mut rng = rand::thread_rng();
84+
let w = Scalar::random(&mut rng);
85+
let x = Scalar::random(&mut rng);
86+
let y = Scalar::random(&mut rng);
87+
test_issue(&w, &x, &y);
88+
}
89+
90+
#[test]
91+
fn test_zero() {
92+
let mut rng = rand::thread_rng();
93+
let w = Scalar::random(&mut rng);
94+
let x = Scalar::ZERO;
95+
let y = Scalar::random(&mut rng);
96+
test_issue(&w, &x, &y);
97+
}
98+

0 commit comments

Comments
 (0)