mcl-wasm
Version:
mcl ; A portable and fast pairing-based cryptography library for Node.js by WebAssembly
243 lines (242 loc) • 10.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.initializeMcl = exports.initializedCurveType = exports._showDebug = exports.free = exports.fromHexStr = exports.toHexStr = exports.toHex = exports.asciiStrToPtr = exports.ptrToAsciiStr = exports.mod = void 0;
const getRandomValues_1 = __importDefault(require("./getRandomValues"));
const constants_1 = require("./constants");
const createModule = require("./mcl_c.js");
const ptrToAsciiStr = (pos, n) => {
let s = '';
for (let i = 0; i < n; i++) {
s += String.fromCharCode(exports.mod.HEAP8[pos + i]);
}
return s;
};
exports.ptrToAsciiStr = ptrToAsciiStr;
const asciiStrToPtr = (pos, s) => {
for (let i = 0; i < s.length; i++) {
exports.mod.HEAP8[pos + i] = s.charCodeAt(i);
}
};
exports.asciiStrToPtr = asciiStrToPtr;
const toHex = (a, start, n) => {
let s = '';
for (let i = 0; i < n; i++) {
s += ('0' + a[start + i].toString(16)).slice(-2);
}
return s;
};
exports.toHex = toHex;
// Uint8Array to hex string
const toHexStr = (a) => {
return (0, exports.toHex)(a, 0, a.length);
};
exports.toHexStr = toHexStr;
// hex string to Uint8Array
const fromHexStr = (s) => {
if ((s.length & 1) !== 0)
throw new Error(`fromHexStr:length must be even (${s.length})`);
const n = s.length / 2;
const a = new Uint8Array(n);
for (let i = 0; i < n; i++) {
a[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);
}
return a;
};
exports.fromHexStr = fromHexStr;
const free = (x) => {
exports.mod._free(x);
};
exports.free = free;
const addWrappedMethods = () => {
const _wrapGetStr = (func, returnAsStr = true) => {
return (x, ioMode = 0) => {
const stack = exports.mod.stackSave();
const maxBufSize = 4096;
const pos = exports.mod.stackAlloc(maxBufSize);
const n = func(pos, maxBufSize, x, ioMode);
if (n > 0) {
let s = null;
if (returnAsStr) {
s = (0, exports.ptrToAsciiStr)(pos, n);
}
else {
s = new Uint8Array(exports.mod.HEAP8.subarray(pos, pos + n));
}
exports.mod.stackRestore(stack);
return s;
}
else {
exports.mod.stackRestore(stack);
throw new Error(`err gen_str:${x}`);
}
};
};
const _wrapSerialize = (func) => {
return _wrapGetStr(func, false);
};
const _wrapDeserialize = (func) => {
return (x, buf) => {
const stack = exports.mod.stackSave();
const pos = exports.mod.stackAlloc(buf.length);
exports.mod.HEAP8.set(buf, pos);
const r = func(x, pos, buf.length);
exports.mod.stackRestore(stack);
if (r === 0 || r !== buf.length)
throw new Error(`err _wrapDeserialize: ${r} != ${buf.length}`);
};
};
/*
argNum : n
func(x0, ..., x_(n-1), buf, ioMode)
=> func(x0, ..., x_(n-1), pos, buf.length, ioMode)
*/
const _wrapInput = (func, argNum) => {
return function (...args) {
const buf = args[argNum];
const typeStr = Object.prototype.toString.apply(buf);
if (!['[object String]', '[object Uint8Array]', '[object Array]'].includes(typeStr)) {
throw new Error(`err bad type:"${typeStr}". Use String or Uint8Array.`);
}
const ioMode = args[argNum + 1]; // may undefined
const stack = exports.mod.stackSave();
const pos = exports.mod.stackAlloc(buf.length);
if (typeStr === '[object String]') {
(0, exports.asciiStrToPtr)(pos, buf);
}
else {
exports.mod.HEAP8.set(buf, pos);
}
const r = func(...args.slice(0, argNum), pos, buf.length, ioMode);
exports.mod.stackRestore(stack);
if (r !== 0)
throw new Error('err _wrapInput');
};
};
exports.mod.mclBnFr_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_FR_SIZE);
};
exports.mod.mclBnFr_setLittleEndian = _wrapInput(exports.mod._mclBnFr_setLittleEndian, 1);
exports.mod.mclBnFr_setLittleEndianMod = _wrapInput(exports.mod._mclBnFr_setLittleEndianMod, 1);
exports.mod.mclBnFr_setBigEndianMod = _wrapInput(exports.mod._mclBnFr_setBigEndianMod, 1);
exports.mod.mclBnFr_setStr = _wrapInput(exports.mod._mclBnFr_setStr, 1);
exports.mod.mclBnFr_getStr = _wrapGetStr(exports.mod._mclBnFr_getStr);
exports.mod.mclBnFr_deserialize = _wrapDeserialize(exports.mod._mclBnFr_deserialize);
exports.mod.mclBnFr_serialize = _wrapSerialize(exports.mod._mclBnFr_serialize);
exports.mod.mclBnFr_setHashOf = _wrapInput(exports.mod._mclBnFr_setHashOf, 1);
/// ////////////////////////////////////////////////////////////
exports.mod.mclBnFp_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_FP_SIZE);
};
exports.mod.mclBnFp_setLittleEndian = _wrapInput(exports.mod._mclBnFp_setLittleEndian, 1);
exports.mod.mclBnFp_setLittleEndianMod = _wrapInput(exports.mod._mclBnFp_setLittleEndianMod, 1);
exports.mod.mclBnFp_setBigEndianMod = _wrapInput(exports.mod._mclBnFp_setBigEndianMod, 1);
exports.mod.mclBnFp_setStr = _wrapInput(exports.mod._mclBnFp_setStr, 1);
exports.mod.mclBnFp_getStr = _wrapGetStr(exports.mod._mclBnFp_getStr);
exports.mod.mclBnFp_deserialize = _wrapDeserialize(exports.mod._mclBnFp_deserialize);
exports.mod.mclBnFp_serialize = _wrapSerialize(exports.mod._mclBnFp_serialize);
exports.mod.mclBnFp_setHashOf = _wrapInput(exports.mod._mclBnFp_setHashOf, 1);
exports.mod.mclBnFp2_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_FP_SIZE * 2);
};
exports.mod.mclBnFp2_deserialize = _wrapDeserialize(exports.mod._mclBnFp2_deserialize);
exports.mod.mclBnFp2_serialize = _wrapSerialize(exports.mod._mclBnFp2_serialize);
/// ////////////////////////////////////////////////////////////
exports.mod.mclBnG1_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_G1_SIZE);
};
exports.mod.mclBnG1_setStr = _wrapInput(exports.mod._mclBnG1_setStr, 1);
exports.mod.mclBnG1_getStr = _wrapGetStr(exports.mod._mclBnG1_getStr);
exports.mod.mclBnG1_deserialize = _wrapDeserialize(exports.mod._mclBnG1_deserialize);
exports.mod.mclBnG1_serialize = _wrapSerialize(exports.mod._mclBnG1_serialize);
exports.mod.mclBnG1_hashAndMapTo = _wrapInput(exports.mod._mclBnG1_hashAndMapTo, 1);
/// ////////////////////////////////////////////////////////////
exports.mod.mclBnG2_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_G2_SIZE);
};
exports.mod.mclBnG2_setStr = _wrapInput(exports.mod._mclBnG2_setStr, 1);
exports.mod.mclBnG2_getStr = _wrapGetStr(exports.mod._mclBnG2_getStr);
exports.mod.mclBnG2_deserialize = _wrapDeserialize(exports.mod._mclBnG2_deserialize);
exports.mod.mclBnG2_serialize = _wrapSerialize(exports.mod._mclBnG2_serialize);
exports.mod.mclBnG2_hashAndMapTo = _wrapInput(exports.mod._mclBnG2_hashAndMapTo, 1);
/// ////////////////////////////////////////////////////////////
exports.mod.mclBnGT_malloc = () => {
return exports.mod._malloc(constants_1.MCLBN_GT_SIZE);
};
exports.mod.mclBnGT_deserialize = _wrapDeserialize(exports.mod._mclBnGT_deserialize);
exports.mod.mclBnGT_serialize = _wrapSerialize(exports.mod._mclBnGT_serialize);
exports.mod.mclBnGT_setStr = _wrapInput(exports.mod._mclBnGT_setStr, 1);
exports.mod.mclBnGT_getStr = _wrapGetStr(exports.mod._mclBnGT_getStr);
exports.mod.g_his = [];
exports.mod.g_ptr = {};
exports.mod.g_total = 0;
/*
she libray always uses (malloc,free) in nested pairs.
*/
exports.mod._mallocDebug = (size) => {
const p = exports.mod._mallocOrg(size + 4);
exports.mod.HEAP8[p + size] = 0x12;
exports.mod.HEAP8[p + size + 1] = 0x34;
exports.mod.HEAP8[p + size + 2] = 0x56;
exports.mod.HEAP8[p + size + 3] = 0x78;
exports.mod.g_his.push([p, size]);
exports.mod.g_ptr[p] = size;
exports.mod.g_total += size;
return p;
};
exports.mod._freeDebug = (pos) => {
const ps = exports.mod.g_his.pop();
const p = ps[0];
const size = ps[1];
if (pos !== p) {
console.log(`pos=${pos} oldPos=${p}`);
}
const v = exports.mod.HEAP8[p + size] + (exports.mod.HEAP8[p + size + 1] << 8) + (exports.mod.HEAP8[p + size + 2] << 16) + (exports.mod.HEAP8[p + size + 3] << 24);
if (v !== 0x78563412) {
console.log(`ERR=${p} v=${v.toString(16)}`);
}
exports.mod._freeOrg(pos);
const s = exports.mod.g_ptr[pos];
if (s === 0) {
console.log(`ERR ${pos}`);
}
else {
delete exports.mod.g_ptr[pos];
exports.mod.g_total -= s;
}
};
exports.mod._mallocOrg = exports.mod._malloc;
exports.mod._freeOrg = exports.mod._free;
exports.mod.debug = false;
if (exports.mod.debug) {
exports.mod._malloc = exports.mod._mallocDebug;
exports.mod._free = exports.mod._freeDebug;
}
};
const _showDebug = () => {
if (exports.mod.debug) {
console.log('malloc DEBUG mode');
console.log(` show total=${exports.mod.g_total}`);
console.log(` g_ptr=${JSON.stringify(exports.mod.g_ptr, null, '\t')}`);
}
};
exports._showDebug = _showDebug;
const initializeMcl = async (curveType = constants_1.CurveType.BN254) => {
exports.mod = await createModule({
cryptoGetRandomValues: (p, n) => {
const a = new Uint8Array(n);
(0, getRandomValues_1.default)(a);
for (let i = 0; i < n; i++) {
exports.mod.HEAP8[p + i] = a[i];
}
}
});
exports.initializedCurveType = curveType;
addWrappedMethods();
const r = exports.mod._mclBn_init(curveType, constants_1.MCLBN_COMPILED_TIME_VAR);
if (r !== 0)
throw new Error(`_mclBn_init err ${r}`);
};
exports.initializeMcl = initializeMcl;