basant307/AI_Governance_Project
048
1/**2 * @license3 * Copyright 2025 Google LLC4 * SPDX-License-Identifier: Apache-2.05 */6 7/**8 * Ed25519 signature verification for standalone update integrity.9 *10 * The release CI signs SHA256SUMS with an Ed25519 private key, producing11 * SHA256SUMS.sig (base64-encoded raw 64-byte signature). This module12 * verifies that signature using the embedded public key.13 *14 * Key generation (one-time):15 * openssl genpkey -algorithm Ed25519 -out release-signing-key.pem16 * openssl pkey -in release-signing-key.pem -pubout -outform DER | base6417 */18 19import { createPublicKey, verify } from 'node:crypto';20 21// Ed25519 public key in DER/SPKI format, base64-encoded.22// Replace this with the production key generated by the release team.23// The corresponding private key must be stored in CI secrets only.24const RELEASE_PUBLIC_KEY_DER_B64 =25 'MCowBQYDK2VwAyEAr9WRFLDauibZQKCe1oKfuFZn6zRMaEkD5+KVqN6mKM4=';26 27/**28 * Verifies an Ed25519 signature over the SHA256SUMS content.29 * @param sha256sumsContent - The raw text of SHA256SUMS30 * @param signatureBase64 - Base64-encoded 64-byte Ed25519 signature31 * @throws if signature is invalid or verification fails32 */33export function verifySignature(34 sha256sumsContent: string,35 signatureBase64: string,36): void {37 const key = createPublicKey({38 key: Buffer.from(RELEASE_PUBLIC_KEY_DER_B64, 'base64'),39 format: 'der',40 type: 'spki',41 });42 43 const signature = Buffer.from(signatureBase64, 'base64');44 if (signature.length !== 64) {45 throw new Error(46 `Invalid signature length: expected 64 bytes, got ${signature.length}`,47 );48 }49 50 const valid = verify(null, Buffer.from(sha256sumsContent), key, signature);51 if (!valid) {52 throw new Error(53 'SHA256SUMS signature verification failed — possible tampering detected',54 );55 }56}57 