-
Notifications
You must be signed in to change notification settings - Fork 264
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
Implement low r signing #259
Implement low r signing #259
Conversation
ca4e660
to
04f7ce3
Compare
04f7ce3
to
1d166d0
Compare
As discussed with @apoelstra I now added a |
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.
ack 1d166d0
This assumes the
But one thing to keep in mind: the s value could also be 31 bytes. (1 byte shorter than normal low-s) I am guessing this is acceptable since the main goal of low-r grinding is "to have a constant size DER signature" It is notable that this implementation's nuance is slightly different. |
Yes, that is why we have two functions, one for grinding small signatures, and one for low-R. |
For a bit of context -- whenever the R value has its high bit set to 1, DER encoding requires we use an extra 0 byte to encode it, as the high bit would otherwise be interpreted as a sign bit. Same for the s value. Like all the other DER noise, this byte is entirely wasted space, but it's also pretty easy to get rid of. For any given sig the chance this bit is set is only 50%, so in (on average) two tries, you can save an entire byte. There would also be a byte to save from the s value, but the low-S rule in Bitcoin actually saves us this byte 100% of the time, without any retries. Since signing is a fairly rare operation, even on the weakest hardware it's reasonable performance-wise to do it twice whenever you do can do it once. But it's probably not reasonable to do it 256 times, or 65536 times, etc etc. So Core implemented the low-R check, which has clear benefit for almost no cost, and didn't bother implementing general signature grinding. And even though the goal was to get short signatures, the way they implemented the grinding was to check the high bit of R and nothing else, since this is a much simpler thing to efficiently implement than doing a variable-length encoding and checking its length. On the other hand, I would like general signature grinding, because for my own purposes I don't mind grinding through millions of signatures to save several bytes, so when @Tibo-lg showed up with an implementation of the low-R check, this seemed like a good opportunity to implement that. But since the low-R check is actually a different check than than the signature-length check, we wound up with two functions and less shared code than I'd hoped for. |
I needed to generate low r signature (bitcoin/bitcoin#13666) and since there is no functionality to do that in rust I ended up implementing it in rust-secp. I thought it could be useful to others, but if not I'll try to put it somewhere else.