@nori-zk/proof-conversion
Version:
Verifying zkVM proofs inside o1js circuits, to generate Mina compatible proof
67 lines • 3.05 kB
JavaScript
import { Field, Provable, VerificationKey, Poseidon, UInt8, Bytes, ZkProgram, Struct, UInt64, Undefined, } from 'o1js';
import { FrC } from '../towers/index.js';
import { NodeProofLeft } from '../structs.js';
import { parsePublicInputsProvable, } from '../plonk/parse_pi.js';
import { wordToBytes } from '../sha/utils.js';
import fs from 'fs';
class Bytes32 extends Bytes(32) {
}
class BlobstreamInput extends Struct({
trustedHeaderHash: Bytes32.provable,
targetHeaderHash: Bytes32.provable,
dataCommitment: Bytes32.provable,
trustedBlockHeight: UInt64,
targetBlockHeight: UInt64,
validatorBitmap: Bytes32.provable,
}) {
}
const padUInt64To32Bytes = (num) => {
const unpadded = wordToBytes(num.toFields()[0]);
return [...unpadded, ...Array(24).fill(UInt8.from(0))].reverse();
};
const blobstreamVerifier = ZkProgram({
name: 'blobstreamVerifier',
publicInput: BlobstreamInput,
publicOutput: Undefined,
methods: {
compute: {
privateInputs: [NodeProofLeft],
async method(input, proof) {
let blobstreamProgramVk;
let blobstreamNodeVk;
let vk;
if (process.env.BLOBSTREAM_ENABLED == 'true') {
blobstreamProgramVk = FrC.from(process.env.BLOBSTREAM_PROGRAM_VK);
const workDir = process.env.BLOBSTREAM_WORK_DIR;
blobstreamNodeVk = Field.from(JSON.parse(fs.readFileSync(`${workDir}/proofs/layer5/p0.json`, 'utf8')).publicOutput[2]);
vk = VerificationKey.fromJSON(JSON.parse(fs.readFileSync(`${workDir}/vks/nodeVk.json`, 'utf8')));
}
else {
blobstreamProgramVk = FrC.from(0n);
blobstreamNodeVk = Field.from(0n);
vk = VerificationKey.empty();
}
proof.verify(vk);
proof.publicOutput.subtreeVkDigest.assertEquals(blobstreamNodeVk);
let bytes = [];
bytes = bytes.concat(input.trustedHeaderHash.bytes);
bytes = bytes.concat(input.targetHeaderHash.bytes);
bytes = bytes.concat(input.dataCommitment.bytes);
bytes = bytes.concat(padUInt64To32Bytes(input.trustedBlockHeight));
bytes = bytes.concat(padUInt64To32Bytes(input.targetBlockHeight));
bytes = bytes.concat(input.validatorBitmap.bytes);
const pi0 = blobstreamProgramVk;
const pi1 = parsePublicInputsProvable(Bytes.from(bytes));
const piDigest = Poseidon.hashPacked(Provable.Array(FrC.provable, 2), [
pi0,
pi1,
]);
piDigest.assertEquals(proof.publicOutput.rightOut);
return undefined;
},
},
},
});
const BlobstreamProof = ZkProgram.Proof(blobstreamVerifier);
export { blobstreamVerifier, BlobstreamProof, BlobstreamInput, Bytes32 };
//# sourceMappingURL=verify_blobstream.js.map