import { readFileSync } from 'node:fs'; import { describe, expect, it } from 'vitest'; import { blake3 } from '../src/blake3.js'; const vectors = JSON.parse( readFileSync( new URL('../../../test/fixtures/blake3-vectors.json', import.meta.url), 'utf8', ), ); /** Official BLAKE3 vector inputs are the repeating byte pattern i % 251. */ function vectorInput(/** @type {number} */ len) { const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) bytes[i] = i % 251; return bytes; } function toHex(/** @type {Uint8Array} */ bytes) { return Array.from(bytes) .map((b) => b.toString(16).padStart(2, '0')) .join(''); } describe('blake3', () => { it('matches the official vectors at 32-byte output', () => { for (const c of vectors.cases) { const out = blake3(vectorInput(c.input_len), 32); expect(toHex(out), `input_len=${c.input_len}`).toBe(c.hash.slice(0, 64)); } }); it('matches the official vectors at extended output length', () => { for (const c of vectors.cases) { const outLen = c.hash.length / 2; const out = blake3(vectorInput(c.input_len), outLen); expect(toHex(out), `input_len=${c.input_len} outLen=${outLen}`).toBe( c.hash, ); } }); it('produces 2048 bytes for LtHash expansion', () => { const out = blake3(new TextEncoder().encode('a'), 2048); expect(out.length).toBe(2048); }); it('defaults to 32 bytes', () => { expect(blake3(new Uint8Array(0)).length).toBe(32); }); });