-
Notifications
You must be signed in to change notification settings - Fork 490
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
Make stateproof verifier snark friendly #3895
Make stateproof verifier snark friendly #3895
Conversation
ac56d80
to
6901d2a
Compare
Codecov Report
@@ Coverage Diff @@
## feature/stateproofs #3895 +/- ##
=======================================================
+ Coverage 50.06% 50.08% +0.02%
=======================================================
Files 396 396
Lines 68413 68364 -49
=======================================================
- Hits 34251 34242 -9
+ Misses 30454 30426 -28
+ Partials 3708 3696 -12
Continue to review full report at Codecov.
|
026a39e
to
485b44d
Compare
Co-authored-by: Shant Karakashian <55754073+algonautshant@users.noreply.github.com>
82d799a
to
2f03f65
Compare
@cpeikert could you please take a second look at the coinGenerator.go? |
e929cab
to
ab2a2ff
Compare
crypto/compactcert/builder.go
Outdated
copy(cpy, b.Params.StateProofMessageHash[:]) // TODO: onmce cfalcon is fixed can remove this copy. | ||
if err := p.PK.VerifyBytes(uint64(b.SigRound), cpy, sig); err != nil { | ||
cpy := make([]byte, len(b.data)) | ||
copy(cpy, b.data[:]) // TODO: onmce cfalcon is fixed can remove this copy. |
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.
Why is this copy still needed here?
The TODO comment seems can be resolved.
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.
we still have a might have problem with c-falcon. when everything will be ready to merge into master we will remove it.
compactcert/builder.go
Outdated
@@ -115,7 +120,7 @@ func (ccw *Worker) initBuilders() { | |||
continue | |||
} | |||
|
|||
if builder.Present(pos) { | |||
if isPresent, err := builder.Present(pos); err != nil || isPresent { |
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.
The error message below needs to be updated here to also consider the possibility of the err
and not just isPresent
.
crypto/compactcert/builder.go
Outdated
lo := uint64(0) | ||
hi := uint64(len(b.sigs)) | ||
|
||
again: | ||
if lo >= hi { | ||
return 0, fmt.Errorf("coinIndex: lo %d >= hi %d", lo, hi) | ||
return 0, fmt.Errorf("%w: lo %d >= hi %d", ErrInternalCoinIndexError, lo, hi) |
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.
This should never happen in the code path. It is expected to have:
b.sigs[0].L = 0 // by construction
b.sigs[last].L + b.sigs[last].Weight == signedWeight // b.sigs[last].L + b.sigs[last].Weight == signedWeight and coinWeight in [0, signedWeight)
In case it happens, the error should say something like:
coinIndex unexpected behavior: lo = %d hi = %d coinWeight = %d
} | ||
|
||
if hdr.Round != votersHdr.Round+basics.Round(proto.CompactCertRounds) { | ||
err = fmt.Errorf("certifying block %d not %d ahead of voters %d", | ||
err := fmt.Errorf("certifying block %d not %d ahead of voters %d", |
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.
The convention followed elsewhere in the code, is to identify the reporter of the error, by mentioning the name of the function.
For example:
./cow_creatables.go�155: return fmt.Errorf("DeleteAppParams: %s not found in deltas for %d", addr.String(), aidx)
./cow_creatables.go�163: return fmt.Errorf("DeleteAppLocalState: %s not found in deltas for %d", addr.String(), aidx)
./cow_creatables.go�171: return fmt.Errorf("DeleteAssetHolding: %s not found in deltas for %d", addr.String(), aidx)
./cow_creatables.go�179: return fmt.Errorf("DeleteAssetParams: %s not found in deltas for %d", addr.String(), aidx)
This convention is not followed in many places in the compactCert code.
@@ -64,15 +64,20 @@ func (ccw *Worker) builderForRound(rnd basics.Round) (builder, error) { | |||
} | |||
ccw.Message = msg | |||
|
|||
p, err := ledger.CompactCertParams(msg, votersHdr, hdr) | |||
provenWeight, err := ledger.GetProvenWeight(votersHdr, hdr) | |||
if err != nil { | |||
return builder{}, err |
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.
Returning the error directly like this is problematic. When eventually the error is logged or reported to the user, it will be very difficult, if not impossible, to know where the error came from.
The convention followed is to wrap the received error before reporting it upwards.
For example, see below (which should be %w and not %v):
ccw.log.Warnf("ccw.handleSigMessage(): decode: %v", err)
Co-authored-by: Shant Karakashian <55754073+algonautshant@users.noreply.github.com>
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.
Looks great!
The logic implementation is correct, well structured, and readable. Very well documented.
I don't have any more suggestions to change anything.
The tests cover the code very well.
Thank you for addressing my previous comments.
A few areas needs some improvement, which can be addressed in a separate PR:
- The error reporting in many places do not list the function generating the error. These error messages need updating to identify the function generating them, as is the convention in the code.
- When a function gets an error and returns it, it needs to wrap it and identify itself, so that when the error is logged upstream, not only the originator of the error is identified, but also the context in which the error occurred.
- The tests do not cover many of the error cases. Most of these cases are fairly simple and basic, but some of them report in the error messages, local variable values. If these messages are not tested, possible panic situation may go unnoticed, and the program panics when it should just be an error.
if !s.Signature.IsVersionEqual(version) { | ||
return ErrInvalidSignatureVersion | ||
// IsSaltVersionEqual validates that the version of the signature is matching the expected version | ||
func (s *Signature) IsSaltVersionEqual(version byte) error { |
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.
We need a test for this.
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.
it is being tested in TestFalconSignature_ValidateVersion
and more important, it is being tested in TestBuilder_AddRejectsInvalidSigVersion
.
@@ -267,23 +267,23 @@ func (v *Verifier) VerifyBytes(round uint64, msg []byte, sig Signature) error { | |||
func (s *Signature) GetFixedLengthHashableRepresentation() ([]byte, error) { |
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.
Unit test is missing for this function.
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.
it is being tested here TestSimulateSignatureVerification
Summary
The goal of this PR is to change part of the stateproof (compactcert) verifier to be SNARK friendly.
this change contains:
1- The verifier no longer computes the exact number of reveals on the cert. Alternatively, it computes a lower bound on the proven weight.
2- To support 1, the verifier uses a
log
approximation technic.3- use SHAKE256 for the coin hashing to be more SNARK friendly
4- use rejection sampling for selecting the next coin
5- the positions to reveal (the result of the coin hashing) are given as part of the cert.
Test Plan
unittest are updated