-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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 SignMessage and VerifyMessage rpc commands #192
Conversation
Coverage increased (+5.1%) to 73.942% when pulling 84c551246681439122fb9d820b019d6e5be6c9a5 on phlip9:master into 4939443 on lightningnetwork:master. |
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.
Hi @phlip9, thanks for this PR!
I've completed an initial round of review. Most of my comments are pretty minor and are concerned with consistent code style throughput the project. After this first round of review is addressed, I'll move onto a bit of local testing before the PR is ultimately approved.
cmd/lncli/commands.go
Outdated
Usage: "the message to verify", | ||
}, | ||
cli.StringFlag{ | ||
Name: "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.
Minor nit: I recommend going with simply sig
here as it's quicker to type on the command line.
lnd_test.go
Outdated
func testNodeSignVerify(net *networkHarness, t *harnessTest) { | ||
ctxb := context.Background() | ||
|
||
// bob should be able to verify alice's 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.
In order to be consistent with the coding style of the project: all comments should be complete sentences and should also be flush with a coding fragment below it (meaning eliminate the extra new-line).
lnd_test.go
Outdated
if verifyResp.Valid { | ||
t.Fatalf("carol's signature should not be valid") | ||
} | ||
} |
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 carol
node should be shutdown at the end of this test as it's no longer of any use:
if err := carol.shutdown()l err != nil {
... handle err...
}
string signature = 2 [ json_name = "signature" ]; | ||
} | ||
message VerifyMessageResponse { | ||
bool valid = 1 [ json_name = "valid" ]; |
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-line with @AndrewSamokhvalov's comment on the original issue, this should also return the compressed public key of the signer that was extracted from the signature. This will allow higher-level to enforce any sort of channel capitalization constraint themselves as additional checks after the signature validates.
nodesigner.go
Outdated
return nil, fmt.Errorf("unknown public key") | ||
} | ||
|
||
// Otherwise, we'll sign the dsha256 of the target message. |
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 line with the contribution guidelines of this project, the code fragment under this line should be modified to have some breathing room.
nodesigner.go
Outdated
// Otherwise, we'll sign the dsha256 of the target message. | ||
digest := chainhash.DoubleHashB(msg) | ||
// Should the signature reference a compressed public key or not. | ||
compressedPubKey := false |
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.
Keys should always be interpreted as being compressed. All public keys circulated within the network are always serialized in compressed format.
nodesigner.go
Outdated
// Should the signature reference a compressed public key or not. | ||
compressedPubKey := false | ||
// btcec.SignCompact returns a pubkey-recoverable signature | ||
sign, err := btcec.SignCompact( |
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.
Minor nit, modify the line-breaking here to be consistent with the rest of the codebase:
sign, err := btcec.SignCompact(btcec.S256(), n.privKey, digest,
compressedPubKey)
nodesigner.go
Outdated
// Should the signature reference a compressed public key or not. | ||
compressedPubKey := false | ||
// btcec.SignCompact returns a pubkey-recoverable signature | ||
sign, err := btcec.SignCompact( |
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.
sign -> sig
nodesigner.go
Outdated
// resident node's private key. If the target public key is _not_ the node's | ||
// private key, then an error will be returned. The returned signature is a | ||
// pubkey-recoverable signature. | ||
func (n *nodeSigner) SignCompact(pubKey *btcec.PublicKey, |
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 we don't need to adhere to a particular interface (yet) here (which is why the SignMessage
method is how it is atm), we can omit the public key argument all together. Implicitly, SignCompact
will always use the resident node's private key.
rpcserver.go
Outdated
} | ||
|
||
graph := r.server.chanDB.ChannelGraph() | ||
// TODO(phlip9): Require valid nodes to have capital in active channels. |
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.
Similar comment here about code spacing.
Coverage remained the same at 73.938% when pulling 635a869d43c66bb661b2b6382576969b0b13c7a2 on phlip9:master into 337a4a4 on lightningnetwork:master. |
Coverage remained the same at 73.938% when pulling 42c79d5a7f0a87d21bf24acf1c67338f6ac0f1e8 on phlip9:master into 337a4a4 on lightningnetwork:master. |
Fixed the review requests. Let me know if you spot anything else! The only notable, recent addition was |
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 ⚡️
Once the last comment is addressed (public keys should always be interpreted as being encoded in compressed format), and the PR is rebased, I'll get this merged!
nodesigner.go
Outdated
digest := chainhash.DoubleHashB(msg) | ||
|
||
// Should the signature reference a compressed public key or not. | ||
isCompressedKey := false |
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.
Public keys within the protocol are always meant to be handled or transferred in a compressed format.
Coverage remained the same at 73.437% when pulling d13c36613217a04e87498c384ae9fa61ff0f526f on phlip9:master into 8e4199e on lightningnetwork:master. |
Coverage decreased (-0.004%) to 73.433% when pulling d13c36613217a04e87498c384ae9fa61ff0f526f on phlip9:master into 8e4199e on lightningnetwork:master. |
Hi @phlip9, think you could rebase this again? Another PR which touched similar files (adding a RPC new command) was merged before this one. Thanks! |
This commit allows users to sign messages with their node's private key with the SignMessage interface. The signatures are zbase32 encoded for human readability/paste-ability. Others users can verify that a message was signed by another node in their channel database with the VerifyMessage interface.
@Roasbeef Ok, just rebased on master; it should be good to merge. |
See Issue: #187