o1js
Version:
TypeScript framework for zk-SNARKs and zkApps
78 lines (69 loc) • 2.14 kB
text/typescript
import { ZkProgram } from '../../proof-system/zkprogram.js';
import { Bytes } from '../wrapped-classes.js';
import { Gadgets } from '../gadgets/gadgets.js';
import { sha256 as nobleSha256 } from '@noble/hashes/sha256';
import { bytes } from './test-utils.js';
import { equivalentAsync, equivalentProvable } from '../../testing/equivalent.js';
import { Random, sample } from '../../testing/random.js';
import { expect } from 'expect';
sample(Random.nat(400), 5).forEach((preimageLength) => {
let inputBytes = bytes(preimageLength);
let outputBytes = bytes(256 / 8);
equivalentProvable({ from: [inputBytes], to: outputBytes, verbose: true })(
(x) => nobleSha256(x),
(x) => Gadgets.SHA256.hash(x),
`sha256 preimage length ${preimageLength}`
);
});
const Sha256Program = ZkProgram({
name: `sha256`,
publicOutput: Bytes(32),
methods: {
sha256: {
privateInputs: [Bytes(192)],
async method(preImage: Bytes) {
return {
publicOutput: Gadgets.SHA256.hash(preImage),
};
},
},
},
});
const RUNS = 2;
await Sha256Program.compile();
await equivalentAsync(
{
from: [bytes(192)],
to: bytes(32),
},
{ runs: RUNS }
)(nobleSha256, async (x) => {
const { proof } = await Sha256Program.sha256(x);
await Sha256Program.verify(proof);
return proof.publicOutput;
});
for (let { preimage, hash } of testVectors()) {
let actual = Gadgets.SHA256.hash(Bytes.fromString(preimage));
expect(actual.toHex()).toEqual(hash);
}
function testVectors() {
return [
{
preimage: 'abc',
hash: 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
},
{
preimage: 'a'.repeat(1000000),
hash: 'cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0',
},
{
preimage: '',
hash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
},
{
preimage:
'de188941a3375d3a8a061e67576e926dc71a7fa3f0cceb97452b4d3227965f9ea8cc75076d9fb9c5417aa5cb30fc22198b34982dbb629e',
hash: '70b6ee0dd06c26d51177d5bb1de954d6d50aa9f7b771b4401415d43da40605ad',
},
];
}