|
15 | 15 | */
|
16 | 16 |
|
17 | 17 | import { expect } from 'chai';
|
18 |
| -import { MerkleHashBuilder } from '../../../src/core/crypto'; |
| 18 | +import { Crypto, MerkleHashBuilder } from '../../../src/core/crypto'; |
19 | 19 | import { Convert } from '../../../src/core/format';
|
20 | 20 |
|
21 |
| -describe('MerkleHashBuilder should', () => { |
22 |
| - it('fill 0s for empty merkle tree', () => { |
23 |
| - // Arrange: |
| 21 | +describe('MerkleHashBuilder', () => { |
| 22 | + const calculateMerkleHash = (hashes) => { |
24 | 23 | const builder = new MerkleHashBuilder(32);
|
| 24 | + hashes.forEach((embeddedHash) => builder.update(embeddedHash)); |
| 25 | + return builder.getRootHash(); |
| 26 | + }; |
| 27 | + |
| 28 | + const assertMerkleHash = (expectedHashHex, hashesHex) => { |
| 29 | + // Act: |
| 30 | + const calculatedHash = calculateMerkleHash(hashesHex.map(Convert.hexToUint8)); |
25 | 31 |
|
26 |
| - const rootHash = builder.getRootHash(); |
| 32 | + // Assert: |
| 33 | + expect(expectedHashHex).to.equal(Convert.uint8ToHex(calculatedHash)); |
| 34 | + }; |
27 | 35 |
|
28 |
| - expect(Convert.uint8ToHex(rootHash)).equal('0000000000000000000000000000000000000000000000000000000000000000'); |
| 36 | + it('fill 0s for empty merkle tree', () => { |
| 37 | + assertMerkleHash('0000000000000000000000000000000000000000000000000000000000000000', []); |
29 | 38 | });
|
30 | 39 |
|
31 | 40 | it('return first hash given single child', () => {
|
32 |
| - // Arrange: |
33 |
| - const builder = new MerkleHashBuilder(32); |
34 |
| - |
35 |
| - builder.update(Convert.hexToUint8('215B158F0BD416B596271BCE527CD9DC8E4A639CC271D896F9156AF6F441EEB9')); |
| 41 | + const randomHashHex = Convert.uint8ToHex(Crypto.randomBytes(32)); |
| 42 | + assertMerkleHash(randomHashHex, [randomHashHex]); |
| 43 | + }); |
36 | 44 |
|
37 |
| - const rootHash = builder.getRootHash(); |
| 45 | + it('can create from balanced tree', () => { |
| 46 | + assertMerkleHash('7D853079F5F9EE30BDAE49C4956AF20CDF989647AFE971C069AC263DA1FFDF7E', [ |
| 47 | + '36C8213162CDBC78767CF43D4E06DDBE0D3367B6CEAEAEB577A50E2052441BC8', |
| 48 | + '8A316E48F35CDADD3F827663F7535E840289A16A43E7134B053A86773E474C28', |
| 49 | + '6D80E71F00DFB73B358B772AD453AEB652AE347D3E098AE269005A88DA0B84A7', |
| 50 | + '2AE2CA59B5BB29721BFB79FE113929B6E52891CAA29CBF562EBEDC46903FF681', |
| 51 | + '421D6B68A6DF8BB1D5C9ACF7ED44515E77945D42A491BECE68DA009B551EE6CE', |
| 52 | + '7A1711AF5C402CFEFF87F6DA4B9C738100A7AC3EDAD38D698DF36CA3FE883480', |
| 53 | + '1E6516B2CC617E919FAE0CF8472BEB2BFF598F19C7A7A7DC260BC6715382822C', |
| 54 | + '410330530D04A277A7C96C1E4F34184FDEB0FFDA63563EFD796C404D7A6E5A20', |
| 55 | + ]); |
| 56 | + }); |
38 | 57 |
|
39 |
| - expect(Convert.uint8ToHex(rootHash)).equal('215B158F0BD416B596271BCE527CD9DC8E4A639CC271D896F9156AF6F441EEB9'); |
| 58 | + it('can build from unbalanced tree', () => { |
| 59 | + assertMerkleHash('DEFB4BF7ACF2145500087A02C88F8D1FCF27B8DEF4E0FDABE09413D87A3F0D09', [ |
| 60 | + '36C8213162CDBC78767CF43D4E06DDBE0D3367B6CEAEAEB577A50E2052441BC8', |
| 61 | + '8A316E48F35CDADD3F827663F7535E840289A16A43E7134B053A86773E474C28', |
| 62 | + '6D80E71F00DFB73B358B772AD453AEB652AE347D3E098AE269005A88DA0B84A7', |
| 63 | + '2AE2CA59B5BB29721BFB79FE113929B6E52891CAA29CBF562EBEDC46903FF681', |
| 64 | + '421D6B68A6DF8BB1D5C9ACF7ED44515E77945D42A491BECE68DA009B551EE6CE', |
| 65 | + ]); |
40 | 66 | });
|
41 | 67 |
|
42 |
| - it('create correct merkle hash given two children', () => { |
| 68 | + it('changing sub hash order changes merkle hash', () => { |
43 | 69 | // Arrange:
|
44 |
| - const builder = new MerkleHashBuilder(32); |
45 |
| - |
46 |
| - builder.update(Convert.hexToUint8('215b158f0bd416b596271bce527cd9dc8e4a639cc271d896f9156af6f441eeb9')); |
47 |
| - builder.update(Convert.hexToUint8('976c5ce6bf3f797113e5a3a094c7801c885daf783c50563ffd3ca6a5ef580e25')); |
48 |
| - |
49 |
| - const rootHash = builder.getRootHash(); |
50 |
| - |
51 |
| - expect(Convert.uint8ToHex(rootHash).toLocaleLowerCase()).equal('1c704e3ac99b124f92d2648649ec72c7a19ea4e2bb24f669b976180a295876fa'); |
| 70 | + const seed1: Uint8Array[] = []; |
| 71 | + for (let i = 0; i < 8; ++i) { |
| 72 | + seed1.push(new Uint8Array(Crypto.randomBytes(32))); |
| 73 | + } |
| 74 | + |
| 75 | + // - swap 5 and 3 |
| 76 | + // eslint-disable-next-line prettier/prettier |
| 77 | + const seed2 = [ |
| 78 | + seed1[0], seed1[1], seed1[2], seed1[5], |
| 79 | + seed1[4], seed1[3], seed1[6], seed1[7] |
| 80 | + ]; |
| 81 | + |
| 82 | + // Act: |
| 83 | + const rootHash1 = calculateMerkleHash(seed1); |
| 84 | + const rootHash2 = calculateMerkleHash(seed2); |
| 85 | + |
| 86 | + // Assert: |
| 87 | + expect(Convert.uint8ToHex(rootHash1)).not.to.equal(Convert.uint8ToHex(rootHash2)); |
52 | 88 | });
|
53 | 89 |
|
54 |
| - it('create correct merkle hash given three children', () => { |
| 90 | + it('changing sub hash changes merkle tree', () => { |
55 | 91 | // Arrange:
|
56 |
| - const builder = new MerkleHashBuilder(32); |
57 |
| - |
58 |
| - builder.update(Convert.hexToUint8('215b158f0bd416b596271bce527cd9dc8e4a639cc271d896f9156af6f441eeb9')); |
59 |
| - builder.update(Convert.hexToUint8('976c5ce6bf3f797113e5a3a094c7801c885daf783c50563ffd3ca6a5ef580e25')); |
60 |
| - builder.update(Convert.hexToUint8('e926cc323886d47234bb0b49219c81e280e8a65748b437c2ae83b09b37a5aaf2')); |
61 |
| - |
62 |
| - const rootHash = builder.getRootHash(); |
63 |
| - |
64 |
| - expect(Convert.uint8ToHex(rootHash).toLocaleLowerCase()).equal('5dc17b2409d50bcc7c1faa720d0ec8b79a1705d0c517bcc0bdbd316540974d5e'); |
| 92 | + const seed1: Uint8Array[] = []; |
| 93 | + for (let i = 0; i < 8; ++i) { |
| 94 | + seed1.push(new Uint8Array(Crypto.randomBytes(32))); |
| 95 | + } |
| 96 | + |
| 97 | + // eslint-disable-next-line prettier/prettier |
| 98 | + const seed2 = [ |
| 99 | + seed1[0], seed1[1], seed1[2], seed1[3], |
| 100 | + new Uint8Array(Crypto.randomBytes(32)), seed1[5], seed1[6], seed1[7] |
| 101 | + ]; |
| 102 | + |
| 103 | + // Act: |
| 104 | + const rootHash1 = calculateMerkleHash(seed1); |
| 105 | + const rootHash2 = calculateMerkleHash(seed2); |
| 106 | + |
| 107 | + // Assert: |
| 108 | + expect(Convert.uint8ToHex(rootHash1)).not.to.equal(Convert.uint8ToHex(rootHash2)); |
65 | 109 | });
|
66 | 110 | });
|
0 commit comments