schnorr: generate nonce pairs.
This commit is contained in:
parent
a0726efe75
commit
0cbab6e72e
@ -9,6 +9,7 @@
|
|||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
var elliptic = require('elliptic');
|
var elliptic = require('elliptic');
|
||||||
var Signature = require('elliptic/lib/elliptic/ec/signature');
|
var Signature = require('elliptic/lib/elliptic/ec/signature');
|
||||||
|
var hmacDRBG = require('elliptic/lib/elliptic/hmac-drbg');
|
||||||
var ec = require('./ec');
|
var ec = require('./ec');
|
||||||
var curve = elliptic.ec('secp256k1').curve;
|
var curve = elliptic.ec('secp256k1').curve;
|
||||||
var sha256 = require('./crypto').sha256;
|
var sha256 = require('./crypto').sha256;
|
||||||
@ -230,7 +231,7 @@ schnorr.combineSigs = function combineSigs(sigs) {
|
|||||||
if (last && last.r.cmp(sig.r) !== 0)
|
if (last && last.r.cmp(sig.r) !== 0)
|
||||||
throw new Error('Bad signature combination.');
|
throw new Error('Bad signature combination.');
|
||||||
|
|
||||||
s.iadd(sig.s);
|
s = s.iadd(sig.s);
|
||||||
s = s.umod(curve.n);
|
s = s.umod(curve.n);
|
||||||
|
|
||||||
last = sig;
|
last = sig;
|
||||||
@ -279,6 +280,7 @@ schnorr.combineKeys = function combineKeys(keys) {
|
|||||||
|
|
||||||
schnorr.partialSign = function partialSign(msg, priv, privnonce, pubs, hash) {
|
schnorr.partialSign = function partialSign(msg, priv, privnonce, pubs, hash) {
|
||||||
var prv = new bn(priv);
|
var prv = new bn(priv);
|
||||||
|
var sig;
|
||||||
|
|
||||||
if (prv.cmpn(0) === 0)
|
if (prv.cmpn(0) === 0)
|
||||||
throw new Error('Bad private key.');
|
throw new Error('Bad private key.');
|
||||||
@ -286,5 +288,104 @@ schnorr.partialSign = function partialSign(msg, priv, privnonce, pubs, hash) {
|
|||||||
if (prv.cmp(curve.n) >= 0)
|
if (prv.cmp(curve.n) >= 0)
|
||||||
throw new Error('Bad private key.');
|
throw new Error('Bad private key.');
|
||||||
|
|
||||||
return schnorr._sign(msg, prv, new bn(privnonce), hash, pubs);
|
sig = schnorr._sign(msg, prv, new bn(privnonce), hash, pubs);
|
||||||
|
|
||||||
|
if (!sig)
|
||||||
|
throw new Error('Bad K value.');
|
||||||
|
|
||||||
|
return sig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schnorr personalization string.
|
||||||
|
* @const {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
schnorr.alg = new Buffer('Schnorr+SHA256 ', 'ascii');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform hmac drbg according to rfc6979.
|
||||||
|
* @param {Buffer} msg
|
||||||
|
* @param {Buffer} priv
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
schnorr.rfc6979 = function rfc6979(msg, priv, data) {
|
||||||
|
var kdata = new Buffer(112);
|
||||||
|
var drbg, prv, pers;
|
||||||
|
|
||||||
|
kdata.fill(0);
|
||||||
|
|
||||||
|
priv.copy(kdata, 0);
|
||||||
|
msg.copy(kdata, 32);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
data.copy(kdata, 64);
|
||||||
|
|
||||||
|
schnorr.alg.copy(kdata, 96);
|
||||||
|
|
||||||
|
prv = toArray(kdata.slice(0, 32));
|
||||||
|
msg = toArray(kdata.slice(32, 64));
|
||||||
|
pers = toArray(kdata.slice(64));
|
||||||
|
|
||||||
|
drbg = new hmacDRBG({
|
||||||
|
hash: require('hash.js').sha256,
|
||||||
|
entropy: prv,
|
||||||
|
nonce: msg,
|
||||||
|
pers: pers
|
||||||
|
});
|
||||||
|
|
||||||
|
drbg = drbg.generate(curve.n.byteLength());
|
||||||
|
|
||||||
|
return new Buffer(drbg);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a schnorr nonce with a nonce callback.
|
||||||
|
* @param {Buffer} msg
|
||||||
|
* @param {Buffer} priv
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @param {Function?} ncb
|
||||||
|
* @returns {BN}
|
||||||
|
*/
|
||||||
|
|
||||||
|
schnorr.nonce = function nonce(msg, priv, data, ncb) {
|
||||||
|
var pubnonce;
|
||||||
|
|
||||||
|
if (!ncb)
|
||||||
|
ncb = schnorr.rfc6979;
|
||||||
|
|
||||||
|
pubnonce = ncb(msg, priv, data);
|
||||||
|
|
||||||
|
return new bn(pubnonce);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate pub+priv nonce pair.
|
||||||
|
* @param {Buffer} msg
|
||||||
|
* @param {Buffer} priv
|
||||||
|
* @param {Buffer} data
|
||||||
|
* @param {Function?} ncb
|
||||||
|
* @returns {Buffer}
|
||||||
|
*/
|
||||||
|
|
||||||
|
schnorr.generateNoncePair = function generateNoncePair(msg, priv, data, ncb) {
|
||||||
|
var k = schnorr.nonce(priv, msg, data, ncb);
|
||||||
|
|
||||||
|
if (k.cmpn(0) === 0)
|
||||||
|
throw new Error('Bad nonce.');
|
||||||
|
|
||||||
|
if (k.cmp(curve.n) >= 0)
|
||||||
|
throw new Error('Bad nonce.');
|
||||||
|
|
||||||
|
return new Buffer(curve.g.mul(k).encode('array', true));
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
function toArray(obj) {
|
||||||
|
return Array.prototype.slice.call(obj);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user