Replies: 2 comments 5 replies
-
Small progress update, we are currently working on removing the dependency on mcl, and adding support instead via https://github.com/cf/antelope-bls12-381/tree/cpp11compat for checking the proof, which is a c++ 11 compatible fork of the bls12-381 implementation already used in production by EOS. |
Beta Was this translation helpful? Give feedback.
-
While I appreciate the depth of the proposal and the work being produced, I could not be more opposed to an specific opcode than this one. While I will sound bias as an employee of StarkWare, this opcode seeks to reproduce the same mistake we saw on Ethereum, enshrining a specific curve into the chain as well as setting a privilege for a specific cryptographic primitive.
Finally and the most important point:
While I am in favor of more ZKPs into Doge, I don’t believe this specific one is the right one. Hence I am opposed to this specific opcode. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Note:
Over the past few months, we have been working on a proposal to an op code to Dogecoin which can verify zero knowledge proofs on Dogecoin. In addition to the proposal, we have wrote working fork of Dogecoin that implements and an end-to-end zk rollup that showcases in practice how a zkRollup could be used to scale Dogecoin.
We hope to gather feedback from the broader community to improve the proposal, with the ultimate goal of delivering new value to Dogecoin users without increasing the barrier of entry to running a full node.
OP_CHECKGROTH16VERIFY
An ultra-lightweight, soft-forkable solution to trustlessly scale and add smart contract-like functionality to Dogecoin
Highlights:
Summary:
We propose adding an op code to dogecoin which verifies a Groth16 zero knowledge proof over BLS12-381, OP_CHECKGROTH16VERIFY.
In particular, we propose that the op code verify a Groth16 proof with two public inputs, and support two modes of operation controlled by the stack:
Mode 0: Verify a proof with 2 public inputs and verifier key, all of which are stored on the stack, marking the transaction if the proof is invalid and behaving like OP_NOP otherwise
Mode 1: Verify a proof with 2 public inputs and verifier key, where the verifier key and first public input are stored on the stack, and the second public input is the transaction's SIGHASH.
By adding this op code (specifically mode 1), it makes it possible to verify any trustless computation on Dogecoin, build recursive covenants and design smart contract functionality via sighash introspection.
A working rough-draft implementation of OP_CHECKGROTH16VERIFY can be found in our fork, and you can also test it out with a docker image we built that includes a local testnet (regtest), block explorer (fork of blockstream electrs):
To test, you can visit http://localhost:1337 for BitIDE with OP_CHECKGROTH16VERIFY enabled, http://localhost:1337/explorer/ to view a block explorer and http://devnet:devnet@localhost:1337/bitcoin-rpc to interact with the local testnet via RPC.
Usage
In order to maintain backwards compatibility, we propose:
The stack parameters accessed by OP_CHECKGROTH16VERIFY are as follows:
Mode 0 (Two public inputs)
Mode 1 (Public Input 0 == user defined public input, Public Input 1 == SIGHASH)
Deep Dive: How Groth16 + Sighash enables trustless scaling and smart contract functionality on Dogecoin
To better explain how the OP_CHECKGROTH16VERIFY can help scale Dogecoin, it is necessary to first examine how zero knowledge proofs enable the verification of arbitrary computation from a birds eye view.
In general, zk-SNARK based zero knowledge proving backends allow a prover to succintly prove that a program described as an arithmetic constraint system is satisfied.
Consider the program:
if we wanted to prove that prover knows two numbers
a
andb
which when multiplied equalc
we could represent this program with the following diagram:One could then take such a circuit and generate a corresponding verifier key which is unique to the program, and can be used to verify arbitrary executions of the program by utilizing a proving backend such as Groth16:
The verifier key of such a circuit can then be encoded in the spend script of a P2SH UTXO, and require a valid proof in order to be spent. One can then utilize a zk proving backend such as Groth16 to generate a valid proof:
The prover could then spend the UTXO by providing the proof in the witness of the P2SH spend transaction to successfully spend the UTXO:
Crucially, the size and complexity of verifying a Groth16 proof does not depend on the complexity or size of the computation being verified, meaning that OP_CHECKGROTH16VERIFY can verify an arbitrary amount of computation performed off chain without increasing the workload on Dogecoin nodes.
This enables Doge to validate new kinds of transactions like smart contract state machines and complex stateful without requiring any further changes to dogecoin, all while still respecting all existing limitations imposed on P2SH spends:
To enable trustless smart contract-like functionality without any additional burden on the network, we can use one of the public inputs as the spend transaction's SIGHASH and use the other public input to store the merkelized state of an application such as a smart contract:
Via the SIGHASH, we can allow the smart contract to be aware of any deposits of Doge made into the contract as well as any withdrawals or outputs that must be made in order to spend the UTXO:
To learn more about this sighash introspection technique, check out our reference implementation in CityRollup
Script Example
Ideally we would like to store the verifier data and current state root in the P2SH redeem script of the UTXO so that the UTXO can only be spent if we provide a valid state transition proof for given logic. Due to script limitations, stack elements must be at most 80 bytes and since the the verifier key is a total size of 480 bytes we can split it up to into 6 80-byte chunks.
In this case, our ideal script would look something like the following:
However, since the redeem script is limited to 520 bytes, we cannot directly use this approach. Instead we can hash the first 80 bytes of the verifier data, store the hash in the redeem script and provide the first 80 byte of the verifier key in the spend witness instead:
To spend the UTXO, we provide the following witness:
Beta Was this translation helpful? Give feedback.
All reactions