chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { readFileSync } from 'node:fs';
import { describe, expect, it } from 'vitest';
import { LTHASH_STATE_BYTES, LtHash } from '../src/lthash.js';
const vectors = JSON.parse(
readFileSync(
new URL('../../../test/fixtures/space-vectors.json', import.meta.url),
'utf8',
),
);
const toHex = (/** @type {Uint8Array} */ bytes) =>
Array.from(bytes)
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
describe('LtHash', () => {
it('starts as 2048 zero bytes', () => {
const h = new LtHash();
expect(h.state()).toEqual(new Uint8Array(LTHASH_STATE_BYTES));
expect(h.isEmpty()).toBe(true);
});
it('rejects a state of the wrong length', () => {
expect(() => new LtHash(new Uint8Array(10))).toThrow(/2048/);
});
it('add then remove returns to the zero state', () => {
const h = new LtHash().add('a');
expect(h.isEmpty()).toBe(false);
h.remove('a');
expect(h.isEmpty()).toBe(true);
});
it('is order-independent', async () => {
const a = new LtHash().add('a').add('b');
const b = new LtHash().add('b').add('a');
expect(a.equals(b)).toBe(true);
expect(await a.digest()).toEqual(await b.digest());
});
it('distinguishes different elements', () => {
expect(new LtHash().add('a').equals(new LtHash().add('b'))).toBe(false);
});
it('round-trips through state()', () => {
const h = new LtHash().add('a').add('b');
expect(new LtHash(h.state()).equals(h)).toBe(true);
});
it('matches the reference empty state', async () => {
const h = new LtHash();
expect(toHex(h.state())).toBe(vectors.lthash.empty.stateHex);
expect(toHex(await h.digest())).toBe(vectors.lthash.empty.digestHex);
});
it('matches the reference for single elements', async () => {
for (const c of vectors.lthash.single) {
const h = new LtHash().add(c.element);
expect(toHex(h.state()), c.element).toBe(c.stateHex);
expect(toHex(await h.digest()), c.element).toBe(c.digestHex);
}
});
it('matches the reference for element sets', async () => {
for (const c of vectors.lthash.sets) {
const h = new LtHash();
for (const e of c.elements) h.add(e);
expect(toHex(await h.digest()), c.elements.join(',')).toBe(c.digestHex);
}
});
});