schnorr: generate nonce pairs.

This commit is contained in:
Christopher Jeffrey 2016-09-01 18:10:50 -07:00
parent a0726efe75
commit 0cbab6e72e
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -9,6 +9,7 @@
var bn = require('bn.js');
var elliptic = require('elliptic');
var Signature = require('elliptic/lib/elliptic/ec/signature');
var hmacDRBG = require('elliptic/lib/elliptic/hmac-drbg');
var ec = require('./ec');
var curve = elliptic.ec('secp256k1').curve;
var sha256 = require('./crypto').sha256;
@ -230,7 +231,7 @@ schnorr.combineSigs = function combineSigs(sigs) {
if (last && last.r.cmp(sig.r) !== 0)
throw new Error('Bad signature combination.');
s.iadd(sig.s);
s = s.iadd(sig.s);
s = s.umod(curve.n);
last = sig;
@ -279,6 +280,7 @@ schnorr.combineKeys = function combineKeys(keys) {
schnorr.partialSign = function partialSign(msg, priv, privnonce, pubs, hash) {
var prv = new bn(priv);
var sig;
if (prv.cmpn(0) === 0)
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)
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);
}