ACTIVE
cyphrex-signer-prod-01
Ed25519 signing key ยท Active since 2026-05-06 ยท Public record
Loading key...
Fetch this key
curl https://cyphrex.io/api/keys/cyphrex-signer-prod-01
Build canonical payload + verify (Node.js, v1.0.0)
The full timestamp object is included in the signed payload. Strip only sha256, signature, algorithm, and publicKeyUrl from the downloaded JSON before canonical JSON and verification.
// =============================================================================
// Cyphrex signed report โ build canonical bytes + verify (schemaVersion 1.0.0)
// =============================================================================
// Environment:
// - Node.js 18+ (LTS recommended). Uses only the built-in `crypto` module โ no npm install.
// - Optional: `fs` (also built-in) if you load JSON/PEM from disk; uncomment the example below.
//
// You must define these two values (paste JSON, or use fs.readFileSync โ see comments at bottom):
// const report = ... // full object from POST /v1/events/export-signed
// const publicKeyPem = `...` // PEM from GET https://cyphrex.io/keys/<keyId> (this page)
// =============================================================================
const { createHash, verify, createPublicKey } = require('crypto');
function sortKeysDeep(value) {
if (value === null || typeof value !== 'object') return value;
if (Array.isArray(value)) return value.map(sortKeysDeep);
const out = {};
Object.keys(value)
.sort()
.forEach((k) => {
out[k] = sortKeysDeep(value[k]);
});
return out;
}
function stableStringify(obj) {
return JSON.stringify(sortKeysDeep(obj));
}
function signedReportCoreFromDownload(report) {
const copy = JSON.parse(JSON.stringify(report));
delete copy.sha256;
delete copy.signature;
delete copy.algorithm;
delete copy.publicKeyUrl;
// timestamp.anchor_tx_signature is part of the signed payload, no special exclusion needed.
return copy;
}
// --- Example: load from files (optional) ---
// const fs = require('fs');
// const report = JSON.parse(fs.readFileSync('cyphrex-report.json', 'utf8'));
// const publicKeyPem = fs.readFileSync('cyphrex-public.pem', 'utf8');
// --- Example: inline paste (replace with your real values) ---
// const report = { ... };
// const publicKeyPem = `-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n`;
if (typeof report === 'undefined') throw new Error('Define `report` (see comments at top of this snippet).');
if (typeof publicKeyPem === 'undefined') throw new Error('Define `publicKeyPem` (see comments at top of this snippet).');
const reportContent = stableStringify(signedReportCoreFromDownload(report));
const computedHash = createHash('sha256').update(reportContent, 'utf8').digest('hex');
if (computedHash !== report.sha256) throw new Error('Hash mismatch');
const publicKey = createPublicKey(publicKeyPem);
const isValid = verify(
null, // required for Ed25519
Buffer.from(reportContent, 'utf8'),
publicKey,
Buffer.from(report.signature, 'base64')
);
console.log(isValid ? 'Valid signature' : 'Invalid signature');Verify only (Node.js)
// =============================================================================
// Cyphrex signed report โ verify only (schemaVersion 1.0.0)
// =============================================================================
// Node.js 18+. Built-in `crypto` only โ no npm packages.
//
// You must define:
// canonical โ UTF-8 string: stableStringify(signedReportCoreFromDownload(report))
// (NOT the full downloaded JSON; see the "Build canonical" snippet above.)
// signature โ base64 string from report.signature
// publicKeyPem โ PEM from this registry page
// =============================================================================
const { verify, createPublicKey } = require('crypto');
if (typeof canonical === 'undefined') throw new Error('Define `canonical` (see comments at top of this snippet).');
if (typeof signature === 'undefined') throw new Error('Define `signature` (see comments at top of this snippet).');
if (typeof publicKeyPem === 'undefined') throw new Error('Define `publicKeyPem` (see comments at top of this snippet).');
const publicKey = createPublicKey(publicKeyPem);
const isValid = verify(
null, // null algorithm for Ed25519
Buffer.from(canonical, 'utf8'),
publicKey,
Buffer.from(signature, 'base64')
);
console.log(isValid ? 'Valid signature' : 'Invalid signature');