Legacy: zero-knowledge step (retired 2026-10-16)

AdPriva no longer generates a zero-knowledge proof for new view batches. This page explains the step that was retired, why it was retired, and how to read the records it left behind.

What changed

New view batches are anchored directly on Horizen. The anchor worker builds a Poseidon Merkle tree over the batch, recomputes the root from the batch’s proof ids and sends the root to AdPriva’s Anchor.sol contract. No Groth16 proof is generated and nothing is sent to zkVerify. View batches created since 2026-09-28 are anchored this way.

What a reader can check is the proof’s Merkle inclusion receipt against the root in the Horizen transaction. See Proof Systems & Verification and Anchor Worker.

What the retired step did

For view batches anchored before 2026-09-28:

  1. The anchor worker grouped new view proofs into a batch and built a Merkle tree over them with the Poseidon hash. The tree has 20 levels, and each leaf is the hash of one proof’s internal number.
  2. For the batch, it generated a Groth16 proof with the circuit merkleroot.circom (circuit version v2.0.0). The statement was: I know a leaf and a Merkle path that hash up to this root. The root was the only public input. The leaf and the path were private inputs.
  3. The proof was submitted to zkVerify, which checked it on its own chain.
  4. After zkVerify accepted it, the batch root was anchored on Horizen through Anchor.sol.

Why it was retired

  • It covered one leaf per batch. The proven leaf was always the batch’s first leaf (zk_proven_leaf_index: 0). Every other proof in the batch relied on its Merkle path and the anchored root.
  • It added no guarantee beyond the anchored root. AdPriva built both the Merkle tree and the proof.
  • It was never part of the Horizen anchor. The Anchored event carries only the batch root. The zkVerify attestation was a separate record on another chain.
  • It was one more outside dependency in the path of every view batch.

The step never said anything about whether a visit was human. The validity score and verdict come from scoring. See Proofs of Engagement.

Reading legacy records

The public API still returns the zkVerify fields on every record. Their values tell you which kind of batch you are looking at:

Batchzkverify_statuszkverify_urlzk_proven_leaf_index
View batch anchored before 2026-09-28 (legacy)FINALIZEDA zkVerify transaction link0
View batch created since 2026-09-28NOT_APPLICABLEnullAbsent

Consent batches have always shown NOT_APPLICABLE. They use a SHA-256 Merkle tree and never had a zero-knowledge step.

Legacy batches stay valid. This is a real legacy record, with the Merkle path fields left out:

{
  "proof_id": "666959fe0c24984a6aec482e4d2835b847341577cb303b34183aa0c6290d6897",
  "type": "view",
  "batch_id_hash": "00000000000007f7",
  "merkle_root": "0x0365496d53b1437195520f69d21296efd113ed17f2c334484b83faed856f5805",
  "leaf": "2895",
  "leaf_index": 0,
  "hash_version": "poseidon",
  "zk_proven_leaf_index": 0,
  "zkverify_status": "FINALIZED",
  "zkverify_url": "https://zkverify.subscan.io/extrinsic/0xe3ceb6532877cf9cf324dfad74bf79f8c3c941751db647b3e68936564e5ab13b",
  "horizen_status": "CONFIRMED",
  "horizen_tx": "0x7fa649ce95ed242b75c5457265c826ab687421ca14a4f12ec3d617df55a08e1a"
}
  • zkverify_url opens the zkVerify transaction that checked the batch’s proof.
  • horizen_tx is the anchor transaction. Its Anchored event carries the same root.
  • leaf, merkle_path and merkle_path_indices let you recompute the root offline, for any proof in the batch, legacy or not. The API Reference has the algorithm.