-
Notifications
You must be signed in to change notification settings - Fork 7
add/remove leading zero on encode/decode #2
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
Conversation
|
The entire point of this module is to be in coherence (with side-by-side readability) with BIP66... I'd rather not. |
|
@dcousens BIP66 says nothing about |
|
Indeed, it really should have been a 64-byte fixed format, maybe with segwit... |
Can you outline where it would be useful? |
|
not a 64-bytes, 66-bytes (2 x 33 bytes)
|
No, I meant 64 bytes. The 33 byte case is basically just a padding byte (for the twos complement) anyway. |
Can you write a test case for that? |
var data = '3044021458a2f39bd87f0000000506030000000000050603022c402dde9afe7f0000010000000100000004000000040000000000000000000000000000000a00000000000000'
require('bip66').check(new Buffer(data, 'hex')) // true |
|
@dcousens what you final thoughts about auto-padding in bip66 instead secp256k1 (and other libraries)? |
|
If you pass a DER-valid encoding of an invalid signature to libsecp256k1, its parsing will succeed, but validation will fail. So typically the steps are:
|
|
On the reason why BIP66 does not enforce a maximum length on R and S: it didn't need to. All BIP66 try to do was to give valid signatures a unique and easy-to-determine encoding. Having an overlength R or S automatically make the transaction invalid, so it was not within scope. Another way of looking at it is, if you're trying to duplicate part of the validation rules in BIP66 (which is about its encoding, not validity), why stop there?
In short, there was no need to add a rule limiting the size of R or S, so we didn't. There is a rule that checks the total length, because if that was over 255 bytes, you'd need a multi-byte-length decoder to check whether the signature is DER. If we'd want to go a step further, I think we should add a rule that a signature either has to be valid (as in, completely valid) or empty. That would remove malleability of invalid signatures. Unfortunately that isn't possible with how CHECKMULTISIG works now. Regarding 64-byte signatures: yes, absolutely. Once segwit is in (which introduces script versioning, making such changes much easier), I do plan on proposing a Schnorr-based scheme with 64-byte signatures. @gmaxwell recently came up with a scheme that would allow reducing all signatures in a transaction into a single one even. |
|
@dcousens please reopen, if you decide inline auto-padding to encode: var r = Buffer.concat([new Buffer([0]), sigObj.r])
for (var lenR = 33, posR = 0; lenR > 1 && r[posR] === 0x00 && !(r[posR + 1] & 0x80); --lenR, ++posR);
var s = Buffer.concat([new Buffer([0]), sigObj.s])
for (var lenS = 33, posS = 0; lenS > 1 && s[posS] === 0x00 && !(s[posS + 1] & 0x80); --lenS, ++posS); |
|
@fanatid would all existing test fixtures still be valid? |
10c67ca to
537e84e
Compare
|
@dcousens not all existed fixtures will be valid (I fixed them in new commit) |
|
you can pass 0 to 32 bytes |
index.js
Outdated
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.
Superfluous recreation of a new Buffer([0]) every time this is called.
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.
you're right, updated!
index.js
Outdated
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 we un-inline this? For readability? With a comment explaining what/where/why.
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.
updated
index.js
Outdated
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 add a comment to explain what this does? (and note it isn't part of BIP66)
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.
added
|
Hmmm, I understand why this is the best place to put this... but that doesn't make this feel a little out of place... but seeing as only |
|
you do not want remove excessive leading zero byte on decode? |
| * -62300 => 0xff0ca4 | ||
| */ | ||
| function encode (r, s) { | ||
| r = Buffer.concat([zeroBuffer1, r]) |
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.
Infact, to avoid superfluous copies everywhere, can you just allocate this in the final signature buffer?
6 + lenR + lenS where lenS = s.length + 1?
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 that this is possible..
If the |
ok, first PR: bip66.encode(new Buffer([1]), new Buffer([128]))
<Buffer 30 07 02 01 01 02 02 00 80>
bip66.decode(bip66.encode(new Buffer([1]), new Buffer([128])))
{ r: <Buffer 01>, s: <Buffer 80> }master: bip66.decode(bip66.encode(new Buffer([1]), new Buffer([128])))
Error: S value is negative
bip66.encode(new Buffer([1]), new Buffer([0, 128]))
<Buffer 30 07 02 01 01 02 02 00 80>
bip66.decode(bip66.encode(new Buffer([1]), new Buffer([0, 128])))
{ r: <Buffer 01>, s: <Buffer 00 80> } |
|
Right. Then this was all my fault. Thanks @fanatid |
|
I'll see if I can't clean up a few things, PR it, merge then release patch. |
|
Thanks, I'll create PR with tape/nyc in nearest time. |
|
@fanatid so turns out this will probably break everything that depends on this package. If we revert, we should really make that clear. Thoughts on a way forward? |
|
@fanatid basically we've "optimised" the package to return positive only integers, makes sense, but, the question is do we make this |
|
Yes, this PR require major version bump :( |
Indeed. |
I want to use this package in cryptocoinjs/secp256k1-node
auto-padding would be nice feature
@dcousens thoughts ?
I'll fix tests after feedback