Bionetta
Bionetta: Efficient Client-Side Zero-Knowledge Machine Learning Proving
Reported benchmarks
| model | params | proving time s | proof size mb | verification time s | constraints | peak ram gb | proving key gb | verification key mb |
|---|---|---|---|---|---|---|---|---|
| MNIST MLP | 2M | 3.05 | 0.00088 | 0.01 | 250000 | 0.27 | 0.2 | 0.004 |
| LeNet5 | — | 3.75 | 0.00088 | 0.01 | 260000 | 0.28 | 0.22 | 0.004 |
| VGG11-mini | — | 7.7 | 0.00088 | 0.02 | 730000 | 0.48 | 0.63 | 0.004 |
| ResNet18 | — | 14.1 | 0.00088 | 0.015 | 1160000 | 0.75 | 1 | 0.004 |
| MobileNetV2 | — | 24.5 | 0.00088 | 0.018 | 2780000 | 1.8 | 2.41 | 0.004 |
| MNIST MLP (iPhone 14 Pro) | 2M | 2.8 | 0.00088 | — | — | 0.23 | — | — |
| LeNet5 (iPhone 14 Pro) | — | 3.55 | 0.00088 | — | — | 0.145 | — | — |
| VGG11-mini (iPhone 14 Pro) | — | 7.65 | 0.00088 | — | — | 0.465 | — | — |
| ResNet18 (iPhone 14 Pro) | — | 13.6 | 0.00088 | — | — | 0.7 | — | — |
| MobileNetV2 (iPhone 14 Pro) | — | 22.96 | 0.00088 | — | — | 1.7 | — | — |
params_note: "We reduced VGG11 for benchmarking since zkml and EZKL frameworks ran out of RAM memory for original architecture." The reduced architecture is not specified. This row is not comparable to anyone else's VGG11.
proving_time_note: Plain Groth16 cannot do this row at all -- both rapidsnark and imp1 run out of RAM on ResNet18 and MobileNetV2 on the phone. UltraGroth's constraint reduction is what makes the difference between "proves in 14 seconds" and "does not fit".
Notes
Three ideas, and the second and third both matter well beyond this paper.
(1) CIRCUIT-EMBEDDED WEIGHTS. Because the model is public, the weights are compiled into the R1CS as CONSTANTS rather than passed in as signals. R1CS charges nothing for multiplication-by-constant, so every linear layer -- every matmul, every convolution, and BatchNorm folded into it -- costs LITERALLY ZERO CONSTRAINTS. Proving cost is then a function of one thing only: the number of non-linearity calls. This is the same conclusion the sum-check line reaches (matmuls are nearly free; the money is at the non-linear seams) arrived at from a completely different direction, and it is worth having both. Measured effect (Table 5): ResNet18 drops from 37.85M constraints to 1.16M (~32x) and from 270 s to 14 s. The catch is that it is only available because the weights are public -- this optimization is structurally unavailable to every MLaaS system in this table.
(2) ULTRAGROTH. Lookup arguments inside Groth16, which is supposed to be impossible: LogUp (Haboeck) needs a verifier challenge sampled AFTER the witness is committed, and Groth16 has no rounds. UltraGroth adds them -- the witness is split into d+1 "rounds", each round's commitment is hashed to derive the next round's challenge (Fiat-Shamir with an in-circuit random oracle), and the extra commitments ride along in the proof. Cost: one extra pairing (4 instead of 3), one extra hash, and d+1 extra G1 elements. Proven complete, sound and zero-knowledge in GGM+ROM (Appendix A). This is the interesting cryptographic contribution and it is buried in a vendor tech report. The payoff: a ReLU's range check drops from b constraints to b/w, with w the limb size; prover complexity O(2^(w+1) + bL/w + 4L) for L range checks, i.e. O(N / log N).
(3) THE RESCALE SEAM IS FREE, WHEN IT RIDES ON A ReLU. This is the fact the numerics page should carry. ReLU already bit-decomposes its input to determine the sign -- that IS the range check. Once you have the bits, dropping the low l*rho of them is a right shift that costs NOTHING: "Computing ReLU(x) >> rhol for some fixed l costs b+1 constraints" -- the same b+1 as a bare ReLU. The rescale after a matmul, which every other system in this corpus pays for at every seam, is here fused into a decomposition it was already buying. It is the strongest form of the "round less often / fuse the seam" result that zkGPT (constraint fusion), DeepProve (delayed requantization) and Jolt Atlas (i64 rebase) each found independently -- and Bionetta found it a fourth time, citing none of them for it.
AND THE COROLLARY IT DRAWS, WHICH CONTRADICTS SAFETYNETS. Bionetta explicitly rejects polynomial activations (pi-nets), and its reason is the seam: a degree-d polynomial costs only d constraints per value, but it RAISES the precision of the result by rhod bits, which forces a precision cut, which costs ~b constraints. "The benefit of d constraints per value is lost in the overhead of precision cuts." Read that against SafetyNets, whose whole cost advantage comes from quadratic activations having no rescale seam at all: Bionetta is saying the seam does not disappear under a polynomial activation, it just moves to where the precision blew up. Nobody has reconciled these two claims and they are both in this corpus.
WHAT IT CANNOT DO. No softmax, no attention, no LayerNorm, no transformer, no general ONNX. The supported non-linearities are exactly ReLU, LeakyReLU (alpha a power of two only), ReLU6, HardSigmoid and HardSwish -- the ReLU family, chosen because they are the ones whose cost the sign-bit decomposition already pays for. ActivationOps.from_keras in the SDK maps Softmax to NOT_SUPPORTED. Do NOT put this system on the tokens-per-minute axis; it is not an LLM prover and does not claim to be.
Threat model
INVERTED relative to every other system in this category, and this is the single most important fact about the paper. The rest of the verifiability column is MLaaS: the SERVER proves, the WEIGHTS are the secret, and the client is the verifier. Bionetta is the opposite -- the CLIENT proves, on their own phone, over a PRIVATE INPUT, against a model whose weights and architecture are PUBLIC. Its motivating applications are biometric proximity ("this face matches the enrolled template") and liveness, where the thing worth hiding is the user's face, not the network. The library's own README states the limit in a warning box -- "the library is not intended for private model weights + public input proving. The library is designed only for public model weights + private/public input proving!" -- which is a restriction the paper's abstract does not mention. Every claim it makes should be read inside that box. It is not competing with DeepProve or zkGPT; it is answering a different question, and it is the only system in this corpus that does.
Quantization, in full
| bits | None |
|---|---|
| bits_note | THE PAPER HAS NO "BIT WIDTH" IN THE SENSE THE REST OF THIS TABLE MEANS IT, and that is a finding rather than an omission. Bionetta does not quantize activations down to a narrow integer. It keeps every value as a full BN254 field element carrying `rho` fractional bits, and the cost of a non-linearity is set by the size of the FIELD (254 bits), not by the width of the value. Raising rho therefore does not change the constraint count at all. The shipped SDK's default is rho = 15 (`Groth16.DEFAULT_PRECISION`), which is the LEAST accurate of the four settings the paper measures. |
| scheme | Fixed point with a precision parameter rho: Q(x) = F_p([2^rho x]), D(x) = 2^-rho Z(x). Sign is decided by the (b-1)-th bit -- the threshold for "negative" is 2^(b-1), NOT the conventional (p-1)/2, a deviation the paper flags as a convenience choice. Rescaling is the "precision cut": a right shift by `l * rho`, needed because a degree-n product accumulates precision n*rho and would otherwise exceed the field. Error bound proved in Appendix C: |D(C_f(x,y)) - f(x,y)| <= 2^-rho * beta + 2^-2rho, with beta = 2 max(|x|,|y|) "assumed to be relatively small" -- an ML assumption doing cryptographic work, as usual. |
| accuracy_retention | Relative error ||y - y_rho|| / ||y||, worst case across all five models, over 10^5 random inputs: 5.2e-3 at rho=15, 3.7e-5 at rho=30, 2.0e-6 at rho=45, 9.4e-7 at rho=60. Note what this says: four orders of magnitude of accuracy bought for ZERO extra constraints, because the b-bit decomposition is over the field element either way. See notes. |
Our reading
Read the threat model before you read anything else, because every number in this paper is downstream of it and the abstract does not tell you.
Every other system in proving inference is MLaaS: a server holds a valuable model, runs it on your input, and proves it did so honestly. The weights are the secret. The server is the prover. Bionetta is the exact inverse, the model is public, the input is private, and the client is the prover, on their phone. The motivating application is a biometric one: prove that your face matches an enrolled template, without handing anybody your face.
The library's own README says the limit out loud, in a warning box, which the paper never does:
Despite astounding performance, the library is not intended for private model weights + public input proving. The library is designed only for public model weights + private/public input proving!
Bionetta README (Anonymous1725/Bionetta) · About
So it is not competing with DeepProve or zkGPT, whatever the benchmark tables suggest. It is answering a question nobody else in this corpus answers, and it is the only entry here whose prover is a phone.
What is new
Circuit-embedded weights, and it is almost embarrassingly simple. R1CS charges nothing for multiplication by a constant. If the weights are public, they do not have to be signals, they can be compiled into the constraint system as constants. So every linear layer, every convolution, and every BatchNorm folded into one, costs exactly zero constraints. Not "cheap". Zero. Proving cost then depends on one quantity: the number of non-linearity calls.
The effect is the largest single lever in the paper: ResNet18 falls from 37.85M constraints to 1.16M, and from 270 seconds to 14. And it is structurally unavailable to every MLaaS system in this SoK, because theirs is the case where the weights are the thing you are hiding. This is the clearest demonstration in the corpus that the threat model, not the proof system, is the dominant term in the cost.
It also lands on the same conclusion the sum-check line reached from the opposite direction. GKR says: matmuls are nearly free, so the money is in the non-linear seams. R1CS-with-constant-weights says: matmuls are literally free, so the money is in the non-linear seams. Two entirely different proof systems, one cost model. That agreement is worth more than either paper's benchmark.
UltraGroth is the cryptographic contribution, and it is the thing that should not be buried in a vendor tech report. Lookup arguments need a verifier challenge sampled after the witness is committed, LogUp's rational-sum identity is checked at a random point, and the prover must not know the point in advance. Groth16 has no rounds, which is exactly why nobody puts lookups in it.
UltraGroth adds rounds. The witness is split into $d+1$ segments; each segment gets its own $\delta_i$ and its own commitment $\pi_C^{\langle i \rangle}$; the commitment is hashed to derive the next segment's challenge, and the challenges are carried as public signals the verifier recomputes. The proof grows to $\pi_A, \pi_B, \pi_C^{\langle 0 \rangle} \dots \pi_C^{\langle d \rangle}$, and verification goes from three pairings to four. That is the entire price: one pairing and one hash buys lookup arguments inside Groth16. Completeness, soundness and zero-knowledge are proved in GGM + ROM in Appendix A.
What it buys downstream is the range check, which, per the numerics page, is where the whole proof actually lives. A ReLU's $b$-constraint bit decomposition becomes $b/w$ lookups for limb size $w$, giving prover complexity $O(2^{w+1} + bL/w + 4L)$ over $L$ range checks, i.e. $O(N/\log N)$. The paper solves for the optimal $w$ ($2^w w^2 = Lb / 2\log 2$, landing near 18); the shipped SDK defaults to 15.
The rescale seam is free. This is the fact that changes how the numerics page has to be written, and Bionetta states it in one line and moves on.
ReLU already decomposes its input into bits, that is how you get a sign out of a field that has no
order. But once you have the bits, a right shift is free: you simply drop the low ones. So the
precision cut, the rescale, the thing every other system in this corpus pays for at every seam,
costs nothing extra when it rides on a ReLU it was already paying for. The paper's proposition
is that ReLU(x) >> ρℓ costs $b+1$ constraints, which is the same $b+1$ as a bare ReLU.
Everyone else fuses seams to make them cheaper: zkGPT's constraint fusion, DeepProve's delayed requantization, Jolt Atlas's i64 accumulate-and-rebase. Bionetta fuses the seam into an operation whose cost it had already spent, which makes it not cheaper but free. It is the strongest form of the result, it is the fourth independent discovery of it, and it cites none of the other three for it.
What it actually proves
One forward pass of a convolutional or fully-connected network, in fixed point with $\rho$ fractional bits, over a public model, on a private input, under a per-circuit Groth16 trusted setup.
Every clause there is load-bearing:
- One forward pass. No tokens, no sequence, no autoregression.
claim_kind: pass. - CNNs and MLPs only. The supported non-linearities are ReLU, LeakyReLU (with $\alpha$ a power
of two, anything else is rejected), ReLU6, HardSigmoid and HardSwish. That is the ReLU family,
and the selection is not arbitrary: those are precisely the activations whose cost the sign-bit
decomposition already pays for. There is no softmax, the SDK's
ActivationOps.from_kerasmapstf.keras.layers.SoftmaxtoNOT_SUPPORTED, and therefore no attention, no LayerNorm, no transformer. It is not on the tokens-per-minute axis and should never be put there. - Per-circuit trusted setup, which cuts two ways and both are interesting. The cost: retraining the model means a new ceremony, which makes this unusable for anything that updates its weights. The benefit, which nobody states: a Groth16 verification key is a commitment to the exact circuit, and the circuit is the architecture. This is the strongest architecture-pinning in the corpus, stronger than zkAudit's public-architecture convention, and it means the precondition of the Fiat–Shamir/GKR attack (the prover chooses the circuit) is cryptographically out of reach here. Bionetta is one of the two systems in this SoK the attack cannot touch, and it got there for free, as a side effect of a design choice made for other reasons.
The benchmarks, and what they actually settle
Two results in Bionetta's Table 4 are more useful to this SoK than its own headline, and neither is about Bionetta.
The Halo2 story is wrong in the half nobody checks. Our own proof systems page says what everyone says: PLONKish is the slow-prover/fast-verifier bargain, and you tolerate the prover because kilobyte proofs and millisecond verification are what make on-chain settlement possible at all. Bionetta measured it. As ezkl actually ships, proofs are hundreds of kilobytes, verification keys reach tens of megabytes, and verification takes seconds to tens of seconds, 40.6 s on MobileNetV2, behind a proving key of 76 GB. None of that is going on a chain. Halo2 can be configured for small proofs; the toolchain people deploy is not, and until now nobody had published the numbers. Meanwhile ZKML, the other Halo2 system, on the same hardware and the same models, verifies in 12–23 ms with 5–7 kB proofs. The two most-deployed PLONKish zkML toolchains do not have the same verifier profile, and the literature treats them as one row.
zkCNN is still the fastest prover on small models, five years on. Bionetta beats it only above roughly 2M parameters, and loses to it below, zkCNN proves LeNet5 in 1.05 s against Bionetta's 3.75 s. What zkCNN pays is what GKR always pays: 23–43 kB proofs and verification in the hundreds of milliseconds to seconds. The 2021 trade has not moved. Only the models have.
What to distrust
The comparison is not the comparison it looks like. Bionetta's linear layers are free because its model is public. ezkl's, ZKML's and zkCNN's are not free because theirs are not. A great deal of the headline gap is therefore not a proof-system result at all, it is the threat model, showing up in the constraint count. The paper never separates the two, and a reader skimming Table 4 will attribute to UltraGroth a win that belongs to a weaker security setting. (To be fair to the paper: its own Table 5 does isolate the two effects, and it is the most honest table in the report. It just is not the one anybody will quote.)
The precision result is real, and it points somewhere the paper does not look. Bionetta measures relative error against TensorFlow at $\rho \in \{15, 30, 45, 60\}$ and gets $5.2\times10^{-3}$ down to $9.4\times10^{-7}$, four orders of magnitude of accuracy, while the constraint count does not change at all, because the bit decomposition is over the 254-bit field element either way. This is DeepProve's "four more bits costs under one percent" finding, reproduced in a completely different proof system, and neither paper knows about the other. See the open question it jointly sharpens. (The shipped SDK's default is $\rho = 15$, the least accurate setting the paper measured.)
The polynomial-activation argument contradicts SafetyNets, and nobody has noticed. Bionetta rejects polynomial activations for a specific reason: a degree-$d$ polynomial costs $d$ constraints per value, but raises the precision of the result by $\rho d$ bits, forcing a precision cut that costs $\approx b$. "The benefit of $d$ constraints per value is lost in the overhead of precision cuts." Now read SafetyNets, whose entire cost advantage, a few percent of overhead, three to six orders of magnitude better than anything since, comes from quadratic activations having no rescale seam at all. Both claims are in this SoK. They cannot both be the whole truth, and the reconciliation (SafetyNets is shallow, and precision growth is exponential in depth) is a paragraph nobody has written.
Unverified, and the thing we would most want somebody to check.
The paper's own reasoning for its ReLU cost (§4.3): decompose $x$ into $b$ bits, boolean-constrain
each with $x_i(1-x_i) = 0$, that is $b$ constraints, then one more for the output. Total $b+1$.
The shipped SDK prices ActivationOps.RELU at exactly 255 under Groth16, with the comment
"costs below are specified manually based on the current Circom implementation". And
$255 = 254 + 1$, with $b = 254$ for BN254.
That count leaves no room for a canonicity check, and BN254 needs one. $2^{254} > p$, so a 254-bit boolean decomposition does not uniquely determine a field element. For any $x < 2^{254} - p$, about $0.32p$, which is every activation any real network will ever produce, the bit string of $x + p$ satisfies every booleanity constraint and recomposes to $x \bmod p$ just as well. And its bit 253 is set. Since Bionetta decides the sign by reading bit $b-1$, the paper deliberately puts the negativity threshold at $2^{b-1}$ rather than the conventional $(p-1)/2$, and flags the choice as a convenience, the malicious decomposition makes a positive activation read as negative, and ReLU returns zero.
This is the textbook Circom Num2Bits versus Num2Bits_strict distinction. The strict version
adds an alias check against $p$ and costs roughly double, which is consistent with 255 being the
unstrict one. If that is what the circuit does, a malicious prover can zero out any ReLU it
chooses and still produce a verifying proof, and in the biometric application, a prover who can
choose the network's activations is a prover who can forge an authentication.
We cannot confirm it. codegen/generator.py clones a repo called bionetta-circom, and that
repo is not public, the Python SDK ships, the constraints do not. So the range checks, which are
the entire proof, are the one part of a deployed biometric system that cannot be
read. That is the finding even if the bug is not there.
It cites nobody who solved its problem
Bionetta derives a fixed-point quantization error bound from first principles in Appendix C. That is the subject matter of SecFloat, Garg et al. (FP) and ZKLP, none of which it cites. A full-text scan of the PDF returns zero occurrences of "MPC", "homomorphic", "SIRNN", "Cheetah", "SecFloat", "ZKLP" and "Mystique". It is the newest node in the corpus and it walks the bridge exactly as far as everyone else at the centre of the column does: not at all.
Citation neighbourhood
Cited by, in this corpus
- none recorded
Edges are a proxy: paper A's text mentions B anywhere (body or bibliography). See the full graph.
Discussed in
Other recorded fields
claim_kind: pass
open_source_note: 'The TensorFlow SDK is public (constraint calculator, codegen, layer
definitions, prover driver). The Circom templates that emit the actual constraints
are NOT: `codegen/generator.py` clones a repo named `bionetta-circom`, and no such
repository is public under rarimo/ or anywhere else we can find. So the range checks
-- which, per the numerics section, ARE the proof -- are the one part you cannot
read. There is also a public JS SDK (rarimo/bionetta-js-sdk) and a developer-docs
repo, i.e. this is deployed, not a preprint artifact: it backs Rarimo''s biometric
identity app.'
objectives:
- inference
conflict_flag: 'Bionetta re-measures ezkl, ddkang/zkml and zkCNN on its own hardware
(Table 4) and those are the only primary-source numbers we have for ezkl anywhere
in this corpus. They are recorded on those systems'' entries and flagged there as
third-party measurements by a competitor. Treat with the usual care: Bionetta chose
the models, chose the hardware, and is the party being flattered.'
audit_flag: 'UNVERIFIED, AND THE ONE THING WE MOST WANT SOMEBODY TO CHECK. Section
4.3''s own reasoning for the ReLU cost is: decompose x into b bits, boolean-constrain
each x_i via x_i(1-x_i)=0 (b constraints), then one more constraint for the output
-- b+1. The shipped SDK prices `ActivationOps.RELU` at exactly 255 under Groth16
("costs below are specified manually based on the current Circom implementation"),
and 255 = 254 + 1 with b = 254 for BN254. That count leaves NO ROOM for a canonicity
check. But 2^254 > p for BN254, so a b-bit boolean decomposition does not uniquely
determine a field element: for any x < 2^254 - p (~0.32p, which is every activation
any real network produces), the bit string of x + p ALSO satisfies every booleanity
constraint and ALSO recomposes to x mod p -- and its bit 253 is SET, so the sign
test reads a positive activation as negative and ReLU returns 0. This is the textbook
Circom `Num2Bits` vs `Num2Bits_strict` distinction; the strict version costs roughly
double, which is consistent with 255 being the unstrict one. It is made worse, not
better, by the paper''s deliberate choice to put the negativity threshold at 2^(b-1)
rather than (p-1)/2. If this is what the circuit does, a malicious prover can zero
out any ReLU it likes and still produce a verifying proof -- which, in the biometric
application, is a forged authentication. WE CANNOT CONFIRM IT: `bionetta-circom`
is not public. This is where we would look, not what we have found.'
ablation:
- mode: UltraGroth + embedded weights (the shipped configuration)
constraints_m:
mnist: 0.25
lenet5: 0.26
vgg11: 0.73
resnet18: 1.16
mobilenetv2: 2.78
proving_time_s:
mnist: 3.05
lenet5: 3.75
vgg11: 7.7
resnet18: 14.1
mobilenetv2: 24.5
- mode: UltraGroth, weights as signals (estimated)
constraints_m:
mnist: 2.19
lenet5: 0.65
vgg11: 4.17
resnet18: 37.85
mobilenetv2: 7.97
proving_time_s:
mnist: 15
lenet5: 6
vgg11: 30
resnet18: 270
mobilenetv2: 60
- mode: Groth16 + embedded weights
constraints_m:
mnist: 1.57
lenet5: 1.69
vgg11: 7.67
resnet18: 12.0
mobilenetv2: 31.8
proving_time_s:
mnist: 8.3
lenet5: 8.7
vgg11: 56.4
resnet18: 87.5
mobilenetv2: 230.0
- mode: Groth16, weights as signals (estimated)
constraints_m:
mnist: 3.51
lenet5: 2.08
vgg11: 11.1
resnet18: 49.0
mobilenetv2: 37.8
proving_time_s:
mnist: 25
lenet5: 15
vgg11: 80
resnet18: 350
mobilenetv2: 270