For the beta version of the protocol the access to Quantum is permissioned. Every permissioned protocol is give an AUTH_KEY and a npm package to communicate with quantum layer rpc endpoint. To get whitelisted and get your key reach out to @garvit_electron on Telegram.

Initialise Connection:

After installing the npm package, quantum client helps you interact with the quantum server seamlessly.

import {Quantum} from "electron-quantum";

Primarily before interacting with server you will need to establish connection.

let rpc_endpoint = "";
let access_key = "xx-xxx"; // AUTH_KEY
const quantum = new Quantum(rpc_endpoint, access_key); 

Check if quantum instance is able to talk with the server. If rpcLive is True that means connection is established.

let rpcLive = await quantum.checkServerConnection();

Circuit Registration

Quantum layer right now supports Groth16, Gnark-groth16, Plonky2 and Halo2-KZG proofs. Only thing required to register a circuit from user is verification_key

// @proof_type
// 1: groth16
// 2: gnark-groth16
// 3: plonky2
// 4: halo2-kzg
let proof_type = 1;//Chose 1,2,3,4 corresponding to your proving scheme
let vkey_path = "../../vkey.json";//Add verification key json path
let cd_path = "../../cd.json";// Add common data json path for plonky2 otherwise add empty string ""
let circuit_id = await quantum.registerCircuit(vkey_path, cd_path, proof_type);

If the circuit_id is successfully returned that means circuit was registered successfully. circuit_id is hash of verification_key and is used to send proofs to the server for aggregation.

Proof Submission

To submit a proof for cheap verification on Ethereum, user sends proof corresponding public_inputs and circuit_id. If proof is successfully submitted proof_id is returned from rpc server.

let proof_path = "../../proof.json";//Add proof json path
let pis_path = "../../pis.json";//Add public inputs json path
let proof_id = await quantum.submit_proof(proof_path, pis_path, circuit_id)

proof_id is used to track the progress or get details of the aggregation request.

// @status:
let status = await quantum.get_proof_data(proof_id)

status contains of various fields explained below:

On-Chain Verification

For protocols to integrate quantum they would have to make some changes to their verification smart contract. The changes required are described below:

Before Quantum Integration (>250K Gas):

// Before Integration
 function verifyProof(
        bytes calldata proof,
        uint256[] calldata publicInputs
    ) external {
        // .. business logic
        bool result = verifier.Verify(proof, publicInputs);// zk proof verification
        if (result) {
            // .. business logic
        } else {

The above contract is a standard zk proof verification contract, where a verifier takes in a proof and public inputs and return True or False.

Since quantum contract stores the keccak-hash of last verified publicInputs corresponding to a circuit_id, all you need to send is publicInputs and match the keccak-hash from quantum verifier contract state.

After Quantum Integration (~30K Gas):

// After Integration
 function verifyProof(
        uint256[] calldata publicInputs
    ) external {
        // .. business logic
        // 1. Do keccak256 hash of public inputs
        bytes memory keccakInput = new bytes(publicInputs.length * 32);
        for (uint256 i = 0; i < keccakInput.length; i++) {
            bytes32 hash = bytes32(publicInputs[i]);
            for (uint256 j = 0; j < 32; j++) {
                keccakInput[i * 32 + j] = hash[j];
        bytes32 publicInputsHash = keccak256(keccakInput);
        // 2. Extract last verified public inputs corresponding to 
        //.   the circuit_id from quantum contract
	bytes32 verified_hash = quantumVerifier.get_pub_input(circuit_id);
        if (publicInputsHash == verified_hash) {
	    // 3. These public inputs were verified as a part of superproof
            // .. business logic
        } else {

Last updated