@gandlaf21/cashu-crypto
Version:
Basic cashu crypto functions
83 lines • 3.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.deriveKeysetId = exports.deserializeMintKeys = exports.serializeMintKeys = exports.createRandomPrivateKey = exports.getKeysetIdInt = exports.pointFromHex = exports.hashToCurve = void 0;
const secp256k1_1 = require("@noble/curves/secp256k1");
const sha256_1 = require("@noble/hashes/sha256");
const utils_1 = require("@noble/curves/abstract/utils");
const utils_js_1 = require("../util/utils.js");
const DOMAIN_SEPARATOR = (0, utils_1.hexToBytes)('536563703235366b315f48617368546f43757276655f43617368755f');
function hashToCurve(secret) {
const msgToHash = (0, sha256_1.sha256)(Buffer.concat([DOMAIN_SEPARATOR, secret]));
const counter = new Uint32Array(1);
const maxIterations = 2 ** 16;
for (let i = 0; i < maxIterations; i++) {
const counterBytes = new Uint8Array(counter.buffer);
const hash = (0, sha256_1.sha256)(Buffer.concat([msgToHash, counterBytes]));
try {
return pointFromHex((0, utils_1.bytesToHex)(Buffer.concat([new Uint8Array([0x02]), hash])));
}
catch (error) {
counter[0]++;
}
}
throw new Error('No valid point found');
}
exports.hashToCurve = hashToCurve;
function pointFromHex(hex) {
return secp256k1_1.secp256k1.ProjectivePoint.fromHex(hex);
}
exports.pointFromHex = pointFromHex;
const getKeysetIdInt = (keysetId) => {
let keysetIdInt;
if (/^[a-fA-F0-9]+$/.test(keysetId)) {
keysetIdInt = (0, utils_js_1.hexToNumber)(keysetId) % BigInt(2 ** 31 - 1);
}
else {
//legacy keyset compatibility
keysetIdInt = (0, utils_js_1.bytesToNumber)((0, utils_js_1.encodeBase64toUint8)(keysetId)) % BigInt(2 ** 31 - 1);
}
return keysetIdInt;
};
exports.getKeysetIdInt = getKeysetIdInt;
function createRandomPrivateKey() {
return secp256k1_1.secp256k1.utils.randomPrivateKey();
}
exports.createRandomPrivateKey = createRandomPrivateKey;
function serializeMintKeys(mintKeys) {
const serializedMintKeys = {};
Object.keys(mintKeys).forEach((p) => {
serializedMintKeys[p] = (0, utils_1.bytesToHex)(mintKeys[p]);
});
return serializedMintKeys;
}
exports.serializeMintKeys = serializeMintKeys;
function deserializeMintKeys(serializedMintKeys) {
const mintKeys = {};
Object.keys(serializedMintKeys).forEach((p) => {
mintKeys[p] = (0, utils_1.hexToBytes)(serializedMintKeys[p]);
});
return mintKeys;
}
exports.deserializeMintKeys = deserializeMintKeys;
function deriveKeysetId(keys) {
const KEYSET_VERSION = '00';
const mapBigInt = (k) => {
return [BigInt(k[0]), k[1]];
};
const pubkeysConcat = Object.entries(serializeMintKeys(keys))
.map(mapBigInt)
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
.map(([, pubKey]) => (0, utils_1.hexToBytes)(pubKey)).reduce((prev, curr) => mergeUInt8Arrays(prev, curr), new Uint8Array());
const hash = (0, sha256_1.sha256)(pubkeysConcat);
const hashHex = Buffer.from(hash).toString('hex').slice(0, 14);
return '00' + hashHex;
}
exports.deriveKeysetId = deriveKeysetId;
function mergeUInt8Arrays(a1, a2) {
// sum of individual array lengths
const mergedArray = new Uint8Array(a1.length + a2.length);
mergedArray.set(a1);
mergedArray.set(a2, a1.length);
return mergedArray;
}
//# sourceMappingURL=index.js.map