mokka
Version:
Mokka Consensus Algorithm implementation in Javascript
112 lines • 5.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pointToPublicKey = exports.pubKeyToPoint = exports.verify = exports.buildSharedSignature = exports.partialSignatureVerify = exports.buildPartialSignature = exports.buildSharedPublicKeyX = exports.buildPublicKeysRootForTerm = exports.buildPublicKeysRoot = void 0;
// tslint:disable:variable-name
const bn_js_1 = __importDefault(require("bn.js"));
const crypto = __importStar(require("crypto"));
const elliptic_1 = require("elliptic");
const ec = new elliptic_1.ec('secp256k1');
const buildPublicKeysRoot = (publicKeys) => {
let X = null;
for (const publicKey of publicKeys) {
const XI = (0, exports.pubKeyToPoint)(Buffer.from(publicKey, 'hex'));
X = X === null ? XI : X.add(XI);
}
return (0, exports.pointToPublicKey)(X).toString('hex');
};
exports.buildPublicKeysRoot = buildPublicKeysRoot;
const buildPublicKeysRootForTerm = (publicKeysRoot, term, nonce, candidatePublicKey) => {
const mHash = crypto.createHash('sha256')
.update(`${nonce}:${term}:${candidatePublicKey}`)
.digest('hex');
const X = (0, exports.pubKeyToPoint)(Buffer.from(publicKeysRoot, 'hex')).mul(new bn_js_1.default(mHash, 16));
return (0, exports.pointToPublicKey)(X).toString('hex');
};
exports.buildPublicKeysRootForTerm = buildPublicKeysRootForTerm;
/* X = X1 * a1 + X2 * a2 + ..Xn * an */
const buildSharedPublicKeyX = (publicKeys, term, nonce, publicKeysRootForTerm) => {
const mHash = crypto.createHash('sha256')
.update(`${nonce}:${term}:${publicKeysRootForTerm}`)
.digest('hex');
let X = null;
for (const publicKey of publicKeys) {
const XI = (0, exports.pubKeyToPoint)(Buffer.from(publicKey, 'hex')).mul(new bn_js_1.default(mHash, 16));
X = X === null ? XI : X.add(XI);
}
return (0, exports.pointToPublicKey)(X).toString('hex');
};
exports.buildSharedPublicKeyX = buildSharedPublicKeyX;
/* let s1 = (R1 + k1 * a1 * e) mod n, where n - is a curve param
* the "n" has been introduced to reduce the signature size
* */
const buildPartialSignature = (privateKeyK, term, nonce, publicKeysRootForTerm) => {
const mHash = crypto.createHash('sha256')
.update(`${nonce}:${term}:${publicKeysRootForTerm}`)
.digest('hex');
return new bn_js_1.default(privateKeyK, 16)
.mul(new bn_js_1.default(mHash, 16))
.mod(ec.n)
.toString(16);
};
exports.buildPartialSignature = buildPartialSignature;
/* let s1 * G = k1 * a1 * e * G = k1 * a1 * G * e = X1 * a1 * e */
const partialSignatureVerify = (partialSignature, publicKey, nonce, term, sharedPublicKeyX) => {
const mHash = crypto.createHash('sha256')
.update(`${nonce}:${term}:${sharedPublicKeyX}`)
.digest('hex');
const spG = ec.g.mul(partialSignature);
const check = (0, exports.pubKeyToPoint)(Buffer.from(publicKey, 'hex')).mul(mHash);
return (0, exports.pointToPublicKey)(spG).toString('hex') === (0, exports.pointToPublicKey)(check).toString('hex');
};
exports.partialSignatureVerify = partialSignatureVerify;
/* s = s1 + s2 + ...sn */
const buildSharedSignature = (partialSignatures) => {
let signature = new bn_js_1.default(0);
for (const sig of partialSignatures) {
signature = signature.add(new bn_js_1.default(sig, 16));
}
return signature.toString(16);
};
exports.buildSharedSignature = buildSharedSignature;
/* sG = X * e */
const verify = (signature, sharedPublicKeyX) => {
const sg = ec.g.mul(signature);
const check = (0, exports.pubKeyToPoint)(Buffer.from(sharedPublicKeyX, 'hex'));
return (0, exports.pointToPublicKey)(sg).toString('hex') === (0, exports.pointToPublicKey)(check).toString('hex');
};
exports.verify = verify;
const pubKeyToPoint = (pubKey) => {
const pubKeyEven = (pubKey[0] - 0x02) === 0;
return ec.curve.pointFromX(pubKey.slice(1, 33).toString('hex'), !pubKeyEven);
};
exports.pubKeyToPoint = pubKeyToPoint;
const pointToPublicKey = (P) => {
const buffer = Buffer.allocUnsafe(1);
// keep sign, if is odd
buffer.writeUInt8(P.getY().isEven() ? 0x02 : 0x03, 0);
return Buffer.concat([buffer, P.getX().toArrayLike(Buffer)]);
};
exports.pointToPublicKey = pointToPublicKey;
//# sourceMappingURL=cryptoUtils.js.map