-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
btcec: add deep copy method for public keys #2288
base: master
Are you sure you want to change the base?
Conversation
Pull Request Test Coverage Report for Build 12273833480Details
💛 - Coveralls |
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.
LGTM 🎉
btcec/pubkey.go
Outdated
@@ -52,6 +52,13 @@ func NewPublicKey(x, y *FieldVal) *PublicKey { | |||
return secp.NewPublicKey(x, y) | |||
} | |||
|
|||
// CopyPublicKey returns a deep copy of the public key. | |||
func CopyPublicKey(p *PublicKey) *PublicKey { | |||
pk := secp.JacobianPoint{} |
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.
nit: use var pk secp.JacobianPoint
instead?
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 don't think we want to copy things this way. You need to call ToAffine
when coming back from the Jacobian coords.
Here's some code examples:
- https://github.com/decred/dcrd/blob/692ec68023fb27eca7d5d32801202eed2d86a5c9/hdkeychain/extendedkey.go#L333-L340
- https://github.com/decred/dcrd/blob/692ec68023fb27eca7d5d32801202eed2d86a5c9/dcrec/secp256k1/privkey.go#L87-L93
Lines 44 to 55 in e646d43
func Generator() *PublicKey { var ( result JacobianPoint k secp.ModNScalar ) k.SetInt(1) ScalarBaseMultNonConst(&k, &result) result.ToAffine() return NewPublicKey(&result.X, &result.Y)
After computations, we always transport/handle in affine form.
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 think we should add a property based test here. I wager it would've caught this issue.
The property we care about here is: pub == copy(pub)
.
If you look at what ToAffine
does, it actually will arrive at new values for x and y, as it's a distinct coordinate system: https://github.com/decred/dcrd/blob/08d8572807872f2b9737f8a118b16c320a04b077/dcrec/secp256k1/curve.go#L136-L149
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 thought the same about ToAffine()
, but since we use AsJacobian()
right before that, those should be affine coordinates already or does that no hold?
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 would still work because we are not doing any operations on it so z is set to 1 anyways and Affine and Jacobian are the same coordinates but technically it's wrong but it just happens to work for this particular cpy method. Will correct it.
btcec/pubkey.go
Outdated
@@ -52,6 +52,13 @@ func NewPublicKey(x, y *FieldVal) *PublicKey { | |||
return secp.NewPublicKey(x, y) | |||
} | |||
|
|||
// CopyPublicKey returns a deep copy of the public key. | |||
func CopyPublicKey(p *PublicKey) *PublicKey { | |||
pk := secp.JacobianPoint{} |
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 don't think we want to copy things this way. You need to call ToAffine
when coming back from the Jacobian coords.
Here's some code examples:
- https://github.com/decred/dcrd/blob/692ec68023fb27eca7d5d32801202eed2d86a5c9/hdkeychain/extendedkey.go#L333-L340
- https://github.com/decred/dcrd/blob/692ec68023fb27eca7d5d32801202eed2d86a5c9/dcrec/secp256k1/privkey.go#L87-L93
Lines 44 to 55 in e646d43
func Generator() *PublicKey { var ( result JacobianPoint k secp.ModNScalar ) k.SetInt(1) ScalarBaseMultNonConst(&k, &result) result.ToAffine() return NewPublicKey(&result.X, &result.Y)
After computations, we always transport/handle in affine form.
70d818e
to
2aa4c46
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.
Nice, LGTM 🎉
2aa4c46
to
d0c01bb
Compare
d0c01bb
to
bf152f9
Compare
We use a lot of pointers to the
PublicKey
type, so it comes very handy to have a deep copy method available.