@toruslabs/metadata-helpers
Version:
Helper methods for metadata
93 lines (90 loc) • 3.83 kB
JavaScript
import { decrypt, encrypt, getPublic } from '@toruslabs/eccrypto';
import { bytesToUtf8, hexToBytes, utf8ToBytes } from './helpers/bytes.js';
import { getPublicKeyCoords, coordsToPublicKey } from './helpers/utils.js';
import { bytesToHex } from '@noble/curves/utils.js';
const WEBAUTHN_TORUS_SHARE = "webauthn_torus_share";
const WEBAUTHN_DEVICE_SHARE = "webauthn_device_share";
function encParamsHexToBuf(encParamsHex) {
return {
iv: hexToBytes(encParamsHex.iv),
ephemPublicKey: hexToBytes(encParamsHex.ephemPublicKey),
ciphertext: hexToBytes(encParamsHex.ciphertext),
mac: hexToBytes(encParamsHex.mac)
};
}
function encParamsBufToHex(encParams) {
return {
iv: bytesToHex(encParams.iv),
ephemPublicKey: bytesToHex(encParams.ephemPublicKey),
ciphertext: bytesToHex(encParams.ciphertext),
mac: bytesToHex(encParams.mac)
};
}
async function encryptData(privKeyBytes, d) {
const serializedData = utf8ToBytes(JSON.stringify(d));
const encParams = await encrypt(getPublic(privKeyBytes), serializedData);
const encParamsHex = encParamsBufToHex(encParams);
return JSON.stringify(encParamsHex);
}
async function decryptData(privKeyBytes, d) {
const encParamsHex = JSON.parse(d);
const encParams = encParamsHexToBuf(encParamsHex);
const serializedBytes = await decrypt(privKeyBytes, encParams);
const data = JSON.parse(bytesToUtf8(serializedBytes));
return data;
}
async function getAndDecryptData(m, privKeyBytes, namespace) {
const {
x,
y
} = getPublicKeyCoords(privKeyBytes);
const serializedData = await m.getMetadata({
pub_key_X: x,
pub_key_Y: y
}, namespace);
if (!serializedData) {
return null;
}
const data = await decryptData(privKeyBytes, serializedData);
return data;
}
async function encryptAndSetData(m, privKeyBytes, d, namespace) {
const sData = await encryptData(privKeyBytes, d);
const metadataParams = m.generateMetadataParams(sData, privKeyBytes);
await m.setMetadata(metadataParams, namespace);
}
async function setTorusShare(m, webAuthnPubKey, webAuthnRefBytes, subspace, subspaceData) {
const pubKeyBytes = coordsToPublicKey(webAuthnPubKey.pub_key_X, webAuthnPubKey.pub_key_Y);
const data = await getAndDecryptData(m, webAuthnRefBytes, WEBAUTHN_TORUS_SHARE);
let d = {};
if (data) d = data;
const serializedSubspaceData = utf8ToBytes(JSON.stringify(subspaceData));
const encSubspaceData = await encrypt(pubKeyBytes, serializedSubspaceData);
const encSubspaceDataHex = encParamsBufToHex(encSubspaceData);
d[subspace] = encSubspaceDataHex;
await encryptAndSetData(m, webAuthnRefBytes, d, WEBAUTHN_TORUS_SHARE);
}
async function setDeviceShare(m, webAuthnRefBytes, subspace, subspaceData) {
const data = await getAndDecryptData(m, webAuthnRefBytes, WEBAUTHN_DEVICE_SHARE);
let d = {};
if (data) d = data;
d[subspace] = subspaceData;
await encryptAndSetData(m, webAuthnRefBytes, d, WEBAUTHN_DEVICE_SHARE);
}
async function getTorusShare(m, webAuthnKeyBytes, webAuthnRefBytes, subspace) {
const data = await getAndDecryptData(m, webAuthnRefBytes, WEBAUTHN_TORUS_SHARE);
if (!data) return null;
const encParamsHex = data[subspace];
if (!encParamsHex) return null;
const encParams = encParamsHexToBuf(encParamsHex);
const privKeyBytes = webAuthnKeyBytes;
const serializedBytes = await decrypt(privKeyBytes, encParams);
const subspaceData = JSON.parse(bytesToUtf8(serializedBytes));
return subspaceData;
}
async function getDeviceShare(m, webAuthnRefBytes, subspace) {
const data = await getAndDecryptData(m, webAuthnRefBytes, WEBAUTHN_DEVICE_SHARE);
if (data) return data[subspace];
return null;
}
export { decryptData, encParamsBufToHex, encParamsHexToBuf, encryptAndSetData, encryptData, getAndDecryptData, getDeviceShare, getTorusShare, setDeviceShare, setTorusShare };