Comments (6)
This library does not need recid, so there are no methods that return or calculate it.
The two bits of the recid are:
LSB = "is Y value for signature r point odd?"
MSB = "is X value for signature r point >= n (order)?"
MSB is almost always 0, so 99.9...% of recid will be integer of 0 or 1
from tiny-secp256k1.
To make it a little easier to understand, here's how it would be calculated in the current pure JS code.
ie. for the JS:
Lines 188 to 205 in 5a311f1
diff --git a/js.js b/js.js
index 5e0fd45..6382476 100644
--- a/js.js
+++ b/js.js
@@ -185,7 +185,7 @@ function __sign (hash, x, addData) {
const d = fromBuffer(x)
const e = fromBuffer(hash)
- let r, s
+ let r, s, recid
const checkSig = function (k) {
const kI = fromBuffer(k)
const Q = G.mul(kI)
@@ -201,6 +201,10 @@ function __sign (hash, x, addData) {
.umod(n)
if (s.isZero() === 0) return false
+ const isOddY = Q.y.isOdd()
+ const isHighX = Q.x.cmp(n) >= 0
+ recid = (isHighX << 1) | (isOddY << 0)
+
return true
}
@@ -214,7 +218,10 @@ function __sign (hash, x, addData) {
const buffer = Buffer.allocUnsafe(64)
toBuffer(r).copy(buffer, 0)
toBuffer(s).copy(buffer, 32)
- return buffer
+ return {
+ signature: buffer,
+ recovery: recid,
+ }
}
function verify (hash, q, signature, strict) {
from tiny-secp256k1.
Also, in the verify function you recreate the R point, so you would be able to calculate the recid if you have the public key and the signature.
from tiny-secp256k1.
This is what it looks like to get the recid during the verify function.
diff --git a/js.js b/js.js
index 5e0fd45..58e4dc2 100644
--- a/js.js
+++ b/js.js
@@ -255,6 +255,10 @@ function verify (hash, q, signature, strict) {
// 1.4.5 (cont.) Enforce R is not at infinity
if (R.isInfinity()) return false
+ const isOddY = R.y.isOdd()
+ const isHighX = R.x.cmp(n) >= 0
+ const recid = (isHighX << 1) | (isOddY << 0)
+
// 1.4.6 Convert the field element R.x to an integer
const xR = R.x
@@ -262,7 +266,11 @@ function verify (hash, q, signature, strict) {
const v = xR.umod(n)
// 1.4.8 If v = r, output "valid", and if v != r, output "invalid"
- return v.eq(r)
+ const isValid = v.eq(r)
+ return {
+ verified: isValid,
+ recovery: isValid ? recid : null,
+ }
}
module.exports = {
from tiny-secp256k1.
Thanks for your help @junderw. In particular your last example got me through my blocker on this. I will share my code for extending a BitcoinJs
library signer into a BitcoinJs-message
signer, in case it helps any other developers working on this particular issue:
export class BitcoinMessageSigner extends BitcoinSigner {
sign(payload) {
const signature = super.sign(payload, true)
const recovery = this.recidFromSig(payload, this.publicKey, signature)
return {
signature,
recovery,
}
}
recidFromSig(payload, publicKey, signature) {
const BN = require('bn.js')
const secp256k1 = new ec('secp256k1')
const n = secp256k1.curve.n
const G = secp256k1.curve.g
const Q = secp256k1.curve.decodePoint(publicKey)
const r = new BN(signature.slice(0, 32))
const s = new BN(signature.slice(32, 64))
const e = new BN(payload)
const sInv = s.invm(n)
const u1 = e.mul(sInv).umod(n)
const u2 = r.mul(sInv).umod(n)
const R = G.mulAdd(u1, Q, u2)
const isOddY = R.y.isOdd()
const isHighX = R.x.cmp(n) >= 0
const recid = (isHighX << 1) | (isOddY << 0)
return recid
}
}
I'm still code-cleaning, but the above example is working.
from tiny-secp256k1.
Be careful, as that is very slow.
You are using Signer because you have some sort of native implementation you're calling into, correct?
In which case you should get your native implementation to have a private method that returns the signature AND recid (in one go) and your key Signer class will throw away the recid and the message Signer class will keep it.
If not, and the private key is being managed in a Buffer in the JavaScript memory... then it is easier to just pass the privateKey Buffer to the message sign function.
from tiny-secp256k1.
Related Issues (20)
- Buffer is not defined HOT 1
- There are 2 test vectors for pointCompress which are not correct HOT 2
- Secp256k1 signature issue with messages > curve_order HOT 2
- Is there a fallback build instead of wasm? HOT 4
- Does this implement deterministic k generation HOT 2
- remove dependancy from `window` object on browser
- no such file or directory node_modules/tiny-secp256k1/lib/secp256k1.wasm HOT 7
- Uncaught TypeError: Cannot read properties of undefined (reading 'buffer') HOT 2
- Discrepancy in signSchnorr output when using zero-filled Buffer versus no Buffer HOT 3
- Cant figure equivalents to `bcrypto.secp256k1` calls HOT 5
- Nestjs ERROR Error: ENOENT: no such file or directory, open '/var/task/node_modules/tiny-secp256k1/lib/secp256k1.wasm' HOT 2
- Two times speed regression between `2.2.2` and `2.2.3` HOT 3
- Docker Build Failure HOT 2
- import tiny-secp256k1 in browser causes TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute HOT 2
- Cannot run react-app example HOT 2
- After bumping ReactNative project from 1.1.6 to 2.0.0 builds for Android fail HOT 6
- Wrong path when bundling tiny-secp256k1 with Electron HOT 1
- tiny-secp compilation in swift and java HOT 2
- Bug when using browserify HOT 3
- Pure-js backport of `xOnlyPointFromPoint()`..? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tiny-secp256k1.