UNPKG

@xmr-core/xmr-crypto-utils

Version:

Core crypto operations for Monero and implementations and interfaces of various hardware devices for creating Monero transactions securely

102 lines (97 loc) 2.67 kB
import { CNCrypto } from "@xmr-core/xmr-vendor"; import { cn_fast_hash } from "@xmr-core/xmr-fast-hash"; import { STRUCT_SIZES, KEY_SIZE, HASH_SIZE } from "./constants"; import { bintohex, hextobin } from "@xmr-core/xmr-str-utils"; import { sc_reduce32 } from "./primitive_ops"; export function hash_to_scalar(buf: string) { const hash = cn_fast_hash(buf); const scalar = sc_reduce32(hash); return scalar; } export function hash_to_ec(key: string) { if (key.length !== KEY_SIZE * 2) { throw Error("Invalid input length"); } const h_m = CNCrypto._malloc(HASH_SIZE); const point_m = CNCrypto._malloc(STRUCT_SIZES.GE_P2); const point2_m = CNCrypto._malloc(STRUCT_SIZES.GE_P1P1); const res_m = CNCrypto._malloc(STRUCT_SIZES.GE_P3); const hash = hextobin(cn_fast_hash(key)); CNCrypto.HEAPU8.set(hash, h_m); CNCrypto.ccall( "ge_fromfe_frombytes_vartime", "void", ["number", "number"], [point_m, h_m], ); CNCrypto.ccall( "ge_mul8", "void", ["number", "number"], [point2_m, point_m], ); CNCrypto.ccall( "ge_p1p1_to_p3", "void", ["number", "number"], [res_m, point2_m], ); const res = CNCrypto.HEAPU8.subarray(res_m, res_m + STRUCT_SIZES.GE_P3); CNCrypto._free(h_m); CNCrypto._free(point_m); CNCrypto._free(point2_m); CNCrypto._free(res_m); return bintohex(res); } //returns a 32 byte point via "ge_p3_tobytes" rather than a 160 byte "p3", otherwise same as above; export function hash_to_ec_2(key: string) { if (key.length !== KEY_SIZE * 2) { throw Error("Invalid input length"); } const h_m = CNCrypto._malloc(HASH_SIZE); const point_m = CNCrypto._malloc(STRUCT_SIZES.GE_P2); const point2_m = CNCrypto._malloc(STRUCT_SIZES.GE_P1P1); const res_m = CNCrypto._malloc(STRUCT_SIZES.GE_P3); const hash = hextobin(cn_fast_hash(key)); const res2_m = CNCrypto._malloc(KEY_SIZE); CNCrypto.HEAPU8.set(hash, h_m); CNCrypto.ccall( "ge_fromfe_frombytes_vartime", "void", ["number", "number"], [point_m, h_m], ); CNCrypto.ccall( "ge_mul8", "void", ["number", "number"], [point2_m, point_m], ); CNCrypto.ccall( "ge_p1p1_to_p3", "void", ["number", "number"], [res_m, point2_m], ); CNCrypto.ccall( "ge_p3_tobytes", "void", ["number", "number"], [res2_m, res_m], ); const res = CNCrypto.HEAPU8.subarray(res2_m, res2_m + KEY_SIZE); CNCrypto._free(h_m); CNCrypto._free(point_m); CNCrypto._free(point2_m); CNCrypto._free(res_m); CNCrypto._free(res2_m); return bintohex(res); } export const hashToPoint = hash_to_ec_2; export function array_hash_to_scalar(array: string[]) { let buf = ""; for (let i = 0; i < array.length; i++) { buf += array[i]; } return hash_to_scalar(buf); }