Skip to content

Commit

Permalink
Add sliding window tests for the new SHA256 class
Browse files Browse the repository at this point in the history
  • Loading branch information
Shigoto-dev19 committed Jan 28, 2024
1 parent 5199fc0 commit 6cf029a
Showing 1 changed file with 82 additions and 20 deletions.
102 changes: 82 additions & 20 deletions src/sha256.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { o1jsHash, nodeHash, generateRandomInput } from './test-utils';
import { bytesToHex } from '@noble/hashes/utils';
import { bytesToHex, concatBytes } from '@noble/hashes/utils';
import { sha256 as nobleHashUint } from '@noble/hashes/sha256';
import { sha256O1js, SHA256 } from './sha256';
import * as crypto from 'crypto';
import { Bytes } from 'o1js';

// NIST test vectors (https://www.di-mgt.com.au/sha_testvectors.html)
// Note: - Input message: one million (1,000,000) repetitions of the character "a" (0x61).
Expand Down Expand Up @@ -97,7 +100,7 @@ describe('Testing o1js SHA256 hash function against to node-js implementation',
}
});

test.skip('should have compliant chained hashes', () => {
test('should have compliant chained hashes', () => {
const input = generateRandomInput(100);
let nodeDigest = nodeHash(input);
let o1jsDigest = o1jsHash(input);
Expand All @@ -109,6 +112,25 @@ describe('Testing o1js SHA256 hash function against to node-js implementation',
}
});

test('should have compliant digest for input=randomUint8Array', () => {
const input = generateRandomInput(31, true);
const actualDigest = o1jsHash(input);
const expectedDigest = bytesToHex(nobleHashUint(input));

expect(actualDigest).toBe(expectedDigest);
});

test('should have compliant digest for input=randomUint8Array - 100 iterations', () => {
for (let i = 0; i < 100; i++) {
let input = generateRandomInput(31, true);
let actualDigest = o1jsHash(input);
let expectedDigest = bytesToHex(nobleHashUint(input));

expect(actualDigest).toBe(expectedDigest);
}
});

// !This test takes an extremely long time to finish
test.skip('should have passing sliding window tests - 4096', () => {
const testWindow4096 = new Array<string>(4096);
for (let i = 0; i < testWindow4096.length; i++)
Expand All @@ -120,31 +142,71 @@ describe('Testing o1js SHA256 hash function against to node-js implementation',
}
});

// ===============================================================

// This test aims to destruct an input into seperate 32-bit blocks and then compare the digest of the full input against recursive updates of the 32-bit blocks
// It has the same concept of the sliding window test but on sequential update of destruced message blocks.
//TODO: This test requires update method for the hash function.
test.skip('should have passing sliding window tests - 3/256', () => {
let testWindow768 = new Array<string>(256 * 3);
test.only('should pass sliding window tests - 3/256', () => {
let BUF_768 = new Uint8Array(256 * 3);

// Fill with random data
for (let i = 0; testWindow768.length; i++)
testWindow768[i] = generateRandomInput(768) as string;
for (let i = 0; i < (256 * 3) / 32; i++)
BUF_768.set(crypto.createHash('sha256').update(new Uint8Array(i)).digest(), i * 32);

let BYTES_768 = Bytes.from(BUF_768);
const digest768 = sha256O1js(BYTES_768);
for (let i = 0; i < 256; i++) {
let b1 = BUF_768.subarray(0, i);
let b1Bytes = Bytes.from(b1);
for (let j = 0; j < 256; j++) {
let b2 = BUF_768.subarray(i, i + j);
let b2Bytes = Bytes.from(b2);

let b3 = BUF_768.subarray(i + j);
let b3Bytes = Bytes.from(b3);

expect(concatBytes(b1, b2, b3)).toStrictEqual(BUF_768);
// expect(nobleHashUint.create().update(b1).update(b2).update(b3).digest()).toStrictEqual(fnH);
expect(new SHA256().update(b1Bytes).update(b2Bytes).digest().toHex())
.toEqual(bytesToHex(nobleHashUint.create().update(b1).update(b2).digest()))
// expect(new SHA256().update(b1Bytes).update(b2Bytes).update(b3Bytes).digest().toHex()).toStrictEqual(digest768.toHex());
}
}
});

test('should have compliant digest for input=randomUint8Array', () => {
const input = generateRandomInput(31, true);
const actualDigest = o1jsHash(input);
const expectedDigest = bytesToHex(nobleHashUint(input));
// ===============================================================
let BUF_768 = new Uint8Array(256 * 3);
// Fill with random data
for (let i = 0; i < (256 * 3) / 32; i++)
BUF_768.set(crypto.createHash('sha256').update(new Uint8Array(i)).digest(), i * 32);
// ===============================================================

expect(actualDigest).toBe(expectedDigest);
test.skip(`Partial: sha256`, () => {
const fnH = nobleHashUint(BUF_768);
for (let i = 0; i < 256; i++) {
let b1 = BUF_768.subarray(0, i);
for (let j = 0; j < 256; j++) {
let b2 = BUF_768.subarray(i, i + j);
let b3 = BUF_768.subarray(i + j);
expect(concatBytes(b1, b2, b3)).toStrictEqual(BUF_768);
expect(nobleHashUint.create().update(b1).update(b2).update(b3).digest()).toStrictEqual(fnH);
}
}
});

test('should have compliant digest for input=randomUint8Array - 100 iterations', () => {
for (let i = 0; i < 100; i++) {
let input = generateRandomInput(31, true);
let actualDigest = o1jsHash(input);
let expectedDigest = bytesToHex(nobleHashUint(input));

expect(actualDigest).toBe(expectedDigest);
// Same as before, but creates copy of each slice, which changes dataoffset of typed array
// Catched bug in blake2
test.skip(`Partial (copy): sha256 partial`, () => {
const fnH = nobleHashUint(BUF_768);
for (let i = 0; i < 256; i++) {
let b1 = BUF_768.subarray(0, i).slice();
for (let j = 0; j < 256; j++) {
let b2 = BUF_768.subarray(i, i + j).slice();
let b3 = BUF_768.subarray(i + j).slice();
expect(concatBytes(b1, b2, b3)).toStrictEqual(BUF_768);
expect(nobleHashUint.create().update(b1).update(b2).update(b3).digest()).toStrictEqual(fnH);
}
}
});
});
});
});

0 comments on commit 6cf029a

Please sign in to comment.