We are proud to announce that Bitcoin now supports PLONK. For a detailed description of how PLONK works, you can refer to our previous explanation Part 1 and Part 2.
We have previously implemented Groth16, the smallest and most efficient SNARK construction. However, it requires a trusted setup for each circuit. By eliminating the need for a per-circuit trusted setup, PLONK both mitigates concerns regarding the security of that process and ensures that no secure multi-party computation (MPC) setup ceremonies will be required again if circuit changes in the future, due to, e.g., critical bug fixes. Universal and updatable setup ceremonies, such as Perpetual Powers of Tau, can be reused for any circuit in PLONK. It makes deploying new circuit and upgrading existing circuits much easier and safer.
Run your first PLONK on Bitcoin
You need to install Circom compiler and our snarkJS first.
curl -Ls https://scrypt.io/scripts/setup-circom.sh | sh
npm i -g snarkjs-scrypt
1. Design a circuit
Implement circuits in Circom language. For example, this simple circuit/program called `factor.circom` proves that people know to factor the integer `n` into two integers without revealing the integers. The circuit has two private inputs named `p` and `q` and one public input named `n`. For more information on how to use Circom, you can refer to https://docs.circom.io.
2. Compile the circuit
Compile the circuit with the following command:
circom factor.circom --r1cs --wasm
3. Start a new **powers of tau** ceremony
The `new` command is used to initiate the ceremony of **powers of tau**.
snarkjs powersoftau new bn128 12 pot12_0000.ptau
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -e="$(openssl rand -base64 20)"
snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau
Finally we verify the protocol so far:
snarkjs powersoftau verify pot12_final.ptau
This will generate a proving key for the circuit and verify that key, using PLONK. Note there is no circuit-specific phase 2 contribution anymore as in Groth16, thanks to PLONK’s universal setup.
snarkjs plonk setup factor.r1cs pot12_final.ptau circuit_final.zkey
5. Export verification key
We export the verification key from `circuit_final.zkey` into `verification_key.json`.
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
6. Calculating a witness
First, we create a file `input.json` containing the circuit inputs with the following contents:
Next, we use the `factor.wasm` obtained from compiling the circuit to calculate the witnesses:
node generate_witness.js factor.wasm ../input.json ../witness.wtns
7. Create a proof
It uses the proving key and witnesses to generate a proof, using PLONK.
snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json
8. Export an sCrypt verifier
This outputs a smart contract file "verifier.scrypt" that contains all the code needed to verify the proof on-chain.
snarkjs zkey export scryptverifier
You can verify it locally:
snarkjs plonk verify verification_key.json public.json proof.json
9. Deploy the verifier
You can now deploy the verifier to Bitcoin. Wrap verifier.scrypt in a test contract PlonkVerifier as below.
Now you can use sCrypt IDE to deploy it.
Right click and select Deploy Contract: Debug.
After the contract is compiled, which shall finish within a few minutes, the following panel should pop up. Click Deploy.
If everything goes right, the verifier contract should have been deployed.
10. Verify the proof
Next, you’ll need to copy and paste from proof.json into Call panel and click on Call unlock().
If everything works ok, you should see the proof validated in a spending transaction.
What is next
Congratulations! You have just created your first PLONK proof on Bitcoin. So far, we have implemented both Groth16 and PLONK. Any proof system can be implemented the same way as a smart contract, thanks to Bitcoin’s programmability and scalability. Now it is time to implement your favorite proof systems, including Marlin, Sonic, Halo, Bulletproof, and STARK.