PLONK on Bitcoin

sCrypt
4 min readOct 17, 2022

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.

Image generated by OpenAI’s Dall-E

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

We have added PLONK support in our existing snarkJS library, which is fully compatible with Circom. All Circom circuits developed for Groth16 can be directly reused in PLONK, without any change at all. The full PLONK verifier code can be found here, along with a test in Javascript. Generating a PLONK verifier is similar to generating a Groth16 verifier in snarkJS.

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

4. Setup

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:

{
"p": 7,
"q": 13
}

Next, we use the `factor.wasm` obtained from compiling the circuit to calculate the witnesses:

cd factor_js/
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.

--

--

sCrypt

sCrypt (https://scrypt.io) is a full-stack smart contract and token development platform for Bitcoin