-
Notifications
You must be signed in to change notification settings - Fork 217
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
Add a transcript protocol function that checks for identity points. #248
Changes from 1 commit
0f2fed9
4af51a5
40def3a
28b22bb
381bc74
5dbbd2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -287,18 +287,19 @@ impl RangeProof { | |
transcript.rangeproof_domain_sep(n as u64, m as u64); | ||
|
||
for V in value_commitments.iter() { | ||
transcript.commit_point(b"V", V); | ||
transcript.validate_and_commit_point(b"V", V)?; | ||
} | ||
transcript.commit_point(b"A", &self.A); | ||
transcript.commit_point(b"S", &self.S); | ||
|
||
transcript.validate_and_commit_point(b"A", &self.A)?; | ||
transcript.validate_and_commit_point(b"S", &self.S)?; | ||
|
||
let y = transcript.challenge_scalar(b"y"); | ||
let z = transcript.challenge_scalar(b"z"); | ||
let zz = z * z; | ||
let minus_z = -z; | ||
|
||
transcript.commit_point(b"T_1", &self.T_1); | ||
transcript.commit_point(b"T_2", &self.T_2); | ||
transcript.validate_and_commit_point(b"T_1", &self.T_1)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. T1 and T2 commit to “leftover” cross-terms and separated from the rest of the statement using non-zero challenge powers. There should not be a valid reason for them to not be allowed to be zero. If there is such reason, it must be specifically explored and called out. Maybe with some choice of prior challenges and zero blinding factors, some cross terms could actually end up being zeroes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I mean, maybe not in this RP protocol, but in R1CS, for instance) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I disagree somewhat with this reasoning. My reasoning for not allowing them to be zero is: allowing prover-supplied points to be the identity point is a risk, because it allows a prover to kill arbitrary terms in the verification equation (by setting those points to the identity, so that their coefficients disappear). It seems to be the case for Bulletproofs that this doesn't cause problems, but there are certainly other protocols where it does. Checking that the prover-supplied points aren't the identity closes off this line of attack upfront, even if, for this protocol, that line may not lead anywhere. So I view this as a defense-in-depth mechanism. Legitimate proofs won't have zero terms (or will have them with negligible probability), so I don't think that this check costs anything to the protocol, but it does add a hedge against a class of risk to the protocol. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a follow-up, here's a concrete example of the kind of thing I'm worried about: https://twitter.com/claudiorlandi/status/1090705045333659648 The description of the protocol implicitly assumed that some data was not the identity and nobody noticed, leaving a gap. Preemptively checking that points are not the identity (unless there's a reason to allow them) seems to me like a low-cost, sensible precaution. |
||
transcript.validate_and_commit_point(b"T_2", &self.T_2)?; | ||
|
||
let x = transcript.challenge_scalar(b"x"); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For completeness sake we need to allow zero V because the proof should be sound even with zero blinding factors, and with zero secret value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a properly-generated Pedersen commitment, the blinding factor will be zero with negligible probability, so a zero blinding factor almost certainly indicates an RNG failure and I don't think there's a good reason to accept them.
It might be the case that some higher-level protocol uses inputs that aren't secret, as you mentioned (private communication), and so someone might choose a zero blinding factor. I'm not sure this is a good design compared to forming the commitment properly and giving the opening
(v, v_blinding)
; if the blinding factor is set to zero, the committer still has to supplyv
(since there's not an easy way to recoverv
fromvB
, even for low-entropyv
). So this "optimization" doesn't seem to really simplify the structure, the committer still has to supply the opening, it's just that the opening is smaller.That said, I'm not totally set on forcing the
V
commitments to be nonzero, I just don't see a good reason to allow it, and there are (in my opinion) good reasons not to allow it (see next comment).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could see two options for resolving this:
V != 0
check to allow the zero-blinding-factors case, and leave other checks in place;V != 0
turns out to block something, we can relax it in the future (since relaxing a check is easier to do later than adding one).WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do (1) and merge this PR?