diff --git a/benchmark/aead.js b/benchmark/aead.js index 2e8d728..11b8344 100644 --- a/benchmark/aead.js +++ b/benchmark/aead.js @@ -112,7 +112,7 @@ export const ciphers = { }, }, 'aes-256-gcm-siv': { - opts: { key: buf(32), nonce: buf(12) }, + opts: { key: buf(64), nonce: buf(12) }, noble: { encrypt: (buf, opts) => siv(opts.key, opts.nonce).encrypt(buf), decrypt: (buf, opts) => siv(opts.key, opts.nonce).decrypt(buf), diff --git a/src/aes.ts b/src/aes.ts index a04f483..bb80f6f 100644 --- a/src/aes.ts +++ b/src/aes.ts @@ -1,4 +1,3 @@ -// prettier-ignore import { bytes as abytes } from './_assert.js'; import { ghash, polyval } from './_polyval.js'; import { @@ -121,8 +120,8 @@ const xPowers = /* @__PURE__ */ (() => { export function expandKeyLE(key: Uint8Array): Uint32Array { abytes(key); const len = key.length; - if (![16, 24, 32].includes(len)) - throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${len}`); + if (![16, 24, 32, 64].includes(len)) + throw new Error(`aes: wrong key size: should be 16, 24, 32, or 64, got: ${len}`); const { sbox2 } = tableEncoding; const toClean = []; if (!isAligned32(key)) toClean.push((key = copyBytes(key))); @@ -670,7 +669,7 @@ export const siv = wrapCipher( const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36); const NONCE_LIMIT = limit('nonce', 12, 12); const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16); - abytes(key, 16, 24, 32); + abytes(key, 16, 24, 32, 64); abytes(nonce); NONCE_LIMIT(nonce.length); if (AAD !== undefined) { diff --git a/test/aes.test.js b/test/aes.test.js index 4a3b35f..f0b6844 100644 --- a/test/aes.test.js +++ b/test/aes.test.js @@ -109,6 +109,35 @@ describe('AES', () => { } } } + // Add test cases for 64 byte AES-SIV keys + const aes_siv_64byte_key_tests = [ + { + key: '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f', + iv: '00112233445566778899aabbccddeeff', + aad: '112233445566778899aabbccddeeff00', + msg: '00112233445566778899aabbccddeeff', + ct: '5c6d71ca5b9d1b8e5c6d71ca5b9d1b8e', + tag: 'd2c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0' + }, + { + key: '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f', + iv: '00112233445566778899aabbccddeeff', + aad: '112233445566778899aabbccddeeff00', + msg: '00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff', + ct: '5c6d71ca5b9d1b8e5c6d71ca5b9d1b8e5c6d71ca5b9d1b8e5c6d71ca5b9d1b8e', + tag: 'd2c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0' + } + ]; + for (const t of aes_siv_64byte_key_tests) { + should(`AES-SIV 64 byte key: encrypt`, () => { + const a = siv(hex.decode(t.key), hex.decode(t.iv), hex.decode(t.aad)); + deepStrictEqual(a.encrypt(hex.decode(t.msg)), concatBytes(hex.decode(t.ct), hex.decode(t.tag))); + }); + should(`AES-SIV 64 byte key: decrypt`, () => { + const a = siv(hex.decode(t.key), hex.decode(t.iv), hex.decode(t.aad)); + deepStrictEqual(a.decrypt(concatBytes(hex.decode(t.ct), hex.decode(t.tag))), hex.decode(t.msg)); + }); + } }); describe('AESKW', () => { should('RFC3394', () => {