Operation Aegis
The Aegis Gateway guards a single number: the master secret . Every second, thousands of users knock on its door, and for each one the gateway must prove "I know " without ever saying what is.
Last week we learned that the gateway's chip was tampered with at the fab. Somewhere in the silicon, a listener is recording wires, every clock cycle, for every request. We can't recall the chip. We can only redesign the circuit that runs on it.
That's your job. Build a prover that stays correct, leaks nothing, and keeps up with the queue on a tight silicon budget.
The mission
For every incoming request , your circuit must output a Schnorr proof :
where is a fresh random nonce. Anyone holding the public key can check the proof with , without learning .
The catch: lives inside a VAULT that never reveals it directly. You hand the vault a random mask , and it gives you back . Using , , and , you have to produce in a way that never exposes to the listener.
You build the circuit in the Playground by dragging hardware blocks onto a canvas and wiring them up. The server then simulates it cycle by cycle on hidden data. A design is judged on three things:
- Correct: every proof verifies, and each one belongs to the request that asked for it.
- Secure: nothing the listener records lets them solve for .
- Efficient: small area, low latency and, in Part B, high throughput.
Conventions
Assume the standard Schnorr setting:
- Scalars are integers mod a large prime .
- is exponentiation in a prime-order group with public generator .
- is a hash mapped into .
The exact constants are fixed by the evaluator and listed at the end of this page, but you never need them: the blocks handle the arithmetic for you. Time is measured in clock cycles, area in gate units G.
Your toolbox
| Block | Does | Latency | Area |
|---|---|---|---|
TRNG | fresh uniform random scalar | 5 | 250 G |
VAULT | 1 | 100 G | |
HASH_256 | 3 | 150 G | |
MOD_EXP | 10 | 400 G | |
MUL · ADD · SUB | , , (mod ) | 2 · 1 · 1 | 100 · 20 · 20 G |
DELAY(d) | the same value, cycles later | G | |
MUX / DEMUX (Part B) | merge / split a stream across copies | 1 | G |
PIPE (Part B) | split MOD_EXP, HASH, MUL into stages | see block | + per stage |
The Playground shows each block's exact numbers when you select it.
How the hardware behaves
- Values last one cycle. A block fires when all of its inputs arrive on the same cycle, and its result appears exactly latency cycles later.
DELAYis the only memory. - Blocks are busy. A block can't accept new work until it has finished, so it must not see requests more often than its latency allows. Pipelining or multiple copies get around this.
- Requests stay separate. Inputs from two different requests must never meet in one block.
- Requests arrive at a fixed rate. A new arrives every cycles (the initiation interval). A
TRNGcan fire before its request arrives (set its offset );MOD_EXPcannot start before the request.
What the listener sees
The listener records the outputs of MOD_EXP, HASH_256 and VAULT, the request IDs, your outputs , and anything computed purely from those. Everything that depends on a TRNG output is hidden from them, but hidden is not the same as safe. The audit fails your design if:
- any wire, hidden or not, carries , or a multiple of , with no randomness left in it;
- can be solved for from what the listener records, across many requests;
- a random value is used for more than one request, or two random values are multiplied together.
The listener is good at algebra and patient. Think about what each shortcut gives them.
The two parts
| Part A | Part B | |
|---|---|---|
| Blocks | the base set | base set + MUX, DEMUX, PIPE |
| Request rate | one every 10 cycles | you choose: one every 1–9 cycles |
| Must be secure? | no, but secure designs score far more | yes |
| You minimise |
is total area, is the latency from a request's arrival to its last output, and is the cycles between requests.
Scoring. Each result lands in a band. Your position inside the band depends on how close your cost is to the best known design:
| Result | Points |
|---|---|
| Part A, correct but insecure | 5 – 15 |
| Part A, correct and secure | 20 – 50 |
| Part B, correct and secure | 70 – 100 |
Your total is your better part. Only your best submission per part counts, and the leaderboard updates live as better designs appear.
Before you start
- Get Part A working first, then make it secure, then make it small.
- When something breaks, Run preview shows the cycle each input arrived at every block. Mismatched arrivals are the usual culprit.
- Every shortcut that saves a block has a price. Make sure the price isn't the secret.
Reference constants
You don't need these to play. They're here for the curious.
- , , and generates the order- subgroup of .
- , with as 33-byte and as 8-byte big-endian integers.
- The server simulates 200 requests with a fresh secret for every run; the browser preview simulates 40.