-
Notifications
You must be signed in to change notification settings - Fork 64
chore: upgrade crypto library to use newer methods from Go's stdlib #230
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
base: package-restructuring
Are you sure you want to change the base?
chore: upgrade crypto library to use newer methods from Go's stdlib #230
Conversation
Co-authored-by: meling <[email protected]>
Co-authored-by: meling <[email protected]>
Co-authored-by: meling <[email protected]>
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.
@copilot I've not reviewed the tests yet, but update them accordingly based on my comments.
security/crypto/ecdsa.go
Outdated
) | ||
|
||
// ecdsaASN1Sig represents the ASN.1 structure of an ECDSA signature | ||
type ecdsaASN1Sig struct { |
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.
@copilot I don't think we need this. We do not store the signatures in a specific format. They go on the wire are a []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.
Removed the ecdsaASN1Sig
struct. Now signatures go on the wire as []byte
directly in the protobuf. (commit: 5e7c8b9)
security/crypto/ecdsa.go
Outdated
// ECDSASignature is an ECDSA signature. | ||
type ECDSASignature struct { | ||
r, s *big.Int | ||
sig []byte // ASN.1 encoded 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.
Remove the 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.
Removed the comment. (commit: 5e7c8b9)
security/crypto/ecdsa.go
Outdated
|
||
// RestoreECDSASignature restores an existing signature. | ||
// It should not be used to create new signatures, use Sign instead. | ||
func RestoreECDSASignature(r, s *big.Int, signer hotstuff.ID) *ECDSASignature { |
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 should change the signature to remove the 'r' and 's' arguments; instead, we should pass in the []byte
we receive from the network. See the QuorumSignatureFromProto
function in internal/hotstuffpb/convert.go
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.
Changed the signature to RestoreECDSASignature(sig []byte, signer hotstuff.ID)
and updated the QuorumSignatureFromProto
function to pass the []byte
received from the network. (commit: 5e7c8b9)
security/crypto/ecdsa.go
Outdated
// It should not be used to create new signatures, use Sign instead. | ||
func RestoreECDSASignature(r, s *big.Int, signer hotstuff.ID) *ECDSASignature { | ||
return &ECDSASignature{r, s, signer} | ||
// Encode r and s as ASN.1 for internal storage |
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.
Remove marshalling logic.
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.
Removed the marshalling logic. (commit: 5e7c8b9)
security/crypto/ecdsa.go
Outdated
|
||
// R returns the r value of the signature. | ||
// This method is primarily used for protobuf serialization and decodes the ASN.1 signature on each call. | ||
func (sig ECDSASignature) R() *big.Int { |
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.
Remove this method.
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.
Removed the R() method. (commit: 5e7c8b9)
security/crypto/ecdsa.go
Outdated
|
||
// S returns the s value of the signature. | ||
// This method is primarily used for protobuf serialization and decodes the ASN.1 signature on each call. | ||
func (sig ECDSASignature) S() *big.Int { |
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.
Remove this method.
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.
Removed the S() method. (commit: 5e7c8b9)
Co-authored-by: meling <[email protected]>
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
…ary-implementation
Creating a Multi signature for ecdsa we now need to do this: crypto.NewMulti(restoredSig) instead of this: crypto.Multi[*crypto.ECDSASignature]{signer: restoredSig}
Ran the modernizer to clean up some quick fixes.
Instead of manually initilizaing a Multi[T] type to create a new signature, we use the NewMulti constructor instead.
Overview
This PR modernizes the ECDSA crypto implementation to use the recommended ASN.1 variants of Sign and Verify functions from Go's standard library, replacing the legacy implementation that exposed
r
ands
as separate*big.Int
parameters.Motivation
The current implementation uses the legacy
ecdsa.Sign()
andecdsa.Verify()
functions which are no longer the recommended practice. As noted in the Go crypto/ecdsa documentation, the ASN.1 variants (SignASN1
andVerifyASN1
) should be used for new code as they provide a more standard representation of ECDSA signatures.Changes
Core Implementation (
security/crypto/ecdsa.go
)Before:
After:
Key Updates
r
ands
valuesecdsa.SignASN1()
which returns ASN.1 DER-encoded signaturesecdsa.VerifyASN1()
which accepts ASN.1 DER-encoded signaturesRestoreECDSASignature(sig []byte, signer hotstuff.ID)
now accepts ASN.1-encoded bytes directlySig bytes
field instead of separateR
andS
fields, matching the pattern used by EDDSAProtobuf Changes (
internal/proto/hotstuffpb/hotstuff.proto
)Before:
After:
Signatures now go on the wire as raw ASN.1-encoded
[]byte
, simplifying the implementation and matching the pattern used by other signature types.Comprehensive Test Suite (
security/crypto/ecdsa_test.go
)Added table-driven tests following best practices, covering:
Compatibility
✅ All existing tests pass - Including security/cert tests that depend on ECDSA signatures.
✅ Security verified - CodeQL analysis reports 0 alerts.
Note: The protobuf wire format has changed to use a single
Sig
field instead of separateR
andS
fields. This is a wire format change that requires all nodes to be upgraded together.Testing
All tests pass successfully with the new implementation.
Statistics
Fixes #229
Original prompt
Fixes #229
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.