@dedis/kyber
Version:
A typescript implementation of Kyber interfaces
123 lines (122 loc) • 3.96 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const blake2xs_1 = require("@stablelib/blake2xs");
const bn_js_1 = __importDefault(require("bn.js"));
const point_1 = require("../../pairing/point");
const scalar_1 = __importDefault(require("../../pairing/scalar"));
const BLS = __importStar(require("../bls"));
const COEF_SIZE = 128 / 8;
/**
* Generate the list of coefficients for the list of public keys
*
* @param pubkeys The list of public keys
* @return The list of coefficients as BigNumber
*/
function hashPointToR(pubkeys) {
const peers = pubkeys.map((p) => p.marshalBinary());
const xof = new blake2xs_1.BLAKE2Xs();
peers.forEach((p) => xof.update(p));
const out = Buffer.allocUnsafe(COEF_SIZE * peers.length);
xof.stream(out);
const coefs = [];
for (let i = 0; i < peers.length; i++) {
coefs[i] = new bn_js_1.default(out.slice(i * COEF_SIZE, (i + 1) * COEF_SIZE), "le");
}
return coefs;
}
exports.hashPointToR = hashPointToR;
/**
* Aggregate the list of points according to the mask participation.
* The length of the mask and the list of points must match. Intermediate
* non-participating points can be null.
*
* @param mask The mask with the participation
* @param points The list of points to aggregate
*/
function aggregatePoints(mask, points) {
if (mask.getCountTotal() !== points.length) {
throw new Error("Length of mask and points does not match");
}
const coefs = hashPointToR(mask.publics);
let agg = null;
for (let i = 0; i < coefs.length; i++) {
if (mask.isIndexEnabled(i)) {
const c = new scalar_1.default(coefs[i]);
const p = points[i].clone();
p.mul(c, p);
// R is in the range [1; 2^128] inclusive thus (c + 1) * p
p.add(p, points[i]);
if (agg == null) {
agg = p;
}
else {
agg.add(agg, p);
}
}
}
return agg;
}
/**
* Aggregate the public keys of the mask
*
* @param mask The mask with the participation and the list of points
* @return The new point representing the aggregation
*/
function aggregatePublicKeys(mask) {
return aggregatePoints(mask, mask.publics);
}
exports.aggregatePublicKeys = aggregatePublicKeys;
/**
* Aggregate a list of signatures according to the given mask
*
* @param mask The mask with the participation
* @param sigs The signatures as bytes
* @return The new point representing the aggregation
*/
function aggregateSignatures(mask, sigs) {
const points = sigs.map((s) => {
if (!s) {
return null;
}
const p = new point_1.BN256G1Point();
p.unmarshalBinary(s);
return p;
});
return aggregatePoints(mask, points);
}
exports.aggregateSignatures = aggregateSignatures;
/**
* Sign the message using the given secret
*
* @param msg The Message to sign
* @param secret The secret key
* @return The BDN signature
*/
function sign(msg, secret) {
return BLS.sign(msg, secret);
}
exports.sign = sign;
/**
* Verify the given signature against the message using the mask
* to aggregate the public keys
*
* @param msg The message
* @param mask The mask with the public keys
* @param sig The signature as bytes
* @return true if the signature matches, false otherwise
*/
function verify(msg, mask, sig) {
const pub = aggregatePublicKeys(mask);
return BLS.verify(msg, pub, sig);
}
exports.verify = verify;