@cdottori/ecdsa-node
Version:
fast openSSL-compatible implementation of the Elliptic Curve Digital Signature Algorithm (ECDSA)
36 lines (30 loc) • 1.51 kB
JavaScript
var sha256 = require("js-sha256");
var BigInt = require("big-integer");
var EcdsaMath = require("./math");
var Signature = require("./signature").Signature;
var BinaryAscii = require("./utils/binary");
var Integer = require("./utils/integer");
var randomInteger = Integer.between;
var modulo = Integer.modulo;
exports.sign = function (message, privateKey, hashfunc=sha256) {
let hashMessage = hashfunc(message);
let numberMessage = BinaryAscii.numberFromHex(hashMessage);
let curve = privateKey.curve;
let randNum = randomInteger(BigInt(1), curve.N.minus(1));
let randSignPoint = EcdsaMath.multiply(curve.G, randNum, curve.N, curve.A, curve.P);
let r = modulo(randSignPoint.x, curve.N);
let s = modulo((numberMessage.add(r.multiply(privateKey.secret)).multiply(EcdsaMath.inv(randNum, curve.N))), curve.N);
return new Signature(r, s);
};
exports.verify = function (message, signature, publicKey, hashfunc=sha256) {
let hashMessage = hashfunc(message);
let numberMessage = BinaryAscii.numberFromHex(hashMessage);
let curve = publicKey.curve;
let sigR = signature.r;
let sigS = signature.s;
let inv = EcdsaMath.inv(sigS, curve.N);
let u1 = EcdsaMath.multiply(curve.G, modulo((numberMessage.multiply(inv)), curve.N), curve.N, curve.A, curve.P);
let u2 = EcdsaMath.multiply(publicKey.point, modulo((sigR.multiply(inv)), curve.N), curve.N, curve.A, curve.P);
let add = EcdsaMath.add(u1, u2, curve.A, curve.P);
return sigR.eq(add.x);
};