Skip to content

Change signature encoding to 64 bytes fixed on wire#86

Merged
Roasbeef merged 3 commits intolightningnetwork:masterfrom
aakselrod:bare-sigs
Dec 8, 2016
Merged

Change signature encoding to 64 bytes fixed on wire#86
Roasbeef merged 3 commits intolightningnetwork:masterfrom
aakselrod:bare-sigs

Conversation

@aakselrod
Copy link
Contributor

Formatting changes are due to go fmt. If you'd like these reverted, please let me know.

I have changed the writeElement and readElement functions to represent the signatures as 64 bytes on the wire with R being the first 32 and S being the second 32 bytes, both big-endian and zero-padded. The interaction between these functions and the rest of the code is not changed.

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

This diff is actually much smaller than smaller then what I had envisioned originally, nice work!

I just have some minor nits related to comments and a bit of refactoring, but once those are addressed I should be able to merge this in pretty quickly.

sig := e.Serialize()
if len(sig) > 73 {
return fmt.Errorf("Signature too long!")
var b [64]byte
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you extract this section into a distinct function? We may want to add some additional test cases in order to ensure the parsing logic is correct. Additonally this set of future test cases could be added to the spec as test vectors to ensure implementations are encoding/decoding the signatures correctly.

The same goes for the newly added case within readElement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. Two new functions in a separate file (signature.go) with tests in signature_test.go. Let me know if you want additional test vectors.

lnwire/lnwire.go Outdated
if len(sig) > 73 {
return fmt.Errorf("Signature too long!")
var b [64]byte
// Extract lengths of R and S
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit, but can you add a comment here which explains that we grab from an index of 3 since the first three bytes within the DER encoding are 0x03 <length> 0x02, with the length of R being the 4th byte and similarly a comment which explains that the length of R there's an additional 0x02 byte which needs to be skipped.

Referring to the godoc for the Serialize method might be helpful.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general having the format of the serialized sig:

0x30 <length> 0x02 <length r> r 0x02 <length s> s

displayed somewhere in the comment can be helpful as it's easier to follow the logic with the full format in mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. I've improved the comments around this with an explanation and the format of the serialized sig.

lnwire/lnwire.go Outdated
// Check to make sure each can fit into the intended buffer
if sLen > 32 {
if (sLen > 33) || (sig[6+rLen] != 0x00) {
return fmt.Errorf("S is over 32 bytes long without padding")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you trim the line to 80 chars here? Thanks!

Same from the error message below on line 193.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. I had tabs shown as 2 spaces instead of 8 like GitHub shows. Fixed.

lnwire/lnwire.go Outdated
} else {
copy(b[64-sLen:], sig[6+rLen:])
}
if rLen > 32 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: I think the code would be easier to follow if this section (for R) was moved to lie before the section that packs S into the buffer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R needs to be after S because we subtract one from rLen, which affects the index lookups in the S extraction. I can create new variables to track this but it wouldn't be as efficient. Let me know what you prefer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added better comments about the logic in this section. If you still want me to switch the code blocks for R and S around, let me know and I'll use more variables to track indices.

lnwire/lnwire.go Outdated
// extractCanonicalPadding is a utility function to extract the canonical
// padding of a big-endian integer from the wire encoding (a 0-padded
// big-endian integer) such that it passes btcec.canonicalPadding test.
func extractCanonicalPadding (b []byte) []byte {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this section been run through gofmt? From a glance it looks like it hasn't been because the indentation looks a bit shallow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. Fixed by gofmt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants