Skip to content

alrevuelta/sp1-proof-aggregation

Repository files navigation

sp1-proof-aggregation

This repo contains an end to end proof of concept of a Pessimistic Proof aggregation of Polygon's Agglayer. Given a set of n Pessimistic Proofs using SP1, the program present in here creates a single PLONK proof verifiable onchain that aggregates all n proofs into a single one. This effectively reduces the onchain gas consumption since instead of verifyng n proofs, just 1 has to be verified.

Content:

  • contracts: Contains solidity code to verify single and multiple Pessimistic Proofs. See VerifyPessimisticProof
  • aggregation: Contains an SP1 program that creates a single proof verifying that n proofs are valid. See main.rs
  • script: Contains a set of commands to generate state transitions, prove them using the Pessimistic Proof and aggregate said proofs into a single one. Outputs what's needed as input for the smart contract. See main.rs

See instruction on how to:

  • Deploy the contracts
  • Create the proofs
  • Verify the proofs

Deploy the contracts

A local test network is used, see anvil. Create an instance of it.

anvil

Configure the key and the rpc. If you are using the defaul anvil parameters they should be these ones.

export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
export RPC_URL=http://127.0.0.1:8545

Now that we have our network up and running, lets deploy the contracts.

cd contracts

Deploy our own SP1 Verifier. Note we are currently pointing to v5.0.0.

forge create \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  lib/sp1-contracts/contracts/src/v5.0.0/SP1VerifierPlonk.sol:SP1Verifier --broadcast

With the address you got, set that as verifier.

export VERIFIER=0xthe_address_you_got

And debug the deployment went fine. You should get the same version from above, v5.0.0 in our case.

cast call $VERIFIER "VERSION()" | cast --to-ascii

Now deploy the Pessimistic Proof contract verifier.

forge create \
  --rpc-url $RPC_URL \
  --private-key $PRIVATE_KEY \
  --broadcast \
  src/VerifyPessimisticProof.sol:VerifyPessimisticProof \
  --constructor-args $VERIFIER

And store the address you got.

export PP_VERIFIER=0xthe_address_you_got

Ensure the deployment worked by calling the following function. Verify it matches your VERIFIER.

cast call \
  $PP_VERIFIER \
  "getVerifier()" \
  --rpc-url $RPC_URL

Now you have your own private network with all the contracts needed for the next section.

Create the proofs

Now lets create some zero-knowledge proofs using SP1. We will create two types of proofs:

  • A PLONK Pessimistic Proof for a given chain.
  • A PLONK Aggregation Proof, that verifies that n PLONK Pessimistic Proofs are valid.

First of all we need to know the so called vkey of your program. Every program is identified by its vkey. We have one for the pessimistic program and one for the aggregation program.

cargo run --release -- --vkeys
aggregation_vk: "0x0075c8c5c73f99b78a8f716cc139155ec6c8bf389c50451bb23759a82629c9bc"
pessimistic_vk: "0x0016184113c3e8415f940f56a6eee68a6e623ae47b837e5633da14b0f1b9119c"
pessimistic_vk_hash: 0x0b0c208970fa10577281ead46eee68a67311d7236e0df95867b4296171b9119c

Store them:

export AGGREGATION_VKEY=...
export PESSIMISTIC_VKEY=...
export PESSIMISTIC_VKEY_HASH=...

Now lets create a PLONK Pessimistic Proof.

First and foremost, you need an account in the SP1 network with some funds. Proof generation should take few cents.

export NETWORK_PRIVATE_KEY=0xyour_sp1_private_key_with_funds

Now run the following command.

RUST_BACKTRACE=1 SP1_PROVER=network NETWORK_PRIVATE_KEY=$NETWORK_PRIVATE_KEY cargo run --release -- --prove

And among other things you will get the proof and public inputs of a PLONK Pessimistic Proof. Two proofs for two chains are generated. You can configure that. Save that for later.

[aggchain_id: 1] Public values: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb70913172e09840453518fe8fe3b5174c1d4ebe3614a492596569acd8c012839135e77a4e3ccd788020f5b86128c69d846faa47e54c2f4e1d85be6020ad75271f173"
[aggchain_id: 1] Proof: "0xd4e8ecd21f7e8271197dcb6c9a6154fabc7a6c4843cf50703404a715d228d5c88f2ab54d1880066bedc41c12e8ef01aa4855825d7701512e98395243b47f65cd95398e0b2bac7edcec5e80d62487484964a39d9967d024a47ab99076eb05ba598e91f8661575dec5e5d53dd8cb28d4af4f09a5f0eb8191d82e4f026d78cc30338704a6c029d6ea051fcec7e9d74e799f29e260d7d11aa12f5c1167e4dc4369c651b588b9104b55a608c72d8fa1a247ee0bac048f83a7c21d944f2e1ee94cb7404610bcb614f47e7c19bab932221f7a2fcf39bbc39f13a7edc75ee4510a197c2e2457cf960ef8afc3d1c0b1a8a20b3cc0a74b3c5777230dcfb86b4b8e4c5d63449f44f0a01e61931eeb0e4c0df8e64546761dc8314ad86d63e1b27a89bf1f482f161be5021eec2473e6e9ff8feed50e7fbe1adcbcee4bd6e2452fa9ab62d58c12cebc3a2f0dcadf8ab61e90b37e102510a48599ff792897a2a7cfaf858f85fb8a3fc123c72bc0952f2a9c43cc3a7b45cef5a52e88ccc60d1d9e4234ee375b89ea0509d1d003e53a03ca1491f2921145643a743a07302f7f1279f7dd2634172d400dc3802f2986ce4b38e6bb4144fad27a4143d75320970cc0cc52464dc4b89c7a185476b10948723a537b2aa9000349dd4188469a372cedb4e90aece69d64e8901d8fd4f5276004cbf6359578cbc6bbb1f879a8aa5a768ed9a4aa48d00c84b329152b03bc1808b3947a0ba3015d554911d6f588f72bc4a79317f472315356a0b1d2707c431e075d6236c8c3e59d9670642fcec2feb87c9fb9798ed83bb897e882af51289c1c37f2c8d70700839b61f7956fc391501cbca787caaf5dee7613670a802f0c7b0036503596a1a02bd3043880ac84fdc88ad581eabc618c6a72a15675587901cd0e9210b026c0b15d845213069bf27abc974795e52a6a52bd390a7b76d1064947247798bb6e341a91f63ec6dc50105d24ed6b7c4708f5d873f77900442e99b5b919f0839e0c12030b0cc88745891d071be6cc021ff98b96a6df43fe16523df27703b5b4a6d9254322c804aabd33952ad3ef61c85bc3eca534d6143e6ff6d8c6ef18e803fc11f6581a7a1e5e15c8cfe708d4f994aa082d85174a27e3a9dc1729ad15e14de0843d59bcf030d6a9fef7e63b3925f6f9fe244aeb9a5202ac88022f4f1b27b3afb64ec98bb61622abe52b9bcbf86b3a5ce4efb1dbc7656cabdd7cb439"

[aggchain_id: 2] Public values: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb709660d137a6b1abe3810e7392a30feccf83ab6be70ab39ec948e0821448be34d89213527e7b945a567dd542fb0d6846e84fe4fea8c11e71e1b2191cfba3c7287f6"
[aggchain_id: 2] Proof: "0xd4e8ecd22db008886e4e0061ac9fb55c08f313cca84e1d6bacb2ae05e5a4e28a1c3c32aa2318a6bb14d9c3ba4c7ae3e30c9eff320040bf82935c706daa4e196c9b73d1f92faf6af5b8f979d30e82d930b232ed4c2ed6d2d78207fb44d0981293b5374186060ffb3f99163b372ef97096f5d9cfe9f8a22ea425a24e5517d466957fd40e4d1103b977c2363cdd2c84b8dfb1554b08530d49c84c6e4bed5c4cededd00973a70f70111194dc8abb9af9f627f60d3a9381215eeb1dd64ac44a1536e5bebbeca52e1775690a3443149fd8dce9ae93cc0afb735af72de1ca56c438c95d64ad41dd14220ce1a57c2005345a1e5b412ec47dd6bd03647acfab9cae2af96856d6ea232f8f5f166bb8539cf5c7cc9c4b19c8be1782836791ec85dde44d030fc9c7c0b20987d1da822c4f13fd7ad8c7792436b99ff074e6a0be551f0ac646d9f789314713fe5f8e50ecc43ae18c6aa36be7421585f5bf559a95c4c134900eaef5cfe5201ff1ef36891c90293bec744c9f3844e0bb462286958e42540e6599ef03f2530101524cdf9ec59f93a9cc29e5c1dc5f38cbbe007d4b71f870d14dcabd2e55c8702479ae2bc68f3648fa7e3e05983fbbc1240924dca81b7599308c86d0faccf3710dfbe75db71dcacffbaeafa45ca997787efd6598ac73315b1708a8b29d1178dc03c0bd9ef99092eaca88ab6a501f0ec0993f91bd4fe85e4faba6b65bbd2781f42c5df42ee66384f49bc60479837f432dc6ca61dcb9e1085e1fa3ccda988f12012774649f05450f898152ccdd23de129d131de5e67b6b587329aa0ab27538693e2139a9dba96fb8012717d7bc8d54339f9f83a2f0b39f21eb113c546f2d27e3c829a4c2ecfdd8a7cae0467af3eb9806a4f7df3beef6e7e7c3f8a3a8637398a91f2e43beb69cf63eaa19d20cc6721ef3cb2fcad8033fca76b164b04c643991e025179978a870deda7d41637888414e4c9bddb77d115bafe6a3769136b851a099622cf8bfe3cd3e3123dc7b636f09bc19284b7ac595de1dd24b59de04308468127a05e35c80933ce4ec4e67b80632cb1c76e93b94f8e150b2f5c3813d94b06f6def1a6e0e92401ffeff58d2ac8db2c28d4123ef3167e2b7b850727eb53f5e5416f706ed7989293054d91f84d6dd8fde21573cb97cf52822ce07a517eae166c7fabd20927bd17add2310768e5440830ddabc52ac26b5c54661c4d421d06e51473e21"

On the other hand, if you want to generate an aggregation proof that verifies that the two other proofs are corrects, you just have to pass the --aggregate flag. This will input an extra proof.

RUST_BACKTRACE=1 SP1_PROVER=network NETWORK_PRIVATE_KEY=$NETWORK_PRIVATE_KEY cargo run --release -- --prove
 --aggregate

Now you have everything you need to use this proofs onchain, with the contracts we deployed before.

Verify the proofs

Using the Pessimistic Proof you got before, and the vkey, you can go directly to the SP1 verifier and verify if its correct. There are three parameters:

  • vkey: Identifies your program.
  • public inputs: Parameters you have commited to.
  • proof: The PLONK proof.

Note that it's a view function since it doesn't modify state, so we can use call.

cast call \
  $VERIFIER \
  "verifyProof(bytes32,bytes,bytes)" \
  "0x0016184113c3e8415f940f56a6eee68a6e623ae47b837e5633da14b0f1b9119c" \
  "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb709de0a705bad84bfa4ac52ec36a5bd703c313d4a4e0b75985ca3d878c4d6db18a6df86f535e358f771906e88e72d72a6fcfc912181f7f05a690f649ac3920dd395" \
  "0xd4e8ecd20e014c7e4f9cd7a519e21ffb7fd7e1c3e67344c113517ff30b778bad367345d20bc2c10c0215f821090ce1917ca116ec3cfcd587c55410ab0d70693670cbf3e81c69d1aeae55cbb5f43f9102a9e9ad4b7117d3330932f233ea1557ad077bb0f9305ba982aba2078938e3b505f2f0089ffdac695a3bac6f67bcd5a68b65058df9046e6292e592a6294687173dc0b8a305039165bf47b75c78a9ece67e0d352c1a14c5afc1b8c04ef8304e408548310fd156f0f4dd95564990c00a244a9dae88f91c3e5beef698f2eeec6239f11bcf1afe5fc643f17524be33067a2c04e4256d940407e69835095b81093d46e21eb728a7ac1c31d4a75d0764211fa68413026a5c1dc9c9b8b824af00e24abc081c1dbc84ae6d3a4d21c3668396ce958f28f987e01713007fcffd598610b4c497fe8e38a76e7e59277ee31a2edbbb739c28146efa09566f19b8510451ce5758e74761a01ef49887c71315aec027495446be18f48e0d7ebdac831978278e227863bae18f71d2047c912d132b63f83c3064be907fd209c5cea777b1b83170a5a264d0c20f422a5c83b9b4133225cd91d41189f284922fa18b6ab7dbcfc95758118e4e14f3c5024250a5716dc1df2fef23d78688b52a2e0355fdd684a2ddd3338c5730bf16c7ccca2b478d468dfd934fd4e8afa1a4a522f10e5d45df6915bd519f7726bee3a62d2945c3831484f947c64bd3b364aa952ac087fec28b8e70c3deabd9166b5c2a4a3ec100819d668d9d0f3fa47ac7878713bd0da236996c224bec790e852414d3b43602b4eddff61f5813a1b95a08910307fea66809754777374765b9e2f761aba14d5cf16bc23bc299f162e6356da83b1d25f84227b7e433f032148dcf7eb4d4f36663cdec66420c0f34f29ca3e756792a3b755b79e9b5cfa6537e21501f2fd261c01b740b262137e2517011e33f350f1227df676ba4f479080aa8bac194344efbdc1f54046c4efd20981a1b8537b2061979660b9fbcc390bcf2bdcc17932bbc81aefb73e168fe04a26211bc2f7ada2e07e932b5dc19a6e09b9fef53e1532c093a9b58e9f077c61aa82af9d21402cc231776ea8fb6d18c4bb9b9e7637110a8d98d766e5e8457bfa96bc523da011885f6149d1f5ee71fc359ed70b6806901c3a433896aa580f903cc58c251cb30457f302432b1e6fb272473c1f82d6b903e2b892f7bcef7525c3e84e386930a07bcec55" \
  --rpc-url $RPC_URL

In reality you won't be calling the SP1 verifier directly, but a contract with some logic to execute if the proof is valid. We can call the verifyPessimisticProof function as follows. This does require gas.

cast send \
  $PP_VERIFIER \
  "verifyPessimisticProof(bytes32,bytes,bytes)" \
  "0x0016184113c3e8415f940f56a6eee68a6e623ae47b837e5633da14b0f1b9119c" \
  "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb709de0a705bad84bfa4ac52ec36a5bd703c313d4a4e0b75985ca3d878c4d6db18a6df86f535e358f771906e88e72d72a6fcfc912181f7f05a690f649ac3920dd395" \
  "0xd4e8ecd20e014c7e4f9cd7a519e21ffb7fd7e1c3e67344c113517ff30b778bad367345d20bc2c10c0215f821090ce1917ca116ec3cfcd587c55410ab0d70693670cbf3e81c69d1aeae55cbb5f43f9102a9e9ad4b7117d3330932f233ea1557ad077bb0f9305ba982aba2078938e3b505f2f0089ffdac695a3bac6f67bcd5a68b65058df9046e6292e592a6294687173dc0b8a305039165bf47b75c78a9ece67e0d352c1a14c5afc1b8c04ef8304e408548310fd156f0f4dd95564990c00a244a9dae88f91c3e5beef698f2eeec6239f11bcf1afe5fc643f17524be33067a2c04e4256d940407e69835095b81093d46e21eb728a7ac1c31d4a75d0764211fa68413026a5c1dc9c9b8b824af00e24abc081c1dbc84ae6d3a4d21c3668396ce958f28f987e01713007fcffd598610b4c497fe8e38a76e7e59277ee31a2edbbb739c28146efa09566f19b8510451ce5758e74761a01ef49887c71315aec027495446be18f48e0d7ebdac831978278e227863bae18f71d2047c912d132b63f83c3064be907fd209c5cea777b1b83170a5a264d0c20f422a5c83b9b4133225cd91d41189f284922fa18b6ab7dbcfc95758118e4e14f3c5024250a5716dc1df2fef23d78688b52a2e0355fdd684a2ddd3338c5730bf16c7ccca2b478d468dfd934fd4e8afa1a4a522f10e5d45df6915bd519f7726bee3a62d2945c3831484f947c64bd3b364aa952ac087fec28b8e70c3deabd9166b5c2a4a3ec100819d668d9d0f3fa47ac7878713bd0da236996c224bec790e852414d3b43602b4eddff61f5813a1b95a08910307fea66809754777374765b9e2f761aba14d5cf16bc23bc299f162e6356da83b1d25f84227b7e433f032148dcf7eb4d4f36663cdec66420c0f34f29ca3e756792a3b755b79e9b5cfa6537e21501f2fd261c01b740b262137e2517011e33f350f1227df676ba4f479080aa8bac194344efbdc1f54046c4efd20981a1b8537b2061979660b9fbcc390bcf2bdcc17932bbc81aefb73e168fe04a26211bc2f7ada2e07e932b5dc19a6e09b9fef53e1532c093a9b58e9f077c61aa82af9d21402cc231776ea8fb6d18c4bb9b9e7637110a8d98d766e5e8457bfa96bc523da011885f6149d1f5ee71fc359ed70b6806901c3a433896aa580f903cc58c251cb30457f302432b1e6fb272473c1f82d6b903e2b892f7bcef7525c3e84e386930a07bcec55" \
  --private-key $PRIVATE_KEY \
  --rpc-url $RPC_URL

Ensure the LER was updated.

cast call \
  $PP_VERIFIER \
  "getLER(uint32)(bytes32)" 0

And finally, you can also call verifyMultiplePessimisticProofs which uses proof aggregation to verify that multiple Pessimistic Proofs are valid. The inputs are the following:

  • Aggregation sp1 vkey.
  • Pessimistic Proof sp1 vkey.
  • Public inputs for each aggchain. See Pessimistic Proof Output.
  • The PLONK proof.
cast send \
  $PP_VERIFIER \
  "verifyMultiplePessimisticProofs(bytes32,bytes32,bytes[],bytes)" \
  $AGGREGATION_VKEY \
  $PESSIMISTIC_VKEY_HASH \
  '[0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb70956e89bd824cc7d85242ce8d71551116030feb1cd7d5794f56af492fa0c4a8d7e78392453e02202258713d73205a965fe8028cdba5af92208fd500a58696372e5, 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013f4b9e2bb63b8a124ca9c44e465dadff6605b3b728a63876df1bc8848fedb70913172e09840453518fe8fe3b5174c1d4ebe3614a492596569acd8c012839135e77a4e3ccd788020f5b86128c69d846faa47e54c2f4e1d85be6020ad75271f173]' \
  "0xd4e8ecd214a11088a28f40d542d29bc966f874d4fde307be6c5288991ec42afbfa4815b22a31424baade7124d52bb6cbc4a198694de572a576f72b21ebf7e456d8ae0d2901ebd55fec8680b7098f17f1f2b0a831cfad69065b12fd5b1fa0cb7122a40f1120a7d509476ec6a25b0d8ec797ff3c1d81bab42ad8844da642ea3e5cdf74d45615e8e77daf9624e8adb97108321c3a2fb79284e1b27cb5b3d9f9f4b827b6e77c0e9707f9dedb27314f488aed8a17d9462121d6830f9181659b98989933d85bc61f674a2c9bb747535352dbaa19e1022d152bbba6d47626ad40752c36321dfc8212a738fe36d250e9727f041e2b4d3eaa98579cb440a111022a36e82ec92c605915725af607697d049d71de2db6dbe16c15399271bba9b6887bd20b7bd5eb89001b5aae0e00188b1179d1f5eb1d26d78da6c8102c0e816c75cd68936a76620f33196e249bf0a4862da35aa8ea9695ded67cb2c453b7a6063058e46303f367b10406e42650a0fe7aceaf22f1909dd5f56eb46a6037d07bbf73ad416072b63706e521e4f8081ddc0f2b79d25183356e32039a225022f9b6a2cf4f62510cce274cc40da36c63a20ebc4a3fc0bf5eaf68070b321753d0853834b34a545cef8c25ba5f2db7164eb855b3db08b9e996b8f47750adae25f1ef774ca8ee66fd623ff7237a00c02b5dda4c79adc707e9b84fc1fe24e88edb009d3bd866cd87deff2e52264d0ebf70d9d52e5b8cde49b4e8f5cfa6682c1eb12f94de6f6e83b17c1de0ac34891380e81e6872c3c09d744af4a7a28687b142339e21b0638eed150e039573244a1e8006c9f7241c53d3897ca251ecd7a45f9d8396164bb046729eb42aa06f0c441239c9a093be98f3f6cf2e45a4dd9bd5cfcb01e4bc6704fc40fbc4d664f09b3d07913a386a04ba4c2a2b32040e65d0a81afe10b88676d4354aa4811cbe252a2d29cc9c9c72ba81ad9a1415ec41baf5a764bac8640f027bf4aa39fd117df8afa4112ea69c3530d51024fbb820d8142dbdde6e5ffd89d3c2989bb71d84908f163421d2a81c91c7f69cc4ced0bf5ba61775d6bc3c94e3531c20ab11820cc22ff2880bff59db4bd27dc22a8aef3686cc4136741e10c3a8559abb9cbf9495c84089531f66b10ac48a422b11b212ba3c2e349820ac908aceca383b09491fdf6569132d1d70c206c40c6acd20fa07f23d05971fa3b813e2ca34adee7597271be76e902e" \
  --private-key $PRIVATE_KEY \
  --rpc-url $RPC_URL

Now you can check that multiple aggchains have been verified, advincing its state (eg LER).

cast call \
  $PP_VERIFIER \
  "getLER(uint32)(bytes32)" 1

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors