-
Notifications
You must be signed in to change notification settings - Fork 486
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 merkle signer SNARK friendly #3263
Make merkle signer SNARK friendly #3263
Conversation
7c23285
to
e5f410f
Compare
Codecov Report
@@ Coverage Diff @@
## feature/dilithium-scheme-integration #3263 +/- ##
========================================================================
- Coverage 47.84% 47.83% -0.01%
========================================================================
Files 381 382 +1
Lines 61651 61643 -8
========================================================================
- Hits 29496 29489 -7
+ Misses 28734 28732 -2
- Partials 3421 3422 +1
Continue to review full report at Codecov.
|
e5f410f
to
a99b0de
Compare
crypto/compactcert/builder_test.go
Outdated
@@ -36,8 +37,7 @@ import ( | |||
|
|||
type TestMessage string | |||
|
|||
// TODO: change to CurrentVersion when updated | |||
var CompactCertRounds = config.Consensus[protocol.ConsensusFuture].CompactCertRounds | |||
const CompactCertRoundsForTests = 128 | |||
|
|||
func (m TestMessage) ToBeHashed() (protocol.HashID, []byte) { |
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.
TestMessage and it's functions do not need to be exported. Use small case for the first letter.
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've made TestMessage private as you've recommended.
However, ToBeHash is an interface implmenation function so it can't be chagned.
crypto/compactcert/structs.go
Outdated
|
||
sigBytes := ssc.Sig.Signature.GetSerializedSignature() | ||
|
||
sigSlotCommitment := make([]byte, 0, len(binaryLValue)+len(sigBytes)) |
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 intend here is to get a fixed sized byte array. However, this function makes no compiler enforced commitment to a fixed size array.
It very difficult to know if GetSerializedSignature
will indeed return a fixed size array every time.
crypto/sig_abstractions.go
Outdated
// GetVerificationBytes returns a serialized version of the public key data (without the use of the msgpack). | ||
GetVerificationBytes() []byte | ||
// GetSerializedSignature returns a serialized version of the signature | ||
GetSerializedSignature(signature ByteSignature) []byte |
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 problem with implementing this function as an interface is that the caller of GetSerializedSignature
will not know what size array it will be receiving.
In some cases, it is important to receive a fixed size array every time. This interface will not permit the compiler to to that enforcement, and in the future someone might change a function implementation which breaks that requirement.
} | ||
|
||
// ToBeHashed implements the crypto.Hashable interface. | ||
// In order to create a more SNARK-friendly commitments on the signature we must avoid using the msgpack infrastructure. |
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 this change for all uses of ToBeHashed
?
Shouldn't this less efficient implementation be restricted only when the target is an SNARK commitment?
If this function is only used in the SNARK context, maybe the name should indicate that this is different, and may not be as efficient to transport as the msgp serialization.
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.
Agree; see also my comment above about the naming of GetSerializedSignature
. The purpose of that function is much narrower than general serialization.
b882c83
to
b733a04
Compare
b733a04
to
da92a85
Compare
b277b6d
to
bba3ba1
Compare
bba3ba1
to
5445566
Compare
ea9a758
to
f33bc88
Compare
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!
I have some comments, mainly clarifications/comment requests.
Also, I added some comments in #2990 which could be addressed here, since the changes here may be impacted by those.
|
||
// Signature is a byte signature on a crypto.Hashable object, | ||
// crypto.GenericVerifyingKey and includes a merkle proof for the key. | ||
Signature struct { | ||
_struct struct{} `codec:",omitempty,omitemptyarray"` | ||
crypto.ByteSignature `codec:"bsig"` | ||
|
||
Proof Proof `codec:"prf"` | ||
VerifyingKey crypto.GenericVerifyingKey `codec:"vkey"` | ||
MerkleArrayIndex uint64 `codec:"idx"` |
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.
Can you please update the comment above (line 30)?
Will be nice to improve the comment by adding some more explanation on Proof, VerifyingKey and MerkleArrayIndex.
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.
agree. let me know if it looks better now.
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return sig.VerifyingKey.GetVerifier().Verify(obj, sig.ByteSignature) | ||
return sig.VerifyingKey.GetVerifier().Verify(msg, sig.ByteSignature) |
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.
In this location, GetVerifier
can it return Ed25519Type
or it always need to be FalconPublicKey
?
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 GetVerifier
could use ed25519 crypto type. this module is built to support it.
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return sig.VerifyingKey.GetVerifier().Verify(obj, sig.ByteSignature) | ||
return sig.VerifyingKey.GetVerifier().Verify(msg, sig.ByteSignature) |
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 the Falcon verification is not made only for the root of the merkle tree?
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 falcon verification is needed to verify that a given signature is valid under this ephemeral pk.
crypto/falconWrapper.go
Outdated
return d.PublicKey[:] | ||
} | ||
|
||
// GetSerializedSignature returns a serialized version of the signature |
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 name and documentation do not really match what this function does. It simply converts a byte array from a COMPRESSED-format signature to a CT-format signature; this is orthogonal to serialization. So I would suggest a name like ConvertCompressedToCT
. Also, a FalconVerifier
is not needed here, and it would be best not to require one.
if err := checkKeystoreParams(firstValid, round, interval); err != nil { | ||
return err | ||
} | ||
func (v *Verifier) Verify(round uint64, msg crypto.Hashable, sig Signature) 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.
As far as I can tell so far, the logic of this function (which is the most important part) looks sound and SNARKable, assuming that merklearray.Verify
is. But I cannot find that function in this PR. Is it somewhere else?
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 will have a different PR for that.
crypto/sig_abstractions.go
Outdated
GetVerificationBytes() []byte | ||
// GetSerializedSignature returns a serialized version of the signature | ||
// muse be const sized | ||
GetSerializedSignature(signature ByteSignature) ([]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.
The name and documentation ("serialized") are not really descriptive of the intended purpose here. It’s more that this is a "hashable (fixed-length) representation" for the SNARK.
} | ||
|
||
// ToBeHashed implements the crypto.Hashable interface. | ||
// In order to create a more SNARK-friendly commitments on the signature we must avoid using the msgpack infrastructure. |
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.
Agree; see also my comment above about the naming of GetSerializedSignature
. The purpose of that function is much narrower than general serialization.
Summary
In this PR we change how the Merkle key store is being hashed.
Test Plan