@toruslabs/metadata-helpers
Version:
Helper methods for metadata
103 lines (100 loc) • 4.54 kB
JavaScript
import { encrypt, getPublic, decrypt } from '@toruslabs/eccrypto';
import { ec } from './utils.js';
const WEBAUTHN_TORUS_SHARE = "webauthn_torus_share";
const WEBAUTHN_DEVICE_SHARE = "webauthn_device_share";
function encParamsHexToBuf(encParamsHex) {
return {
iv: Buffer.from(encParamsHex.iv, "hex"),
ephemPublicKey: Buffer.from(encParamsHex.ephemPublicKey, "hex"),
ciphertext: Buffer.from(encParamsHex.ciphertext, "hex"),
mac: Buffer.from(encParamsHex.mac, "hex")
};
}
function encParamsBufToHex(encParams) {
return {
iv: Buffer.from(encParams.iv).toString("hex"),
ephemPublicKey: Buffer.from(encParams.ephemPublicKey).toString("hex"),
ciphertext: Buffer.from(encParams.ciphertext).toString("hex"),
mac: Buffer.from(encParams.mac).toString("hex")
};
}
async function encryptData(privKeyHex, d) {
const serializedDec = JSON.stringify(d);
const serializedBuf = Buffer.from(serializedDec, "utf-8");
const encParams = await encrypt(getPublic(Buffer.from(privKeyHex, "hex")), serializedBuf);
const encParamsHex = encParamsBufToHex(encParams);
const sData = JSON.stringify(encParamsHex);
return sData;
}
async function decryptData(privKeyHex, d) {
const encParamsHex = JSON.parse(d);
const encParams = encParamsHexToBuf(encParamsHex);
const keyPair = ec.keyFromPrivate(privKeyHex);
const serializedBuf = await decrypt(Buffer.from(keyPair.getPrivate().toString("hex", 64), "hex"), encParams);
const serializedDec = serializedBuf.toString("utf-8");
const data = JSON.parse(serializedDec);
return data;
}
async function getAndDecryptData(m, privKeyHex, namespace) {
const keyPair = ec.keyFromPrivate(privKeyHex, "hex");
const pubKey = keyPair.getPublic();
const serializedData = await m.getMetadata({
pub_key_X: pubKey.getX().toString(16, 64),
pub_key_Y: pubKey.getY().toString(16, 64)
}, namespace);
if (!serializedData) {
return null;
}
const data = await decryptData(privKeyHex, serializedData);
return data;
}
async function encryptAndSetData(m, privKeyHex, d, namespace) {
const sData = await encryptData(privKeyHex, d);
const metadataParams = m.generateMetadataParams(sData, privKeyHex);
await m.setMetadata(metadataParams, namespace);
}
async function setTorusShare(m, webAuthnPubKey, webAuthnRefHex, subspace, subspaceData) {
const refKeyPair = ec.keyFromPrivate(webAuthnRefHex);
const privKey = refKeyPair.getPrivate();
const pubKey = ec.keyFromPublic({
x: webAuthnPubKey.pub_key_X,
y: webAuthnPubKey.pub_key_Y
});
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_TORUS_SHARE);
let d = {};
if (data) d = data;
const serializedSubspaceData = JSON.stringify(subspaceData);
const serializedSubspaceDataBuf = Buffer.from(serializedSubspaceData, "utf-8");
const encSubspaceData = await encrypt(Buffer.from(pubKey.getPublic("hex"), "hex"), serializedSubspaceDataBuf);
const encSubspaceDataHex = encParamsBufToHex(encSubspaceData);
d[subspace] = encSubspaceDataHex;
await encryptAndSetData(m, privKey.toString("hex", 64), d, WEBAUTHN_TORUS_SHARE);
}
async function setDeviceShare(m, webAuthnRefHex, subspace, subspaceData) {
const keyPair = ec.keyFromPrivate(webAuthnRefHex);
const privKey = keyPair.getPrivate();
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_DEVICE_SHARE);
let d = {};
if (data) d = data;
d[subspace] = subspaceData;
await encryptAndSetData(m, privKey.toString("hex", 64), d, WEBAUTHN_DEVICE_SHARE);
}
async function getTorusShare(m, webAuthnKeyHex, webAuthnRefHex, subspace) {
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_TORUS_SHARE);
if (!data) return null;
const encParamsHex = data[subspace];
if (!encParamsHex) return null;
const encParams = encParamsHexToBuf(encParamsHex);
const keyPair = ec.keyFromPrivate(webAuthnKeyHex);
const privKey = keyPair.getPrivate();
const serializedSubspaceDataBuf = await decrypt(Buffer.from(privKey.toString("hex", 64), "hex"), encParams);
const serializedSubspaceData = serializedSubspaceDataBuf.toString("utf-8");
const subspaceData = JSON.parse(serializedSubspaceData);
return subspaceData;
}
async function getDeviceShare(m, webAuthnRefHex, subspace) {
const data = await getAndDecryptData(m, webAuthnRefHex, WEBAUTHN_DEVICE_SHARE);
if (data) return data[subspace];
return null;
}
export { decryptData, encParamsBufToHex, encParamsHexToBuf, encryptAndSetData, encryptData, getAndDecryptData, getDeviceShare, getTorusShare, setDeviceShare, setTorusShare };