tests.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import assert from "assert"
  2. import fs from "fs";
  3. import { join, resolve } from "path";
  4. import * as aes from "./index.js";
  5. interface TestCase {
  6. modeOfOperation: string;
  7. iv: Array<number>;
  8. key: Array<number>;
  9. plaintext: Array<Array<number>>;
  10. encrypted: Array<Array<number>>;
  11. segmentSize: number;
  12. }
  13. const root = (function() {
  14. let root = process.cwd();
  15. while (true) {
  16. if (fs.existsSync(join(root, "package.json"))) { return root; }
  17. const parent = join(root, "..");
  18. if (parent === root) { break; }
  19. root = parent;
  20. }
  21. throw new Error("could not find root");
  22. })();
  23. describe("Tests Encrypting and Decrypting", function() {
  24. const json = fs.readFileSync(resolve(root, "./test/test-vectors.json")).toString()
  25. const tests: Array<TestCase> = JSON.parse(json);
  26. function getCrypter(key: Uint8Array, test: TestCase): null | aes.ModeOfOperation {
  27. switch (test.modeOfOperation) {
  28. case "ctr":
  29. return new aes.CTR(key, 0);
  30. case "cbc":
  31. return new aes.CBC(key, Buffer.from(test.iv));
  32. case "cfb":
  33. return new aes.CFB(key, Buffer.from(test.iv), test.segmentSize * 8);
  34. case "ecb":
  35. return new aes.ECB(key);
  36. case "ofb":
  37. return new aes.OFB(key, Buffer.from(test.iv));
  38. }
  39. return null;
  40. }
  41. tests.forEach((test, index) => {
  42. it(`tests encrypting: ${ test. modeOfOperation}.${ index }`, function() {
  43. const encrypter = getCrypter(Buffer.from(test.key), test);
  44. if (!encrypter) { this.skip(); }
  45. for (let i = 0; i < test.plaintext.length; i++) {
  46. const plaintext = Buffer.from(test.plaintext[i]);
  47. const ciphertext = Buffer.from(test.encrypted[i]);
  48. const result = Buffer.from(encrypter.encrypt(plaintext));
  49. assert.ok(ciphertext.equals(result), "encrypting failed");
  50. }
  51. });
  52. it(`tests decrypting: ${ test. modeOfOperation}.${ index }`, function() {
  53. const decrypter = getCrypter(Buffer.from(test.key), test);
  54. if (!decrypter) { this.skip(); }
  55. for (let i = 0; i < test.plaintext.length; i++) {
  56. const plaintext = Buffer.from(test.plaintext[i]);
  57. const ciphertext = Buffer.from(test.encrypted[i]);
  58. const result = Buffer.from(decrypter.decrypt(ciphertext));
  59. assert.ok(plaintext.equals(result), "decrypting failed");
  60. }
  61. });
  62. });
  63. });
  64. describe("Tests Padding", function() {
  65. for (let size = 0; size < 100; size++) {
  66. it(`tests padding: length=${ size }`, function() {
  67. // Create a random piece of data
  68. const data = new Uint8Array(size);
  69. data.fill(42);
  70. // Pad it
  71. const padded = aes.pkcs7Pad(data);
  72. assert.ok((padded.length % 16) === 0, "Failed to pad to block size");
  73. assert.ok(data.length <= padded.length && padded.length <= data.length + 16, "Padding went awry");
  74. assert.ok(padded[padded.length - 1] >= 1 && padded[padded.length - 1] <= 16, "Failed to pad to block size");
  75. // Trim it
  76. const trimmed = aes.pkcs7Strip(padded);
  77. assert.ok(Buffer.from(data).equals(trimmed), "Failed to trim to original data");
  78. });
  79. }
  80. });