Files
xahau.js/src/core/sjcl-custom/sjcl-validecc.js
2015-05-29 10:49:14 -07:00

48 lines
1.6 KiB
JavaScript

/* eslint new-cap: [2, {newIsCapExceptions: ["corrupt"]}] */
'use strict';
var sjcl = require('sjcl');
sjcl.ecc.ecdsa.secretKey.prototype.sign = function(hash, paranoia,
k_for_testing) {
var R = this._curve.r,
l = R.bitLength();
// k_for_testing should ONLY BE SPECIFIED FOR TESTING
// specifying it will make the signature INSECURE
var k;
if (typeof k_for_testing === 'object' && k_for_testing.length > 0
&& typeof k_for_testing[0] === 'number') {
k = k_for_testing;
} else if (typeof k_for_testing === 'string'
&& /^[0-9a-fA-F]+$/.test(k_for_testing)) {
k = sjcl.bn.fromBits(sjcl.codec.hex.toBits(k_for_testing));
} else {
// This is the only option that should be used in production
k = sjcl.bn.random(R.sub(1), paranoia).add(1);
}
var r = this._curve.G.mult(k).x.mod(R);
var s = sjcl.bn.fromBits(hash).add(r.mul(this._exponent))
.mul(k.inverseMod(R)).mod(R);
return sjcl.bitArray.concat(r.toBits(l), s.toBits(l));
};
sjcl.ecc.ecdsa.publicKey.prototype.verify = function(hash, rs) {
var w = sjcl.bitArray;
var R = this._curve.r;
var l = R.bitLength();
var r = sjcl.bn.fromBits(w.bitSlice(rs, 0, l));
var s = sjcl.bn.fromBits(w.bitSlice(rs, l, 2 * l));
var sInv = s.inverseMod(R);
var hG = sjcl.bn.fromBits(hash).mul(sInv).mod(R);
var hA = r.mul(sInv).mod(R);
var r2 = this._curve.G.mult2(hG, hA, this._point).x;
if (r.equals(0) || s.equals(0) || r.greaterEquals(R) || s.greaterEquals(R)
|| !r2.equals(r)) {
throw (new sjcl.exception.corrupt('signature didn\'t check out'));
}
return true;
};