ZK Hack Kraków

ZK Hack Kraków: Winning Double with Risc0

Andrzej Broński
Casper Association R & D
5 min readJun 22, 2024

--

Hackathons are renowned for fostering innovation and creativity, and ZK Hack Kraków was no exception. For me, it was an event of personal triumph and professional growth ✨. Hosted from May 17th to 19th, this event was a deep dive into the world of zero-knowledge technology, an opportunity to meet brilliant minds, and a personal triumph as I was awarded with a double bounty 💸. Here is a glimpse into my unforgettable journey at ZK Hack Kraków.

Event opening — posted by @Agni_deneve.

A Glimpse into the Hackathon

The third IRL hackathon organized by ZK Hack took place in Kraków, and it was a bustling hub of activity with two main paths: the Product Path, where participants built new zk projects like games, DAOs, and lending platforms, and the Hacker Path, focused on optimizing proving time on the client-side.

Held at the industrial-chic Centrum Konferencyjne Fabryczna 13 — the site of the former Polmos vodka distillery 🍸 — event attracted hackers and builders from around the world.

Conference entrance.

With top sponsors like Aleph Zero, o1labs, and MINA, the stage was set for three days of intense hacking, learning, and collaboration.

Gevulot Bounty

As this was my first hackathon, I was not sure what to expect but was excited to dive in. The atmosphere was incredibly welcoming, filled with passionate and knowledgeable individuals eager to share their insights. I was so engrossed in conversation that I missed the team formation event😅.

I met Norbert, a protocol researcher at Gevulot, who introduced me to their side bounties.

Gevulot — A decentralized network optimizing the offloading of arbitrary provable compute; uses Nanos unikernel for workload execution.

One bounty involved deploying any existing prover to the devnet, and leveraging my Casper R&D experience, I realized I could deploy Risc0 integration.

I quickly dove into the coding, leading to my double bounty win with the GevuRisc project!

Gevulot revealing bounty winner.

Primarily, the 3 best projects would be awarded, but since others failed, they decided to give me the double bounty ☺.

Project overview

I built Risc0 prover/verifier integration for Gevulot, aptly named GevuRisc.

Along the way, I encountered several challenges and hiccups that I would like to present below.

1. Custom binary changes

Gevulot’s environment uses a Nanos unikernel, which is quite similar to a normal Linux system but with a few restrictions. Not all syscalls are supported, there is no fork(), networking is restricted, and the root filesystem is read-only.

What is important, that for proving and verification, we need to pass input, and in Gevulot’s environment, workloads are passed via gRPC with a dedicated shim helper. Output is handled differently as well.

To tackle this, I decided to place the proving/verification logic in a common library and handle dedicated input/output in a thin binaries:

Binary difference: left — traditional CLI, right — Gevulot specific.

This setup allowed me to run it locally and ensure that both proving and verification worked as expected. At this point, I was able to successfuly deploy the prover and verifier program 😄.

IMO, Gevulot environment should be improved to pass CLI arguments directly, rather than forcing users to implement custom workload handling.

2. Format of Risc0 Guest Input

Since the prover must pass additional input for the Risc0 guest, it must be stored in a specific format. I replicated Risc0 serialization logic so that the bytes of each argument could be passed directly to EnvBuilder.

To store each serialized argument, I used a JSON array containing hex-encoded bytes. For example, two u32 arguments 1787569 and 1337 are represented as [“b1461b00”, ”39050000"].

3. Default Risc0 Prover

So far, things were relatively easy. The real problems started when I deployed the workload:

Deploying example workload.

Even though deployment was successful, the transaction got stuck. No error code, just stuck.

I reached out to the Gevulot team, and they provided me with internal node logs. It turned out that the Risc0 prover failed to run the r0vm subprocess 😮.

This was surprising because the prover returned by default_prover() should run in the same process, since I enabled the proverfeature. I even tried explicitly setting RISC0_PROVER=local, but it still did not work.

Eventually, I discovered a terrible bug — I specified dependency feature = [“prover”] instead of features = [“prover"] 🐵.

Connecting with Other ZK Projects

One of the most rewarding aspects of the hackathon was the opportunity to engage directly with teams from prominent ZK projects like Risc0 and L2BEAT. The former, widely known for its developer-friendly proving stack, and the latter, which performs comprehensive L2 audits, provided invaluable insights.

Discussing the centralized nature of most L2s and the risks associated with validiums’ Data Availability was particularly enlightening. This resonated deeply with me, given my work on Kairos, an L2 solution for processing payments. As our R&D team approaches our first MVP demo, meeting with L2Beat was invaluable for future improvements, ensuring that our solution is secure and production-ready.

Wrap up

ZK Hack Kraków was a whirlwind of learning, coding, and connecting. Winning the Gevulot bounty was undoubtedly a highlight, but the real value lay in the experiences and relationships formed. This hackathon was a catalyst for future innovations and collaborations.

If you are passionate about zk-tech, I highly encourage you to attend a hackathon. You will gain more than just technical skills — you will join a vibrant community pushing the boundaries of what is possible.

Source: r/ProgrammerHumor.

🚀 Stay tuned for more updates on Kairos as we gear up for our MVP demo. Until then, happy hacking!

--

--