"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fileHash = fileHash; exports.hmac = hmac; exports.verificationHash = verificationHash; const blake3_jit_1 = require("@huggingface/blake3-jit"); const xorb_hash_js_1 = require("./xorb-hash.js"); const ZERO_KEY = new Uint8Array(32); const VERIFICATION_KEY = new Uint8Array([ 127, 24, 87, 214, 206, 86, 237, 102, 18, 127, 249, 19, 231, 165, 195, 243, 164, 205, 38, 213, 181, 219, 73, 230, 65, 36, 152, 127, 40, 251, 148, 195, ]); const fileHasher = blake3_jit_1.Hasher.newKeyed(ZERO_KEY); const verificationHasher = blake3_jit_1.Hasher.newKeyed(VERIFICATION_KEY); /** * file_hash = hmac(xorb_hash(chunks), zero_key) * * Matches Rust's `merklehash::file_hash` which calls * `file_hash_with_salt(chunks, &[0; 32])`. */ function fileHash(chunks) { // Empty input short-circuits to the all-zero MerkleHash, matching Rust's // `file_hash_with_salt` (`if chunks.is_empty() { return MerkleHash::default(); }`). // Without this we'd return `hmac(0, zero_key)`, which the CAS shard validation rejects // for empty files with "file reconstruction does not produce this hash". if (chunks.length === 0) { return new Uint8Array(32); } const xorb = (0, xorb_hash_js_1.xorbHash)(chunks); return fileHasher.reset().update(xorb).finalize(32); } /** * HMAC: blake3_keyed_hash(key_bytes, hash_bytes) * * Both inputs are 32-byte Uint8Arrays. * Matches Rust's `DataHash::hmac`. * * Uses a fresh hasher per call since the key varies. */ function hmac(hash, key) { return blake3_jit_1.Hasher.newKeyed(key).update(hash).finalize(32); } /** * Verification hash for a range of chunk hashes. * Concatenates all 32-byte hashes and applies blake3_keyed_hash * with VERIFICATION_KEY. * * Matches Rust's `chunk_verification::range_hash_from_chunks`. */ function verificationHash(chunkHashes) { const combined = new Uint8Array(chunkHashes.length * 32); for (let i = 0; i < chunkHashes.length; i++) { combined.set(chunkHashes[i], i * 32); } return verificationHasher.reset().update(combined).finalize(32); }