ChainSafe / ssz

Typescript implementation of Simple Serialize (SSZ)
https://simpleserialize.com/
Other
50 stars 19 forks source link

sha256 hash returns incorrect result if input's `(byteLength & 63) == 63` #376

Open 0xproto opened 4 months ago

0xproto commented 4 months ago

The hash function returns incorrect result for any inputs where byteLength % 64 == 63. To reproduce create a test case where byte length % 64 == 63 and compare it against another implementation of sha256.

example test one:

 it("hex bytes of 191 byte length", function () {
      const inputStr = "1".repeat(382);
      const input = Buffer.from(inputStr, "hex");
      expect(input.length).to.be.equal(191);

      const output = Buffer.from(sha256.digest(input)).toString("hex");
      expect(output).to.be.equal("b8ffd888fe6ffff63cb0193ad93b0fee6bda8ea913e4e75424af7914f55d3411");
    });

example one output running yarn test

AssertionError: expected 'de66d39d769de0b512fe724191d53339a3efc…' to equal 'b8ffd888fe6ffff63cb0193ad93b0fee6bda8…'
      + expected - actual

      -de66d39d769de0b512fe724191d53339a3efc491875c25795a2c20bb7c03ad32
      +b8ffd888fe6ffff63cb0193ad93b0fee6bda8ea913e4e75424af7914f55d3411

example two

it("hex bytes of 676 byte length", function () {
      const inputStr = "1".repeat(1150);
      const input = Buffer.from(inputStr, "hex");
      expect(input.length).to.be.equal(575);

      const output = Buffer.from(sha256.digest(input)).toString("hex");
      expect(output).to.be.equal("fc6b0073005a8ce2b4bf9a9c482bb2b1707bc1dab06c0185752104157edb62c6");
    });

example two output running yarn test

digest function
         hex bytes of 575 byte length:

      AssertionError: expected '758a6d0187dfd01483d6a7e742bdda25a2f47…' to equal 'fc6b0073005a8ce2b4bf9a9c482bb2b1707bc…'
      + expected - actual

      -758a6d0187dfd01483d6a7e742bdda25a2f47ef804fed45423484b27a6717243
      +fc6b0073005a8ce2b4bf9a9c482bb2b1707bc1dab06c0185752104157edb62c6

      at Context.<anonymous> (test/unit/index.test.ts:22:28)
      at processImmediate (node:internal/timers:478:21)

I am still working through why this behavior occurs - I believe this could be an edge case in the math that is not handled correctly, any assistance on this would be greatly appreciated.