/** * Node (brittle-node tests / `node index.js`): lazy `require('bare-crypto')` inside try/catch. * `bare-crypto` is Bare-oriented and typically throws under Node; callers still get a boolean. */ import b4a from 'b4a' import path from 'path' import { createRequire } from 'node:module' const require = createRequire(import.meta.url) function loadEd25519PublicKeyCtor() { const pkgJson = require.resolve('bare-crypto/package') const keyModule = path.join(path.dirname(pkgJson), 'lib', 'key.js') return require(keyModule).Ed25519PublicKey } /** * @param {Uint8Array | null | undefined} manifestBytes * @param {Uint8Array | null | undefined} signatureBytes * @param {string} publicKeyHex 64 hex chars (32-byte Ed25519 public key) * @returns {boolean} */ export function verifyBootManifestEd25519(manifestBytes, signatureBytes, publicKeyHex) { if (!manifestBytes?.length || !signatureBytes?.length) return false const hex = String(publicKeyHex || '').trim().toLowerCase().replace(/^0x/, '') if (!/^[0-9a-f]{64}$/.test(hex)) return false /** @type {Uint8Array} */ let sig if (signatureBytes.length === 64) { sig = signatureBytes } else { const t = b4a.toString(signatureBytes, 'utf8').trim() if (/^[0-9a-f]{128}$/i.test(t)) { sig = b4a.from(t, 'hex') } else { try { sig = b4a.from(t, 'base64') } catch { return false } } } if (sig.length !== 64) return false try { const { verify } = require('bare-crypto') const Ed25519PublicKey = loadEd25519PublicKeyCtor() const pub = b4a.from(hex, 'hex') const key = new Ed25519PublicKey(pub) return verify('ed25519', manifestBytes, key, sig) } catch { return false } }