// Telling which Sia account an s3d uses: BLAKE2b-256 against RFC 7693, and // requests signed the way indexd's app API checks them (api/app/auth.go). import test from 'node:test'; import assert from 'node:assert/strict'; import crypto from 'node:crypto'; import { blake2b, blake2b256 } from '../core/blake2b.js'; import { signRequest, fingerprint } from '../core/sia-account.js'; test('BLAKE2b matches RFC 7693 and OpenSSL', () => { assert.equal(blake2b256('').toString('hex'), '0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8'); assert.equal(blake2b('abc', 64).toString('hex'), 'ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923'); for (const n of [1, 127, 128, 129, 255, 256, 257, 1000]) { const b = crypto.randomBytes(n); assert.ok(blake2b(b, 64).equals(crypto.createHash('blake2b512').update(b).digest()), `length ${n}`); } }); test('signed /account request: what indexd verifies', () => { // A Go types.PrivateKey: 32-byte seed followed by the 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]); const sv = 1_900_000_000; const u = signRequest(appKey, 'GET', 'https://sia.storage/account', sv); const q = u.searchParams; // Go's base64.URLEncoding: URL-safe alphabet, with padding. assert.match(q.get('sc'), /^[A-Za-z0-9_-]{43}=$/); assert.match(q.get('ss'), /^[A-Za-z0-9_-]{86}==$/); assert.equal(q.get('sv'), String(sv)); assert.ok(Buffer.from(q.get('sc'), 'base64').equals(pub)); const exp = Buffer.alloc(8); exp.writeBigUInt64LE(BigInt(sv)); const digest = blake2b256(Buffer.concat([Buffer.from('GET'), Buffer.from('sia.storage'), Buffer.from('/account'), exp])); assert.ok(crypto.verify(null, digest, publicKey, Buffer.from(q.get('ss'), 'base64'))); // Host and path come from the indexer URL, port included. const v = signRequest(appKey, 'GET', 'http://127.0.0.1:9880/base/account', sv); const d2 = blake2b256(Buffer.concat([Buffer.from('GET127.0.0.1:9880/base/account'), exp])); assert.ok(crypto.verify(null, d2, publicKey, Buffer.from(v.searchParams.get('ss'), 'base64'))); assert.equal(fingerprint('3cc1a2f2' + '0'.repeat(52) + 'ac52'), 'ed25519:3cc1a2f2…ac52'); });