import { describe, expect, it } from 'vitest'; import { decapsulate, encapsulate, uncompressedKey } from '../src/kem.js'; import { SpaceMacError } from '../src/mac.js'; import { makeKemKey } from './helpers/kem.js'; import { fromHex, toHex, vectors } from './helpers/vectors.js'; describe('KEM', () => { it('derives the reference shared secret from its key share', async () => { const secret = await decapsulate( fromHex(vectors.kem.authorPrivateKeyHex), vectors.kem.keyShare, ); expect(toHex(secret)).toBe(vectors.kem.sharedSecretHex); }); it('derives the same secret on both sides', async () => { const author = await makeKemKey(); const { keyShare, sharedSecret } = await encapsulate(author.didKey); expect(sharedSecret).toHaveLength(32); expect(await decapsulate(author.privateKey, keyShare)).toEqual( sharedSecret, ); }); it('uses a fresh key share per encapsulation', async () => { const { didKey } = await makeKemKey(); const a = await encapsulate(didKey); const b = await encapsulate(didKey); expect(a.keyShare).not.toBe(b.keyShare); expect(a.sharedSecret).not.toEqual(b.sharedSecret); }); it('derives a different secret under a different author key', async () => { const author = await makeKemKey(); const other = await makeKemKey(); const { keyShare, sharedSecret } = await encapsulate(author.didKey); expect(await decapsulate(other.privateKey, keyShare)).not.toEqual( sharedSecret, ); }); it('decompresses both parities of y', async () => { for (let i = 0; i < 8; i++) { const { didKey } = await makeKemKey(); const key = uncompressedKey(didKey); expect(key).toHaveLength(65); expect(key[0]).toBe(4); } }); it('rejects a key that is not P-256', async () => { const k256 = 'did:key:zQ3shokFTS3brHcDQrn82RUDfCZESWL1ZdCEJwekUDPQiYBme'; await expect(encapsulate(k256)).rejects.toThrow(SpaceMacError); const author = await makeKemKey(); await expect(decapsulate(author.privateKey, k256)).rejects.toThrow( SpaceMacError, ); await expect( decapsulate(author.privateKey, 'did:key:nope'), ).rejects.toThrow(SpaceMacError); }); it('refuses a private key of the wrong length', async () => { await expect( decapsulate(new Uint8Array(31), vectors.kem.keyShare), ).rejects.toThrow(/32 bytes/); }); });