I'm particularly impressed with my own team's work on Ironwood, particularly Tachyon's @MariusMargulus who has been stitching together lemmas with the help of cryptographers from @zkSecurity, @zodl_co and others!
Here's a visualization of just a subset of the proofs needed.
Aaaand we have reached SOTA on (emulated) fixed-based scalar multiplication as well:
https://t.co/8uzFujNiJJ
Thanks to https://t.co/1nF3hjxdgi and all the other golfers that made this possible.
Hinkal is back
Our EVM (Polygon, Ethereum, Base, and Arbitrum) contracts have been redeployed, independently audited, and are now live. You can resume using Hinkal Pay & Prime as normal, starting today. Solana, Tron, APIs and Hinkal Wallet will follow over the next few days.
What we did
We worked with @zksecurityXYZ, one of the best ZK security teams in the space, following the incident. The process combined zkao, zkSecurity’s automated vulnerability scanner, with a manual review of the circuit-level fix for the identified double-spend condition.
The review focused on the identified double-spend condition and on verifying that the proposed circuit-level change prevented a single deposit from being spent more than once (a double-spend), and that there isn't an invalid proof that could be accepted as valid (a proof forgery).
The issue is now fixed.
Issue
nullifyingPrivateKey was range-checked to be a canonical field element (< p, the BN254 scalar field prime), never reduced to or bounded by the BabyJubjub prime-subgroup order l. This is the precondition for a double-spend: a note bound only to the derived point k·G could be nullified by any scalar in the same residue class mod l.
Fix
We resolved the double-spend risk by binding the raw nullifyingPrivateKey scalar directly into the UTXO's stealth-address hash, rather than deriving the note's public key solely from the curve point k·H0.
Because the scalar itself is now part of the commitment preimage, two congruent scalars k and k+l (which map to the same BabyJubjub point) now produce different public keys, and therefore different commitments: distinct tree leaves instead of one shared UTXO. Each committed note is reconstructable by exactly one scalar, its nullifier is unique, and the ~8 same-subgroup representatives can no longer open the same UTXO, closing the malleability path that would otherwise have allowed multiple valid nullifiers for a single note.
We're proud to announce Zakura: a new Zcash full node.
Scaling Zcash means our upcoming protocol upgrades (like Tachyon) will need significant full-stack performance improvements. Today's 1.0.0 release puts us on that path.
Excited to announce Zakura! A new Zcash full node, built around scale!
We've teamed up with @TachyonZcash to make this a reality.
Our first release solves many painpoints for the ecosystem:
- Much faster sync
- Pruned nodes
- Snapshots
- Support for Zcashd wallets
🧵
In spite of using many different models from many different LLM providers, our philosophy is still to just throw everything we have at bugs, and in that spirit we are now investigating time and money into fine tuning open-weight models and see how far we can get there
It feels weird but Kevin is part of the family now in @zksecurityXYZ xD he manages our schedule, reminds us to invoice clients, gathers updates from team members on Fridays to write an internal tribune on Mondays, and even tell us every weeks about what changed in zkao dev branch
We believe the challenge is now robust against adversarial circuits, and want to thank the community for trying break it. Please continue to do so!
Happy zkGolfing ⛳️
Shout-out to @QED_Audit for breaking our leaderboard by finding a neat exploit, exposing a gap in the Clean framework.
We fixed the issue and redeployed zkGolf with updated statements and the original leaderboard.
What happened?
https://t.co/BrmPhwddMm by @zksecurityXYZ challenges you to write the cheapest formally verified circuit and prove it correct in Lean 4.
For the SHA-256 challenge, we submitted a circuit with 1 witness and 1 constraint. It still verified.
Here is how we broke the spec. 🧵
In the challenge format, we cannot run submitted code because that would open a pandora's box of other exploits: Lean is not designed for running adversarial code without breaking its trust guarantees. We need to rely purely on the Lean kernel, which can only check types.