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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

# Noir and prover artifacts
*.json
# Allow JSON files in csca_registry
!**/csca_registry/**/*.json
*.gz
*.bin
*.nps
Expand Down
1 change: 1 addition & 0 deletions playground/passport-input-gen/.cargo/katex-header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPE html>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah. while running cargo test. i was getting this error without katex-header.html. not sure what is the reason

image

17 changes: 14 additions & 3 deletions playground/passport-input-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@ description = "Passport input generator"
[dependencies]
rsa = { version = "0.9.8", features = ["sha2"] }
sha2 = { version = "0.10", features = ["compress"] }
x509-parser = "0.16"
base64 = "0.22"
hex = "0.4"
rasn = "0.15"
rasn-pkix = "0.15"
rasn-cms = "0.15"
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.143"
toml = "0.8"
noir-bignum-paramgen = "0.1.5"
thiserror = "2.0.16"
signature = "2.2"
lazy_static = "1.5.0"

[[bin]]
name = "passport-input-generator"
path = "src/main.rs"
110 changes: 110 additions & 0 deletions playground/passport-input-gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Passport Input Generator

A Rust crate for parsing passport data and generating circuit inputs for Noir Circuits.

## Overview

This crate provides functionality to:

- Parse passport Machine Readable Zone (MRZ) data from DG1 and SOD
- Validate passport signatures using DSC and CSCA certificates
- Generate mock passport data for testing
- Convert passport data to circuit inputs for Noir zero-knowledge circuits

### `PassportReader`

Main structure for reading and validating passport data.

**Structure:**

```rust
pub struct PassportReader {
dg1: Binary, // DG1 (Machine Readable Zone) data
sod: SOD, // Security Object Document
mockdata: bool, // Flag indicating mock vs real passport data
csca_pubkey: Option<RsaPublicKey>, // Optional CSCA public key for mock data
}
```

**Key Behavior:**

- When `mockdata: false`: The reader searches for existing CSCA keys from a predefined set. Currently supports USA CSCA keys loaded from the system. The `validate()` method iterates through all available USA CSCA keys to find one that successfully validates the passport signature.

- When `mockdata: true`: The reader uses the provided `csca_pubkey` for validation. This is useful for testing with synthetic passport data generated using mock keys.

**Methods:**

- `validate() -> Result<usize, PassportError>` - Validates the passport signatures and returns the CSCA key index used. For mock data, always returns index 0. For real data, returns the index of the USA CSCA key that successfully validated the passport.
- `to_circuit_inputs(current_date: u64, min_age_required: u8, max_age_required: u8, csca_key_index: usize) -> Result<CircuitInputs, PassportError>` - Converts passport data to circuit inputs

#### `CircuitInputs`

Contains all necessary inputs for Noir circuits.

**Methods:**

- `to_toml_string() -> String` - Converts circuit inputs to TOML format string
- `save_to_toml_file<P: AsRef<Path>>(path: P) -> std::io::Result<()>` - Saves circuit inputs to a TOML file

### Mock Data Generation

#### `mock_generator` module

**Functions:**

- `dg1_bytes_with_birthdate_expiry_date(birthdate: &[u8; 6], expiry: &[u8; 6]) -> Vec<u8>` - Generates fake DG1 data with specified birth and expiry dates (format: YYMMDD)
- `generate_fake_sod(dg1: &[u8], dsc_priv: &RsaPrivateKey, dsc_pub: &RsaPublicKey, csca_priv: &RsaPrivateKey, _csca_pub: &RsaPublicKey) -> SOD` - Creates a synthetic SOD structure for testing

#### `mock_keys` module

**Constants:**

- `MOCK_CSCA_PRIV_KEY_B64: &str` - Base64-encoded mock CSCA private key for testing
- `MOCK_DSC_PRIV_KEY_B64: &str` - Base64-encoded mock DSC private key for testing

## Usage Example

```rust
use passport_input_gen::{PassportReader, mock_generator, mock_keys};
use base64::{engine::general_purpose::STANDARD, Engine as _};
use rsa::{RsaPrivateKey, pkcs8::DecodePrivateKey};

// Load mock keys
let csca_der = STANDARD.decode(mock_keys::MOCK_CSCA_PRIV_KEY_B64)?;
let csca_priv = RsaPrivateKey::from_pkcs8_der(&csca_der)?;
let csca_pub = csca_priv.to_public_key();

let dsc_der = STANDARD.decode(mock_keys::MOCK_DSC_PRIV_KEY_B64)?;
let dsc_priv = RsaPrivateKey::from_pkcs8_der(&dsc_der)?;
let dsc_pub = dsc_priv.to_public_key();

// Generate mock passport data
let dg1 = mock_generator::dg1_bytes_with_birthdate_expiry_date(b"900101", b"300101");
let sod = mock_generator::generate_fake_sod(&dg1, &dsc_priv, &dsc_pub, &csca_priv, &csca_pub);

// Create passport reader
let reader = PassportReader {
dg1: Binary::from_slice(&dg1),
sod,
mockdata: true,
csca_pubkey: Some(csca_pub),
};

// Validate passport
let csca_index = reader.validate()?;

// Generate circuit inputs
let current_timestamp = chrono::Utc::now().timestamp() as u64;
let inputs = reader.to_circuit_inputs(current_timestamp, 18, 70, csca_index)?;

// Export to TOML
inputs.save_to_toml_file("circuit_inputs.toml")?;
```

## Testing

The crate includes tests for mock data generation and validation. Run tests with:

```bash
cargo test
```
52 changes: 52 additions & 0 deletions playground/passport-input-gen/csca_registry/csca_public_key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"USA": [
{
"filename": "cert-00267-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAw4VGHnr3jsI//bv4fKBmGYLcrdcABkQNmVr8xkmlS7xxkDEQCohnzKSk8v0T+L0yp3h+WctO1ZwsaJfU0HDdMogDmEv3SeoNImOuqiofzkDLdH6/IWA/JfEwBYDz+1cn7/rbHuFCwo/dkPNJkeE7OrLGd9g6tsj8YibMZrB8N7nIVgEa9QOEiqXmUUV4KNKKRZJLu/RaWzZGNq+JqlXgANKvSwKWVW+aINb84UfkBIdbPfIkEq6JMdok+YIQyHemEP6nxnHAVQwOYRkgHidw9YHXZZkHgh75efixMoAy3LQxvoknECrlpZgxqIpdup+AwsEW8hoJZbpd3Dxeb27AAF3Rl9LBGPi1thd1A4Qb/AjVDtIyQaU62cHo7fEGcW5kVg/BLGhKH+RJKOqEZoG8b80X0jv/Z2VNNtDU/8flcKG9DkD+d+kgjMQAyPCOjC2achDcK5Zc1Q8/tq0T25x6GoRjbxadqR6MKrAYaP8KOLCrL0MJsjvcfD3M+hdyJXJPN/7TeCyKbK+dBvVCk9BePi6lBKmp6lEHjyyydgNBBzZPrTNf5l60Oh9eWpaIoTHcmToS6zKVffFb/dWnkCTF1BBuy1VgJNeIspn8n1PhY5Q23qvV8q+Q1Ta1X3TFGkvAb1SXGiPQW4Hd2JrFJEBo8Ah8nn8rQKX999PLI+An1acCAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2014-12-18T16:21:01Z",
"notAfter": "2035-07-18T16:51:01Z",
"serial": "4E322929"
},
{
"filename": "cert-00444-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4yGdJKQ7D4DCDPGseAdOMC6Dgj8Xa91oXgHgPtgLW7y3kGm2Z4u9yXLciMebRCoq55wfO4ZcGv+mnMHpkv7fnFWSnG+8pP1BRUEKCYhXAbeWSww+CpMFEagzP7miPZg1TsE4QKFhGyRAfMdJFuG1aGQTtEdjgAWkat7YovTSA0pC7V/PwMlagZZwTsz8OOiO0w0eS9uIHGJKylg8gi9RSQZ/Hm2r4oOYvx3G3Iqa4OlNXO/KKD9mwd19+BFjuJ1cdqfzcYejhMPothyvlUgbWeaYek3ZfXuqz9XjYBF3rnacVKE9w4ydncRpUpOrSV/qSwxZA46QBuKAGxCS3kOUjgEmAj74/dLI8IaqHhYfSwchQdiT7FhQQ+YZENkRI5Gm4QDVLrT01plMK5ytX7mo4F83Hb1uE+WGgjTk9VDEKfZsERscCiArR7oUoRWZyuH81aMScMVzDVpFxvOg6Md7rWk5k8hRwL75nZtkFilsNnIVGMtuQP7DSG0xcKJ3EZT69YsRH0oEAa4sfa5fm4/X/WVfkNl51tI71PmYvnzcO6UVt42pgGiAJGoy5YmdhKKmXBgj0aVmzFRxd/+Jx2SgyccLeiIIA6y5bn6av/KuUB2wi9NLPbFz0OxvdKYqtfqNL+E6WmpeHHiiGGCrUes15d7fs/65QCvamV7fFBn8+lcCAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2024-09-30T16:38:20Z",
"notAfter": "2045-03-30T17:08:20Z",
"serial": "5DCE72E1"
},
{
"filename": "cert-00443-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAozIONhYqXeLWTi2rhDm+X2ZX1OMUr/j7DZgc6zXZ7VzsYVB+6ARiIbok77SxPtk9ZeUIqujjW59Jyb+EUiI6giIZOu9zY7BA+NQfhZeywzr1XKXhfROd5mmUiv3Nz5ukMBFwBoCaOHUchoqwml35lCk+X7K3NOS++HWbnxvRQFqOItsTcaMg2jp9BF+vmHr0nbucsi4zA3BzUKWsrbvcV05M4H/yoyru/5uq8JktSxbxCzK3iKXVyi6SwRkOiJekbztVKouELQlVhlhGacUOQ8ub+PTa4gRWKVHth68YmYW5k12/2B52CrzAndxCGewfN5KvDy5woQEDXHcJ+O9s53liYjZFNU5ceL+R48jUoXLVPuCmXFQKqo1N/t++lWR6icWy8tllHZGsr1GDVX0+EY+0gJUULR+SPzsAqt5IgCq0BlQ/iz4iLUS8fAoHs46AU3u/yHNRapBu3XOqKwCmQH2HNUufUZyD56cVaIBzE0ILWKwY7HaEcP28y0D/++OpqPz44c8YhwLcSdoIYJIOb3FzBVsq+1B23VeqTZ8IxpDkI4wumBLwJS+eJ136XBUegL1hQQv5BRrcN/XgJ9wyC43QN+d8LfBWUZQody7kKXC0KtratgHwwazCdxl8PR3p0aeXbveUBbJmyRQS27jDykncrYUrzkG8WRWhrW0tUR0CAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2019-11-14T16:37:12Z",
"notAfter": "2040-05-14T17:07:12Z",
"serial": "4E32D006"
},
{
"filename": "cert-00265-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAw9Pm+vLMuE/h005EKy6NVXhI+afR9iaURn6ENVOrAy+QBNvol4vNRCCqEcHwrc21e8KmRoFqoN7a1/YidoZKIsBG/8HkitFqPX76FudVcY1npqzRFMlv+3kf5YANrhbzCqVlo1UCGXOfRJwZUKgJQ9Wb++OMSMmzSJwgXQP9bxRURHRlGl833CCudrdHajKfEF0f/f5WNx4/s2/DbfBaW+FK9LAeXIqjFkS8xDGv1La785gohpIDAk6dbKMhVWWT7YwPm3T5ox2E59IIN65qJzmKeKKdhaZdr7ZzrxhYVxVjce6KFTlcrN1fqtAnAjeETEEEnfIgw4tlV827Pm1S9dEZnHzkxWmusRo1UNeQw7pdO/sAuy34uVRA9CBhdETxTvRMpBrnzM1G5mB7H7ltsS0T2Gp8QiRxaXR9CnpJAI3Bil6lJJ/fKJwVyzr7xR9c2ws4DIJ/uh0Jgy8wkeVOie0ava6KEI7PCz0N2GNz0Jd2sAXUBDsfs/nNKw7K2k5HLJ/5bJz90d8TwoE6j5xaB2ObOhCwBFyTb0CsLrWnaIu/ZyJr0P/NqWYaZXhv4oIeousUHEl4qpvn7K9hVNKT1c7qAKH3ZEbLEnxV5DYh5qsRwImt4M9B5LJsFojJ28TqOE1DB+4Dqg9mhQ+CaX1s1Urw7PqOqA8u/euk0YxD86kCAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2004-11-19T20:57:05Z",
"notAfter": "2025-06-19T21:27:05Z",
"serial": "419E6523"
},
{
"filename": "cert-00266-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvbwV+zl/vBzLWAadrtTSpC9l/zOOzAQKbwhVXCGPKK0SfOjiqIJSVfboQ+Tvz67Fgxb8LDhUJzoUSxHjh7PvO8NYwGXMhQrw0JzAARjPqbGUST3qXO/DfEwAilFKx1NvmlrxZgAS64iIqUjl7IGwYApALE1Ok5jkEvYDTE16uCe5RQz0vuqaKcgirrhwIW6C4r2wx9G1xr7/piII7fo97D7h5y0206OwshClHAmQ0p4LSK+Nxexp6sWaDsb/E7jKjLcxkcKJLsayGF58edW4fnI92BuI3pAhPSJpMmCImdN8LvF32o0jnYmYPsRFlLsj2+UEAnH13bs1qS07vvRnx3CXmPYTGl6amlbmePaMDgV4qWM8e71ddVgj1jyZANgzx4fDT9B82A8+Iw13ZOpU/rBW9OZ3Rk2aSOmFC69Vq12cbYrfXobc3GXyQ/hb4yMi3tfNS2nqeesb2a5/GrxKhwOIiNrJcClnzTlqrdcjEHdZYCXT4kR6wpbGAQNruew/BWIuWrGugXPB8ah8f8ttLetGO55kMaPDbk+ZXY6DlDjDLznurF0bEzZiNcRmUQ8p2rpToRqmH/XntE0OgasGzBmcJX5oMNC+7zvELBJcc9YzMIgXX7R5VlI5/Gvnnn4x6lmiio5FWb3ksMc1MWYTN2bmk5tyyKxvQ6Z4rZdx+1UCAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2010-01-08T16:06:27Z",
"notAfter": "2030-08-08T16:36:27Z",
"serial": "45DE28DD"
},
{
"filename": "cert-00456-pubkey.pem",
"public_key": "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAozIONhYqXeLWTi2rhDm+X2ZX1OMUr/j7DZgc6zXZ7VzsYVB+6ARiIbok77SxPtk9ZeUIqujjW59Jyb+EUiI6giIZOu9zY7BA+NQfhZeywzr1XKXhfROd5mmUiv3Nz5ukMBFwBoCaOHUchoqwml35lCk+X7K3NOS++HWbnxvRQFqOItsTcaMg2jp9BF+vmHr0nbucsi4zA3BzUKWsrbvcV05M4H/yoyru/5uq8JktSxbxCzK3iKXVyi6SwRkOiJekbztVKouELQlVhlhGacUOQ8ub+PTa4gRWKVHth68YmYW5k12/2B52CrzAndxCGewfN5KvDy5woQEDXHcJ+O9s53liYjZFNU5ceL+R48jUoXLVPuCmXFQKqo1N/t++lWR6icWy8tllHZGsr1GDVX0+EY+0gJUULR+SPzsAqt5IgCq0BlQ/iz4iLUS8fAoHs46AU3u/yHNRapBu3XOqKwCmQH2HNUufUZyD56cVaIBzE0ILWKwY7HaEcP28y0D/++OpqPz44c8YhwLcSdoIYJIOb3FzBVsq+1B23VeqTZ8IxpDkI4wumBLwJS+eJ136XBUegL1hQQv5BRrcN/XgJ9wyC43QN+d8LfBWUZQody7kKXC0KtratgHwwazCdxl8PR3p0aeXbveUBbJmyRQS27jDykncrYUrzkG8WRWhrW0tUR0CAwEAAQ==",
"subject": "C=US, O=U.S. Government, OU=Department of State, OU=MRTD, OU=Certification Authorities, OU=U.S. Department of State MRTD CA",
"notBefore": "2019-11-14T16:37:12Z",
"notAfter": "2040-05-14T17:07:12Z",
"serial": "4E32D03F"
}
]
}
Loading
Loading