@xmr-core/xmr-crypto-utils
Version:
Core crypto operations for Monero and implementations and interfaces of various hardware devices for creating Monero transactions securely
137 lines • 6.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const xmr_vendor_1 = require("@xmr-core/xmr-vendor");
const xmr_str_utils_1 = require("@xmr-core/xmr-str-utils");
const constants_1 = require("./constants");
const hash_ops_1 = require("./hash_ops");
//curve and scalar functions; split out to make their host functions cleaner and more readable
//inverts X coordinate -- this seems correct ^_^ -luigi1111
function ge_neg(point) {
if (point.length !== 64) {
throw Error("expected 64 char hex string");
}
return (point.slice(0, 62) +
((parseInt(point.slice(62, 63), 16) + 8) % 16).toString(16) +
point.slice(63, 64));
}
function ge_add(p1, p2) {
if (p1.length !== 64 || p2.length !== 64) {
throw Error("Invalid input length!");
}
return xmr_str_utils_1.bintohex(xmr_vendor_1.nacl.ge_add(xmr_str_utils_1.hextobin(p1), xmr_str_utils_1.hextobin(p2)));
}
exports.ge_add = ge_add;
//order matters
function ge_sub(point1, point2) {
const point2n = ge_neg(point2);
return ge_add(point1, point2n);
}
exports.ge_sub = ge_sub;
//adds two scalars together
function sc_add(scalar1, scalar2) {
if (scalar1.length !== 64 || scalar2.length !== 64) {
throw Error("Invalid input length!");
}
const scalar1_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
const scalar2_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(scalar1), scalar1_m);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(scalar2), scalar2_m);
const derived_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto.ccall("sc_add", "void", ["number", "number", "number"], [derived_m, scalar1_m, scalar2_m]);
const res = xmr_vendor_1.CNCrypto.HEAPU8.subarray(derived_m, derived_m + constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto._free(scalar1_m);
xmr_vendor_1.CNCrypto._free(scalar2_m);
xmr_vendor_1.CNCrypto._free(derived_m);
return xmr_str_utils_1.bintohex(res);
}
exports.sc_add = sc_add;
//subtracts one scalar from another
function sc_sub(scalar1, scalar2) {
if (scalar1.length !== 64 || scalar2.length !== 64) {
throw Error("Invalid input length!");
}
const scalar1_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
const scalar2_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(scalar1), scalar1_m);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(scalar2), scalar2_m);
const derived_m = xmr_vendor_1.CNCrypto._malloc(constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto.ccall("sc_sub", "void", ["number", "number", "number"], [derived_m, scalar1_m, scalar2_m]);
const res = xmr_vendor_1.CNCrypto.HEAPU8.subarray(derived_m, derived_m + constants_1.STRUCT_SIZES.EC_SCALAR);
xmr_vendor_1.CNCrypto._free(scalar1_m);
xmr_vendor_1.CNCrypto._free(scalar2_m);
xmr_vendor_1.CNCrypto._free(derived_m);
return xmr_str_utils_1.bintohex(res);
}
exports.sc_sub = sc_sub;
//res = c - (ab) mod l; argument names copied from the signature implementation
function sc_mulsub(sigc, sec, k) {
if (k.length !== constants_1.KEY_SIZE * 2 ||
sigc.length !== constants_1.KEY_SIZE * 2 ||
sec.length !== constants_1.KEY_SIZE * 2 ||
!xmr_str_utils_1.valid_hex(k) ||
!xmr_str_utils_1.valid_hex(sigc) ||
!xmr_str_utils_1.valid_hex(sec)) {
throw Error("bad scalar");
}
const sec_m = xmr_vendor_1.CNCrypto._malloc(constants_1.KEY_SIZE);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(sec), sec_m);
const sigc_m = xmr_vendor_1.CNCrypto._malloc(constants_1.KEY_SIZE);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(sigc), sigc_m);
const k_m = xmr_vendor_1.CNCrypto._malloc(constants_1.KEY_SIZE);
xmr_vendor_1.CNCrypto.HEAPU8.set(xmr_str_utils_1.hextobin(k), k_m);
const res_m = xmr_vendor_1.CNCrypto._malloc(constants_1.KEY_SIZE);
xmr_vendor_1.CNCrypto.ccall("sc_mulsub", "void", ["number", "number", "number", "number"], [res_m, sigc_m, sec_m, k_m]);
const res = xmr_vendor_1.CNCrypto.HEAPU8.subarray(res_m, res_m + constants_1.KEY_SIZE);
xmr_vendor_1.CNCrypto._free(k_m);
xmr_vendor_1.CNCrypto._free(sec_m);
xmr_vendor_1.CNCrypto._free(sigc_m);
xmr_vendor_1.CNCrypto._free(res_m);
return xmr_str_utils_1.bintohex(res);
}
exports.sc_mulsub = sc_mulsub;
function ge_double_scalarmult_base_vartime(c, P, r) {
if (c.length !== 64 || P.length !== 64 || r.length !== 64) {
throw Error("Invalid input length!");
}
return xmr_str_utils_1.bintohex(xmr_vendor_1.nacl.ge_double_scalarmult_base_vartime(xmr_str_utils_1.hextobin(c), xmr_str_utils_1.hextobin(P), xmr_str_utils_1.hextobin(r)));
}
exports.ge_double_scalarmult_base_vartime = ge_double_scalarmult_base_vartime;
function ge_double_scalarmult_postcomp_vartime(r, P, c, I) {
if (c.length !== 64 ||
P.length !== 64 ||
r.length !== 64 ||
I.length !== 64) {
throw Error("Invalid input length!");
}
const Pb = hash_ops_1.hash_to_ec_2(P);
return xmr_str_utils_1.bintohex(xmr_vendor_1.nacl.ge_double_scalarmult_postcomp_vartime(xmr_str_utils_1.hextobin(r), xmr_str_utils_1.hextobin(Pb), xmr_str_utils_1.hextobin(c), xmr_str_utils_1.hextobin(I)));
}
exports.ge_double_scalarmult_postcomp_vartime = ge_double_scalarmult_postcomp_vartime;
function ge_scalarmult_base(sec) {
if (sec.length !== 64) {
throw Error("Invalid sec length");
}
return xmr_str_utils_1.bintohex(xmr_vendor_1.nacl.ge_scalarmult_base(xmr_str_utils_1.hextobin(sec)));
}
exports.ge_scalarmult_base = ge_scalarmult_base;
function ge_scalarmult(pub, sec) {
if (pub.length !== 64 || sec.length !== 64) {
throw Error("Invalid input length");
}
return xmr_str_utils_1.bintohex(xmr_vendor_1.nacl.ge_scalarmult(xmr_str_utils_1.hextobin(pub), xmr_str_utils_1.hextobin(sec)));
}
exports.ge_scalarmult = ge_scalarmult;
function sc_reduce32(hex) {
const input = xmr_str_utils_1.hextobin(hex);
if (input.length !== 32) {
throw Error("Invalid input length");
}
const mem = xmr_vendor_1.CNCrypto._malloc(32);
xmr_vendor_1.CNCrypto.HEAPU8.set(input, mem);
xmr_vendor_1.CNCrypto.ccall("sc_reduce32", "void", ["number"], [mem]);
const output = xmr_vendor_1.CNCrypto.HEAPU8.subarray(mem, mem + 32);
xmr_vendor_1.CNCrypto._free(mem);
return xmr_str_utils_1.bintohex(output);
}
exports.sc_reduce32 = sc_reduce32;
//# sourceMappingURL=primitive_ops.js.map