node.test.js 9.4 KB

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