mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-06 17:27:59 +00:00
48 lines
1.6 KiB
JavaScript
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;
|
|
};
|