Skip to content

Add r0 support#137

Open
someone235 wants to merge 2 commits into
kaspanet:masterfrom
someone235:zk
Open

Add r0 support#137
someone235 wants to merge 2 commits into
kaspanet:masterfrom
someone235:zk

Conversation

@someone235

Copy link
Copy Markdown
Contributor

No description provided.

@michaelsutton

Copy link
Copy Markdown
Contributor

assuming we have #138 by @elldeeone which adds the lower-level builtin:

g16.verify(byte[] verifyingKey, byte[] proof, byte[32] ...publicInputs): bool

i wonder if r0.g16.verify(...) should be implemented as a silverscript std fn rather than as a dedicated compiler lowering. that might make the r0 mapping much easier to audit, because the code can describe the risc0 claim/public-input construction directly, while g16.verify remains the only raw zk opcode intrinsic.

rough sketch:

byte[16] constant ZERO16 = 0x00000000000000000000000000000000;

byte[32] constant R0_CONTROL_ROOT_A0 = 0x...; // control_root[0..16] || ZERO16
byte[32] constant R0_CONTROL_ROOT_A1 = 0x...; // control_root[16..32] || ZERO16
byte[32] constant R0_BN254_CONTROL_ID = 0x...;

byte[32] constant R0_OUTPUT_TAG_DIGEST = 0x...;  // sha256("risc0.Output")
byte[] constant R0_OUTPUT_DIGEST_SUFFIX = 0x...; // ZERO digest || u16_le(2)

byte[] constant R0_RECEIPT_CLAIM_PREFIX = 0x...; // sha256("risc0.ReceiptClaim") || ZERO input
byte[32] constant R0_POST_DIGEST_HALTED_ZERO = 0x...;
byte[] constant R0_RECEIPT_CLAIM_SUFFIX = 0x...; // sys_exit || user_exit || u16_le(4)

byte[] constant R0_G16_VK = 0x...;

function r0_g16_verify(byte[32] journal_hash, byte[] proof, byte[32] image_id) : bool {
    byte[32] output_digest = sha256(
        R0_OUTPUT_TAG_DIGEST
            + journal_hash
            + R0_OUTPUT_DIGEST_SUFFIX
    );

    byte[32] claim_digest = sha256(
        R0_RECEIPT_CLAIM_PREFIX
            + image_id
            + R0_POST_DIGEST_HALTED_ZERO
            + output_digest
            + R0_RECEIPT_CLAIM_SUFFIX
    );

    byte[32] c0 = byte[32](claim_digest.slice(0, 16) + ZERO16);
    byte[32] c1 = byte[32](claim_digest.slice(16, 32) + ZERO16);

    return g16.verify(
        R0_G16_VK,
        proof,
        R0_CONTROL_ROOT_A0,
        R0_CONTROL_ROOT_A1,
        c0,
        c1,
        R0_BN254_CONTROL_ID
    );
}

of course we can still pin this with tests against the rk zk sdk by running the same r0 groth16 fixture through both paths and require identical verification behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants