bitcore-lib-cash
Advanced tools
Comparing version 8.22.0 to 8.22.1
'use strict'; | ||
// Important references for schnorr implementation | ||
// https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/2019-05-15-schnorr.md | ||
// https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/2019-11-15-schnorrmultisig.md#wallet-implementation-guidelines | ||
var BN = require('./bn'); | ||
@@ -22,2 +26,47 @@ var Point = require('./point'); | ||
/** | ||
* Function written to ensure r part of signature is at least 32 bytes, when converting | ||
* from a BN to type Buffer. | ||
* The BN type naturally cuts off leading zeros, e.g. | ||
* <BN: 4f92d8094f710bc11b93935ac157730dda26c5c2a856650dbd8ebcd730d2d4> 31 bytes | ||
* Buffer <00 4f 92 d8 09 4f 71 0b c1 1b 93 93 5a c1 57 73 0d da 26 c5 c2 a8 56 65 0d bd 8e bc d7 30 d2 d4> 32 bytes | ||
* Both types are equal, however Schnorr signatures must be a minimum of 64 bytes. | ||
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures. | ||
* (Although it would have been verified, it's proper to ensure the min requirement) | ||
* @param {*} s BN | ||
* @return {Buffer} | ||
*/ | ||
function getrBuffer(r) { | ||
let rNaturalLength = r.toBuffer().length; | ||
if (rNaturalLength < 32) { | ||
return r.toBuffer({size: 32}); | ||
} | ||
return r.toBuffer(); | ||
} | ||
/** | ||
* Function written to ensure s part of signature is at least 32 bytes, when converting | ||
* from a BN to type Buffer. | ||
* The BN type naturally cuts off leading zeros, e.g. | ||
* <BN: 4f92d8094f710bc11b93935ac157730dda26c5c2a856650dbd8ebcd730d2d4> 31 bytes | ||
* Buffer <00 4f 92 d8 09 4f 71 0b c1 1b 93 93 5a c1 57 73 0d da 26 c5 c2 a8 56 65 0d bd 8e bc d7 30 d2 d4> 32 bytes | ||
* Both types are equal, however Schnorr signatures must be a minimum of 64 bytes. | ||
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures. | ||
* (Although it would have been verified, it's proper to ensure the min requirement) | ||
* @param {*} s BN | ||
* @return {Buffer} | ||
*/ | ||
function getsBuffer(s) { | ||
let sNaturalLength = s.toBuffer().length; | ||
if (sNaturalLength < 32) { | ||
return s.toBuffer({size: 32}); | ||
} | ||
return s.toBuffer(); | ||
} | ||
/* jshint maxcomplexity: 9 */ | ||
@@ -76,3 +125,3 @@ Schnorr.prototype.set = function(obj) { | ||
let k = nonceFunctionRFC6979(d.toBuffer({ size: 32 }), e.toBuffer({ size: 32 })); | ||
let k = this.nonceFunctionRFC6979(d.toBuffer({ size: 32 }), e.toBuffer({ size: 32 })); | ||
@@ -90,3 +139,3 @@ let P = G.mul(d); | ||
let r = R.getX(); | ||
let e0 = BN.fromBuffer(Hash.sha256(Buffer.concat([r.toBuffer(), Point.pointToCompressed(P), e.toBuffer({ size: 32 })]))); | ||
let e0 = BN.fromBuffer(Hash.sha256(Buffer.concat([getrBuffer(r), Point.pointToCompressed(P), e.toBuffer({ size: 32 })]))); | ||
@@ -100,2 +149,3 @@ let s = ((e0.mul(d)).add(k)).mod(n); | ||
}; | ||
@@ -107,3 +157,3 @@ Schnorr.prototype.sigError = function() { | ||
let sigLength = this.sig.r.toBuffer().length + this.sig.s.toBuffer().length; | ||
let sigLength = getrBuffer(this.sig.r).length + getsBuffer(this.sig.s).length; | ||
@@ -114,3 +164,2 @@ if(!(sigLength === 64 || sigLength === 65)) { | ||
let hashbuf = this.endian === 'little' ? BufferUtil.reverse(this.hashbuf) : this.hashbuf | ||
@@ -134,3 +183,3 @@ | ||
let Br = r.toBuffer(); | ||
let Br = getrBuffer(this.sig.r); | ||
let Bp = Point.pointToCompressed(P); | ||
@@ -167,3 +216,3 @@ | ||
*/ | ||
function nonceFunctionRFC6979(privkey, msgbuf) { | ||
Schnorr.prototype.nonceFunctionRFC6979 = function(privkey, msgbuf) { | ||
let V = Buffer.from("0101010101010101010101010101010101010101010101010101010101010101","hex"); | ||
@@ -185,6 +234,6 @@ let K = Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex"); | ||
T = BN.fromBuffer(V); | ||
$.checkState(T.toBuffer().length >= 32, "T failed test"); | ||
k = T; | ||
if (k.gt(new BN(0) && k.lt(Point.getN()))) { | ||
$.checkState(V.length >= 32, "V length should be >= 32"); | ||
if (k.gt(new BN(0)) && k.lt(Point.getN())) { | ||
break; | ||
@@ -191,0 +240,0 @@ } |
@@ -8,2 +8,3 @@ 'use strict'; | ||
var JSUtil = require('../util/js'); | ||
const { sign } = require('./ecdsa'); | ||
@@ -68,3 +69,3 @@ var Signature = function Signature(r, s, isSchnorr) { | ||
// Schnorr Signatures use 65 byte for in tx r [len] 32 , s [len] 32, nhashtype | ||
if((buf.length === 64) && buf[0] != 0x30) { | ||
if((buf.length === 64 || buf.length === 65) && buf[0] != 0x30) { | ||
let obj = Signature.parseSchnorrEncodedSig(buf); | ||
@@ -77,3 +78,3 @@ let sig = new Signature(); | ||
} if (buf.length === 64 && buf[0] === 0x30) { | ||
return "64 DER (ecdsa) signautres not allowed"; | ||
return "64 DER (ecdsa) signatures not allowed"; | ||
} | ||
@@ -80,0 +81,0 @@ |
{ | ||
"name": "bitcore-lib-cash", | ||
"version": "8.22.0", | ||
"version": "8.22.1", | ||
"description": "A pure and powerful JavaScript Bitcoin Cash library.", | ||
@@ -38,3 +38,3 @@ "author": "BitPay <dev@bitpay.com>", | ||
"dependencies": { | ||
"bitcore-lib": "^8.22.0", | ||
"bitcore-lib": "^8.22.1", | ||
"bn.js": "=4.11.8", | ||
@@ -49,3 +49,3 @@ "bs58": "^4.0.1", | ||
"base-x": "=3.0.4", | ||
"bitcore-build": "^8.22.0", | ||
"bitcore-build": "^8.22.1", | ||
"brfs": "^2.0.1", | ||
@@ -52,0 +52,0 @@ "chai": "^4.2.0", |
@@ -164,2 +164,24 @@ 'use strict'; | ||
}); | ||
it("Schnorr nonceFunctionRFC6979", function() { | ||
var privkey = [247,229,95,194,90,177,180,124,16,212,194,1,4,84,217,63,135,141,214,161,83,44,149,178,196,172,199,160,224,226,3,171] | ||
var msgbuf = [203,64,126,5,128,46,163,26,233,17,17,84,85,232,237,114,254,233,21,23,122,3,27,106,32,178,75,75,119,76,13,176] | ||
var k = schnorr.nonceFunctionRFC6979(Buffer.from(privkey), Buffer.from(msgbuf)); | ||
k.toString().should.equal('40736259912772382559816990380041422373693363729339996443093592104584195165'); | ||
}); | ||
it('Schnorr Sign/Verify Test X, case previously produced 63 byte signature', function() { | ||
let hashbuf = Buffer.from('a330930ce36be70a744d057dd2a2d0c55a8418ee706e662fcb8d4ab5ef845e03','hex'); | ||
let privbn = Buffer.from('ef209804744733771a07eac71d2288db0b3030c91fa49382037fb8a5aad0f1ca','hex'); | ||
let privkey = new Privkey(privbn); | ||
let schnorrSig = Schnorr({ | ||
hashbuf: hashbuf, | ||
endian: 'little', | ||
privkey: privkey, | ||
hashtype: 65 | ||
}); | ||
schnorrSig.sign(); | ||
let verified = schnorrSig.verify().verified; | ||
verified.should.equal(true); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2562574
150
32945
Updatedbitcore-lib@^8.22.1