diff --git a/README.md b/README.md index 0769365..914e48f 100644 --- a/README.md +++ b/README.md @@ -299,23 +299,20 @@ of a random function. See [RFC draft](https://datatracker.ietf.org/doc/draft-irt For non-deterministic (not ECB) schemes, initialization vector (IV) is mixed to block/key; and each new round either depends on previous block's key, or on some counter. -As for block modes: we only expose GCM & SIV for now. - - ECB — simple deterministic replacement. Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/) - CBC — key is previous round’s block. Hard to use: need proper padding, also needs MAC - CTR — counter, allows to create streaming cipher. Requires good IV. Parallelizable. OK, but no MAC -- GCM — modern CTR, parallel, with MAC. Not ideal: - - Conservative key wear-out is `2**32` (4B) msgs - - MAC can be forged: see Poly1305 section above -- SIV — synthetic initialization vector, nonce-misuse-resistant - - Can be 1.5-2x slower than GCM by itself - - nonce misuse-resistant schemes guarantee that if a - nonce repeats, then the only security loss is that identical - plaintexts will produce identical ciphertexts - - MAC can be forged: see Poly1305 section above +- GCM — modern CTR, parallel, with MAC +- SIV — synthetic initialization vector, nonce-misuse-resistant, 1.5-2x slower than GCM. + Guarantees that, when a nonce is repeated, the only security loss is that identical + plaintexts will produce identical ciphertexts. - XTS — used in hard drives. Similar to ECB (deterministic), but has `[i][j]` tweak arguments corresponding to sector i and 16-byte block (part of sector) j. Not authenticated! +GCM / SIV are not ideal: + - Conservative key wear-out is `2**32` (4B) msgs + - MAC can be forged: see Poly1305 section above. Same for SIV + ## Security The library has not been independently audited yet. @@ -369,19 +366,27 @@ Benchmark results on Apple M2 with node v20: encrypt (64B) ├─xsalsa20poly1305 x 484,966 ops/sec @ 2μs/op ├─chacha20poly1305 x 442,282 ops/sec @ 2μs/op -└─xchacha20poly1305 x 300,842 ops/sec @ 3μs/op +├─xchacha20poly1305 x 300,842 ops/sec @ 3μs/op +├─aes-gcm-256 x 93,144 ops/sec @ 10μs/op +└─aes-gcm-siv-256 x 79,339 ops/sec @ 12μs/op encrypt (1KB) ├─xsalsa20poly1305 x 143,905 ops/sec @ 6μs/op ├─chacha20poly1305 x 141,663 ops/sec @ 7μs/op -└─xchacha20poly1305 x 122,639 ops/sec @ 8μs/op +├─xchacha20poly1305 x 122,639 ops/sec @ 8μs/op +├─aes-gcm-256 x 25,685 ops/sec @ 38μs/op +└─aes-gcm-siv-256 x 24,762 ops/sec @ 40μs/op encrypt (8KB) ├─xsalsa20poly1305 x 23,373 ops/sec @ 42μs/op ├─chacha20poly1305 x 23,683 ops/sec @ 42μs/op -└─xchacha20poly1305 x 23,066 ops/sec @ 43μs/op +├─xchacha20poly1305 x 23,066 ops/sec @ 43μs/op +├─aes-gcm-256 x 4,067 ops/sec @ 245μs/op +└─aes-gcm-siv-256 x 4,128 ops/sec @ 242μs/op encrypt (1MB) ├─xsalsa20poly1305 x 193 ops/sec @ 5ms/op ├─chacha20poly1305 x 196 ops/sec @ 5ms/op -└─xchacha20poly1305 x 195 ops/sec @ 5ms/op +├─xchacha20poly1305 x 195 ops/sec @ 5ms/op +├─aes-gcm-256 x 33 ops/sec @ 30ms/op +└─aes-gcm-siv-256 x 33 ops/sec @ 29ms/op ``` Unauthenticated encryption: @@ -407,6 +412,24 @@ encrypt (1MB) ├─chacha x 474 ops/sec @ 2ms/op ├─xsalsa x 466 ops/sec @ 2ms/op └─xchacha x 476 ops/sec @ 2ms/op + +AES +encrypt (64B) +├─ctr-256 x 689,179 ops/sec @ 1μs/op +├─cbc-256 x 639,795 ops/sec @ 1μs/op +└─ecb-256 x 668,449 ops/sec @ 1μs/op +encrypt (1KB) +├─ctr-256 x 93,668 ops/sec @ 10μs/op +├─cbc-256 x 94,428 ops/sec @ 10μs/op +└─ecb-256 x 151,699 ops/sec @ 6μs/op +encrypt (8KB) +├─ctr-256 x 13,342 ops/sec @ 74μs/op +├─cbc-256 x 13,664 ops/sec @ 73μs/op +└─ecb-256 x 22,426 ops/sec @ 44μs/op +encrypt (1MB) +├─ctr-256 x 106 ops/sec @ 9ms/op +├─cbc-256 x 109 ops/sec @ 9ms/op +└─ecb-256 x 179 ops/sec @ 5ms/op ``` Compare to other implementations: @@ -414,20 +437,27 @@ Compare to other implementations: ``` xsalsa20poly1305 (encrypt, 1MB) ├─tweetnacl x 108 ops/sec @ 9ms/op -├─noble x 190 ops/sec @ 5ms/op -└─micro x 21 ops/sec @ 47ms/op +└─noble x 190 ops/sec @ 5ms/op chacha20poly1305 (encrypt, 1MB) ├─node x 1,360 ops/sec @ 735μs/op ├─stablelib x 117 ops/sec @ 8ms/op -├─noble x 193 ops/sec @ 5ms/op -└─micro x 19 ops/sec @ 50ms/op +└─noble x 193 ops/sec @ 5ms/op chacha (encrypt, 1MB) ├─node x 2,035 ops/sec @ 491μs/op ├─stablelib x 206 ops/sec @ 4ms/op -├─noble x 474 ops/sec @ 2ms/op -└─micro x 61 ops/sec @ 16ms/op +└─noble x 474 ops/sec @ 2ms/op + +ctr-256 (encrypt, 64B) +├─node x 640,204 ops/sec @ 1μs/op ± 1.67% (min: 1μs, max: 1ms) +├─stablelib x 484,261 ops/sec @ 2μs/op +└─noble x 685,871 ops/sec @ 1μs/op + +cbc-256 (encrypt, 64B) +├─node x 549,450 ops/sec @ 1μs/op ± 2.47% (min: 1μs, max: 3ms) +├─stablelib x 407,166 ops/sec @ 2μs/op ± 1.02% (min: 2μs, max: 3ms) +└─noble x 616,142 ops/sec @ 1μs/op ± 1.19% (min: 1μs, max: 2ms) ``` ## Contributing & testing diff --git a/benchmark/_utils.js b/benchmark/_utils.js index 9f6bfcb..d3d836b 100644 --- a/benchmark/_utils.js +++ b/benchmark/_utils.js @@ -16,6 +16,8 @@ export async function crossValidate(buffers, ciphers) { const b = buf.slice(); // ciphers for (let [k, libs] of Object.entries(ciphers)) { + // Skip some buffers for block ciphers without padding + if (libs.opts.blockSize && b.length % libs.opts.blockSize) continue; let encrypted; for (const [lib, fn] of Object.entries(libs)) { if (lib === 'opts') continue; diff --git a/benchmark/aes.js b/benchmark/aes.js index e807f38..9010f93 100644 --- a/benchmark/aes.js +++ b/benchmark/aes.js @@ -1,16 +1,25 @@ import { utils as butils } from 'micro-bmark'; import { createCipheriv, createDecipheriv } from 'node:crypto'; -import { aes_256_gcm } from '@noble/ciphers/webcrypto/aes'; -// import { aes_256_gcm_siv } from '@noble/ciphers/webcrypto/siv'; +import { aes_256_gcm, aes_128_gcm } from '@noble/ciphers/webcrypto/aes'; import { concatBytes } from '@noble/ciphers/utils'; -import { crossValidate, onlyNoble, buf } from './_utils.js'; +import * as aes from '@noble/ciphers/aes'; +import { + crossValidate, + onlyNoble, + buf, + benchmarkAllLibraries, + benchmarkOnlyNoble, +} from './_utils.js'; +import { CTR as STABLE_CTR } from '@stablelib/ctr'; +import { AES as STABLE_AES } from '@stablelib/aes'; +import { GCM as STABLE_GCM } from '@stablelib/gcm'; // Works for gcm only? const nodeGCM = (name) => { return { encrypt: (buf, opts) => { - const res = [opts.iv]; + const res = []; const c = createCipheriv(name, opts.key, opts.iv); if (opts.aad) c.setAAD(opts.aad); res.push(c.update(buf)); @@ -19,7 +28,7 @@ const nodeGCM = (name) => { return concatBytes(...res.map((i) => Uint8Array.from(i))); }, decrypt: (buf, opts) => { - const ciphertext = buf.slice(12, -16); + const ciphertext = buf.slice(0, -16); const authTag = buf.slice(-16); const decipher = createDecipheriv(name, opts.key, opts.iv); if (opts.aad) c.setAAD(opts.aad); @@ -31,51 +40,267 @@ const nodeGCM = (name) => { }; }; -const cipherSame = (fn) => ({ encrypt: fn, decrypt: fn }); +const nodeAES = (name, pcks7 = true) => { + return { + encrypt: (buf, opts) => { + const res = []; + const c = createCipheriv(name, opts.key, opts.iv); + c.setAutoPadding(pcks7); // disable pkcs7Padding + res.push(c.update(buf)); + res.push(c.final()); + return concatBytes(...res.map((i) => Uint8Array.from(i))); + }, + decrypt: (buf, opts) => { + const ciphertext = buf.slice(); + const c = createDecipheriv(name, opts.key, opts.iv); + c.setAutoPadding(pcks7); // disable pkcs7Padding + return concatBytes(...[c.update(ciphertext), c.final()].map((i) => Uint8Array.from(i))); + }, + }; +}; + +// Stablellib doesn't support, so we create simple version +const stableCBC = { + encrypt: (buf, opts) => { + const c = new STABLE_AES(opts.key); + let left = c.blockSize - (buf.length % c.blockSize); + if (!left) left = c.blockSize; + const out = new Uint8Array(buf.length + left); + let prev = opts.iv.slice(); + let b = buf, + o = out; + while (b.length) { + for (let i = 0; i < c.blockSize; i++) prev[i] ^= b[i]; + if (b.length < c.blockSize) break; + c.encryptBlock(prev, prev); + o.set(prev, 0); + b = b.subarray(c.blockSize); + o = o.subarray(c.blockSize); + } + // pcks7 padding + for (let i = c.blockSize - left; i < c.blockSize; i++) prev[i] ^= left; + c.encryptBlock(prev, o); + return out; + }, + decrypt: (buf, opts) => { + const c = new STABLE_AES(opts.key); + let prev = opts.iv.slice(); + const out = new Uint8Array(buf.length); + let b = buf, + o = out; + while (b.length) { + let pad = prev; + prev = b; + c.decryptBlock(b, o); + for (let i = 0; i < c.blockSize; i++) o[i] ^= pad[i]; + b = b.subarray(c.blockSize); + o = o.subarray(c.blockSize); + } + // strip pcks7 padding + return out.subarray(0, -out[out.length - 1]); + }, +}; +const stableECB = { + encrypt: (buf, opts) => { + const c = new STABLE_AES(opts.key); + let left = c.blockSize - (buf.length % c.blockSize); + if (!left) left = c.blockSize; + const out = new Uint8Array(buf.length + left); + let b = buf, + o = out; + while (b.length) { + if (b.length < c.blockSize) break; + c.encryptBlock(b, o); + b = b.subarray(c.blockSize); + o = o.subarray(c.blockSize); + } + // pcks7 padding + for (let i = 0; i < b.length; i++) o[i] = b[i]; + for (let i = c.blockSize - left; i < c.blockSize; i++) o[i] = left; + c.encryptBlock(o, o); + return out; + }, + decrypt: (buf, opts) => { + const c = new STABLE_AES(opts.key); + const out = new Uint8Array(buf.length); + let b = buf, + o = out; + while (b.length) { + c.decryptBlock(b, o); + b = b.subarray(c.blockSize); + o = o.subarray(c.blockSize); + } + // strip pcks7 padding + return out.subarray(0, -out[out.length - 1]); + }, +}; + +const stableCTR = { + encrypt: (buf, opts) => { + const cipher = new STABLE_AES(opts.key); + const ctr = new STABLE_CTR(cipher, opts.iv); + const res = new Uint8Array(buf.length); + ctr.streamXOR(buf, res); + return res; + }, + decrypt: (buf, opts) => { + const cipher = new STABLE_AES(opts.key); + const ctr = new STABLE_CTR(cipher, opts.iv); + const res = new Uint8Array(buf.length); + ctr.streamXOR(buf, res); + return res; + }, +}; export const CIPHERS = { - // TODO: why this is so slow? + 'ctr-128': { + opts: { key: buf(16), iv: buf(16) }, + node: nodeAES('aes-128-ctr'), + stablelib: stableCTR, + noble: { + encrypt: (buf, opts) => aes.ctr(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.ctr(opts.key, opts.iv).decrypt(buf), + }, + }, + 'ctr-256': { + opts: { key: buf(32), iv: buf(16) }, + node: nodeAES('aes-256-ctr'), + stablelib: stableCTR, + noble: { + encrypt: (buf, opts) => aes.ctr(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.ctr(opts.key, opts.iv).decrypt(buf), + }, + }, + 'cbc-128': { + opts: { key: buf(16), iv: buf(16) }, + node: nodeAES('aes-128-cbc'), + stablelib: stableCBC, + noble: { + encrypt: (buf, opts) => aes.cbc(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.cbc(opts.key, opts.iv).decrypt(buf), + }, + }, + 'cbc-256': { + opts: { key: buf(32), iv: buf(16) }, + node: nodeAES('aes-256-cbc'), + stablelib: stableCBC, + noble: { + encrypt: (buf, opts) => aes.cbc(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.cbc(opts.key, opts.iv).decrypt(buf), + }, + }, + 'ecb-128': { + opts: { key: buf(16), iv: null }, + node: nodeAES('aes-128-ecb'), + stablelib: stableECB, + noble: { + encrypt: (buf, opts) => aes.ecb(opts.key).encrypt(buf), + decrypt: (buf, opts) => aes.ecb(opts.key).decrypt(buf), + }, + }, + 'ecb-256': { + opts: { key: buf(32), iv: null }, + node: nodeAES('aes-256-ecb'), + stablelib: stableECB, + noble: { + encrypt: (buf, opts) => aes.ecb(opts.key).encrypt(buf), + decrypt: (buf, opts) => aes.ecb(opts.key).decrypt(buf), + }, + }, + // Not very important, but useful (also cross-test) + 'cbc-128-no-padding': { + opts: { key: buf(16), iv: buf(16), blockSize: 16 }, + node: nodeAES('aes-128-cbc', false), + noble: { + encrypt: (buf, opts) => aes.cbc(opts.key, opts.iv, { disablePadding: true }).encrypt(buf), + decrypt: (buf, opts) => aes.cbc(opts.key, opts.iv, { disablePadding: true }).decrypt(buf), + }, + }, + 'cbc-256-no-padding': { + opts: { key: buf(32), iv: buf(16), blockSize: 16 }, + node: nodeAES('aes-256-cbc', false), + noble: { + encrypt: (buf, opts) => aes.cbc(opts.key, opts.iv, { disablePadding: true }).encrypt(buf), + decrypt: (buf, opts) => aes.cbc(opts.key, opts.iv, { disablePadding: true }).decrypt(buf), + }, + }, + 'ecb-128-no-padding': { + opts: { key: buf(16), iv: null, blockSize: 16 }, + node: nodeAES('aes-128-ecb', false), + noble: { + encrypt: (buf, opts) => aes.ecb(opts.key, { disablePadding: true }).encrypt(buf), + decrypt: (buf, opts) => aes.ecb(opts.key, { disablePadding: true }).decrypt(buf), + }, + }, + 'ecb-256-no-padding': { + opts: { key: buf(32), iv: null, blockSize: 16 }, + node: nodeAES('aes-256-ecb', false), + noble: { + encrypt: (buf, opts) => aes.ecb(opts.key, { disablePadding: true }).encrypt(buf), + decrypt: (buf, opts) => aes.ecb(opts.key, { disablePadding: true }).decrypt(buf), + }, + }, + // GCM related (slow) + 'gcm-128': { + opts: { key: buf(16), iv: buf(12) }, + node: nodeGCM('aes-128-gcm'), + stablelib: { + encrypt: (buf, opts) => new STABLE_GCM(new STABLE_AES(opts.key)).seal(opts.iv, buf), + decrypt: (buf, opts) => new STABLE_GCM(new STABLE_AES(opts.key)).open(opts.iv, buf), + }, + nobleOld: { + encrypt: (buf, opts) => aes_128_gcm(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes_128_gcm(opts.key, opts.iv).decrypt(buf), + }, + noble: { + encrypt: (buf, opts) => aes.gcm(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.gcm(opts.key, opts.iv).decrypt(buf), + }, + }, 'gcm-256': { opts: { key: buf(32), iv: buf(12) }, node: nodeGCM('aes-256-gcm'), + stablelib: { + encrypt: (buf, opts) => new STABLE_GCM(new STABLE_AES(opts.key)).seal(opts.iv, buf), + decrypt: (buf, opts) => new STABLE_GCM(new STABLE_AES(opts.key)).open(opts.iv, buf), + }, + nobleOld: { + encrypt: (buf, opts) => aes_256_gcm(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes_256_gcm(opts.key, opts.iv).decrypt(buf), + }, noble: { - encrypt: (buf, opts) => aes_256_gcm.encrypt(opts.key, buf, opts.iv), - decrypt: (buf, opts) => aes_256_gcm.decrypt(opts.key, buf, opts.iv), + encrypt: (buf, opts) => aes.gcm(opts.key, opts.iv).encrypt(buf), + decrypt: (buf, opts) => aes.gcm(opts.key, opts.iv).decrypt(buf), }, }, 'gcm-siv-128': { opts: { key: buf(16), aad: buf(0), nonce: buf(12) }, noble: { - encrypt: async (buf, opts) => - await (await aes_256_gcm_siv(opts.key, opts.nonce, opts.aad)).encrypt(buf), - decrypt: async (buf, opts) => - await (await aes_256_gcm_siv(opts.key, opts.nonce, opts.aad)).decrypt(buf), + encrypt: (buf, opts) => aes.siv(opts.key, opts.nonce, opts.aad).encrypt(buf), + decrypt: (buf, opts) => aes.siv(opts.key, opts.nonce, opts.aad).decrypt(buf), }, }, 'gcm-siv-256': { - opts: { key: buf(32), aad: buf(0), nonce: buf(12) }, + opts: { key: buf(32), nonce: buf(12), aad: buf(16) }, noble: { - encrypt: async (buf, opts) => - await (await aes_256_gcm_siv(opts.key, opts.nonce, opts.aad)).encrypt(buf), - decrypt: async (buf, opts) => - await (await aes_256_gcm_siv(opts.key, opts.nonce, opts.aad)).decrypt(buf), + encrypt: (buf, opts) => aes.siv(opts.key, opts.nonce, opts.aad).encrypt(buf), + decrypt: (buf, opts) => aes.siv(opts.key, opts.nonce, opts.aad).decrypt(buf), }, }, }; // buffer title, sample count, data -const buffers = { - '32B': [2000000, buf(32)], - '64B': [1000000, buf(64)], - '1KB': [66667, buf(1024)], - '8KB': [8333, buf(1024 * 8)], - '1MB': [524, buf(1024 * 1024)], -}; +const buffers = [ + { size: '64B', samples: 50_000, data: buf(64) }, + { size: '1KB', samples: 15_000, data: buf(1024) }, + { size: '8KB', samples: 2_000, data: buf(1024 * 8) }, + { size: '1MB', samples: 100, data: buf(1024 * 1024) }, +]; export async function main() { - await crossValidate(buffers, ciphers); - if (onlyNoble) return benchmarkOnlyNoble(buffers, ciphers); - benchmarkAllLibraries(buffers, ciphers); + await crossValidate(buffers, CIPHERS); + if (onlyNoble) return benchmarkOnlyNoble(buffers, CIPHERS); + benchmarkAllLibraries(buffers, CIPHERS); butils.logMem(); } diff --git a/benchmark/package-lock.json b/benchmark/package-lock.json index 202cf44..98dafc1 100644 --- a/benchmark/package-lock.json +++ b/benchmark/package-lock.json @@ -12,9 +12,14 @@ "@chainsafe/as-chacha20poly1305": "0.1.0", "@devtomio/sodium": "0.3.0", "@noble/ciphers": "file:..", + "@stablelib/aes": "^1.0.1", "@stablelib/chacha": "1.0.1", "@stablelib/chacha20poly1305": "1.0.1", + "@stablelib/ctr": "^1.0.2", + "@stablelib/gcm": "^1.0.2", + "@stablelib/poly1305": "^1.0.1", "@stablelib/salsa20": "1.0.2", + "@stablelib/siv": "^1.0.2", "@stablelib/xchacha20": "1.0.1", "@stablelib/xchacha20poly1305": "1.0.1", "@stablelib/xsalsa20": "1.0.2", @@ -24,7 +29,7 @@ }, "..": { "name": "@noble/ciphers", - "version": "0.1.4", + "version": "0.3.0", "license": "MIT", "devDependencies": { "@scure/base": "1.1.1", @@ -206,6 +211,16 @@ "resolved": "https://registry.npmjs.org/@stablelib/aead/-/aead-1.0.1.tgz", "integrity": "sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==" }, + "node_modules/@stablelib/aes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/aes/-/aes-1.0.1.tgz", + "integrity": "sha512-bMiezJDeFONDHbMEa+Kic26962+bwkZfsHPAmcqTjLaHCAhEQuK3i1H0POPOkcHCdj75oVRIqFCraCA0cyHPvw==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, "node_modules/@stablelib/binary": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", @@ -214,6 +229,11 @@ "@stablelib/int": "^1.0.1" } }, + "node_modules/@stablelib/blockcipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/blockcipher/-/blockcipher-1.0.1.tgz", + "integrity": "sha512-4bkpV8HUAv0CgI1fUqkPUEEvv3RXQ3qBkuZaSWhshXGAz1JCpriesgiO9Qs4f0KzBJkCtvcho5n7d/RKvnHbew==" + }, "node_modules/@stablelib/chacha": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/chacha/-/chacha-1.0.1.tgz", @@ -236,11 +256,43 @@ "@stablelib/wipe": "^1.0.1" } }, + "node_modules/@stablelib/cmac": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/cmac/-/cmac-1.0.1.tgz", + "integrity": "sha512-q9mAkBMVJkquqSN2q2AtkcXYO0cH1qdcV4d8MUMGmqUNwdf9ACTDMBXrgMBHpxTVv7ZaPjuUwwvxhzoiVRaSRA==", + "dependencies": { + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, "node_modules/@stablelib/constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz", "integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==" }, + "node_modules/@stablelib/ctr": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/ctr/-/ctr-1.0.2.tgz", + "integrity": "sha512-Wq/Zr5QWNiXUu1UMhbeSIWhUm4YOhl01owaZOehxKFOKp6PPuUi9kAUAHv9cE5yQm9PLvIxzhwFco36sRpcOTQ==", + "dependencies": { + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/gcm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/gcm/-/gcm-1.0.2.tgz", + "integrity": "sha512-sQIRPGti1UXm740RTI38Apbl3t0oEEQMsdKN6VbC8a2lFHff6Stg90IqbF1xSrMLmm52gDGwtODhub3rKOMkfQ==", + "dependencies": { + "@stablelib/aead": "^1.0.1", + "@stablelib/binary": "^1.0.1", + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/ctr": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, "node_modules/@stablelib/int": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", @@ -265,6 +317,18 @@ "@stablelib/wipe": "^1.0.1" } }, + "node_modules/@stablelib/siv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stablelib/siv/-/siv-1.0.2.tgz", + "integrity": "sha512-s8Ke+6qLFlZIAEJPdcS1/xUZ4npsDAYUxaeD9HITrAhKO83c7cIatQC1Kay5Pjl20LlL2UV3DvNK98EqrePifQ==", + "dependencies": { + "@stablelib/blockcipher": "^1.0.1", + "@stablelib/cmac": "^1.0.1", + "@stablelib/constant-time": "^1.0.1", + "@stablelib/ctr": "^1.0.2", + "@stablelib/wipe": "^1.0.1" + } + }, "node_modules/@stablelib/wipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", diff --git a/benchmark/package.json b/benchmark/package.json index 30bc3d2..9a23e15 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -15,9 +15,14 @@ "@chainsafe/as-chacha20poly1305": "0.1.0", "@devtomio/sodium": "0.3.0", "@noble/ciphers": "file:..", + "@stablelib/aes": "^1.0.1", "@stablelib/chacha": "1.0.1", "@stablelib/chacha20poly1305": "1.0.1", + "@stablelib/ctr": "^1.0.2", + "@stablelib/gcm": "^1.0.2", + "@stablelib/poly1305": "^1.0.1", "@stablelib/salsa20": "1.0.2", + "@stablelib/siv": "^1.0.2", "@stablelib/xchacha20": "1.0.1", "@stablelib/xchacha20poly1305": "1.0.1", "@stablelib/xsalsa20": "1.0.2", diff --git a/package-lock.json b/package-lock.json index 156e23f..9e9c4c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@noble/ciphers", - "version": "0.2.0", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@noble/ciphers", - "version": "0.2.0", + "version": "0.3.0", "license": "MIT", "devDependencies": { "@scure/base": "1.1.1", diff --git a/package.json b/package.json index df6ace5..a44ef1a 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,16 @@ "import": "./esm/_poly1305.js", "default": "./_poly1305.js" }, + "./_polyval": { + "types": "./_polyval.d.ts", + "import": "./esm/_polyval.js", + "default": "./_polyval.js" + }, + "./aes": { + "types": "./aes.d.ts", + "import": "./esm/aes.js", + "default": "./aes.js" + }, "./chacha": { "types": "./chacha.d.ts", "import": "./esm/chacha.js", @@ -88,11 +98,6 @@ "import": "./esm/webcrypto/aes.js", "default": "./webcrypto/aes.js" }, - "./webcrypto/siv": { - "types": "./webcrypto/siv.d.ts", - "import": "./esm/webcrypto/siv.js", - "default": "./webcrypto/siv.js" - }, "./webcrypto/ff1": { "types": "./webcrypto/ff1.d.ts", "import": "./esm/webcrypto/ff1.js", @@ -128,4 +133,4 @@ "siv" ], "funding": "https://paulmillr.com/funding/" -} +} \ No newline at end of file diff --git a/src/_polyval.ts b/src/_polyval.ts index 27f9661..00ee3af 100644 --- a/src/_polyval.ts +++ b/src/_polyval.ts @@ -1,107 +1,208 @@ -import { ensureBytes, u8, u32 } from './utils.js'; +import { createView, toBytes, Input, Hash, u32 } from './utils.js'; +import { exists as aexists, output as aoutput } from './_assert.js'; -// AES-SIV polyval, little-endian "mirror image" of AES-GCM GHash -// polynomial hash function. Defined in RFC 8452. +// GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV. +// Implemented in terms of GHash with conversion function for keys +// GCM GHASH from NIST SP800-38d, SIV from RFC 8452. +// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf -// Reverse bits in u32, constant-time, precompute will be faster, but non-constant time -function rev32(x: number) { - x = ((x & 0x5555_5555) << 1) | ((x >>> 1) & 0x5555_5555); - x = ((x & 0x3333_3333) << 2) | ((x >>> 2) & 0x3333_3333); - x = ((x & 0x0f0f_0f0f) << 4) | ((x >>> 4) & 0x0f0f_0f0f); - x = ((x & 0x00ff_00ff) << 8) | ((x >>> 8) & 0x00ff_00ff); - return (x << 16) | (x >>> 16); -} +// GHASH modulo: x^128 + x^7 + x^2 + x + 1 +// POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1 -// wrapped 32 bit multiplication -const wrapMul = (a: number, b: number) => Math.imul(a, b) >>> 0; +const BLOCK_SIZE = 16; +// TODO: rewrite +// temporary padding buffer +const ZEROS16 = /* @__PURE__ */ new Uint8Array(16); +const ZEROS32 = u32(ZEROS16); +const POLY = 0xe1; // v = 2*v % POLY -// https://timtaubert.de/blog/2017/06/verified-binary-multiplication-for-ghash/ -function bmul32(x: number, y: number) { - const x0 = x & 0x1111_1111; - const x1 = x & 0x2222_2222; - const x2 = x & 0x4444_4444; - const x3 = x & 0x8888_8888; - const y0 = y & 0x1111_1111; - const y1 = y & 0x2222_2222; - const y2 = y & 0x4444_4444; - const y3 = y & 0x8888_8888; - let res = (wrapMul(x0, y0) ^ wrapMul(x1, y3) ^ wrapMul(x2, y2) ^ wrapMul(x3, y1)) & 0x1111_1111; - res |= (wrapMul(x0, y1) ^ wrapMul(x1, y0) ^ wrapMul(x2, y3) ^ wrapMul(x3, y2)) & 0x2222_2222; - res |= (wrapMul(x0, y2) ^ wrapMul(x1, y1) ^ wrapMul(x2, y0) ^ wrapMul(x3, y3)) & 0x4444_4444; - res |= (wrapMul(x0, y3) ^ wrapMul(x1, y2) ^ wrapMul(x2, y1) ^ wrapMul(x3, y0)) & 0x8888_8888; - return res >>> 0; +// 128x128 multiplication table for key. Same as noble-curves, but window size=1. +// TODO: investigate perf boost using bigger window size. +function genMulTable(s0: number, s1: number, s2: number, s3: number): Uint32Array { + const t = new Uint32Array(128 * 4); // 128x128 multiplication table for key + for (let i = 0, pos = 0, t0, t1, t2, t3; i < 128; i++) { + (t[pos++] = s0), (t[pos++] = s1), (t[pos++] = s2), (t[pos++] = s3); + const hiBit = s3 & 1; + t3 = (s2 << 31) | (s3 >>> 1); + t2 = (s1 << 31) | (s2 >>> 1); + t1 = (s0 << 31) | (s1 >>> 1); + t0 = (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)); // reduce % poly + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + // ({ s0, s1, s2, s3 } = mul2(s0, s1, s2, s3)); + } + return t.map(swapLE); // convert to LE, so we can use u32 } -function mulPart(arr: Uint32Array) { - const a = new Uint32Array(18); - a[0] = arr[0]; - a[1] = arr[1]; - a[2] = arr[2]; - a[3] = arr[3]; - a[4] = a[0] ^ a[1]; - a[5] = a[2] ^ a[3]; - a[6] = a[0] ^ a[2]; - a[7] = a[1] ^ a[3]; - a[8] = a[6] ^ a[7]; - a[9] = rev32(arr[0]); - a[10] = rev32(arr[1]); - a[11] = rev32(arr[2]); - a[12] = rev32(arr[3]); - a[13] = a[9] ^ a[10]; - a[14] = a[11] ^ a[12]; - a[15] = a[9] ^ a[11]; - a[16] = a[10] ^ a[12]; - a[17] = a[15] ^ a[16]; - return a; +/** + * `mulX_POLYVAL(ByteReverse(H))` from spec + * @param k mutated in place + */ +export function _toGHASHKey(k: Uint8Array): Uint8Array { + k.reverse(); + const hiBit = k[15] & 1; + // k >>= 1 + let carry = 0; + for (let i = 0; i < k.length; i++) { + const t = k[i]; + k[i] = (t >>> 1) | carry; + carry = (t & 1) << 7; + } + k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000; + return k; } -export function polyval(h: Uint8Array, data: Uint8Array) { - ensureBytes(h); - ensureBytes(data); - const s = new Uint32Array(4); - // Precompute for multiplication - const a = mulPart(u32(h)); - if (data.length % 16) throw new Error('polyval: data must be padded to 16 bytes'); - const data32 = u32(data); - for (let i = 0; i < data32.length; i += 4) { - // Xor - s[0] ^= data32[i + 0]; - s[1] ^= data32[i + 1]; - s[2] ^= data32[i + 2]; - s[3] ^= data32[i + 3]; +const swapLE = (n: number) => + ((((n >>> 0) & 0xff) << 24) | + (((n >>> 8) & 0xff) << 16) | + (((n >>> 16) & 0xff) << 8) | + ((n >>> 24) & 0xff)) >>> + 0; - // Dot via Karatsuba multiplication, based on MIT-licensed - // https://bearssl.org/gitweb/?p=BearSSL;a=blob;f=src/hash/ghash_ctmul32.c;hb=4b6046412 - const b = mulPart(s); +class GHASH implements Hash { + readonly blockLen = BLOCK_SIZE; + readonly outputLen = BLOCK_SIZE; + protected s0 = 0; + protected s1 = 0; + protected s2 = 0; + protected s3 = 0; + protected mulTable: Uint32Array; // 128x128 multiplication table for key + protected finished = false; - const c = new Uint32Array(18); - for (let i = 0; i < 18; i++) c[i] = bmul32(a[i], b[i]); - c[4] ^= c[0] ^ c[1]; - c[5] ^= c[2] ^ c[3]; - c[8] ^= c[6] ^ c[7]; - c[13] ^= c[9] ^ c[10]; - c[14] ^= c[11] ^ c[12]; - c[17] ^= c[15] ^ c[16]; - - const zw = new Uint32Array(8); - zw[0] = c[0]; - zw[1] = c[4] ^ (rev32(c[9]) >>> 1); - zw[2] = c[1] ^ c[0] ^ c[2] ^ c[6] ^ (rev32(c[13]) >>> 1); - zw[3] = c[4] ^ c[5] ^ c[8] ^ (rev32(c[10] ^ c[9] ^ c[11] ^ c[15]) >>> 1); - zw[4] = c[2] ^ c[1] ^ c[3] ^ c[7] ^ (rev32(c[13] ^ c[14] ^ c[17]) >>> 1); - zw[5] = c[5] ^ (rev32(c[11] ^ c[10] ^ c[12] ^ c[16]) >>> 1); - zw[6] = c[3] ^ (rev32(c[14]) >>> 1); - zw[7] = rev32(c[12]) >>> 1; - for (let i = 0; i < 4; i++) { - const lw = zw[i]; - zw[i + 4] ^= lw ^ (lw >>> 1) ^ (lw >>> 2) ^ (lw >>> 7); - zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); + constructor(key: Input) { + key = toBytes(key); + const v = createView(key); + let k0 = v.getUint32(0, false); + let k1 = v.getUint32(4, false); + let k2 = v.getUint32(8, false); + let k3 = v.getUint32(12, false); + this.mulTable = genMulTable(k0, k1, k2, k3); + } + protected _updateBlock(s0: number, s1: number, s2: number, s3: number) { + (s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3); + const { mulTable } = this; + const mulNum = (num: number, pos: number, o0: number, o1: number, o2: number, o3: number) => { + for (let bytePos = 0; bytePos < 4; bytePos++) { + const byte = (num >>> (8 * bytePos)) & 0xff; + for (let bitPos = 7; bitPos >= 0; bitPos--) { + const bit = (byte >>> bitPos) & 1; + const mask = ~(bit - 1); + // const-time addition regardless of bit value + o0 ^= mulTable[pos++] & mask; + o1 ^= mulTable[pos++] & mask; + o2 ^= mulTable[pos++] & mask; + o3 ^= mulTable[pos++] & mask; + } + } + return { o0, o1, o2, o3 }; + }; + // prettier-ignore + let o0 = 0, o1 = 0, o2 = 0, o3 = 0; + ({ o0, o1, o2, o3 } = mulNum(s0, 0, o0, o1, o2, o3)); + ({ o0, o1, o2, o3 } = mulNum(s1, 128, o0, o1, o2, o3)); + ({ o0, o1, o2, o3 } = mulNum(s2, 256, o0, o1, o2, o3)); + ({ o0: s0, o1: s1, o2: s2, o3: s3 } = mulNum(s3, 384, o0, o1, o2, o3)); + this.s0 = s0; + this.s1 = s1; + this.s2 = s2; + this.s3 = s3; + } + update(data: Input): this { + data = toBytes(data); + aexists(this); + const b32 = u32(data); + const blocks = Math.floor(data.length / BLOCK_SIZE); + const left = data.length % BLOCK_SIZE; + for (let i = 0; i < blocks; i++) { + this._updateBlock(b32[i * 4 + 0], b32[i * 4 + 1], b32[i * 4 + 2], b32[i * 4 + 3]); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + this._updateBlock(ZEROS32[0], ZEROS32[1], ZEROS32[2], ZEROS32[3]); + ZEROS32.fill(0); // clean tmp buffer } + return this; + } + destroy() {} + digestInto(out: Uint8Array) { + aexists(this); + aoutput(out, this); + this.finished = true; + const { s0, s1, s2, s3 } = this; + const o32 = u32(out); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + return out; + } + digest(): Uint8Array { + const res = new Uint8Array(BLOCK_SIZE); + this.digestInto(res); + this.destroy(); + return res; + } +} - s[0] = zw[4]; - s[1] = zw[5]; - s[2] = zw[6]; - s[3] = zw[7]; +class Polyval extends GHASH { + constructor(key: Input) { + key = toBytes(key); + const ghKey = _toGHASHKey(key.slice()); + super(ghKey); + ghKey.fill(0); + } + update(data: Input): this { + data = toBytes(data); + aexists(this); + const b32 = u32(data); + const left = data.length % BLOCK_SIZE; + const blocks = Math.floor(data.length / BLOCK_SIZE); + for (let i = 0; i < blocks; i++) { + this._updateBlock( + swapLE(b32[i * 4 + 3]), + swapLE(b32[i * 4 + 2]), + swapLE(b32[i * 4 + 1]), + swapLE(b32[i * 4 + 0]) + ); + } + if (left) { + ZEROS16.set(data.subarray(blocks * BLOCK_SIZE)); + this._updateBlock( + swapLE(ZEROS32[3]), + swapLE(ZEROS32[2]), + swapLE(ZEROS32[1]), + swapLE(ZEROS32[0]) + ); + ZEROS32.fill(0); // clean tmp buffer + } + return this; } - return u8(s); + digestInto(out: Uint8Array) { + aexists(this); + aoutput(out, this); + this.finished = true; + // tmp ugly hack + const { s0, s1, s2, s3 } = this; + const o32 = u32(out); + o32[0] = s0; + o32[1] = s1; + o32[2] = s2; + o32[3] = s3; + return out.reverse(); + } +} + +export type CHash = ReturnType; +export function wrapConstructorWithKey>(hashCons: (key: Input) => Hash) { + const hashC = (msg: Input, key: Input): Uint8Array => hashCons(key).update(toBytes(msg)).digest(); + const tmp = hashCons(new Uint8Array(32)); + hashC.outputLen = tmp.outputLen; + hashC.blockLen = tmp.blockLen; + hashC.create = (key: Input) => hashCons(key); + return hashC; } + +export const ghash = wrapConstructorWithKey((key) => new GHASH(key)); +export const polyval = wrapConstructorWithKey((key) => new Polyval(key)); diff --git a/src/aes.ts b/src/aes.ts new file mode 100644 index 0000000..a3ec5ce --- /dev/null +++ b/src/aes.ts @@ -0,0 +1,628 @@ +import { equalBytes, u32, u8, ensureBytes, Cipher, CipherWithOutput } from './utils.js'; +import { createView, setBigUint64 } from './utils.js'; +import { ghash, polyval } from './_polyval.js'; + +// AES (Advanced Encryption Standard) aka Rijndael block cipher. +// +// Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256bit). Every round: +// 1. **S-box**, table substitution +// 2. **Shift rows**, cyclic shift left of all rows of data array +// 3. **Mix columns**, multiplying every column by fixed polynomial +// 4. **Add round key**, round_key xor i-th column of array +// +// Resources: +// - FIPS-197 https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf +// - Original proposal: https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf + +const BLOCK_SIZE = 16; +const BLOCK_SIZE32 = 4; +const EMPTY_BLOCK = new Uint8Array(BLOCK_SIZE); +const POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8 + +// TODO: remove multiplication, binary ops only +function mul2(n: number) { + return (n << 1) ^ (POLY & -(n >> 7)); +} +function mul(a: number, b: number) { + let res = 0; + for (; b > 0; b >>= 1) { + // Montgomery ladder + res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time). + a = mul2(a); // a = 2*a + } + return res; +} + +// AES S-box is generated using finite field inversion, +// an affine transform, and xor of a constant 0x63. +const _sbox = /* @__PURE__ */ (() => { + let t = new Uint8Array(256); + for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x)) t[i] = x; + const sbox = new Uint8Array(256); + sbox[0] = 0x63; // first elm + for (let i = 0; i < 255; i++) { + let x = t[255 - i]; + x |= x << 8; + sbox[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff; + } + return sbox; +})(); + +// Inverted S-box +const _inv_sbox = /* @__PURE__ */ _sbox.map((_, j) => _sbox.indexOf(j)); + +// Rotate u32 by 8 +const rotr32_8 = (n: number) => (n << 24) | (n >>> 8); +const rotl32_8 = (n: number) => (n << 8) | (n >>> 24); + +// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes: +// - LE instead of BE +// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23; +// so index is u16, instead of u8. This speeds up things, unexpectedly +function genTtable(sbox: Uint8Array, fn: (n: number) => number) { + if (sbox.length !== 256) throw new Error('Wrong sbox length'); + const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j])); + const T1 = T0.map(rotl32_8); + const T2 = T1.map(rotl32_8); + const T3 = T2.map(rotl32_8); + const T01 = new Uint32Array(256 * 256); + const T23 = new Uint32Array(256 * 256); + const sbox2 = new Uint16Array(256 * 256); + for (let i = 0; i < 256; i++) { + for (let j = 0; j < 256; j++) { + const idx = i * 256 + j; + T01[idx] = T0[i] ^ T1[j]; + T23[idx] = T2[i] ^ T3[j]; + sbox2[idx] = (sbox[i] << 8) | sbox[j]; + } + } + return { sbox, sbox2, T0, T1, T2, T3, T01, T23 }; +} + +const TABLE_ENC = /* @__PURE__ */ genTtable( + _sbox, + (s: number) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2) +); +const TABLE_DEC = /* @__PURE__ */ genTtable( + _inv_sbox, + (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14) +); + +const POWX = /* @__PURE__ */ (() => { + const p = new Uint8Array(16); + for (let i = 0, x = 1; i < 16; i++, x = mul2(x)) p[i] = x; + return p; +})(); + +function expandKeyLE(key: Uint8Array): Uint32Array { + ensureBytes(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}`); + const { sbox2 } = TABLE_ENC; + const k32 = u32(key); + const Nk = k32.length; + const subByte = (n: number) => applySbox(sbox2, n, n, n, n); + const xk = new Uint32Array(len + 28); // expanded key + xk.set(k32); + // 4.3.1 Key expansion + for (let i = Nk; i < xk.length; i++) { + let t = xk[i - 1]; + if (i % Nk === 0) t = subByte(rotr32_8(t)) ^ POWX[i / Nk - 1]; + else if (Nk > 6 && i % Nk === 4) t = subByte(t); + xk[i] = xk[i - Nk] ^ t; + } + return xk; +} + +function expandKeyDecLE(key: Uint8Array): Uint32Array { + const encKey = expandKeyLE(key); + const xk = encKey.slice(); + const Nk = encKey.length; + const { sbox2 } = TABLE_ENC; + const { T0, T1, T2, T3 } = TABLE_DEC; + // Inverse key by chunks of 4 (rounds) + for (let i = 0; i < Nk; i += 4) { + for (let j = 0; j < 4; j++) xk[i + j] = encKey[Nk - i - 4 + j]; + } + encKey.fill(0); + // apply InvMixColumn except first & last round + for (let i = 4; i < Nk - 4; i++) { + const x = xk[i]; + const w = applySbox(sbox2, x, x, x, x); + xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24]; + } + return xk; +} + +// Apply tables +function apply0123( + T01: Uint32Array, + T23: Uint32Array, + s0: number, + s1: number, + s2: number, + s3: number +) { + return ( + T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^ + T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)] + ); +} + +function applySbox(sbox2: Uint16Array, s0: number, s1: number, s2: number, s3: number) { + return ( + sbox2[(s0 & 0xff) | (s1 & 0xff00)] | + (sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16) + ); +} + +function encrypt(xk: Uint32Array, s0: number, s1: number, s2: number, s3: number) { + const { sbox2, T01, T23 } = TABLE_ENC; + let k = 0; + (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]); + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2); + (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3); + } + // last round (without mixcolumns, so using SBOX2 table) + const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3); + const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0); + const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1); + const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} + +function decrypt(xk: Uint32Array, s0: number, s1: number, s2: number, s3: number) { + const { sbox2, T01, T23 } = TABLE_DEC; + let k = 0; + (s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]); + const rounds = xk.length / 4 - 2; + for (let i = 0; i < rounds; i++) { + const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1); + const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2); + const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3); + const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0); + (s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3); + } + // Last round + const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1); + const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2); + const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3); + const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0); + return { s0: t0, s1: t1, s2: t2, s3: t3 }; +} + +function getDst(len: number, dst?: Uint8Array) { + if (!dst) return new Uint8Array(len); + ensureBytes(dst); + if (dst.length < len) + throw new Error(`aes: wrong destination length, expected at least ${len}, got: ${dst.length}`); + return dst; +} + +// TODO: investigate merging with ctr32 +function ctrCounter(xk: Uint32Array, nonce: Uint8Array, src: Uint8Array, dst?: Uint8Array) { + ensureBytes(nonce, BLOCK_SIZE); + ensureBytes(src); + const srcLen = src.length; + dst = getDst(srcLen, dst); + const ctr = nonce.slice(); + const c32 = u32(ctr); + // Fill block (empty, ctr=0) + let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]); + const src32 = u32(src); + const dst32 = u32(dst); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ s0; + dst32[i + 1] = src32[i + 1] ^ s1; + dst32[i + 2] = src32[i + 2] ^ s2; + dst32[i + 3] = src32[i + 3] ^ s3; + // Full 128 bit counter with wrap around + let carry = 1; + for (let i = ctr.length - 1; i >= 0; i--) { + carry = (carry + (ctr[i] & 0xff)) | 0; + ctr[i] = carry & 0xff; + carry >>>= 8; + } + ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3])); + } + // leftovers (less than block) + // It's possible to handle > u32 fast, but is it worth it? + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos]; + } + return dst; +} + +// AES CTR with overflowing 32 bit counter +// It's possible to do 32le significantly simpler (and probably faster) by using u32. +// But, we need both, and perf bottleneck is in ghash anyway. +function ctr32( + xk: Uint32Array, + isLE: boolean, + nonce: Uint8Array, + src: Uint8Array, + dst?: Uint8Array +) { + ensureBytes(nonce, BLOCK_SIZE); + ensureBytes(src); + dst = getDst(src.length, dst); + const ctr = nonce; // write new value to nonce, so it can be re-used + const c32 = u32(ctr); + const view = createView(ctr); + const src32 = u32(src); + const dst32 = u32(dst); + const ctrPos = isLE ? 0 : 12; + const srcLen = src.length; + // Fill block (empty, ctr=0) + let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value + let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]); + // process blocks + for (let i = 0; i + 4 <= src32.length; i += 4) { + dst32[i + 0] = src32[i + 0] ^ s0; + dst32[i + 1] = src32[i + 1] ^ s1; + dst32[i + 2] = src32[i + 2] ^ s2; + dst32[i + 3] = src32[i + 3] ^ s3; + ctrNum = (ctrNum + 1) >>> 0; // u32 wrap + view.setUint32(ctrPos, ctrNum, isLE); + ({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3])); + } + // leftovers (less than a block) + const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32); + if (start < srcLen) { + const b32 = new Uint32Array([s0, s1, s2, s3]); + const buf = u8(b32); + for (let i = start, pos = 0; i < srcLen; i++, pos++) dst[i] = src[i] ^ buf[pos]; + } + return dst; +} + +/** + * CTR: counter mode. Creates stream cipher. + * Requires good IV. Parallelizable. OK, but no MAC. + */ +export function ctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput { + ensureBytes(key); + ensureBytes(nonce, BLOCK_SIZE); + function processCtr(buf: Uint8Array, dst?: Uint8Array) { + const xk = expandKeyLE(key); + const out = ctrCounter(xk, nonce, buf, dst); + xk.fill(0); + return out; + } + return { + encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => processCtr(plaintext, dst), + decrypt: (ciphertext: Uint8Array, dst?: Uint8Array) => processCtr(ciphertext, dst), + }; +} + +function validateBlockDecrypt(data: Uint8Array) { + ensureBytes(data); + if (data.length % BLOCK_SIZE !== 0) { + throw new Error( + `aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE}` + ); + } +} + +function validateBlockEncrypt(plaintext: Uint8Array, pcks5: boolean, dst?: Uint8Array) { + let outLen = plaintext.length; + const remaining = outLen % BLOCK_SIZE; + if (!pcks5 && remaining !== 0) + throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding'); + const b = u32(plaintext); + if (pcks5) { + let left = BLOCK_SIZE - remaining; + if (!left) left = BLOCK_SIZE; // if no bytes left, create empty padding block + outLen = outLen + left; + } + const out = getDst(outLen, dst); + const o = u32(out); + return { b, o, out }; +} + +function validatePCKS(data: Uint8Array, pcks5: boolean) { + if (!pcks5) return data; + const len = data.length; + if (!len) throw new Error(`aes/pcks5: empty ciphertext not allowed`); + const lastByte = data[len - 1]; + if (lastByte <= 0 || lastByte > 16) throw new Error(`aes/pcks5: wrong padding byte: ${lastByte}`); + const out = data.subarray(0, -lastByte); + for (let i = 0; i < lastByte; i++) + if (data[len - i - 1] !== lastByte) throw new Error(`aes/pcks5: wrong padding`); + return out; +} + +function padPCKS(left: Uint8Array) { + const tmp = new Uint8Array(16); + const tmp32 = u32(tmp); + tmp.set(left); + const paddingByte = BLOCK_SIZE - left.length; + for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++) tmp[i] = paddingByte; + return tmp32; +} + +export type BlockOpts = { disablePadding?: boolean }; + +/** + * ECB: Electronic CodeBook. Simple deterministic replacement. + * Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/). + */ +export function ecb(key: Uint8Array, opts: BlockOpts = {}): Cipher { + ensureBytes(key); + const pcks5 = !opts.disablePadding; + return { + encrypt: (plaintext: Uint8Array, dst?: Uint8Array) => { + ensureBytes(plaintext); + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst); + const xk = expandKeyLE(key); + let i = 0; + for (; i + 4 <= b.length; ) { + const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3); + } + if (pcks5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]); + (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3); + } + xk.fill(0); + return _out; + }, + decrypt: (ciphertext: Uint8Array) => { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + const out = ciphertext.slice(); + const b = u32(ciphertext); + const o = u32(out); + for (let i = 0; i + 4 <= b.length; ) { + const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]); + (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3); + } + xk.fill(0); + return validatePCKS(out, pcks5); + }, + }; +} + +/** + * CBC: Cipher-Block-Chaining. Key is previous round’s block. + * Fragile: needs proper padding. Unauthenticated: needs MAC. + */ +export function cbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): Cipher { + ensureBytes(key); + ensureBytes(iv, 16); + const pcks5 = !opts.disablePadding; + return { + encrypt: (plaintext: Uint8Array) => { + const xk = expandKeyLE(key); + const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5); + const n32 = u32(iv); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + let i = 0; + for (; i + 4 <= b.length; ) { + (s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3); + } + if (pcks5) { + const tmp32 = padPCKS(plaintext.subarray(i * 4)); + (s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]); + ({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3)); + (o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3); + } + xk.fill(0); + return _out; + }, + decrypt: (ciphertext: Uint8Array) => { + validateBlockDecrypt(ciphertext); + const xk = expandKeyDecLE(key); + const n32 = u32(iv); + const out = ciphertext.slice(); + const b = u32(ciphertext); + const o = u32(out); + // prettier-ignore + let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3]; + for (let i = 0; i + 4 <= b.length; ) { + // prettier-ignore + const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3; + (s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]); + const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3); + (o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3); + } + xk.fill(0); + return validatePCKS(out, pcks5); + }, + }; +} + +// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen +function computeTag( + fn: typeof ghash, + isLE: boolean, + key: Uint8Array, + data: Uint8Array, + AAD?: Uint8Array +) { + const h = fn.create(key); + if (AAD) h.update(AAD); + h.update(data); + const num = new Uint8Array(16); + const view = createView(num); + if (AAD) setBigUint64(view, 0, BigInt(AAD.length * 8), isLE); + setBigUint64(view, 8, BigInt(data.length * 8), isLE); + h.update(num); + return h.digest(); +} + +/** + * GCM: Galois/Counter Mode. + * Good, modern version of CTR, parallel, with MAC. + * Be careful: MACs can be forged. + */ +export function gcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher { + ensureBytes(nonce); + // Nonce can be pretty much anything (even 1 byte). But smaller nonces less secure. + if (nonce.length === 0) throw new Error('aes/gcm: empty nonce'); + const tagLength = 16; + function _computeTag(authKey: Uint8Array, tagMask: Uint8Array, data: Uint8Array) { + const tag = computeTag(ghash, false, authKey, data, AAD); + for (let i = 0; i < tagMask.length; i++) tag[i] ^= tagMask[i]; + return tag; + } + function deriveKeys() { + const xk = expandKeyLE(key); + const authKey = EMPTY_BLOCK.slice(); + const counter = EMPTY_BLOCK.slice(); + ctr32(xk, false, counter, counter, authKey); + if (nonce.length === 12) { + counter.set(nonce); + } else { + // Spec (NIST 800-38d) supports variable size nonce. + // Not supported for now, but can be useful. + const nonceLen = EMPTY_BLOCK.slice(); + const view = createView(nonceLen); + setBigUint64(view, 8, BigInt(nonce.length * 8), false); + // ghash(nonce || u64be(0) || u64be(nonceLen*8)) + ghash.create(authKey).update(nonce).update(nonceLen).digestInto(counter); + } + const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK); + return { xk, authKey, counter, tagMask }; + } + return { + tagLength, + encrypt: (plaintext: Uint8Array) => { + ensureBytes(plaintext); + const { xk, authKey, counter, tagMask } = deriveKeys(); + const out = new Uint8Array(plaintext.length + tagLength); + ctr32(xk, false, counter, plaintext, out); + const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength)); + out.set(tag, plaintext.length); + xk.fill(0); + return out; + }, + decrypt: (ciphertext: Uint8Array) => { + ensureBytes(ciphertext); + if (ciphertext.length < tagLength) + throw new Error(`aes/gcm: ciphertext less than tagLen (${tagLength})`); + const { xk, authKey, counter, tagMask } = deriveKeys(); + const data = ciphertext.subarray(0, -tagLength); + const passedTag = ciphertext.subarray(-tagLength); + const tag = _computeTag(authKey, tagMask, data); + if (!equalBytes(tag, passedTag)) throw new Error('aes/gcm: invalid ghash tag'); + const out = ctr32(xk, false, counter, data); + authKey.fill(0); + tagMask.fill(0); + xk.fill(0); + return out; + }, + }; +} + +const limit = (name: string, min: number, max: number) => (value: number) => { + if (!Number.isSafeInteger(value) || min > value || value > max) + throw new Error(`${name}: invalid value=${value}, must be [${min}..${max}]`); +}; + +/** + * AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance. + * Guarantees that, when a nonce is repeated, the only security loss is that identical + * plaintexts will produce identical ciphertexts. + * RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452 + */ +export function siv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher { + const tagLength = 16; + // From RFC 8452: Section 6 + const AAD_LIMIT = limit('AAD', 0, 2 ** 36); + const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36); + const NONCE_LIMIT = limit('nonce', 12, 12); + const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16); + ensureBytes(nonce); + NONCE_LIMIT(nonce.length); + if (AAD) { + ensureBytes(AAD); + AAD_LIMIT(AAD.length); + } + function deriveKeys() { + const len = key.length; + if (len !== 16 && len !== 32) + throw new Error(`key length must be 16 or 32 bytes, got: ${len} bytes`); + const xk = expandKeyLE(key); + const encKey = new Uint8Array(len); + const authKey = new Uint8Array(16); + const n32 = u32(nonce); + // prettier-ignore + let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2]; + let counter = 0; + for (const derivedKey of [authKey, encKey].map(u32)) { + const d32 = u32(derivedKey); + for (let i = 0; i < d32.length; i += 2) { + // aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ... + const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3); + d32[i + 0] = o0; + d32[i + 1] = o1; + s0 = ++counter; // increment counter inside state + } + } + xk.fill(0); + return { authKey, encKey: expandKeyLE(encKey) }; + } + function _computeTag(encKey: Uint32Array, authKey: Uint8Array, data: Uint8Array) { + const tag = computeTag(polyval, true, authKey, data, AAD); + // Compute the expected tag by XORing S_s and the nonce, clearing the + // most significant bit of the last byte and encrypting with the + // message-encryption key. + for (let i = 0; i < 12; i++) tag[i] ^= nonce[i]; + tag[15] &= 0x7f; // Clear the highest bit + // encrypt tag as block + const t32 = u32(tag); + // prettier-ignore + let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3]; + ({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3)); + (t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3); + return tag; + } + // actual decrypt/encrypt of message. + function processSiv(encKey: Uint32Array, tag: Uint8Array, input: Uint8Array) { + let block = tag.slice(); + block[15] |= 0x80; // Force highest bit + return ctr32(encKey, true, block, input); + } + return { + tagLength, + encrypt: (plaintext: Uint8Array) => { + ensureBytes(plaintext); + PLAIN_LIMIT(plaintext.length); + const { encKey, authKey } = deriveKeys(); + const tag = _computeTag(encKey, authKey, plaintext); + const out = new Uint8Array(plaintext.length + tagLength); + out.set(tag, plaintext.length); + out.set(processSiv(encKey, tag, plaintext)); + encKey.fill(0); + authKey.fill(0); + return out; + }, + decrypt: (ciphertext: Uint8Array) => { + ensureBytes(ciphertext); + CIPHER_LIMIT(ciphertext.length); + const tag = ciphertext.subarray(-tagLength); + const { encKey, authKey } = deriveKeys(); + const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength)); + const expectedTag = _computeTag(encKey, authKey, plaintext); + encKey.fill(0); + authKey.fill(0); + if (!equalBytes(tag, expectedTag)) throw new Error('invalid polyval tag'); + return plaintext; + }, + }; +} diff --git a/src/webcrypto/ff1.ts b/src/webcrypto/ff1.ts index d617ae7..a13145b 100644 --- a/src/webcrypto/ff1.ts +++ b/src/webcrypto/ff1.ts @@ -1,5 +1,4 @@ -import type { AsyncCipher } from '../utils.js'; -import { bytesToNumberBE, numberToBytesBE } from '../utils.js'; +import { AsyncCipher, bytesToNumberBE, numberToBytesBE } from '../utils.js'; import { cryptoSubtleUtils } from './utils.js'; // Format-preserving encryption algorithm (FPE-FF1) specified in NIST Special Publication 800-38G. diff --git a/src/webcrypto/siv.ts b/src/webcrypto/siv.ts deleted file mode 100644 index 1f2beb7..0000000 --- a/src/webcrypto/siv.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { AsyncCipher, createView, setBigUint64 } from '../utils.js'; -import { polyval } from '../_polyval.js'; -import { cryptoSubtleUtils } from './utils.js'; - -/** - * AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance. - * RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452 - */ - -// Kinda constant-time equality -function equalBytes(a: Uint8Array, b: Uint8Array): boolean { - // Should not happen - if (a.length !== b.length) throw new Error('equalBytes: Different size of Uint8Arrays'); - let flag = true; - for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) flag &&= false; - return flag; -} -// Wrap position so it will be in padded to blockSize -const wrapPos = (pos: number, blockSize: number) => Math.ceil(pos / blockSize) * blockSize; - -const limit = (name: string, min: number, max: number) => (value: number) => { - if (!Number.isSafeInteger(value) || min > value || value > max) - throw new Error(`${name}: invalid value=${value}, must be [${min}..${max}]`); -}; - -// From RFC 8452: Section 6 -const AAD_LIMIT = limit('AAD', 0, 2 ** 36); -const PLAIN_LIMIT = limit('Plaintext', 0, 2 ** 36); -const NONCE_LIMIT = limit('Nonce', 12, 12); -const CIPHER_LIMIT = limit('Ciphertext', 16, 2 ** 36 + 16); - -// nodejs api doesn't support 32bit counters, browser does -async function ctr(key: Uint8Array, tag: Uint8Array, input: Uint8Array) { - // The initial counter block is the tag with the most significant bit of the last byte set to one. - let block = tag.slice(); - block[15] |= 0x80; - let view = createView(block); - let output = new Uint8Array(input.length); - for (let pos = 0; pos < input.length; ) { - const encryptedBlock = await cryptoSubtleUtils.aesEncryptBlock(block, key); - view.setUint32(0, view.getUint32(0, true) + 1, true); - const take = Math.min(input.length, encryptedBlock.length); - for (let j = 0; j < take; j++, pos++) output[pos] = encryptedBlock[j] ^ input[pos]; - } - return new Uint8Array(output); -} - -export async function deriveKeys(key: Uint8Array, nonce: Uint8Array) { - NONCE_LIMIT(nonce.length); - const len = key.length; - if (len !== 16 && len !== 32) - throw new Error(`key length must be 16 or 32 bytes, got: ${len} bytes`); - const encKey = new Uint8Array(len); - const authKey = new Uint8Array(16); - let counter = 0; - const deriveBlock = new Uint8Array(nonce.length + 4); - deriveBlock.set(nonce, 4); - const view = createView(deriveBlock); - for (const derivedKey of [authKey, encKey]) { - for (let i = 0; i < derivedKey.length; i += 8) { - view.setUint32(0, counter++, true); - const block = await cryptoSubtleUtils.aesEncryptBlock(deriveBlock, key); - derivedKey.set(block.subarray(0, 8), i); - } - } - return { authKey, encKey }; -} - -export async function aes_256_gcm_siv( - key: Uint8Array, - nonce: Uint8Array, - AAD: Uint8Array -): Promise { - const { encKey, authKey } = await deriveKeys(key, nonce); - const computeTag = async (data: Uint8Array, AAD: Uint8Array) => { - const dataPos = wrapPos(AAD.length, 16); - const lenPos = wrapPos(dataPos + data.length, 16); - const block = new Uint8Array(lenPos + 16); - const view = createView(block); - block.set(AAD); - block.set(data, dataPos); - setBigUint64(view, lenPos, BigInt(AAD.length * 8), true); - setBigUint64(view, lenPos + 8, BigInt(data.length * 8), true); - // Compute the expected tag by XORing S_s and the nonce, clearing the - // most significant bit of the last byte and encrypting with the - // message-encryption key. - const tag = polyval(authKey, block); - for (let i = 0; i < 12; i++) tag[i] ^= nonce[i]; - // Clear the highest bit - tag[15] &= 0x7f; - return await cryptoSubtleUtils.aesEncryptBlock(tag, encKey); - }; - return { - // computeTag, - encrypt: async (plaintext: Uint8Array) => { - AAD_LIMIT(AAD.length); - PLAIN_LIMIT(plaintext.length); - const tag = await computeTag(plaintext, AAD); - const out = new Uint8Array(plaintext.length + 16); - out.set(tag, plaintext.length); - out.set(await ctr(encKey, tag, plaintext)); - return out; - }, - decrypt: async (ciphertext: Uint8Array) => { - CIPHER_LIMIT(ciphertext.length); - AAD_LIMIT(AAD.length); - const tag = ciphertext.subarray(-16); - const plaintext = await ctr(encKey, tag, ciphertext.subarray(0, -16)); - const expectedTag = await computeTag(plaintext, AAD); - if (!equalBytes(tag, expectedTag)) throw new Error('invalid poly1305 tag'); - return plaintext; - }, - }; -} diff --git a/src/webcrypto/utils.ts b/src/webcrypto/utils.ts index fa924fd..f742b70 100644 --- a/src/webcrypto/utils.ts +++ b/src/webcrypto/utils.ts @@ -4,7 +4,7 @@ // from `crypto` to `cryptoNode`, which imports native module. // Makes the utils un-importable in browsers without a bundler. // Once node.js 18 is deprecated, we can just drop the import. -import { crypto } from '@noble/ciphers/webcrypto/crypto'; +import { crypto } from './crypto.js'; /** * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS. diff --git a/test/aes.test.js b/test/aes.test.js new file mode 100644 index 0000000..642bba0 --- /dev/null +++ b/test/aes.test.js @@ -0,0 +1,113 @@ +const { deepStrictEqual, throws } = require('assert'); +const { should, describe } = require('micro-should'); +const crypto = require('node:crypto'); +const { hex } = require('@scure/base'); +const { concatBytes } = require('../utils.js'); +const { ecb, cbc, ctr, siv, gcm } = require('../aes.js'); +// https://datatracker.ietf.org/doc/html/rfc8452#appendix-C +const NIST_VECTORS = require('./vectors/nist_800_38a.json'); +const VECTORS = require('./vectors/siv.json'); +const aes_gcm_test = require('./wycheproof/aes_gcm_test.json'); +const aes_gcm_siv_test = require('./wycheproof/aes_gcm_siv_test.json'); +const aes_cbc = require('./wycheproof/aes_cbc_pkcs5_test.json'); + +// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf + +const CIPHERS = { ecb, cbc, ctr, siv, gcm }; + +describe('AES', () => { + should('CTR', () => { + const nodeAES = (name) => ({ + encrypt: (buf, opts) => + Uint8Array.from(crypto.createCipheriv(name, opts.key, opts.nonce).update(buf)), + decrypt: (buf, opts) => + Uint8Array.from(crypto.createDecipheriv(name, opts.key, opts.nonce).update(buf)), + }); + // MDN says counter should be 64 bit + // https://developer.mozilla.org/en-US/docs/Web/API/AesCtrParams + // and links NIST SP800-38A which actually says in B.1 that standard increment function + // uses all bits, so 128 bit counter. Which is the same as in OpenSSL. + const key = new Uint8Array(32).fill(32); + const msg = new Uint8Array(64).fill(64); + const nonces = [ + new Uint8Array(16).fill(1), + // 64 bit + concatBytes(new Uint8Array(8), new Uint8Array(8).fill(255)), + concatBytes(new Uint8Array(8).fill(255), new Uint8Array(8)), + // 32 bit + concatBytes(new Uint8Array(12), new Uint8Array(4).fill(255)), + concatBytes(new Uint8Array(4).fill(255), new Uint8Array(12)), + new Uint8Array(16).fill(255), // this wraps in 128 bit + ]; + // So, current behaviour seems reasonable. + // We don't have variable counter length at web version for now, but it works. + for (const nonce of nonces) { + const nodeVal = nodeAES('aes-256-ctr').encrypt(msg, { key, nonce }); + const c = ctr(key, nonce); + deepStrictEqual(c.encrypt(msg), nodeVal); + deepStrictEqual(c.decrypt(nodeVal), msg); + } + }); + describe('NIST 800-38a', () => { + for (const t of NIST_VECTORS) { + should(`${t.name}`, () => { + let c; + const cipher = CIPHERS[t.cipher]; + if (t.iv) c = cipher(hex.decode(t.key), hex.decode(t.iv || ''), { disablePadding: true }); + else c = cipher(hex.decode(t.key), { disablePadding: true }); + const ciphertext = concatBytes(...t.blocks.map((i) => hex.decode(i.ciphertext))); + const plaintext = concatBytes(...t.blocks.map((i) => hex.decode(i.plaintext))); + deepStrictEqual(c.decrypt(ciphertext), plaintext); + deepStrictEqual(c.encrypt(plaintext), ciphertext); + }); + } + }); + describe('GCM-SIV', () => { + for (const flavor of ['aes128', 'aes256', 'counterWrap']) { + for (let i = 0; i < VECTORS[flavor].length; i++) { + const v = VECTORS[flavor][i]; + should(`${flavor}(${i}).encrypt`, () => { + let a = siv(hex.decode(v.key), hex.decode(v.nonce), hex.decode(v.AAD)); + deepStrictEqual(a.encrypt(hex.decode(v.plaintext)), hex.decode(v.result)); + }); + should(`${flavor}(${i}).decrypt`, () => { + let a = siv(hex.decode(v.key), hex.decode(v.nonce), hex.decode(v.AAD)); + deepStrictEqual(a.decrypt(hex.decode(v.result)), hex.decode(v.plaintext)); + }); + } + } + }); + + describe('Wycheproof', () => { + const cases = [ + { name: 'GCM-SIV', groups: aes_gcm_siv_test.testGroups, cipher: 'siv' }, + { name: 'GCM', groups: aes_gcm_test.testGroups, cipher: 'gcm' }, + { name: 'CBC', groups: aes_cbc.testGroups, cipher: 'cbc' }, // PCKS5 is enabled by default + ]; + for (const c of cases) { + for (const g of c.groups) { + const name = `Wycheproof/${c.name}/${g.ivSize}/${g.keySize}/${g.tagSize}/${g.type}`; + for (let i = 0; i < g.tests.length; i++) { + const t = g.tests[i]; + should(`${name}: ${i}`, () => { + const ct = concatBytes(hex.decode(t.ct), hex.decode(t.tag || '')); + const msg = hex.decode(t.msg); + const cipher = CIPHERS[c.cipher]; + if (t.result === 'valid') { + const a = cipher(hex.decode(t.key), hex.decode(t.iv), hex.decode(t.aad || '')); + const ct = concatBytes(hex.decode(t.ct), hex.decode(t.tag || '')); + deepStrictEqual(a.decrypt(ct), msg); + deepStrictEqual(a.encrypt(msg), ct); + } else { + throws(() => + cipher(hex.decode(t.key), hex.decode(t.iv), hex.decode(t.aad || '')).decrypt(ct) + ); + } + }); + } + } + } + }); +}); + +if (require.main === module) should.run(); diff --git a/test/basic.test.js b/test/basic.test.js index 9f25284..7f0b085 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -23,7 +23,7 @@ const stable_poly1305 = require('./vectors/stablelib_poly1305.json'); // Wycheproof const wycheproof_chacha20_poly1305 = require('./wycheproof/chacha20_poly1305_test.json'); const wycheproof_xchacha20_poly1305 = require('./wycheproof/xchacha20_poly1305_test.json'); - +const aes = require('../aes.js'); // getKey for hsalsa/hchacha const utils = require('../utils.js'); const sigma16 = utils.utf8ToBytes('expand 16-byte k'); diff --git a/test/ff1.test.js b/test/ff1.test.js index 53d2961..7a6b48f 100644 --- a/test/ff1.test.js +++ b/test/ff1.test.js @@ -1,8 +1,12 @@ +const { webcrypto } = require('node:crypto'); +if (!globalThis.crypto) globalThis.crypto = webcrypto; + const assert = require('assert'); const { should } = require('micro-should'); const { FF1, BinaryFF1 } = require('../webcrypto/ff1.js'); const v = require('./vectors/ff1.json'); const BIN_VECTORS = v.v; +// @ts-ignore const fromHex = (hex) => hex ? Uint8Array.from(Buffer.from(hex.replace(/ /g, ''), 'hex')) : new Uint8Array([]); diff --git a/test/gcm-siv.test.js b/test/gcm-siv.test.js deleted file mode 100644 index ea39b95..0000000 --- a/test/gcm-siv.test.js +++ /dev/null @@ -1,74 +0,0 @@ -const { deepStrictEqual, rejects } = require('assert'); -const { should, describe } = require('micro-should'); -const { hex } = require('@scure/base'); -const utils = require('../utils.js'); -const siv = require('../webcrypto/siv.js'); -const { polyval } = require('../_polyval.js'); - -// https://datatracker.ietf.org/doc/html/rfc8452#appendix-C -const VECTORS = require('./vectors/siv.json'); -const aes_gcm_siv_test = require('./wycheproof/aes_gcm_siv_test.json'); - -describe('AES-GCM-SIV', () => { - should('Polyval', () => { - const h = polyval( - hex.decode('25629347589242761d31f826ba4b757b'), - hex.decode('4f4f95668c83dfb6401762bb2d01a262d1a24ddd2721d006bbe45f20d3c9f362') - ); - deepStrictEqual(hex.encode(h), 'f7a3b47b846119fae5b7866cf5e5b77e'); - }); - for (const flavor of ['aes128', 'aes256', 'counterWrap']) { - for (let i = 0; i < VECTORS[flavor].length; i++) { - const v = VECTORS[flavor][i]; - should(`${flavor}(${i}): init`, async () => { - const { encKey, authKey } = await siv.deriveKeys(hex.decode(v.key), hex.decode(v.nonce)); - deepStrictEqual(encKey, hex.decode(v.encKey)); - deepStrictEqual(authKey, hex.decode(v.authKey)); - }); - should(`${flavor}(${i}): polyval`, async () => { - deepStrictEqual( - polyval(hex.decode(v.authKey), hex.decode(v.polyvalInput)), - hex.decode(v.polyvalResult) - ); - }); - should(`${flavor}(${i}).encrypt`, async () => { - let a = await siv.aes_256_gcm_siv( - hex.decode(v.key), - hex.decode(v.nonce), - hex.decode(v.AAD) - ); - deepStrictEqual(await a.encrypt(hex.decode(v.plaintext)), hex.decode(v.result)); - }); - should(`${flavor}(${i}).decrypt`, async () => { - let a = await siv.aes_256_gcm_siv( - hex.decode(v.key), - hex.decode(v.nonce), - hex.decode(v.AAD) - ); - deepStrictEqual(await a.decrypt(hex.decode(v.result)), hex.decode(v.plaintext)); - }); - } - } -}); - -describe('Wycheproof', () => { - for (const g of aes_gcm_siv_test.testGroups) { - const name = `Wycheproof/${g.ivSize}/${g.keySize}/${g.tagSize}/${g.type}`; - for (let i = 0; i < g.tests.length; i++) { - const t = g.tests[i]; - should(`${name}: ${i}`, async () => { - const a = await siv.aes_256_gcm_siv(hex.decode(t.key), hex.decode(t.iv), hex.decode(t.aad)); - const ct = utils.concatBytes(hex.decode(t.ct), hex.decode(t.tag)); - const msg = hex.decode(t.msg); - if (t.result === 'valid') { - deepStrictEqual(await a.decrypt(ct), msg); - deepStrictEqual(await a.encrypt(msg), ct); - } else { - await rejects(async () => await a.decrypt(ct)); - } - }); - } - } -}); - -if (require.main === module) should.run(); diff --git a/test/gcm.test.js b/test/gcm.test.js deleted file mode 100644 index 0943570..0000000 --- a/test/gcm.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const { deepStrictEqual, rejects } = require('assert'); -const { should, describe } = require('micro-should'); -const utils = require('../utils.js'); -const { aes_256_gcm, aes_128_gcm } = require('../webcrypto/aes.js'); -const { randomBytes } = require('../webcrypto/utils.js'); -const aes_gcm_test = require('./wycheproof/aes_gcm_test.json'); - -describe('AES-GCM', () => { - should('encrypt and decrypt', async () => { - const plaintext = utils.utf8ToBytes('Hello world'); - const knownKey = Uint8Array.from([ - 64, 196, 127, 247, 172, 2, 34, 159, 6, 241, 30, 174, 183, 229, 41, 114, 253, 122, 119, 168, - 177, 243, 155, 236, 164, 159, 98, 72, 162, 243, 224, 195, - ]); - const settings = [ - [aes_256_gcm, knownKey], - [aes_128_gcm, randomBytes(16)], - ]; - const aads = [randomBytes(16), new Uint8Array(), utils.utf8ToBytes('data'), undefined]; - for (const [cipher, key] of settings) { - for (const aad of aads) { - const gcm = cipher(key, randomBytes(12), aad); - const ciphertext = await gcm.encrypt(plaintext); - const plaintext2 = await gcm.decrypt(ciphertext); - deepStrictEqual(plaintext2, plaintext); - } - } - }); -}); - -describe('Wycheproof', () => { - for (const g of aes_gcm_test.testGroups) { - let cipher; - if (g.keySize === 256) { - cipher = aes_256_gcm; - } else if (g.keySize === 128) { - cipher = aes_128_gcm; - } else { - continue; - } - - // invalid iv sizes for webcrypto - if ([8, 16, 32, 48, 64, 80, 2056].includes(g.ivSize)) continue; - - const name = `Wycheproof/${g.ivSize}/${g.keySize}/${g.tagSize}/${g.type}`; - for (let i = 0; i < g.tests.length; i++) { - const t = g.tests[i]; - should(`${name}: ${t.tcId}`, async () => { - const key = utils.hexToBytes(t.key); - const iv = utils.hexToBytes(t.iv); - const msg = utils.hexToBytes(t.msg); - const aad = utils.hexToBytes(t.aad); - const gcm = cipher(key, iv, aad); - const ct = utils.concatBytes(utils.hexToBytes(t.ct), utils.hexToBytes(t.tag)); - - if (t.result === 'valid') { - deepStrictEqual(await gcm.encrypt(msg), ct); - deepStrictEqual(await gcm.decrypt(ct), msg); - } else { - await rejects(async () => await a.decrypt(ct)); - } - }); - } - } -}); - -if (require.main === module) should.run(); diff --git a/test/index.js b/test/index.js index 469cae4..9b8698d 100644 --- a/test/index.js +++ b/test/index.js @@ -1,7 +1,7 @@ const { should } = require('micro-should'); require('./basic.test.js'); -require('./gcm.test.js'); -require('./gcm-siv.test.js'); +require('./polyval.test.js'); +require('./aes.test.js'); require('./ff1.test.js'); if (require.main === module) should.run(); diff --git a/test/polyval.test.js b/test/polyval.test.js new file mode 100644 index 0000000..9c46b01 --- /dev/null +++ b/test/polyval.test.js @@ -0,0 +1,69 @@ +const { deepStrictEqual } = require('assert'); +const { should, describe } = require('micro-should'); +const { hex } = require('@scure/base'); +const utils = require('../utils.js'); +const { ghash, polyval, _toGHASHKey } = require('../_polyval.js'); + +// https://datatracker.ietf.org/doc/html/rfc8452#appendix-C +const VECTORS = require('./vectors/siv.json'); + +// https://datatracker.ietf.org/doc/html/rfc8452#appendix-A +const VECTORS_GHASH = [ + { + fn: polyval, + key: hex.decode('25629347589242761d31f826ba4b757b'), + msg: ['4f4f95668c83dfb6401762bb2d01a262', 'd1a24ddd2721d006bbe45f20d3c9f362'].map(hex.decode), + exp: hex.decode('f7a3b47b846119fae5b7866cf5e5b77e'), + }, + { + fn: ghash, + key: hex.decode('25629347589242761d31f826ba4b757b'), + msg: ['4f4f95668c83dfb6401762bb2d01a262', 'd1a24ddd2721d006bbe45f20d3c9f362'].map(hex.decode), + exp: hex.decode('bd9b3997046731fb96251b91f9c99d7a'), + }, + // Ghash as polyval + { + fn: ghash, + key: _toGHASHKey(hex.decode('25629347589242761d31f826ba4b757b')), + msg: ['4f4f95668c83dfb6401762bb2d01a262', 'd1a24ddd2721d006bbe45f20d3c9f362'] + .map(hex.decode) + .map((i) => i.reverse()), + exp: hex.decode('f7a3b47b846119fae5b7866cf5e5b77e').reverse(), + }, +]; + +describe('Polyval', () => { + should('_toGHASHKey', () => { + const vectors = { + '7b754bba26f8311d7642925847936225': 'dcbaa5dd137c188ebb21492c23c9b112', + '01000000000000000000000000000000': '00800000000000000000000000000000', + '9c98c04df9387ded828175a92ba652d8': '4e4c6026fc9c3ef6c140bad495d3296c', + }; + for (const k in vectors) + deepStrictEqual(hex.encode(_toGHASHKey(hex.decode(k).reverse())), vectors[k]); + }); + + should('Basic', () => { + for (const v of VECTORS_GHASH) { + const concated = utils.concatBytes(...v.msg); + deepStrictEqual(hex.encode(v.fn(concated, v.key)), hex.encode(v.exp)); + const h = v.fn.create(v.key); + for (const m of v.msg) h.update(m); + deepStrictEqual(hex.encode(h.digest()), hex.encode(v.exp)); + } + }); + + for (const flavor of ['aes128', 'aes256', 'counterWrap']) { + for (let i = 0; i < VECTORS[flavor].length; i++) { + const v = VECTORS[flavor][i]; + should(`${flavor}(${i}): polyval`, () => { + deepStrictEqual( + hex.encode(polyval(hex.decode(v.polyvalInput), hex.decode(v.authKey))), + v.polyvalResult + ); + }); + } + } +}); + +if (require.main === module) should.run(); diff --git a/test/vectors/nist_800_38a.json b/test/vectors/nist_800_38a.json new file mode 100644 index 0000000..d32737f --- /dev/null +++ b/test/vectors/nist_800_38a.json @@ -0,0 +1,572 @@ +[ + { + "name": "F.1.1 ECB-AES128.Encrypt", + "cipher": "ecb", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc1bee22e409f96e93d7e117393172a", + "output": "3ad77bb40d7a3660a89ecaf32466ef97", + "ciphertext": "3ad77bb40d7a3660a89ecaf32466ef97" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "ae2d8a571e03ac9c9eb76fac45af8e51", + "output": "f5d3d58503b9699de785895a96fdbaaf", + "ciphertext": "f5d3d58503b9699de785895a96fdbaaf" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "30c81c46a35ce411e5fbc1191a0a52ef", + "output": "43b1cd7f598ece23881b00e3ed030688", + "ciphertext": "43b1cd7f598ece23881b00e3ed030688" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "f69f2445df4f9b17ad2b417be66c3710", + "output": "7b0c785e27e8ad3f8223207104725dd4", + "ciphertext": "7b0c785e27e8ad3f8223207104725dd4" + } + ] + }, + { + "name": "ECB-AES128.Decrypt", + "cipher": "ecb", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "blocks": [ + { + "ciphertext": "3ad77bb40d7a3660a89ecaf32466ef97", + "input": "3ad77bb40d7a3660a89ecaf32466ef97", + "output": "6bc1bee22e409f96e93d7e117393172a", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "f5d3d58503b9699de785895a96fdbaaf", + "input": "f5d3d58503b9699de785895a96fdbaaf", + "output": "ae2d8a571e03ac9c9eb76fac45af8e51", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "43b1cd7f598ece23881b00e3ed030688", + "input": "43b1cd7f598ece23881b00e3ed030688", + "output": "30c81c46a35ce411e5fbc1191a0a52ef", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "7b0c785e27e8ad3f8223207104725dd4", + "input": "7b0c785e27e8ad3f8223207104725dd4", + "output": "f69f2445df4f9b17ad2b417be66c3710", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "ECB-AES192.Encrypt", + "cipher": "ecb", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc1bee22e409f96e93d7e117393172a", + "output": "bd334f1d6e45f25ff712a214571fa5cc", + "ciphertext": "bd334f1d6e45f25ff712a214571fa5cc" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "ae2d8a571e03ac9c9eb76fac45af8e51", + "output": "974104846d0ad3ad7734ecb3ecee4eef", + "ciphertext": "974104846d0ad3ad7734ecb3ecee4eef" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "30c81c46a35ce411e5fbc1191a0a52ef", + "output": "ef7afd2270e2e60adce0ba2face6444e", + "ciphertext": "ef7afd2270e2e60adce0ba2face6444e" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "f69f2445df4f9b17ad2b417be66c3710", + "output": "9a4b41ba738d6c72fb16691603c18e0e", + "ciphertext": "9a4b41ba738d6c72fb16691603c18e0e" + } + ] + }, + { + "name": "F.1.4 ECB-AES192.Decrypt", + "cipher": "ecb", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "blocks": [ + { + "ciphertext": "bd334f1d6e45f25ff712a214571fa5cc", + "input": "bd334f1d6e45f25ff712a214571fa5cc", + "output": "6bc1bee22e409f96e93d7e117393172a", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "974104846d0ad3ad7734ecb3ecee4eef", + "input": "974104846d0ad3ad7734ecb3ecee4eef", + "output": "ae2d8a571e03ac9c9eb76fac45af8e51", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "ef7afd2270e2e60adce0ba2face6444e", + "input": "ef7afd2270e2e60adce0ba2face6444e", + "output": "30c81c46a35ce411e5fbc1191a0a52ef", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "9a4b41ba738d6c72fb16691603c18e0e", + "input": "9a4b41ba738d6c72fb16691603c18e0e", + "output": "f69f2445df4f9b17ad2b417be66c3710", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.1.5 ECB-AES256.Encrypt", + "cipher": "ecb", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc1bee22e409f96e93d7e117393172a", + "output": "f3eed1bdb5d2a03c064b5a7e3db181f8", + "ciphertext": "f3eed1bdb5d2a03c064b5a7e3db181f8" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "ae2d8a571e03ac9c9eb76fac45af8e51", + "output": "591ccb10d410ed26dc5ba74a31362870", + "ciphertext": "591ccb10d410ed26dc5ba74a31362870" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "30c81c46a35ce411e5fbc1191a0a52ef", + "output": "b6ed21b99ca6f4f9f153e7b1beafed1d", + "ciphertext": "b6ed21b99ca6f4f9f153e7b1beafed1d" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "f69f2445df4f9b17ad2b417be66c3710", + "output": "23304b7a39f9f3ff067d8d8f9e24ecc7", + "ciphertext": "23304b7a39f9f3ff067d8d8f9e24ecc7" + } + ] + }, + { + "name": "F.1.6 ECB-AES256.Decrypt", + "cipher": "ecb", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "blocks": [ + { + "ciphertext": "f3eed1bdb5d2a03c064b5a7e3db181f8", + "input": "f3eed1bdb5d2a03c064b5a7e3db181f8", + "output": "6bc1bee22e409f96e93d7e117393172a", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "591ccb10d410ed26dc5ba74a31362870", + "input": "591ccb10d410ed26dc5ba74a31362870", + "output": "ae2d8a571e03ac9c9eb76fac45af8e51", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "b6ed21b99ca6f4f9f153e7b1beafed1d", + "input": "b6ed21b99ca6f4f9f153e7b1beafed1d", + "output": "30c81c46a35ce411e5fbc1191a0a52ef", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "23304b7a39f9f3ff067d8d8f9e24ecc7", + "input": "23304b7a39f9f3ff067d8d8f9e24ecc7", + "output": "f69f2445df4f9b17ad2b417be66c3710", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.2.1 CBC-AES128.Encrypt", + "cipher": "cbc", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc0bce12a459991e134741a7f9e1925", + "output": "7649abac8119b246cee98e9b12e9197d", + "ciphertext": "7649abac8119b246cee98e9b12e9197d" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "d86421fb9f1a1eda505ee1375746972c", + "output": "5086cb9b507219ee95db113a917678b2", + "ciphertext": "5086cb9b507219ee95db113a917678b2" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "604ed7ddf32efdff7020d0238b7c2a5d", + "output": "73bed6b8e3c1743b7116e69e22229516", + "ciphertext": "73bed6b8e3c1743b7116e69e22229516" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "8521f2fd3c8eef2cdc3da7e5c44ea206", + "output": "3ff1caa1681fac09120eca307586e1a7", + "ciphertext": "3ff1caa1681fac09120eca307586e1a7" + } + ] + }, + { + "name": "F.2.2 CBC-AES128.Decrypt", + "cipher": "cbc", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "ciphertext": "7649abac8119b246cee98e9b12e9197d", + "input": "7649abac8119b246cee98e9b12e9197d", + "output": "6bc0bce12a459991e134741a7f9e1925", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "5086cb9b507219ee95db113a917678b2", + "input": "5086cb9b507219ee95db113a917678b2", + "output": "d86421fb9f1a1eda505ee1375746972c", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "73bed6b8e3c1743b7116e69e22229516", + "input": "73bed6b8e3c1743b7116e69e22229516", + "output": "604ed7ddf32efdff7020d0238b7c2a5d", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "3ff1caa1681fac09120eca307586e1a7", + "input": "3ff1caa1681fac09120eca307586e1a7", + "output": "8521f2fd3c8eef2cdc3da7e5c44ea206", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.2.3 CBC-AES192.Encrypt", + "cipher": "cbc", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc0bce12a459991e134741a7f9e1925", + "output": "4f021db243bc633d7178183a9fa071e8", + "ciphertext": "4f021db243bc633d7178183a9fa071e8" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "e12f97e55dbfcfa1efcf7796da0fffb9", + "output": "b4d9ada9ad7dedf4e5e738763f69145a", + "ciphertext": "b4d9ada9ad7dedf4e5e738763f69145a" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "8411b1ef0e2109e5001cf96f256346b5", + "output": "571b242012fb7ae07fa9baac3df102e0", + "ciphertext": "571b242012fb7ae07fa9baac3df102e0" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "a1840065cdb4e1f7d282fbd7db9d35f0", + "output": "08b0e27988598881d920a9e64f5615cd", + "ciphertext": "08b0e27988598881d920a9e64f5615cd" + } + ] + }, + { + "name": " F.2.4 CBC-AES192.Decrypt", + "cipher": "cbc", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "ciphertext": "4f021db243bc633d7178183a9fa071e8", + "input": "4f021db243bc633d7178183a9fa071e8", + "output": "6bc0bce12a459991e134741a7f9e1925", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "b4d9ada9ad7dedf4e5e738763f69145a", + "input": "b4d9ada9ad7dedf4e5e738763f69145a", + "output": "e12f97e55dbfcfa1efcf7796da0fffb9", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "571b242012fb7ae07fa9baac3df102e0", + "input": "571b242012fb7ae07fa9baac3df102e0", + "output": "8411b1ef0e2109e5001cf96f256346b5", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "08b0e27988598881d920a9e64f5615cd", + "input": "08b0e27988598881d920a9e64f5615cd", + "output": "a1840065cdb4e1f7d282fbd7db9d35f0", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": " F.2.4 CBC-AES192.Decrypt", + "cipher": "cbc", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "input": "6bc0bce12a459991e134741a7f9e1925", + "output": "f58c4c04d6e5f1ba779eabfb5f7bfbd6", + "ciphertext": "f58c4c04d6e5f1ba779eabfb5f7bfbd6" + }, + { + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "input": "5ba1c653c8e65d26e929c4571ad47587", + "output": "9cfc4e967edb808d679f777bc6702c7d", + "ciphertext": "9cfc4e967edb808d679f777bc6702c7d" + }, + { + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "input": "ac3452d0dd87649c8264b662dc7a7e92", + "output": "39f23369a9d9bacfa530e26304231461", + "ciphertext": "39f23369a9d9bacfa530e26304231461" + }, + { + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "input": "cf6d172c769621d8081ba318e24f2371", + "output": "b2eb05e2c39be9fcda6c19078c6a9d1b", + "ciphertext": "b2eb05e2c39be9fcda6c19078c6a9d1b" + } + ] + }, + { + "name": "F.2.6 CBC-AES256.Decrypt", + "cipher": "cbc", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "iv": "000102030405060708090a0b0c0d0e0f", + "blocks": [ + { + "ciphertext": "f58c4c04d6e5f1ba779eabfb5f7bfbd6", + "input": "f58c4c04d6e5f1ba779eabfb5f7bfbd6", + "output": "6bc0bce12a459991e134741a7f9e1925", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "ciphertext": "9cfc4e967edb808d679f777bc6702c7d", + "input": "9cfc4e967edb808d679f777bc6702c7d", + "output": "5ba1c653c8e65d26e929c4571ad47587", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "ciphertext": "39f23369a9d9bacfa530e26304231461", + "input": "39f23369a9d9bacfa530e26304231461", + "output": "ac3452d0dd87649c8264b662dc7a7e92", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "ciphertext": "b2eb05e2c39be9fcda6c19078c6a9d1b", + "input": "b2eb05e2c39be9fcda6c19078c6a9d1b", + "output": "cf6d172c769621d8081ba318e24f2371", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.5.1 CTR-AES128.Encrypt", + "cipher": "ctr", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "ec8cdf7398607cb0f2d21675ea9ea1e4", + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "ciphertext": "874d6191b620e3261bef6864990db6ce" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "362b7c3c6773516318a077d7fc5073ae", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "ciphertext": "9806f66b7970fdff8617187bb9fffdff" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "6a2cc3787889374fbeb4c81b17ba6c44", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "ciphertext": "5ae4df3edbd5d35e5b4f09020db03eab" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "e89c399ff0f198c6d40a31db156cabfe", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "ciphertext": "1e031dda2fbe03d1792170a0f3009cee" + } + ] + }, + { + "name": "F.5.1 CTR-AES128.Encrypt", + "cipher": "ctr", + "key": "2b7e151628aed2a6abf7158809cf4f3c", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "ec8cdf7398607cb0f2d21675ea9ea1e4", + "ciphertext": "874d6191b620e3261bef6864990db6ce", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "362b7c3c6773516318a077d7fc5073ae", + "ciphertext": "9806f66b7970fdff8617187bb9fffdff", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "6a2cc3787889374fbeb4c81b17ba6c44", + "ciphertext": "5ae4df3edbd5d35e5b4f09020db03eab", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "e89c399ff0f198c6d40a31db156cabfe", + "ciphertext": "1e031dda2fbe03d1792170a0f3009cee", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.5.3 CTR-AES192.Encrypt", + "cipher": "ctr", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "717d2dc639128334a6167a488ded7921", + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "ciphertext": "1abc932417521ca24f2b0459fe7e6e0b" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "a72eb3bb14a556734b7bad6ab16100c5", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "ciphertext": "090339ec0aa6faefd5ccc2c6f4ce8e94" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "2efeae2d72b722613446dc7f4c2af918", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "ciphertext": "1e36b26bd1ebc670d1bd1d665620abf7" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "b9e783b30dd7924ff7bc9b97beaa8740", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "ciphertext": "4f78a7f6d29809585a97daec58c6b050" + } + ] + }, + { + "name": "CTR-AES192.Decrypt", + "cipher": "ctr", + "key": "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "717d2dc639128334a6167a488ded7921", + "ciphertext": "1abc932417521ca24f2b0459fe7e6e0b", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "a72eb3bb14a556734b7bad6ab16100c5", + "ciphertext": "090339ec0aa6faefd5ccc2c6f4ce8e94", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "2efeae2d72b722613446dc7f4c2af918", + "ciphertext": "1e36b26bd1ebc670d1bd1d665620abf7", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "b9e783b30dd7924ff7bc9b97beaa8740", + "ciphertext": "4f78a7f6d29809585a97daec58c6b050", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + }, + { + "name": "F.5.5 CTR-AES256.Encrypt", + "cipher": "ctr", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "0bdf7df1591716335e9a8b15c860c502", + "plaintext": "6bc1bee22e409f96e93d7e117393172a", + "ciphertext": "601ec313775789a5b7a7f504bbf3d228" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "5a6e699d536119065433863c8f657b94", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51", + "ciphertext": "f443e3ca4d62b59aca84e990cacaf5c5" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "1bc12c9c01610d5d0d8bd6a3378eca62", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef", + "ciphertext": "2b0930daa23de94ce87017ba2d84988d" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "2956e1c8693536b1bee99c73a31576b6", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710", + "ciphertext": "dfc9c58db67aada613c2dd08457941a6" + } + ] + }, + { + "name": "F.5.6 CTR-AES256.Decrypt", + "cipher": "ctr", + "key": "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", + "iv": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "blocks": [ + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "output": "0bdf7df1591716335e9a8b15c860c502", + "ciphertext": "601ec313775789a5b7a7f504bbf3d228", + "plaintext": "6bc1bee22e409f96e93d7e117393172a" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "output": "5a6e699d536119065433863c8f657b94", + "ciphertext": "f443e3ca4d62b59aca84e990cacaf5c5", + "plaintext": "ae2d8a571e03ac9c9eb76fac45af8e51" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "output": "1bc12c9c01610d5d0d8bd6a3378eca62", + "ciphertext": "2b0930daa23de94ce87017ba2d84988d", + "plaintext": "30c81c46a35ce411e5fbc1191a0a52ef" + }, + { + "input": "f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "output": "2956e1c8693536b1bee99c73a31576b6", + "ciphertext": "dfc9c58db67aada613c2dd08457941a6", + "plaintext": "f69f2445df4f9b17ad2b417be66c3710" + } + ] + } +] diff --git a/test/wycheproof/aes_cbc_pkcs5_test.json b/test/wycheproof/aes_cbc_pkcs5_test.json new file mode 100644 index 0000000..313b623 --- /dev/null +++ b/test/wycheproof/aes_cbc_pkcs5_test.json @@ -0,0 +1,2639 @@ +{ + "algorithm" : "AES-CBC-PKCS5", + "schema" : "ind_cpa_test_schema.json", + "generatorVersion" : "0.9", + "numberOfTests" : 216, + "header" : [ + "Test vectors of type IndCpaTest are intended for tests that verify", + "encryption and decryption of symmetric ciphers without authentication." + ], + "notes" : { + "BadPadding" : { + "bugType" : "MISSING_STEP", + "description" : "The ciphertext in this test vector is the message encrypted without a correct PKCS #5 padding. The goal is to find implementations that accept alternative paddings and implementations that are not properly checking the padding during decryption." + }, + "NoPadding" : { + "bugType" : "MISSING_STEP", + "description" : "The ciphertext in this test vector is empty. Hence the ciphertext is not valid." + }, + "Pseudorandom" : { + "bugType" : "FUNCTIONALITY", + "description" : "The test vector contains pseudorandomly generated inputs. The goal of the test vector is to check the correctness of the implementation for various sizes of the input parameters." + } + }, + "testGroups" : [ + { + "type" : "IndCpaTest", + "keySize" : 128, + "ivSize" : 128, + "tests" : [ + { + "tcId" : 1, + "comment" : "empty message", + "flags" : [ + "Pseudorandom" + ], + "key" : "e34f15c7bd819930fe9d66e0c166e61c", + "iv" : "da9520f7d3520277035173299388bee2", + "msg" : "", + "ct" : "b10ab60153276941361000414aed0a9d", + "result" : "valid" + }, + { + "tcId" : 2, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "e09eaa5a3f5e56d279d5e7a03373f6ea", + "iv" : "c9ee3cd746bf208c65ca9e72a266d54f", + "msg" : "ef4eab37181f98423e53e947e7050fd0", + "ct" : "d1fa697f3e2e04d64f1a0da203813ca5bc226a0b1d42287b2a5b994a66eaf14a", + "result" : "valid" + }, + { + "tcId" : 3, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "9bd3902ed0996c869b572272e76f3889", + "iv" : "8b2e86a9a185cfa6f51c7cc595b822bc", + "msg" : "a7ba19d49ee1ea02f098aa8e30c740d893a4456ccc294040484ed8a00a55f93e", + "ct" : "514cbc69aced506926deacdeb0cc0a5a07d540f65d825b65c7db0075cf930a06e0124ae598461cab0b3251baa853e377", + "result" : "valid" + }, + { + "tcId" : 4, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "75ce184447cada672e02290310d224f7", + "iv" : "2717d10eb2eea3b39ec257e43307a260", + "msg" : "c774810a31a6421ad8eaafd5c22fa2455e2c167fee4a0b73ff927b2d96c69da1e939407b86b1c19bcfc69c434c3cf8a2", + "ct" : "137c824d7f7dc36f24216dde37c2e1c10cee533f6453de92e44b898fc3037d2e9e19d67a96387136dd9717a56e28614a5c177158f402ce2936fd98d1feb6a817", + "result" : "valid" + }, + { + "tcId" : 5, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "e1e726677f4893890f8c027f9d8ef80d", + "iv" : "155fd397579b0b5d991d42607f2cc9ad", + "msg" : "3f", + "ct" : "599d77aca16910b42d8b4ac9560efe1b", + "result" : "valid" + }, + { + "tcId" : 6, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "b151f491c4c006d1f28214aa3da9a985", + "iv" : "4eb836be6808db264cb1111a3283b394", + "msg" : "27d9", + "ct" : "74e20bf03a0ad4b49edc86a1b19c3d1d", + "result" : "valid" + }, + { + "tcId" : 7, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "c36ff15f72777ee21deec07b63c1a0cd", + "iv" : "a8446c27ea9068d8d924d5c4eac91157", + "msg" : "50b428", + "ct" : "3f7a26558ba51cf352219d34c46907ae", + "result" : "valid" + }, + { + "tcId" : 8, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "32b9c5c78c3a0689a86052420fa1e8fc", + "iv" : "ef026d27da3702d7bb72e5e364a8f8f2", + "msg" : "0b9262ec", + "ct" : "c29d1463baccc558fd720c897da5bb98", + "result" : "valid" + }, + { + "tcId" : 9, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "43151bbaef367277ebfc97509d0aa49c", + "iv" : "c9defd3929dcd6c355c144e9750dd869", + "msg" : "eaa91273e7", + "ct" : "e24a717914f9cc8eaa1dc96f7840d6af", + "result" : "valid" + }, + { + "tcId" : 10, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "481440298525cc261f8159159aedf62d", + "iv" : "ce91e0454b0123f1ead0f158826459e9", + "msg" : "6123c556c5cc", + "ct" : "f080e487f4e5b7aed793ea95ffe4bb30", + "result" : "valid" + }, + { + "tcId" : 11, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "9ca26eb88731efbf7f810d5d95e196ac", + "iv" : "1cb7bc8fe00523e7743d3cd9f483d6fe", + "msg" : "7e48f06183aa40", + "ct" : "27cadee413ed901f51c9366d731d95f6", + "result" : "valid" + }, + { + "tcId" : 12, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "48f0d03e41cc55c4b58f737b5acdea32", + "iv" : "a345f084229dbfe0ceab6c6939571532", + "msg" : "f4a133aa6d5985a0", + "ct" : "59bf12427b51a3aee0c9d3c540d04d24", + "result" : "valid" + }, + { + "tcId" : 13, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "1c958849f31996b28939ce513087d1be", + "iv" : "e5b6f73f132355b7be7d977bea068dfc", + "msg" : "b0d2fee11b8e2f86b7", + "ct" : "1a0a18355f8ca4e6e2cf31da18d070da", + "result" : "valid" + }, + { + "tcId" : 14, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "39de0ebea97c09b2301a90009a423253", + "iv" : "c7cd10ca949ea03e7d4ba204b69e09b8", + "msg" : "81e5c33b4c620852f044", + "ct" : "cef498ea61715a27f400418d1d5bfbf0", + "result" : "valid" + }, + { + "tcId" : 15, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "91656d8fc0aced60ddb1c4006d0dde53", + "iv" : "bb8c9af30821dfeb7124392a554d9f01", + "msg" : "7b3e440fe566790064b2ec", + "ct" : "7ab43ddc45835ce40d2280bcea6a63f2", + "result" : "valid" + }, + { + "tcId" : 16, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "af7d5134720b5386158d51ea126e7cf9", + "iv" : "54c3b90ca6e933f9094334d0263d3775", + "msg" : "7cc6fcc925c20f3c83b5567c", + "ct" : "c70b457c945ad40895cf4c8be3ce7c66", + "result" : "valid" + }, + { + "tcId" : 17, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "4ed56753de6f75a032ebabca3ce27971", + "iv" : "9a2c5e91d4f0b9b9da64b46c5c2c8cb2", + "msg" : "0c8c0f5619d9f8da5339281285", + "ct" : "f9900afee2acfe63f8f15d81bbf64c39", + "result" : "valid" + }, + { + "tcId" : 18, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "beba50c936b696c15e25046dffb23a64", + "iv" : "cf7951501104e1434309e6b936ec1742", + "msg" : "821ea8532fbabffb6e3d212e9b46", + "ct" : "da4137bd8ac78e75a700b3de806f2d6f", + "result" : "valid" + }, + { + "tcId" : 19, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "501d81ebf912ddb87fbe3b7aac1437bc", + "iv" : "90f5cf4fbfd2e2a1ab8eef402617bd5c", + "msg" : "2368e3c3636b5e8e94d2081adbf798", + "ct" : "fed05321d11d978e2ec32527ecfce06c", + "result" : "valid" + }, + { + "tcId" : 20, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "831e664c9e3f0c3094c0b27b9d908eb2", + "iv" : "54f2459e40e002763144f4752cde2fb5", + "msg" : "26603bb76dd0a0180791c4ed4d3b058807", + "ct" : "8d55dc10584e243f55d2bdbb5758b7fabcd58c8d3785f01c7e3640b2a1dadcd9", + "result" : "valid" + }, + { + "tcId" : 21, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "cbffc6c8c7f76f46349c32d666f4efb0", + "iv" : "088e01c2c65b26e7ad6af7b92ea09d73", + "msg" : "6df067add738195fd55ac2e76b476971b9a0e6d8", + "ct" : "e9199842355ea0c3dbf1b2a94fef1c802a95d024df9e407883cf5bf1f02c3cdc", + "result" : "valid" + }, + { + "tcId" : 22, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "fda6a01194beb462953d7e6c49b32dac", + "iv" : "d9c9468796a2f5741b84d2d41430c5d3", + "msg" : "f60ae3b036abcab78c98fc1d4b67970c0955cb6fe24483f8907fd73319679b", + "ct" : "19beb4db2be0f3aff0083583038b2281a77c85b5f345ba4d2bc7f742a14f9247", + "result" : "valid" + }, + { + "tcId" : 23, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "efd9caa8ac68e9e29acdae57e93bcea8", + "iv" : "c98b47808add45c0c891983ec4b09846", + "msg" : "3e1d2001f1e475b972738936443a5f51eedaf802a66fadf2406cfaadb0549149fcb9f485e534dc2d", + "ct" : "84904fc92bd2e7590aa268e667370327b9446f41067dd40d3e5091a63a0d5687e4926e00cc3cb461c3b85d80ee2da818", + "result" : "valid" + }, + { + "tcId" : 24, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "37e4dbdc436258d5a9adb9f205c77cf3", + "iv" : "08e9410de244d3f40607ebae38fa74e7", + "msg" : "24a874aec067116ad22eb55846ded3f5e86919a135585c929a86d92b2958fed110e52e33804887243584a6a94402cc9a105e0c940ec335bd2890f16dcce3fc8bd02873c80ade6f1ac08683130bcca454", + "ct" : "1d1391593a336be4b207295ad0542bc4ef2f39053066e12c38f71603f377fd42f4f0b2b5a42cdfeaee2af039f06fcf347abe171af3157ff07f3cdd3b33e11a60caecf9890325c132eeb66ab847278d165c26bca7c30486bb2fd83b63c5ff7ae0", + "result" : "valid" + }, + { + "tcId" : 25, + "comment" : "empty ciphertext", + "flags" : [ + "NoPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "", + "result" : "invalid" + }, + { + "tcId" : 26, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "aa62606a287476777b92d8e4c4e53028", + "result" : "invalid" + }, + { + "tcId" : 27, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "ada437b682c92384b6c23ec10a21b3d8", + "result" : "invalid" + }, + { + "tcId" : 28, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "303132333435363738396162636465", + "ct" : "26c5b3e540ee3dd6b52d14afd01a44f8", + "result" : "invalid" + }, + { + "tcId" : 29, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbc0deb417e98aba3ee12fea2921f8ae51", + "result" : "invalid" + }, + { + "tcId" : 30, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb1188ff22f6563f6173440547d1e0dfd8", + "result" : "invalid" + }, + { + "tcId" : 31, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff182842411005a1322b61f608c69f46d6e6b450bc1fde", + "result" : "invalid" + }, + { + "tcId" : 32, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "726570a34cea08139d9f836579102a0e", + "result" : "invalid" + }, + { + "tcId" : 33, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "c8ef7ac3fd659ce7157d72a25f0a5048", + "result" : "invalid" + }, + { + "tcId" : 34, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "303132333435363738396162636465", + "ct" : "6123c889bbc766acd4bca4cb982f9978", + "result" : "invalid" + }, + { + "tcId" : 35, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb442cd16f7410fca70924b573f7967e84", + "result" : "invalid" + }, + { + "tcId" : 36, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbb20f899b0e7c1d65b931af94b5c44c25", + "result" : "invalid" + }, + { + "tcId" : 37, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff1828424110053c2f51db27813b3ba2a63dac2b665897", + "result" : "invalid" + }, + { + "tcId" : 38, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "50aeed98a820c5a037a5aa4d4ef3090b", + "result" : "invalid" + }, + { + "tcId" : 39, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "25ee339006f948f42713543c62467ef9", + "result" : "invalid" + }, + { + "tcId" : 40, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "303132333435363738396162636465", + "ct" : "97914574676ed5b8db0b6f3931195b3f", + "result" : "invalid" + }, + { + "tcId" : 41, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb2874a1e2d28dd18e5573df9fd59fd789", + "result" : "invalid" + }, + { + "tcId" : 42, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbb547c4fddbdcd3e02f438a2e48587594", + "result" : "invalid" + }, + { + "tcId" : 43, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff1828424110058e5fef15502ed315a7b8c7f483168431", + "result" : "invalid" + }, + { + "tcId" : 44, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "d17ccbb26f0aa95f397b20063547349bac24c5429cbea591e96595cccc11451b", + "result" : "invalid" + }, + { + "tcId" : 45, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "fc07025e81d43efa85f92afdf8781b1e88598e12d6812df43733e93414b9e901", + "result" : "invalid" + }, + { + "tcId" : 46, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "303132333435363738396162636465", + "ct" : "deb1746f4e9e0be4a21825b071b6e93303031651e0c59091e2ae0fbcce11b987", + "result" : "invalid" + }, + { + "tcId" : 47, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb563d35096fde10ccb6f768438c9eb4ec90f399b76924c716e9f94143263306c6", + "result" : "invalid" + }, + { + "tcId" : 48, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbc8fd2e2c5362acf5212bd47859aa827d8469b87b0e6adafe3dba98c1885b6345", + "result" : "invalid" + }, + { + "tcId" : 49, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff18284241100511eec58e0bc17750fed7cb2219afb5aa76b93855aee87afebea0856414829a3a", + "result" : "invalid" + }, + { + "tcId" : 50, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "ca5dd2d09bd56eec9e8acaeca20af68e", + "result" : "invalid" + }, + { + "tcId" : 51, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "01e53a5ec9b0957c45f79ed0f4b2b982", + "result" : "invalid" + }, + { + "tcId" : 52, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbd3909bb3457e5b946ff709be9a2ed84d", + "result" : "invalid" + }, + { + "tcId" : 53, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbc5ab3ab637166a6a067b82b5672c08f8", + "result" : "invalid" + }, + { + "tcId" : 54, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff182842411005cc51f7f4500445a15cc476a7d262c78e", + "result" : "invalid" + }, + { + "tcId" : 55, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "ba0726bd6dea11382b19c842e2ddead2", + "result" : "invalid" + }, + { + "tcId" : 56, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "22f18b85c729903744fb8db5ed2840d4", + "result" : "invalid" + }, + { + "tcId" : 57, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb6b103fbe43519a18880b7e6d9153e1c2", + "result" : "invalid" + }, + { + "tcId" : 58, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbe00bdb15b8a61285447498700d35e0c6", + "result" : "invalid" + }, + { + "tcId" : 59, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff18284241100537f7563e3977426b9c60ff8156e89c1c", + "result" : "invalid" + }, + { + "tcId" : 60, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "d17ccbb26f0aa95f397b20063547349b", + "result" : "invalid" + }, + { + "tcId" : 61, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "2056dfa339fa00be6836999411a98c76", + "result" : "invalid" + }, + { + "tcId" : 62, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "303132333435363738396162636465", + "ct" : "f92628f6418d8d9c9afac233861b3835", + "result" : "invalid" + }, + { + "tcId" : 63, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbc0c41093b495a7d5a080d976493fd0e7", + "result" : "invalid" + }, + { + "tcId" : 64, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb6770446a5ccaa26f7d4f970cc5834eba", + "result" : "invalid" + }, + { + "tcId" : 65, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff182842411005c71deff2b83c2bd536231d13fb767205", + "result" : "invalid" + }, + { + "tcId" : 66, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "", + "ct" : "4ff3e623fdd432608c183f40864177af", + "result" : "invalid" + }, + { + "tcId" : 67, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "6162636465666768", + "ct" : "6a1ef1e6ae6a788777aabd9ccf3cf43a", + "result" : "invalid" + }, + { + "tcId" : 68, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbee1345cd513161b241f4ae2799b0327f", + "result" : "invalid" + }, + { + "tcId" : 69, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "3031323334353637383941424344454647", + "ct" : "fbcbdfdaaf17980be939c0b243266ecbe0d539beef6f2d4f7cda4fd9f4f05570", + "result" : "invalid" + }, + { + "tcId" : 70, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff182842411005bde40966f0eb8b4f598c61158aebc9d3", + "result" : "invalid" + }, + { + "tcId" : 71, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "30313233343536373839414243444546", + "ct" : "fbcbdfdaaf17980be939c0b243266ecb", + "result" : "invalid" + }, + { + "tcId" : 72, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "db4f3e5e3795cc09a073fa6a81e5a6bc", + "iv" : "23468aa734f5f0f19827316ff168e94f", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "87ff6a2fc6920ce4769cbf6532f84dde389de7c3b693c5e0ceff182842411005", + "result" : "invalid" + } + ] + }, + { + "type" : "IndCpaTest", + "keySize" : 192, + "ivSize" : 128, + "tests" : [ + { + "tcId" : 73, + "comment" : "empty message", + "flags" : [ + "Pseudorandom" + ], + "key" : "3d6bf9edae6d881eade0ff8c7076a4835b71320c1f36b631", + "iv" : "db20f9a6f4d6b4e478f1a4b9d4051d34", + "msg" : "", + "ct" : "ff0c315873b4b1872abef2353b792ef0", + "result" : "valid" + }, + { + "tcId" : 74, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "f4bfa5aa4f0f4d62cf736cd2969c43d580fdb92f2753bedb", + "iv" : "69a76dc4da64d89c580eb75ae975ec39", + "msg" : "0e239f239705b282ce2200fe20de1165", + "ct" : "7dbd573e4db58a318edfe29f199d8cda538a49f36486337c2711163e55fd5d0b", + "result" : "valid" + }, + { + "tcId" : 75, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "9d11abc1fcb248a436598e695be12c3c2ed90a18ba09d62c", + "iv" : "6525667350930fb945dd1895a3abfcd1", + "msg" : "aa5182cae2a8fb068c0b3fb2be3e57ae523d13dffd1a944587707c2b67447f3f", + "ct" : "bd0258909e5b72438d95ca4b29c8a79c6228fd06a3b2fa06f7659654c7b24610f23f2fb16313b7d3614cb0cd16fabb8e", + "result" : "valid" + }, + { + "tcId" : 76, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "7e41d83181659a2c38da5ead353cdb04c2b4d4a3cfe58e25", + "iv" : "3943d8fddd5bb2a59772df31a31a8fff", + "msg" : "8a32d11c7a11aa72e13381632b1310f4fd90fc209a6a350e61c069a561871214f9c04fc1df7354cbe4d8d639c525d324", + "ct" : "6cbeacf8de25d7dd9dcdc087bf2f80873b1eb335400589076f8d2bf81e294c5d72b85eb8ac9558b0de9e9fbee4b18716e5220c507fbb9d319a08f67816765ca6", + "result" : "valid" + }, + { + "tcId" : 77, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "915429743435c28997a33b33b6574a953d81dae0e7032e6a", + "iv" : "1379d48493f743e6a149deb3b9bab31e", + "msg" : "58", + "ct" : "519925956d32e4fa350b1144f088e4e8", + "result" : "valid" + }, + { + "tcId" : 78, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "f0c288ba26b284f9fb321b444a6517b3cdda1a799d55fdff", + "iv" : "48c7f44b43a1279d820733e6cb30617a", + "msg" : "0f7e", + "ct" : "bfb90aa7de1bdeed5bdc5703bdfd9630", + "result" : "valid" + }, + { + "tcId" : 79, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "6b55e4d4fd6847a80a6bfb0dcc0aa93f9fd797fc5c50292e", + "iv" : "2c287b38cc30c8c351b087b91a6a97ba", + "msg" : "33f530", + "ct" : "b1a25816908c086f26037d10b7be9ad9", + "result" : "valid" + }, + { + "tcId" : 80, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "1eb21a9e995a8e45c9e71ecbd6fe615b3e0318007c64b644", + "iv" : "61f6060919c9c09ef06be28f39c344aa", + "msg" : "3aa73c48", + "ct" : "74dbdecbfa94b71d2d6ef03200c7d095", + "result" : "valid" + }, + { + "tcId" : 81, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "710e2d5d4a9f0bc7e50796655e046a18cc5769d7764355da", + "iv" : "7682005907bfef3ce00196a17ad2246d", + "msg" : "7e4c690a88", + "ct" : "10c860aaee23c3c3c1b9306b189dd80d", + "result" : "valid" + }, + { + "tcId" : 82, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "d8c09ea400779b63e774bdacd0cb7b5dd6f736ca23d52acf", + "iv" : "1f6c912997ce007701e5fdf407c6b421", + "msg" : "e9520280973b", + "ct" : "673dcd444386930a0cc577fab4501e5c", + "result" : "valid" + }, + { + "tcId" : 83, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "8e67e9a0863b55bed408866f1cbc05357abe3f9d79f406f2", + "iv" : "5854033ae50de090678432781a168b6c", + "msg" : "4880b412287a0b", + "ct" : "059e5f72a81d8820add8eae8fabcdd42", + "result" : "valid" + }, + { + "tcId" : 84, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "28d8da67806410e5565bcc5a9d7ab9fb357413fa0158378c", + "iv" : "003b2d86d8b636c58cf664565572d5e6", + "msg" : "004e3f4a4e6db955", + "ct" : "c412159fd5ae20d771b7d2e734124d6a", + "result" : "valid" + }, + { + "tcId" : 85, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "dc968dd89fd602bb7eca6f3a8a13e4f59c08d02a514b1934", + "iv" : "3f22b50f888ab9424ba871d15aac55b7", + "msg" : "41a25354efeb1bc3b8", + "ct" : "4aba571c2c5ab9a6140f16efc68c8ec1", + "result" : "valid" + }, + { + "tcId" : 86, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "7658951c0f620d82afd92756cc2d7983b79da3e56fdd1b78", + "iv" : "e4b8dde04b49fa6b88bfccd8d70c21d1", + "msg" : "f0e82fb5c5666f4af49f", + "ct" : "66d1b9152a8cd1a88eab341c775070b4", + "result" : "valid" + }, + { + "tcId" : 87, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "d9574c3a221b986690931faac5258d9d3c52362b2cb9b054", + "iv" : "7753f616cd8796c9b8a3bbfbe6cb1e7f", + "msg" : "178ea8404ba54ee4e4522c", + "ct" : "d9377788e2881a48f9347786db7df51f", + "result" : "valid" + }, + { + "tcId" : 88, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "704409bab28085c44981f28f75dd143a4f747106f63f262e", + "iv" : "eae9ee19ccb7f8b087675709c4d35f73", + "msg" : "cda5709e7f115624e74ab031", + "ct" : "db825f4434ea3bb53576fa7385fb7dfe", + "result" : "valid" + }, + { + "tcId" : 89, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "d8d06ef6a53bbff5c8f12d791b8f4c67e574bf440736d1cc", + "iv" : "a6aaff339a729d30a7ec1328db36d23e", + "msg" : "a1171eae1979f48345dd9485a0", + "ct" : "3e7287df2a5ed9de4d817e352bd47ea7", + "result" : "valid" + }, + { + "tcId" : 90, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "71129e781613f39d9ac39fbde2628b44c250c14deb5ef9e2", + "iv" : "92fda71e88c70d18ed71b992735a2150", + "msg" : "967593cc64bcbf7f3c58d04cb82b", + "ct" : "17c3ade4b469ae614760039a8fa6250e", + "result" : "valid" + }, + { + "tcId" : 91, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "850fc859e9f7b89a367611dee6698f33962d8245ca8dc331", + "iv" : "ed6596c86b98123ad2f3c573e974d051", + "msg" : "586f4f171af116519061a8e0e77940", + "ct" : "9cafecff2a28d02f732573f65a2cadca", + "result" : "valid" + }, + { + "tcId" : 92, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "cfd3f68873d81a27d2bfce876c79f6e609074dec39e34614", + "iv" : "c45b52a240eba3bdde5dfd57f3d474fb", + "msg" : "b1973cb25aa87ef9d1a8888b0a0f5c04c6", + "ct" : "401ad889bdb9d38816c782e00b168ccccde9bf75f4be868ceb91237e8b37b750", + "result" : "valid" + }, + { + "tcId" : 93, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "b7f165bced1613da5e747fdf9255832d30c07f2deeb5a326", + "iv" : "07ece5fe02266e073499fd4d66929034", + "msg" : "289647ea8d0ff31375a82aa1c620903048bb1d0e", + "ct" : "455d516e87851e6c894578a0f7126e0acbc7cfbb1d80296647ab89a79dfa6f71", + "result" : "valid" + }, + { + "tcId" : 94, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "9bbe6e004fb260dadb02b68b78954f1da5e6a2d02e0aeefe", + "iv" : "d799157bc1f77c182027be918b30783a", + "msg" : "665423092ce95b927e98b8082030f58e33f3ec1b0c29532c2f421855f00f97", + "ct" : "cbf541330a5a9bda24984976b0cf96ba08ef521fa2cdb3df839128570e222ac4", + "result" : "valid" + }, + { + "tcId" : 95, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "1381fbd5e79045d40f29790fc1a436c95b040a046ebf0b0f", + "iv" : "fdf97645e4192ba84728bbf6683f79de", + "msg" : "d575dce596dd0a2cd1c18dab7eb0948fafb8669969a48b6314493bfb8daf8acacd51382f9bb5b357", + "ct" : "03225f08592efca14ad8ecf822465e8be4157465d0be150dd3d645b6fef1b19ca7bbaa5940b2a7895fa2b0ee55b0d4ec", + "result" : "valid" + }, + { + "tcId" : 96, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "1bb4ed0e8435e20729f48c1b7e3af6e69e4cebf0731131cf", + "iv" : "059685f59247eea5d3f2a1532cb9d6b2", + "msg" : "6d29dab6a0568c961ab3c825e0d89940cef06c63ade7e557cd3e92792eaf23c8cd5a0f029c63b1cdce4754ccfad7a73c7c9e50ffe081e9136f5e9a424077339de12ea43572afe1b034e833e5887763aa", + "ct" : "27ad00313f328f0d3e6c3238ab560cb7243a9f54f7dff79b5a7a879439993d458017f09e8d3f694098bc19e61fe54085138664abb51a5b328cf2c9ce5d59726fff5e1b7553c143d9e0493c51cab23ff2ecdad91bd72bb12b32f3b611f9a4225d", + "result" : "valid" + }, + { + "tcId" : 97, + "comment" : "empty ciphertext", + "flags" : [ + "NoPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "", + "result" : "invalid" + }, + { + "tcId" : 98, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "2c010faa25c68c3b30b8c1491c316d5f", + "result" : "invalid" + }, + { + "tcId" : 99, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "818454d433154a8e00e8f590b8a1c38c", + "result" : "invalid" + }, + { + "tcId" : 100, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "303132333435363738396162636465", + "ct" : "0a7423fae3f4c8d4633f839d36f2e9ff", + "result" : "invalid" + }, + { + "tcId" : 101, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432e83f6e522c371e6e71bde539595b70b7", + "result" : "invalid" + }, + { + "tcId" : 102, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b6143254d15f47701fa54f5957828f386e1d97", + "result" : "invalid" + }, + { + "tcId" : 103, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99950977c1735eebd4cca1d16eb34eabdc", + "result" : "invalid" + }, + { + "tcId" : 104, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "6ded36cc7603e514014dfb7199900676", + "result" : "invalid" + }, + { + "tcId" : 105, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "839f772f8e5f50afdc02f954094869fe", + "result" : "invalid" + }, + { + "tcId" : 106, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "303132333435363738396162636465", + "ct" : "eefe3553c099c187929b287e54f95726", + "result" : "invalid" + }, + { + "tcId" : 107, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432d0531a2641d40467353542d79ce20ea8", + "result" : "invalid" + }, + { + "tcId" : 108, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432aaf08a090ecf66167ba5958100be7950", + "result" : "invalid" + }, + { + "tcId" : 109, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99c8003e49eba55789722a032aaa35ef19", + "result" : "invalid" + }, + { + "tcId" : 110, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "c0e402c8bbdda18c8ddd86470bd4b244", + "result" : "invalid" + }, + { + "tcId" : 111, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "dc185d4572565e01131e471ec4c48125", + "result" : "invalid" + }, + { + "tcId" : 112, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "303132333435363738396162636465", + "ct" : "3ad1ddf3c3b320398785e6ec6544e9a2", + "result" : "invalid" + }, + { + "tcId" : 113, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b614325876f90cfbbdbcd85e8252d37c44c638", + "result" : "invalid" + }, + { + "tcId" : 114, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432d18f57216b0e6426d911998a0e44156b", + "result" : "invalid" + }, + { + "tcId" : 115, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99da7c1dfafb5aa853a2c9ab1cb4362609", + "result" : "invalid" + }, + { + "tcId" : 116, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "f1605abb4e6628347c616da350fe243043a8d7b6aea244ca013f45241d802213", + "result" : "invalid" + }, + { + "tcId" : 117, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "a5f027fb9514ec8844534d452c940feb2c1807f57ed628156cf753f2ab698356", + "result" : "invalid" + }, + { + "tcId" : 118, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "303132333435363738396162636465", + "ct" : "f346fbc9744d723c42bbb2a4c934cdd4f1019e58c226cb2491fed621271a38f3", + "result" : "invalid" + }, + { + "tcId" : 119, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b6143263eb325d36e13aa1d3dd1d7e071700104c7eb3e22e0859aa06296bc3194bb909", + "result" : "invalid" + }, + { + "tcId" : 120, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432219485d41584bd110a6d7a9cad472815d93921c48d4bcb509fdf2e63d7627c37", + "result" : "invalid" + }, + { + "tcId" : 121, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c991937c7fe69e3b9159e480480d8d7cbefcd768eda18d3bd52c5d756bdd723a198", + "result" : "invalid" + }, + { + "tcId" : 122, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "215571a18a70140f3a0fd4c1b2dd6316", + "result" : "invalid" + }, + { + "tcId" : 123, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "2529985ec0ec3cf4bd22746e00d7bdc6", + "result" : "invalid" + }, + { + "tcId" : 124, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b614329a8058657ac4a150e995cf83efccf051", + "result" : "invalid" + }, + { + "tcId" : 125, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b614328a068626780ba600f880bd5323f8ac15", + "result" : "invalid" + }, + { + "tcId" : 126, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99363bf99b2c769a56b498e4d8bb76299b", + "result" : "invalid" + }, + { + "tcId" : 127, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "13e75f9ffe2afa81b9a2e7faf74aab6d", + "result" : "invalid" + }, + { + "tcId" : 128, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "a382197fe491f5c3f91b629dc47c3d58", + "result" : "invalid" + }, + { + "tcId" : 129, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b614320b842e5d6e32660263ff814a0277659f", + "result" : "invalid" + }, + { + "tcId" : 130, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b614321d2f736515cfe17921800eb392e0139d", + "result" : "invalid" + }, + { + "tcId" : 131, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99ea8866f7cc7ed448108f9ce64e17b6d3", + "result" : "invalid" + }, + { + "tcId" : 132, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "f1605abb4e6628347c616da350fe2430", + "result" : "invalid" + }, + { + "tcId" : 133, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "b3602ff0f797cbbdde35105d27e55b94", + "result" : "invalid" + }, + { + "tcId" : 134, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "303132333435363738396162636465", + "ct" : "0334c1bc34b597f60a639e74d8b45c4e", + "result" : "invalid" + }, + { + "tcId" : 135, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432c3f9fe42d9715035bcda97d27405ced7", + "result" : "invalid" + }, + { + "tcId" : 136, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432362b014a9abdaf25ae1f6dfb99d03d9d", + "result" : "invalid" + }, + { + "tcId" : 137, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99c6a5874185a0dcddf13518b88b8571a7", + "result" : "invalid" + }, + { + "tcId" : 138, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "", + "ct" : "97ab405b86c388f144cf74fbb9358493", + "result" : "invalid" + }, + { + "tcId" : 139, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "6162636465666768", + "ct" : "691f6009802f0fb4920928db7eca1349", + "result" : "invalid" + }, + { + "tcId" : 140, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432a99fc96a6fa0c9fcb18de1672d74914d", + "result" : "invalid" + }, + { + "tcId" : 141, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "3031323334353637383941424344454647", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432dd1bb2e98102322fb1aa92c979d4c7c3", + "result" : "invalid" + }, + { + "tcId" : 142, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99560b982813ca721da46fb015b4db9df4", + "result" : "invalid" + }, + { + "tcId" : 143, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "30313233343536373839414243444546", + "ct" : "a7cfcdabcc5a2736a2708c1cb0b61432", + "result" : "invalid" + }, + { + "tcId" : 144, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "9e20311eaf2eaf3e3a04bc52564e67313c84940a2996e3f2", + "iv" : "a3fe6f76e8f582830bbe83574a7bb729", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "afb5768311592c06f085dc84734fd2320b1dd17b7f9012b9f7f85f7039871c99", + "result" : "invalid" + } + ] + }, + { + "type" : "IndCpaTest", + "keySize" : 256, + "ivSize" : 128, + "tests" : [ + { + "tcId" : 145, + "comment" : "empty message", + "flags" : [ + "Pseudorandom" + ], + "key" : "7bf9e536b66a215c22233fe2daaa743a898b9acb9f7802de70b40e3d6e43ef97", + "iv" : "eb38ef61717e1324ae064e86f1c3e797", + "msg" : "", + "ct" : "e7c166554d1bb32792c981fa674cc4d8", + "result" : "valid" + }, + { + "tcId" : 146, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "612e837843ceae7f61d49625faa7e7494f9253e20cb3adcea686512b043936cd", + "iv" : "9ec7b863ac845cad5e4673da21f5b6a9", + "msg" : "cc37fae15f745a2f40e2c8b192f2b38d", + "ct" : "299295be47e9f5441fe83a7a811c4aeb2650333e681e69fa6b767d28a6ccf282", + "result" : "valid" + }, + { + "tcId" : 147, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "96e1e4896fb2cd05f133a6a100bc5609a7ac3ca6d81721e922dadd69ad07a892", + "iv" : "e70d83a77a2ce722ac214c00837acedf", + "msg" : "91a17e4dfcc3166a1add26ff0e7c12056e8a654f28a6de24f4ba739ceb5b5b18", + "ct" : "a615a39ff8f59f82cf72ed13e1b01e32459700561be112412961365c7a0b58aa7a16d68c065e77ebe504999051476bd7", + "result" : "valid" + }, + { + "tcId" : 148, + "comment" : "message size divisible by block size", + "flags" : [ + "Pseudorandom" + ], + "key" : "649e373e681ef52e3c10ac265484750932a9918f28fb824f7cb50adab39781fe", + "iv" : "bd003c0a9d804c29f053a77cb380cb47", + "msg" : "39b447bd3a01983c1cb761b456d69000948ceb870562a536126a0d18a8e7e49b16de8fe672f13d0808d8b7d957899917", + "ct" : "ed3ed8ecdbabc0a8c06259e913f3ab9a1f1dc6d05e5dfdd9c80e1008f3423064d540681291bbd3e159820fee3ff190a68fe506d8ab9e62c8e7b3816093336dbc", + "result" : "valid" + }, + { + "tcId" : 149, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "e754076ceab3fdaf4f9bcab7d4f0df0cbbafbc87731b8f9b7cd2166472e8eebc", + "iv" : "014d2e13dfbcb969ba3bb91442d52eca", + "msg" : "40", + "ct" : "42c0b89a706ed2606cd94f9cb361fa51", + "result" : "valid" + }, + { + "tcId" : 150, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "ea3b016bdd387dd64d837c71683808f335dbdc53598a4ea8c5f952473fafaf5f", + "iv" : "fae3e2054113f6b3b904aadbfe59655c", + "msg" : "6601", + "ct" : "b90c326b72eb222ddb4dae47f2bc223c", + "result" : "valid" + }, + { + "tcId" : 151, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "73d4709637857dafab6ad8b2b0a51b06524717fedf100296644f7cfdaae1805b", + "iv" : "203cd3e0068e43d38b6f2e48a188f252", + "msg" : "f1d300", + "ct" : "567c45c5e6d570bef583d21cac43757d", + "result" : "valid" + }, + { + "tcId" : 152, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "d5c81b399d4c0d1583a13da56de6d2dc45a66e7b47c24ab1192e246dc961dd77", + "iv" : "abcf220eede012279c3a2d33295ff273", + "msg" : "2ae63cbf", + "ct" : "c45afe62fc9351ad0fc9b03bc2f3a91f", + "result" : "valid" + }, + { + "tcId" : 153, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "2521203fa0dddf59d837b2830f87b1aa61f958155df3ca4d1df2457cb4284dc8", + "iv" : "01373953578902909ae4f6cb0a72587c", + "msg" : "af3a015ea1", + "ct" : "281fa533d0740cc6cdf94dd1a5f7402d", + "result" : "valid" + }, + { + "tcId" : 154, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c", + "iv" : "3fb0d5ecd06c71150748b599595833cb", + "msg" : "3f56935def3f", + "ct" : "3f3f39697bd7e88d85a14132be1cbc48", + "result" : "valid" + }, + { + "tcId" : 155, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "facd75b22221380047305bc981f570e2a1af38928ea7e2059e3af5fc6b82b493", + "iv" : "27a2db6114ece34fb6c23302d9ba07c6", + "msg" : "57bb86beed156f", + "ct" : "379990d91557614836381d5026fa04a0", + "result" : "valid" + }, + { + "tcId" : 156, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "505aa98819809ef63b9a368a1e8bc2e922da45b03ce02d9a7966b15006dba2d5", + "iv" : "9b2b631e3f24bdc814a14abb3416059e", + "msg" : "2e4e7ef728fe11af", + "ct" : "7ecefe24caa78a68f4031d40fdb9a43a", + "result" : "valid" + }, + { + "tcId" : 157, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "f942093842808ba47f64e427f7351dde6b9546e66de4e7d60aa6f328182712cf", + "iv" : "92cfc4eb146b18b73fc76483fc5e1229", + "msg" : "852a21d92848e627c7", + "ct" : "ffe4ec8baf4af40ab2e7f4d6193fae9c", + "result" : "valid" + }, + { + "tcId" : 158, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "64be162b39c6e5f1fed9c32d9f674d9a8cde6eaa2443214d86bd4a1fb53b81b4", + "iv" : "4ceed8dcb75b6259dad737bdef96f099", + "msg" : "195a3b292f93baff0a2c", + "ct" : "ef96215e7950e7be8aae78b9ec8aaf39", + "result" : "valid" + }, + { + "tcId" : 159, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "b259a555d44b8a20c5489e2f38392ddaa6be9e35b9833b67e1b5fdf6cb3e4c6c", + "iv" : "2d4cead3f1120a2b4b59419d04951e20", + "msg" : "afd73117330c6e8528a6e4", + "ct" : "4ed0eac75b05868078303875f82fb4f0", + "result" : "valid" + }, + { + "tcId" : 160, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "2c6fc62daa77ba8c6881b3dd6989898fef646663cc7b0a3db8228a707b85f2dc", + "iv" : "a10392634143c2a3332fa0fb3f72200a", + "msg" : "0ff54d6b6759120c2e8a51e3", + "ct" : "f4d298caea7c390fc8c7f558f584f852", + "result" : "valid" + }, + { + "tcId" : 161, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "abab815d51df29f740e4e2079fb798e0152836e6ab57d1536ae8929e52c06eb8", + "iv" : "38b916a7ad3a9251ae3bd8865ca3a688", + "msg" : "f0058d412a104e53d820b95a7f", + "ct" : "5e1c00e2ec829f92b87c6adf5c25262d", + "result" : "valid" + }, + { + "tcId" : 162, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "3d5da1af83f7287458bff7a7651ea5d8db72259401333f6b82096996dd7eaf19", + "iv" : "bfcc3ac44d12e42d780c1188ac64b57f", + "msg" : "aacc36972f183057919ff57b49e1", + "ct" : "bf3a04ddb2dbfe7c6dc9e15aa67be25d", + "result" : "valid" + }, + { + "tcId" : 163, + "comment" : "small plaintext size", + "flags" : [ + "Pseudorandom" + ], + "key" : "c19bdf314c6cf64381425467f42aefa17c1cc9358be16ce31b1d214859ce86aa", + "iv" : "35bc82e3503b95044c6406a8b2c2ecff", + "msg" : "5d066a92c300e9b6ddd63a7c13ae33", + "ct" : "fdcfa77f5bd09326b4c11f9281b72474", + "result" : "valid" + }, + { + "tcId" : 164, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "73216fafd0022d0d6ee27198b2272578fa8f04dd9f44467fbb6437aa45641bf7", + "iv" : "4b74bd981ea9d074757c3e2ef515e5fb", + "msg" : "d5247b8f6c3edcbfb1d591d13ece23d2f5", + "ct" : "fbea776fb1653635f88e2937ed2450ba4e9063e96d7cdba04928f01cb85492fe", + "result" : "valid" + }, + { + "tcId" : 165, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "c2039f0d05951aa8d9fbdf68be58a37cf99bd1afcedda286a9db470c3729ca92", + "iv" : "9a1d8ccc24c5e4d3995480af236be103", + "msg" : "ed5b5e28e9703bdf5c7b3b080f2690a605fcd0d9", + "ct" : "3a79bb6084c7116b58afe52d7181a0aacee1caa11df959090e2e7b0073d74817", + "result" : "valid" + }, + { + "tcId" : 166, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "4f097858a1aec62cf18f0966b2b120783aa4ae9149d3213109740506ae47adfe", + "iv" : "400aab92803bcbb44a96ef789655b34e", + "msg" : "ee53d8e5039e82d9fcca114e375a014febfea117a7e709d9008d43858e3660", + "ct" : "642b11efb79b49e5d038bc7aa29b8c6c3ce0bf11c3a69670eb565799908be66d", + "result" : "valid" + }, + { + "tcId" : 167, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "5f99f7d60653d79f088dd07ef306b65e057d36e053fa1c9f6854425c019fd4df", + "iv" : "6eedf45753ffe38f2407fbc28ab5959c", + "msg" : "fcc9212c23675c5d69a1266c77389bc955e453daba20034aabbcd502a1b73e05af30f8b7622abdbc", + "ct" : "a9b051354f0cf61f11921b330e60f996de796aeb68140a0f9c5962e1f48e4805262fb6f53b26d9bb2fa0e359efe14734", + "result" : "valid" + }, + { + "tcId" : 168, + "comment" : "plaintext size > 16", + "flags" : [ + "Pseudorandom" + ], + "key" : "95aaa5df4ccb529e9b2dc929e770c1f419f8e8933bfb36f632f532b3dcad2ba6", + "iv" : "f88551c6aa197f9ad80251c2e32d7663", + "msg" : "f5735567b7c8312f116517788b091cc6cb1d474b010a77910154fd11c3b2f0cd19f713b63d66492e8cc7ee8ad714783f46c305a26416e11ff4b99ec5ce2550593cc5ec1b86ba6a66d10f82bdff827055", + "ct" : "5074f46f1a6d0eeff070d623172eb15bbfc83e7d16466a00c9da5f4545eecf44adbf60cf9ac9aa1a3ec5eca22d4a34a7b21ca44d214c9d04ab1cb0b2c07001de9adb46f3c12f8f48436b516a409bf6cbdf1871dee3115d5cbb7943558b68867e", + "result" : "valid" + }, + { + "tcId" : 169, + "comment" : "empty ciphertext", + "flags" : [ + "NoPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "", + "result" : "invalid" + }, + { + "tcId" : 170, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "e07558d746574528fb813f34e3fb7719", + "result" : "invalid" + }, + { + "tcId" : 171, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "c01af61276368818a8295f7d4b5bb2fd", + "result" : "invalid" + }, + { + "tcId" : 172, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "303132333435363738396162636465", + "ct" : "97dd9716f06be49160399a5b212250ae", + "result" : "invalid" + }, + { + "tcId" : 173, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce783bb4b4e18d7c646f38e0bb8ff92896", + "result" : "invalid" + }, + { + "tcId" : 174, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce64679a46621b792f643542a735f0bbbf", + "result" : "invalid" + }, + { + "tcId" : 175, + "comment" : "Using zero padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb741bad06f9eb681b7551e61cd06ddc3b", + "result" : "invalid" + }, + { + "tcId" : 176, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "c007ddffb76b95208505fe7f3be96172", + "result" : "invalid" + }, + { + "tcId" : 177, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "e9b7719c4c2b9fa6b94cb50e87b28156", + "result" : "invalid" + }, + { + "tcId" : 178, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "303132333435363738396162636465", + "ct" : "77b31f474c4bd489dbadd532643d1fa5", + "result" : "invalid" + }, + { + "tcId" : 179, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7cea0166e9e1c0122cb2e2983fc0fac7176", + "result" : "invalid" + }, + { + "tcId" : 180, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce6f0effa789cbb0b875cc53cc8f7b3caf", + "result" : "invalid" + }, + { + "tcId" : 181, + "comment" : "Using a padding with 0xff instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb995e2e26439a158562e95b344713b852", + "result" : "invalid" + }, + { + "tcId" : 182, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "4dd5f910c94700235c9ed239160e34e2", + "result" : "invalid" + }, + { + "tcId" : 183, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "94d18b5923f8f3608ae7ad494fbb517e", + "result" : "invalid" + }, + { + "tcId" : 184, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "303132333435363738396162636465", + "ct" : "0c92886dbcb030b873123a25d224da42", + "result" : "invalid" + }, + { + "tcId" : 185, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce851be67798a2937cd6681165da6dce03", + "result" : "invalid" + }, + { + "tcId" : 186, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce45658a37aaebc51098866b0894007e8e", + "result" : "invalid" + }, + { + "tcId" : 187, + "comment" : "Using ISO/IEC 7816-4 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb32f2d2a5e14951df84a8f343648c6341", + "result" : "invalid" + }, + { + "tcId" : 188, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "524236e25956e950713bec0d3d579068f34e4d18c4ccab081317dae526fe7fca", + "result" : "invalid" + }, + { + "tcId" : 189, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "d29eb845640c3a8878f51bc50e290aa4a65a34a93728fe8f82fdb8d3d2b7c648", + "result" : "invalid" + }, + { + "tcId" : 190, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "303132333435363738396162636465", + "ct" : "c34563be2952277c0f5c67ae1d6f847118730dd7f6a502ceef3c4bce5999f7aa", + "result" : "invalid" + }, + { + "tcId" : 191, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7cec0f74a1aa92fd9c96f9d15d193d1695c1eb33486e269277612f90f509f0535c2", + "result" : "invalid" + }, + { + "tcId" : 192, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce151ade309ec5200bacdd83b57ce794cd2b3bf9f8957def829e8465f7db266f9e", + "result" : "invalid" + }, + { + "tcId" : 193, + "comment" : "The length of the padding is longer than 1 block", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb25dae5c6058a15360a09decb9dce95abd77450fd7ddb4f6ad224623f43603b12", + "result" : "invalid" + }, + { + "tcId" : 194, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "fb38cbef13f1d5be9c0ac7ed9cbe023c", + "result" : "invalid" + }, + { + "tcId" : 195, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "18cf8988abe9a2463a3a75db1fac8bcc", + "result" : "invalid" + }, + { + "tcId" : 196, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7cee16d6fc4b4d3cdf6f915996e437fd4cc", + "result" : "invalid" + }, + { + "tcId" : 197, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7cea8f41f61ead6e9936cbe7ee5a1163b9b", + "result" : "invalid" + }, + { + "tcId" : 198, + "comment" : "Using ANSI X.923 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb9c56c79b4d3b1ea9f316552a71efc862", + "result" : "invalid" + }, + { + "tcId" : 199, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "a05c14da0109093c195b4998812fe150", + "result" : "invalid" + }, + { + "tcId" : 200, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "c477877250c8e4ca2869f35c4757cdb4", + "result" : "invalid" + }, + { + "tcId" : 201, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce69f57c6e99c7b9df7d4879ccd15caf3d", + "result" : "invalid" + }, + { + "tcId" : 202, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce77f89a247c928f147748ce6bc8fc4b67", + "result" : "invalid" + }, + { + "tcId" : 203, + "comment" : "Using ISO 10126 padding instead of PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb172816916516df2569a9aa94315c873e", + "result" : "invalid" + }, + { + "tcId" : 204, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "524236e25956e950713bec0d3d579068", + "result" : "invalid" + }, + { + "tcId" : 205, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "e03b6f2ae1c963b6dfa40b42d34314b7", + "result" : "invalid" + }, + { + "tcId" : 206, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "303132333435363738396162636465", + "ct" : "df14f4cbbccca57b9727d68270a1b6c1", + "result" : "invalid" + }, + { + "tcId" : 207, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ceea228bf1edd41c390e2eef140142bc00", + "result" : "invalid" + }, + { + "tcId" : 208, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce3937e0e9abf7f672a34a500ba8e9099a", + "result" : "invalid" + }, + { + "tcId" : 209, + "comment" : "Padding is longer than the message", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb502050eb4bcd00325f43eab3677f4c66", + "result" : "invalid" + }, + { + "tcId" : 210, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "", + "ct" : "32ac6057df2a5d1e2e5131348c6ebc4e", + "result" : "invalid" + }, + { + "tcId" : 211, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "6162636465666768", + "ct" : "df4a7c3b9f4756d30fca0d18e9b28960", + "result" : "invalid" + }, + { + "tcId" : 212, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ceae2855c47c7988873d57f901e049494b", + "result" : "invalid" + }, + { + "tcId" : 213, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "3031323334353637383941424344454647", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce0714c8de200b27ac91d9257fc93c13be", + "result" : "invalid" + }, + { + "tcId" : 214, + "comment" : "Invalid PKCS #5 padding", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffba4d88412b6ccfce7563d4b56bd00fd4d", + "result" : "invalid" + }, + { + "tcId" : 215, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "30313233343536373839414243444546", + "ct" : "8881e9e02fa9e3037b397957ba1fb7ce", + "result" : "invalid" + }, + { + "tcId" : 216, + "comment" : "Using no padding at all", + "flags" : [ + "BadPadding" + ], + "key" : "7c78f34dbce8f0557d43630266f59babd1cb92ba624bd1a8f45a2a91c84a804a", + "iv" : "f010f61c31c9aa8fa0d5be5f6b0f2f70", + "msg" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "ct" : "706029a204cc11e69b5bc1a84e6a8ef75fe891cc466d6fb1bbf65135727a1ffb", + "result" : "invalid" + } + ] + } + ] +}