Skip to content
This repository has been archived by the owner on Apr 20, 2022. It is now read-only.

Commit

Permalink
rfc6979
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Reeves committed Dec 16, 2014
1 parent c737873 commit 0765daf
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 9 deletions.
86 changes: 80 additions & 6 deletions bitcoinjs-lib/src/ecdsa.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,68 @@
// https://tools.ietf.org/html/rfc6979#section-3.2
function deterministicGenerateK(n, hash, d) {

This comment has been minimized.

Copy link
@dcousens

dcousens Dec 16, 2014

Please add some reference to https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.js#L12, where this code was taken derived from :).

// sanity check
if (hash.length != 32) {
throw 'Hash must be 256 bit';
}

var fill = function (a, b) {
for(var i = 0; i < a.length; ++i) {
a[i] = b;
}
}

var x = d.toByteArrayUnsigned();

//Pad to 32 bytes
var zeros = [];
var padding = 32 - x.length;
while (zeros.length < padding) {
zeros.push(0);
}
x = zeros.concat(x);

var k = new Array(32);
var v = new Array(32);
var ZERO = [0];
var ONE = [1];

// Step B
fill(v, 1);

// Step C
fill(k, 0);

// Step D
k = Crypto.HMAC(Crypto.SHA256, v.concat(ZERO).concat(x).concat(hash), k, {asBytes: true});

// Step E
v = Crypto.HMAC(Crypto.SHA256, v, k, {asBytes: true});

// Step F
k = Crypto.HMAC(Crypto.SHA256, v.concat(ONE).concat(x).concat(hash), k, {asBytes: true});

// Step G
v = Crypto.HMAC(Crypto.SHA256, v, k, {asBytes: true});

// Step H1/H2a, ignored as tlen === qlen (256 bit)
// Step H2b
// v = crypto.createHmac('sha256', k).update(v).digest()
v = Crypto.HMAC(Crypto.SHA256, v, k, {asBytes: true});

var T = BigInteger.fromByteArrayUnsigned(v)

// Step H3, repeat until T is within the interval [1, n - 1]
while ((T.signum() <= 0) || (T.compareTo(n) >= 0)) {
k = Crypto.HMAC(Crypto.SHA256, v.concat(ZERO), k, {asBytes: true});

v = Crypto.HMAC(Crypto.SHA256, v, k, {asBytes: true});

T = BigInteger.fromByteArrayUnsigned(v);
}

return T;
}

function integerToBytes(i, len) {
var bytes = i.toByteArrayUnsigned();

Expand Down Expand Up @@ -233,15 +298,24 @@ Bitcoin.ECDSA = (function () {
var n = ecparams.getN();
var e = BigInteger.fromByteArrayUnsigned(hash);

do {
var k = ECDSA.getBigRandom(n);
var G = ecparams.getG();
var Q = G.multiply(k);
var r = Q.getX().toBigInteger().mod(n);
} while (r.compareTo(BigInteger.ZERO) <= 0);
var k = deterministicGenerateK(n, hash, d);
var G = ecparams.getG();
var Q = G.multiply(k);
var r = Q.getX().toBigInteger().mod(n);

if (r.signum() == 0) throw 'Invalid R';

var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);

if (s.signum() == 0) throw 'Invalid S';

var N_OVER_TWO = n.shiftRight(1)

// enforce low S values, see bip62: 'low s values in signatures'
if (s.compareTo(N_OVER_TWO) > 0) {
s = n.subtract(s);
}

return {r : r, s : s };
},

Expand Down
6 changes: 3 additions & 3 deletions signer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1676,11 +1676,11 @@ function initNewTx() {
self.worker[i].postMessage({cmd : 'load_resource' , path : MyWallet.getWebWorkerLoadPrefix() + 'bitcoinjs' + (min ? '.min.js' : '.js')});

//Generate and pass seed to the webworker
var seed = new Array(rng_psize);
/*var seed = new Array(rng_psize);
rng.nextBytes(seed);
self.worker[i].postMessage({cmd : 'seed', seed : Crypto.util.bytesToHex(seed)});
self.worker[i].postMessage({cmd : 'seed', seed : Crypto.util.bytesToHex(seed)});*/
}

for (var outputN = 0; outputN < self.selected_outputs.length; ++ outputN) {
Expand Down Expand Up @@ -1754,7 +1754,7 @@ function initNewTx() {
};

//Be sure the RNG is fully seeded
MyWallet._seed();
//MyWallet._seed(); No longer needed with rfc6979

self.signWebWorker(success, function(e) {
console.log(e);
Expand Down

0 comments on commit 0765daf

Please sign in to comment.