schnorr: generate nonce pairs.
This commit is contained in:
parent
a0726efe75
commit
0cbab6e72e
@ -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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user