// The indexer signs requests with BLAKE2b-256 + Ed25519 (indexd api/app); // a wrong hash or key layout fails with "invalid signature" at the indexer. import test from 'node:test'; import assert from 'node:assert/strict'; import crypto from 'node:crypto'; import { blake2b256, signIndexerUrl } from '../core/space.js'; test('BLAKE2b-256 matches the RFC 7693 / reference vectors', () => { const h = (s) => blake2b256(Buffer.from(s)).toString('hex'); assert.equal(h(''), '0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8'); assert.equal(h('abc'), 'bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319'); // multi-block inputs (reference: Python hashlib.blake2b(digest_size=32)) assert.equal(h('a'.repeat(128)), 'ae2aa48507885c4c950fb809b2076f959cde9f8ea6da260d9a3587df33dac450'); assert.equal(h('a'.repeat(129)), '2f64744a6de0d2c0b56e64cf6e29a5aaa255010d415d51c75ccc82f73dccd865'); }); test('signed indexer URL carries sv/sc/ss and verifies against the app public key', () => { const { privateKey, publicKey } = crypto.generateKeyPairSync('ed25519'); const seed = privateKey.export({ format: 'der', type: 'pkcs8' }).subarray(-32); const pub = publicKey.export({ format: 'der', type: 'spki' }).subarray(-32); const appKey = Buffer.concat([seed, pub]); // Sia layout: seed || public key const u = signIndexerUrl(appKey, 'GET', 'https://sia.storage/account', 1_800_000_000); const unb64 = (s) => Buffer.from(s.replace(/-/g, '+').replace(/_/g, '/'), 'base64'); assert.equal(u.searchParams.get('sv'), '1800000000'); assert.deepEqual(unb64(u.searchParams.get('sc')), pub); const until = Buffer.alloc(8); until.writeBigUInt64LE(1_800_000_000n); const hash = blake2b256(Buffer.concat([Buffer.from('GET'), Buffer.from('sia.storage'), Buffer.from('/account'), until])); assert.ok(crypto.verify(null, hash, publicKey, unb64(u.searchParams.get('ss')))); });