node.test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4. return new (P || (P = Promise))(function (resolve, reject) {
  5. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  6. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  7. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  8. step((generator = generator.apply(thisArg, _arguments || [])).next());
  9. });
  10. };
  11. var __importStar = (this && this.__importStar) || function (mod) {
  12. if (mod && mod.__esModule) return mod;
  13. var result = {};
  14. if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
  15. result["default"] = mod;
  16. return result;
  17. };
  18. Object.defineProperty(exports, "__esModule", { value: true });
  19. const wasm = __importStar(require("./node"));
  20. const native = __importStar(require("./node-native"));
  21. const chai_1 = require("chai");
  22. const test_helpers_1 = require("./base/test-helpers");
  23. const stream_buffers_1 = require("stream-buffers");
  24. const hash_reader_1 = require("./base/hash-reader");
  25. function suite({ hash, createHash, keyedHash, deriveKey, createDeriveKey, createKeyed, }) {
  26. describe('encoding', () => {
  27. it('hashes a buffer', () => {
  28. chai_1.expect(hash(Buffer.from(test_helpers_1.inputs.hello.input))).to.deep.equal(test_helpers_1.inputs.hello.hash);
  29. });
  30. it('hashes a string', () => {
  31. chai_1.expect(hash(test_helpers_1.inputs.hello.input)).to.deep.equal(test_helpers_1.inputs.hello.hash);
  32. });
  33. it('hashes an arraybuffer', () => {
  34. const buf = Buffer.from(test_helpers_1.inputs.hello.input);
  35. chai_1.expect(hash(new Uint8Array(buf).buffer)).to.deep.equal(test_helpers_1.inputs.hello.hash);
  36. });
  37. it('customizes the output length', () => {
  38. chai_1.expect(hash(test_helpers_1.inputs.hello.input, { length: 16 })).to.deep.equal(test_helpers_1.inputs.hello.hash.slice(0, 16));
  39. });
  40. });
  41. describe('memory-safety (#5)', () => {
  42. it('hash', () => {
  43. const hashA = hash('hello');
  44. const hashB = hash('goodbye');
  45. chai_1.expect(hashA.toString('hex')).to.equal('ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200f');
  46. chai_1.expect(hashB.toString('hex')).to.equal('f94a694227c5f31a07551908ad5fb252f5f0964030df5f2f200adedfae4d9b69');
  47. });
  48. it('hasher', () => {
  49. const hasherA = createHash();
  50. const hasherB = createHash();
  51. hasherA.update('hel');
  52. hasherB.update('good');
  53. hasherA.update('lo');
  54. hasherB.update('bye');
  55. const hashA = hasherA.digest();
  56. const hashB = hasherB.digest();
  57. chai_1.expect(hashA.toString('hex')).to.equal('ea8f163db38682925e4491c5e58d4bb3506ef8c14eb78a86e908c5624a67200f');
  58. chai_1.expect(hashB.toString('hex')).to.equal('f94a694227c5f31a07551908ad5fb252f5f0964030df5f2f200adedfae4d9b69');
  59. });
  60. });
  61. describe('hasher', () => {
  62. it('digests', callback => {
  63. const buffer = new stream_buffers_1.ReadableStreamBuffer();
  64. buffer.put(Buffer.from(test_helpers_1.inputs.large.input));
  65. buffer.stop();
  66. const hash = createHash();
  67. buffer.on('data', b => hash.update(b));
  68. buffer.on('end', () => {
  69. const actual = hash.digest();
  70. chai_1.expect(actual).to.deep.equal(test_helpers_1.inputs.large.hash);
  71. callback();
  72. });
  73. });
  74. it('is a transform stream', callback => {
  75. const buffer = new stream_buffers_1.ReadableStreamBuffer();
  76. buffer.put(Buffer.from(test_helpers_1.inputs.large.input));
  77. buffer.stop();
  78. buffer
  79. .pipe(createHash())
  80. .on('error', callback)
  81. .on('data', hash => {
  82. chai_1.expect(hash).to.deep.equal(test_helpers_1.inputs.large.hash);
  83. callback();
  84. });
  85. });
  86. it('customizes the output length', () => {
  87. const hash = createHash();
  88. hash.update(test_helpers_1.inputs.hello.input);
  89. chai_1.expect(hash.digest('hex', { length: 16 })).to.equal(test_helpers_1.inputs.hello.hash.slice(0, 16).toString('hex'));
  90. });
  91. it('throws on write after dispose', () => {
  92. const hash = createHash();
  93. hash.dispose();
  94. chai_1.expect(() => hash.update('')).to.throw(/after dispose/);
  95. });
  96. it('allows taking incremental hashes', () => {
  97. const hasher = createHash();
  98. hasher.update('hel');
  99. const hashA = hasher.digest(undefined, { dispose: false });
  100. const readA = hasher.reader({ dispose: false });
  101. hasher.update('lo');
  102. const hashB = hasher.digest(undefined, { dispose: false });
  103. const readB = hasher.reader({ dispose: false });
  104. const expectedA = Buffer.from('3121c5bb1b9193123447ac7cfda042f67f967e7a8cf5c12e7570e25529746e4a', 'hex');
  105. chai_1.expect(hashA).to.deep.equal(expectedA);
  106. chai_1.expect(readA.toBuffer()).to.deep.equal(expectedA);
  107. chai_1.expect(hashB).to.deep.equal(test_helpers_1.inputs.hello.hash);
  108. chai_1.expect(readB.toBuffer()).to.deep.equal(test_helpers_1.inputs.hello.hash);
  109. hasher.dispose();
  110. readA.dispose();
  111. readB.dispose();
  112. });
  113. });
  114. describe('reader', () => {
  115. let reader;
  116. beforeEach(() => {
  117. const hash = createHash();
  118. hash.update(test_helpers_1.inputs.hello.input);
  119. reader = hash.reader();
  120. });
  121. afterEach(() => reader.dispose());
  122. it('implements toString()', () => {
  123. chai_1.expect(reader.toString('hex')).to.equal(test_helpers_1.inputs.hello.hash.toString('hex'));
  124. reader.position = BigInt(42);
  125. chai_1.expect(reader.toString('hex')).to.equal(test_helpers_1.inputs.hello.hash.toString('hex'));
  126. });
  127. it('implements toBuffer()', () => {
  128. chai_1.expect(reader.toBuffer()).to.deep.equal(test_helpers_1.inputs.hello.hash);
  129. reader.position = BigInt(42);
  130. chai_1.expect(reader.toBuffer()).to.deep.equal(test_helpers_1.inputs.hello.hash);
  131. });
  132. it('implements readInto() and advances', () => {
  133. const actual = Buffer.alloc(32);
  134. reader.readInto(actual.slice(0, 10));
  135. reader.readInto(actual.slice(10));
  136. chai_1.expect(actual).to.deep.equal(test_helpers_1.inputs.hello.hash);
  137. chai_1.expect(reader.position).to.equal(BigInt(32));
  138. });
  139. it('implements read() and advances', () => {
  140. const actual = reader.read(32);
  141. chai_1.expect(actual).to.deep.equal(test_helpers_1.inputs.hello.hash);
  142. chai_1.expect(reader.position).to.equal(BigInt(32));
  143. const actualNext = reader.read(16);
  144. chai_1.expect(actualNext).to.deep.equal(test_helpers_1.hello48.slice(32));
  145. chai_1.expect(reader.position).to.equal(BigInt(48));
  146. });
  147. it('manually sets position', () => {
  148. reader.position = BigInt(32);
  149. const actual = reader.read(16);
  150. chai_1.expect(actual).to.deep.equal(test_helpers_1.hello48.slice(32));
  151. });
  152. it('throws if set out of range', () => {
  153. chai_1.expect(() => (reader.position = BigInt(-1))).to.throw(RangeError);
  154. chai_1.expect(() => (reader.position = BigInt('18446744073709551616'))).to.throw(RangeError);
  155. reader.position = hash_reader_1.maxHashBytes - BigInt(1);
  156. chai_1.expect(() => reader.read(2)).to.throw(RangeError);
  157. });
  158. });
  159. describe('original test vectors', () => {
  160. for (const { inputLen, expectedDerive, expectedKeyed, expectedHash } of test_helpers_1.ogTestVectors.cases) {
  161. describe(`${inputLen}`, () => __awaiter(this, void 0, void 0, function* () {
  162. const input = Buffer.alloc(inputLen);
  163. for (let i = 0; i < inputLen; i++) {
  164. input[i] = i % 251;
  165. }
  166. it('hash()', () => {
  167. chai_1.expect(hash(input, { length: expectedHash.length / 2 }).toString('hex')).to.equal(expectedHash);
  168. });
  169. it('deriveKey()', () => {
  170. chai_1.expect(deriveKey(test_helpers_1.ogTestVectors.context, input, { length: expectedDerive.length / 2 }).toString('hex')).to.equal(expectedDerive);
  171. });
  172. it('createDeriveKey()', callback => {
  173. const buffer = new stream_buffers_1.ReadableStreamBuffer();
  174. buffer.put(Buffer.from(input));
  175. buffer.stop();
  176. const hash = createDeriveKey(test_helpers_1.ogTestVectors.context);
  177. buffer.on('data', b => hash.update(b));
  178. buffer.on('end', () => {
  179. const actual = hash.digest({ length: expectedDerive.length / 2 }).toString('hex');
  180. chai_1.expect(actual).to.equal(expectedDerive);
  181. callback();
  182. });
  183. });
  184. it('keyedHash()', () => {
  185. chai_1.expect(keyedHash(Buffer.from(test_helpers_1.ogTestVectors.key), input, {
  186. length: expectedKeyed.length / 2,
  187. }).toString('hex')).to.equal(expectedKeyed);
  188. });
  189. it('createKeyed()', callback => {
  190. const buffer = new stream_buffers_1.ReadableStreamBuffer();
  191. buffer.put(Buffer.from(input));
  192. buffer.stop();
  193. const hash = createKeyed(Buffer.from(test_helpers_1.ogTestVectors.key));
  194. buffer.on('data', b => hash.update(b));
  195. buffer.on('end', () => {
  196. const actual = hash.digest({ length: expectedDerive.length / 2 }).toString('hex');
  197. chai_1.expect(actual).to.equal(expectedKeyed);
  198. callback();
  199. });
  200. });
  201. }));
  202. }
  203. });
  204. }
  205. describe('node.js wasm', () => suite(wasm));
  206. describe('node.js native', () => suite(native));
  207. //# sourceMappingURL=node.test.js.map