import { hex } from '@fuman/utils' import { beforeAll, describe, expect, it } from 'vitest' import { __getWasm, createCtr256, ctr256, freeCtr256 } from '../src/index.js' import { initWasm } from './init.js' beforeAll(async () => { await initWasm() }) describe('aes-ctr', () => { const key = hex.decode('603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4') const iv = hex.decode('F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF') describe('NIST', () => { // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf const data = hex.decode( `6BC1BEE2 2E409F96 E93D7E11 7393172A AE2D8A57 1E03AC9C 9EB76FAC 45AF8E51 30C81C46 A35CE411 E5FBC119 1A0A52EF F69F2445 DF4F9B17 AD2B417B E66C3710`.replace(/\s/g, ''), ) const dataEnc = hex.decode( `601EC313 775789A5 B7A7F504 BBF3D228 F443E3CA 4D62B59A CA84E990 CACAF5C5 2B0930DA A23DE94C E87017BA 2D84988D DFC9C58D B67AADA6 13C2DD08 457941A6`.replace(/\s/g, ''), ) it('should correctly encrypt', () => { const ctr = createCtr256(key, iv) const res = ctr256(ctr, data) freeCtr256(ctr) expect(hex.encode(res)).toEqual(hex.encode(dataEnc)) }) it('should correctly decrypt', () => { const ctr = createCtr256(key, iv) const res = ctr256(ctr, dataEnc) freeCtr256(ctr) expect(hex.encode(res)).toEqual(hex.encode(data)) }) }) describe('stream', () => { const data = hex.decode('6BC1BEE22E409F96E93D7E117393172A') const dataEnc1 = hex.decode('601ec313775789a5b7a7f504bbf3d228') const dataEnc2 = hex.decode('31afd77f7d218690bd0ef82dfcf66cbe') const dataEnc3 = hex.decode('7000927e2f2192cbe4b6a8b2441ddd48') it('should correctly encrypt', () => { const ctr = createCtr256(key, iv) const res1 = ctr256(ctr, data) const res2 = ctr256(ctr, data) const res3 = ctr256(ctr, data) freeCtr256(ctr) expect(hex.encode(res1)).toEqual(hex.encode(dataEnc1)) expect(hex.encode(res2)).toEqual(hex.encode(dataEnc2)) expect(hex.encode(res3)).toEqual(hex.encode(dataEnc3)) }) it('should correctly decrypt', () => { const ctr = createCtr256(key, iv) const res1 = ctr256(ctr, dataEnc1) const res2 = ctr256(ctr, dataEnc2) const res3 = ctr256(ctr, dataEnc3) freeCtr256(ctr) expect(hex.encode(res1)).toEqual(hex.encode(data)) expect(hex.encode(res2)).toEqual(hex.encode(data)) expect(hex.encode(res3)).toEqual(hex.encode(data)) }) }) describe('stream (unaligned)', () => { const data = hex.decode('6BC1BEE22E40') const dataEnc1 = hex.decode('601ec3137757') const dataEnc2 = hex.decode('7df2e078a555') const dataEnc3 = hex.decode('a3a17be0742e') const dataEnc4 = hex.decode('025ced833746') const dataEnc5 = hex.decode('3ff238dea125') const dataEnc6 = hex.decode('1055a52302dc') it('should correctly encrypt', () => { const ctr = createCtr256(key, iv) const res1 = ctr256(ctr, data) const res2 = ctr256(ctr, data) const res3 = ctr256(ctr, data) const res4 = ctr256(ctr, data) const res5 = ctr256(ctr, data) const res6 = ctr256(ctr, data) freeCtr256(ctr) expect(hex.encode(res1)).toEqual(hex.encode(dataEnc1)) expect(hex.encode(res2)).toEqual(hex.encode(dataEnc2)) expect(hex.encode(res3)).toEqual(hex.encode(dataEnc3)) expect(hex.encode(res4)).toEqual(hex.encode(dataEnc4)) expect(hex.encode(res5)).toEqual(hex.encode(dataEnc5)) expect(hex.encode(res6)).toEqual(hex.encode(dataEnc6)) }) it('should correctly decrypt', () => { const ctr = createCtr256(key, iv) const res1 = ctr256(ctr, dataEnc1) const res2 = ctr256(ctr, dataEnc2) const res3 = ctr256(ctr, dataEnc3) const res4 = ctr256(ctr, dataEnc4) const res5 = ctr256(ctr, dataEnc5) const res6 = ctr256(ctr, dataEnc6) freeCtr256(ctr) expect(hex.encode(res1)).toEqual(hex.encode(data)) expect(hex.encode(res2)).toEqual(hex.encode(data)) expect(hex.encode(res3)).toEqual(hex.encode(data)) expect(hex.encode(res4)).toEqual(hex.encode(data)) expect(hex.encode(res5)).toEqual(hex.encode(data)) expect(hex.encode(res6)).toEqual(hex.encode(data)) }) }) it('should not leak memory', () => { const data = hex.decode('6BC1BEE22E409F96E93D7E117393172A') const mem = __getWasm().memory.buffer const memSize = mem.byteLength for (let i = 0; i < 100; i++) { const ctrEnc = createCtr256(key, iv) const ctrDec = createCtr256(key, iv) for (let i = 0; i < 100; i++) { ctr256(ctrDec, ctr256(ctrEnc, data)) } freeCtr256(ctrEnc) freeCtr256(ctrDec) } expect(mem.byteLength).toEqual(memSize) }) })