Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<p align="center">
<img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License" />
<img src="https://img.shields.io/badge/noir-1.0.0--beta.18-blueviolet" alt="Noir" />
<img src="https://img.shields.io/badge/noir-1.0.0--beta.19-blueviolet" alt="Noir" />
<img src="https://img.shields.io/badge/circuits-15-green" alt="Circuits" />
<img src="https://img.shields.io/badge/contracts-2-green" alt="Contracts" />
</p>
Expand Down Expand Up @@ -85,18 +85,18 @@ Apertrue uses a **split-proof architecture** that separates verification into tw
| `aztec_verifier` | On-chain proof verification + verification record storage |
| `webauthn_account` | WebAuthn P-256 account contract with session key support |

Both target [Aztec Network](https://aztec.network/) v3.0.3.
Both target [Aztec Network](https://aztec.network/) v4 devnet.

## Building

### Prerequisites

- [Nargo](https://noir-lang.org/docs/getting_started/installation/) **v1.0.0-beta.18** (not stable — circuits depend on beta.18-specific features)
- [Nargo](https://noir-lang.org/docs/getting_started/installation/) **v1.0.0-beta.19** (not stable — circuits depend on beta.19-specific features)
- Docker (for Aztec contract transpilation only)

> **Version constraint**: These circuits require exactly `nargo` v1.0.0-beta.18. Later versions may introduce breaking changes to the constraint system or standard library. Install with:
> **Version constraint**: These circuits require exactly `nargo` v1.0.0-beta.19. Later versions may introduce breaking changes to the constraint system or standard library. Install with:
> ```bash
> noirup -v 1.0.0-beta.18
> noirup -v 1.0.0-beta.19
> ```

### Compile
Expand Down Expand Up @@ -125,19 +125,19 @@ cd aztec_verifier
./build.sh --skip-compile # Reprocess without recompiling
```

The build script runs `bb-avm aztec_process` in Docker for AVM transpilation and verification key generation, then generates TypeScript bindings via `@aztec/builder@3.0.3`.
The build script runs `bb-avm aztec_process` in Docker for AVM transpilation and verification key generation, then generates TypeScript bindings via `@aztec/builder`.

## Dependencies

| Library | Version | Purpose |
|---------|---------|---------|
| `noir_rsa` | 0.9.2 (zkpassport fork) | RSA verification with PSS support |
| `bignum` | 0.8.0 | Big integer arithmetic for RSA |
| `sha256` | 0.2.1 | SHA-256 hash computation |
| `noir_rsa` | 0.10.0 (zkpassport fork) | RSA verification with PSS support |
| `bignum` | 0.9.2 | Big integer arithmetic for RSA |
| `sha256` | 0.3.0 | SHA-256 hash computation |
| `poseidon` | 0.1.1 | ZK-friendly Poseidon hash for commitments |
| `bb_proof_verification` | 3.0.3 | Recursive proof verification (aggregation) |
| `bb_proof_verification` | 4.0.0-devnet.2-patch.3 | Recursive proof verification (aggregation) |

The `noir_rsa` dependency uses [zkpassport's fork](https://github.com/zkpassport/noir_rsa) which adds RSA-PSS support required for Adobe and ChatGPT-signed images.
The `noir_rsa` dependency uses [zkpassport's fork](https://github.com/zkpassport/noir_rsa) which adds RSA-PSS support required for Adobe and ChatGPT-signed images. Vendored snapshots under `vendor/` may use separately pinned versions for compatibility reasons (see `vendor/noir-rsa/VENDORED_FROM.md`).

## Security Model

Expand All @@ -146,7 +146,7 @@ The `noir_rsa` dependency uses [zkpassport's fork](https://github.com/zkpassport
- **Nullifiers** (content hash + leaf key hash) — prevent replay attacks
- **Commitment salts never revealed** — only Poseidon hashes are public outputs
- **Trust list Merkle proofs** — issuer inclusion proven against a signed oracle bundle
- **Known limitations**: Session key expiry and scope are not enforced in-circuit (Aztec v3.0.3 limitation — documented in `webauthn_account/src/main.nr`)
- **Known limitations**: Session key expiry and scope are stored in notes but not enforced in-circuit — expiry is checked client-side (documented in `webauthn_account/src/main.nr`)

## Acknowledgements

Expand All @@ -161,7 +161,7 @@ These circuits are built on the work of:
- [zk-kit.noir](https://github.com/privacy-scaling-explorations/zk-kit.noir) by [Privacy & Scaling Explorations](https://pse.dev/) (Ethereum Foundation) — binary Merkle root verification
- [Poseidon](https://github.com/noir-lang/poseidon), [SHA-256](https://github.com/noir-lang/sha256), [Schnorr](https://github.com/noir-lang/schnorr), [Base64](https://github.com/noir-lang/noir_base64) by Noir Lang — standard cryptographic primitives
- [C2PA](https://c2pa.org/) — Coalition for Content Provenance and Authenticity open standard
- [Aztec Network](https://aztec.network/) — private smart contract platform (v3.0.3)
- [Aztec Network](https://aztec.network/) — private smart contract platform (v4 devnet)

## License

Expand Down
5 changes: 3 additions & 2 deletions proof_a/Prover.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ time_max = "1737158400"
# London area: 51.5074 N, 0.1278 W with 10km radius
center_lat_scaled = "515074000"
center_lon_scaled = "1278000"
center_lat_is_negative = "0"
center_lon_is_negative = "1"
# location_flags: bit 0 = lat negative (South), bit 1 = lon negative (West)
# 0b10 = lat positive (N), lon negative (W) = London
location_flags = "2"
radius_squared_scaled = "806962652721" # ~10km radius squared (corrected)

# === EXACT TIMESTAMP (private) ===
Expand Down
14 changes: 9 additions & 5 deletions selective_disclosure/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,14 @@ fn main(
assert(lon <= lon_max, "longitude above maximum bound");

// Verify sign bits match actual signs
// disclosed_location_flags encodes: bit0 = lat_min_neg, bit1 = lat_max_neg,
// bit2 = lon_min_neg, bit3 = lon_max_neg
// The exact sign must be consistent with the bounding box signs.
// (If exact lat is negative, it must be within negative bounds)
// disclosed_location_flags encodes: bit0 = lat_neg, bit1 = lon_neg
// The exact coordinate signs must match the disclosed signs.
let disclosed_location_flags_u8 = disclosed_location_flags as u8;
assert(disclosed_location_flags_u8 <= 3, "disclosed_location_flags must only use bits 0-1");
let disclosed_lat_neg = (disclosed_location_flags_u8 & 1) as Field;
let disclosed_lon_neg = ((disclosed_location_flags_u8 >> 1) & 1) as Field;
assert(disclosed_lat_neg == exact_lat_is_negative, "disclosed latitude sign does not match exact latitude sign");
assert(disclosed_lon_neg == exact_lon_is_negative, "disclosed longitude sign does not match exact longitude sign");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
} else {
// When not disclosing: all location public inputs must be zero
assert(disclosed_lat_min == 0, "disclosed_lat_min must be 0 when hidden");
Expand Down Expand Up @@ -318,7 +322,7 @@ fn test_single_image_v2_all_disclosed() {
150, // disclosed_lat_max
100, // disclosed_lon_min
300, // disclosed_lon_max
1, // disclosed_location_flags
2, // disclosed_location_flags (bit0=lat_neg=0, bit1=lon_neg=1)
1706700000, // disclosed_time_min
1706800000, // disclosed_time_max
1708900000, // disclosed_edit_time_min
Expand Down
Loading
Loading