diff --git a/README.md b/README.md index fbec0b5..bdafdd0 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

License - Noir + Noir Circuits Contracts

@@ -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 @@ -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 @@ -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 @@ -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 diff --git a/proof_a/Prover.toml b/proof_a/Prover.toml index fc3dfd4..86b09b9 100644 --- a/proof_a/Prover.toml +++ b/proof_a/Prover.toml @@ -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) === diff --git a/selective_disclosure/src/main.nr b/selective_disclosure/src/main.nr index abb7869..0b818aa 100644 --- a/selective_disclosure/src/main.nr +++ b/selective_disclosure/src/main.nr @@ -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"); } else { // When not disclosing: all location public inputs must be zero assert(disclosed_lat_min == 0, "disclosed_lat_min must be 0 when hidden"); @@ -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 diff --git a/src/main.nr b/src/main.nr deleted file mode 100644 index 57ca1bc..0000000 --- a/src/main.nr +++ /dev/null @@ -1,324 +0,0 @@ -/// Apertrue C2PA Verifier Circuit v2.3 - Full RSA Support (COSE + Certificate) -/// -/// This circuit proves that: -/// 1. An image has a valid C2PA COSE signature (leaf key signed content) -/// 2. The leaf certificate was signed by an intermediate CA (cert signature over TBS DER) -/// 3. The intermediate CA is in the Oracle's promoted trust list (via Merkle proof) -/// 4. The leaf pubkey used in COSE matches the pubkey in the signed certificate (SPKI binding) -/// 5. The proof is bound to specific image content (nullifier prevents replay) -/// 6. The certificate was valid at the time the proof was generated (expiry enforcement) -/// -/// Privacy: The circuit hides: -/// - Which specific device signed the content (leaf identity) -/// - Which intermediate CA issued the certificate (Merkle proof hides this) -/// - The certificate chain details -/// -/// The verifier sees: trust_list_root, content_hash, nullifier, proof_timestamp, cert_not_before, cert_not_after -/// -/// Architecture: "Intermediate Promotion" -/// - Instead of enumerating millions of device leaf keys, we promote ~50-100 intermediate CAs -/// - The Oracle verifies intermediate -> root chains and publishes a Merkle tree -/// - Client proves leaf was signed by a promoted intermediate -/// -/// Revocation Strategy: -/// - Revoked intermediates are removed from the Oracle trust list -/// - The trust_list_root is updated to exclude revoked entries -/// - Oracle publishes epochs (weekly) with fresh Merkle roots -/// - No explicit non-membership proof needed in circuit - membership proof fails for revoked entries -/// - Future: In-circuit non-membership proof against revoked set for finer control -/// -/// Algorithm Support: -/// - COSE signature: ECDSA P-256 (ES256) or RSA-2048 (PS256) -/// - Certificate signature: ECDSA P-256 or RSA-2048 -/// - Supports: ChatGPT (ES256 COSE + RSA cert), Adobe (PS256 COSE + RSA cert), Leica (ES256 + ECDSA cert) - -use std::ecdsa_secp256r1::verify_signature; -use std::hash::pedersen_hash; -use std::hash::sha256_var; - -// RSA verification from noir_rsa -use noir_rsa::rsa::verify_sha256_pkcs1v15; -use noir_rsa::types::RBN2048; -use bignum::params::BigNumParams; - -/// Maximum depth of the Merkle tree for promoted intermediates -/// 2^8 = 256 intermediates capacity (sufficient for C2PA ecosystem) -global MERKLE_TREE_DEPTH: u32 = 8; - -/// Maximum TBS certificate size (in bytes) -/// Most leaf certs are 500-1500 bytes, 2KB covers 99% -global MAX_TBS_SIZE: u32 = 2048; - -/// RSA-2048 parameters -/// Uses 18 limbs of 120 bits each -global RSA_NUM_LIMBS: u32 = 18; - -/// Algorithm selectors -global ALG_ECDSA: Field = 0; -global ALG_RSA: Field = 1; - -/// The main circuit entry point -fn main( - // === PUBLIC INPUTS (minimal - what verifier sees) === - trust_list_root: pub Field, - content_hash: pub Field, - nullifier: pub Field, - - // === PUBLIC: TIME-BOUND VALIDITY === - proof_timestamp: pub Field, // Unix timestamp (seconds) when proof was generated - cert_not_before: pub Field, // Unix timestamp (seconds) - cert validity start - cert_not_after: pub Field, // Unix timestamp (seconds) - cert validity end - - // === PRIVATE: ALGORITHM SELECTORS === - cose_algorithm: Field, // 0 = ECDSA (ES256), 1 = RSA (PS256) - cert_algorithm: Field, // 0 = ECDSA, 1 = RSA - - // === PRIVATE: ECDSA COSE SIGNATURE (used when cose_algorithm == 0) === - cose_signature_ecdsa: [u8; 64], - leaf_pubkey_x: [u8; 32], - leaf_pubkey_y: [u8; 32], - - // === PRIVATE: RSA COSE SIGNATURE (used when cose_algorithm == 1) === - cose_signature_rsa_limbs: [u128; RSA_NUM_LIMBS], - leaf_rsa_modulus_limbs: [u128; RSA_NUM_LIMBS], - leaf_rsa_redc_limbs: [u128; RSA_NUM_LIMBS], - - // === PRIVATE: COSE MESSAGE HASH (shared by both algorithms) === - cose_message_hash: [u8; 32], - - // === PRIVATE: CERTIFICATE DATA === - tbs_certificate: [u8; MAX_TBS_SIZE], - tbs_len: u32, - - // === PRIVATE: ECDSA CERT SIGNATURE (used when cert_algorithm == 0) === - cert_signature_ecdsa: [u8; 64], - intermediate_pubkey_x: [u8; 32], - intermediate_pubkey_y: [u8; 32], - - // === PRIVATE: RSA CERT SIGNATURE (used when cert_algorithm == 1) === - cert_signature_rsa_limbs: [u128; RSA_NUM_LIMBS], - intermediate_rsa_modulus_limbs: [u128; RSA_NUM_LIMBS], - intermediate_rsa_redc_limbs: [u128; RSA_NUM_LIMBS], - - // === PRIVATE: SPKI EXTRACTION OFFSETS === - spki_offset: u32, - pubkey_offset: u32, - // For RSA leaf keys, we need additional offset for modulus in TBS - rsa_modulus_offset: u32, - rsa_modulus_len: u32, - - // === PRIVATE: MERKLE MEMBERSHIP === - merkle_path: [Field; MERKLE_TREE_DEPTH], - merkle_indices: [Field; MERKLE_TREE_DEPTH] -) { - // Validate algorithm selectors - assert((cose_algorithm == ALG_ECDSA) | (cose_algorithm == ALG_RSA), "Invalid COSE algorithm"); - assert((cert_algorithm == ALG_ECDSA) | (cert_algorithm == ALG_RSA), "Invalid cert algorithm"); - - // ================================================================ - // STEP 1: Verify COSE signature (leaf key signed the C2PA claim) - // ================================================================ - if cose_algorithm == ALG_ECDSA { - // ES256: ECDSA P-256 signature - let cose_valid = verify_signature( - leaf_pubkey_x, - leaf_pubkey_y, - cose_signature_ecdsa, - cose_message_hash - ); - assert(cose_valid, "Invalid ECDSA COSE signature"); - } else { - // PS256: RSA-2048 PKCS#1 v1.5 signature - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - leaf_rsa_modulus_limbs, - leaf_rsa_redc_limbs - ); - let signature: RBN2048 = RBN2048::from_array(params, cose_signature_rsa_limbs); - let rsa_valid = verify_sha256_pkcs1v15(cose_message_hash, signature, 65537); - assert(rsa_valid, "Invalid RSA COSE signature"); - } - - // ================================================================ - // STEP 2: Hash the TBS certificate - // ================================================================ - let tbs_hash: [u8; 32] = sha256_var(tbs_certificate, tbs_len as u32); - - // ================================================================ - // STEP 3: Verify certificate signature (intermediate signed leaf cert) - // ================================================================ - if cert_algorithm == ALG_ECDSA { - // ECDSA P-256 certificate signature - let cert_valid = verify_signature( - intermediate_pubkey_x, - intermediate_pubkey_y, - cert_signature_ecdsa, - tbs_hash - ); - assert(cert_valid, "Invalid ECDSA certificate signature"); - } else { - // RSA-2048 certificate signature with PKCS#1 v1.5 padding - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - intermediate_rsa_modulus_limbs, - intermediate_rsa_redc_limbs - ); - let signature: RBN2048 = RBN2048::from_array(params, cert_signature_rsa_limbs); - let rsa_valid = verify_sha256_pkcs1v15(tbs_hash, signature, 65537); - assert(rsa_valid, "Invalid RSA certificate signature"); - } - - // ================================================================ - // STEP 4: Validate SPKI and bind leaf pubkey - // ================================================================ - assert(spki_offset < tbs_len, "SPKI offset out of bounds"); - assert(pubkey_offset < tbs_len, "Pubkey offset out of bounds"); - assert(pubkey_offset > spki_offset, "Pubkey must be after SPKI start"); - - assert(tbs_certificate[spki_offset] == 0x30, "SPKI must start with SEQUENCE"); - - if cose_algorithm == ALG_ECDSA { - // ECDSA leaf key: Extract EC point from BIT STRING - assert(tbs_certificate[pubkey_offset] == 0x03, "Expected BIT STRING for EC pubkey"); - - // Extract pubkey from BIT STRING: tag(1) + len(1) + unused(1) + uncompressed(1) = 4 bytes header - let key_start = pubkey_offset + 4; - assert(tbs_certificate[key_start - 1] == 0x04, "Expected uncompressed EC point"); - - // Verify X coordinate - for i in 0..32 { - assert(tbs_certificate[key_start + i] == leaf_pubkey_x[i], "Leaf pubkey X mismatch"); - } - - // Verify Y coordinate - for i in 0..32 { - assert(tbs_certificate[key_start + 32 + i] == leaf_pubkey_y[i], "Leaf pubkey Y mismatch"); - } - } else { - // RSA leaf key: Verify modulus bytes match - // RSA SPKI structure: SEQUENCE { AlgorithmID, BIT STRING { SEQUENCE { modulus INTEGER, exponent INTEGER } } } - // The modulus is at rsa_modulus_offset, length rsa_modulus_len - assert(rsa_modulus_offset < tbs_len, "RSA modulus offset out of bounds"); - assert(rsa_modulus_offset + rsa_modulus_len <= tbs_len, "RSA modulus extends beyond TBS"); - - // Reconstruct modulus from limbs and verify against TBS bytes - // For RSA-2048, modulus is 256 bytes - // We verify by reconstructing bytes from the first few limbs and checking - // Note: Full 256-byte comparison would be expensive; we verify key limbs suffice - // The signature verification already binds the modulus cryptographically - - // Verify the modulus INTEGER tag at the offset - assert(tbs_certificate[rsa_modulus_offset] == 0x02, "Expected INTEGER for RSA modulus"); - } - - // ================================================================ - // STEP 5: Compute intermediate identity for Merkle lookup - // ================================================================ - let intermediate_leaf = if cert_algorithm == ALG_ECDSA { - // ECDSA: hash(x, y) - let x_field = bytes_to_field(intermediate_pubkey_x); - let y_field = bytes_to_field(intermediate_pubkey_y); - pedersen_hash([x_field, y_field]) - } else { - // RSA: hash first two modulus limbs (sufficient for uniqueness) - pedersen_hash([intermediate_rsa_modulus_limbs[0] as Field, intermediate_rsa_modulus_limbs[1] as Field]) - }; - - // ================================================================ - // STEP 6: Verify intermediate is in Oracle's trust list - // ================================================================ - let computed_root = compute_merkle_root(intermediate_leaf, merkle_path, merkle_indices); - assert(computed_root == trust_list_root, "Intermediate not in trust list"); - - // ================================================================ - // STEP 7: Verify nullifier derivation - // ================================================================ - let leaf_pubkey_hash = if cose_algorithm == ALG_ECDSA { - // ECDSA: hash(x, y) coordinates - let leaf_x_field = bytes_to_field(leaf_pubkey_x); - let leaf_y_field = bytes_to_field(leaf_pubkey_y); - pedersen_hash([leaf_x_field, leaf_y_field]) - } else { - // RSA: hash first two modulus limbs - pedersen_hash([leaf_rsa_modulus_limbs[0] as Field, leaf_rsa_modulus_limbs[1] as Field]) - }; - - let expected_nullifier = pedersen_hash([content_hash, leaf_pubkey_hash]); - assert(nullifier == expected_nullifier, "Invalid nullifier"); - - // ================================================================ - // STEP 8: Verify certificate validity at proof time - // ================================================================ - // Ensure proof_timestamp is within certificate validity window - // Cast to u64 for comparison (Fields cannot be compared directly) - let ts = proof_timestamp as u64; - let not_before = cert_not_before as u64; - let not_after = cert_not_after as u64; - assert(ts >= not_before, "Certificate not yet valid at proof time"); - assert(ts <= not_after, "Certificate expired at proof time"); -} - -/// Convert 32 bytes to Field (big-endian) -fn bytes_to_field(bytes: [u8; 32]) -> Field { - let mut result: Field = 0; - for i in 0..32 { - result = result * 256 + bytes[i] as Field; - } - result -} - -/// Compute Merkle root from leaf and proof -fn compute_merkle_root( - leaf: Field, - path: [Field; MERKLE_TREE_DEPTH], - indices: [Field; MERKLE_TREE_DEPTH] -) -> Field { - let mut current = leaf; - - for i in 0..MERKLE_TREE_DEPTH { - let path_element = path[i]; - let is_right = indices[i]; - let left = if is_right == 0 { current } else { path_element }; - let right = if is_right == 0 { path_element } else { current }; - current = pedersen_hash([left, right]); - } - - current -} - -// ==================================================================== -// TESTS -// ==================================================================== - -#[test] -fn test_bytes_to_field() { - let bytes: [u8; 32] = [ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0 - ]; - let result = bytes_to_field(bytes); - assert(result == 256); -} - -#[test] -fn test_merkle_single_level() { - let leaf: Field = 123; - let sibling: Field = 456; - - let mut path: [Field; MERKLE_TREE_DEPTH] = [0; MERKLE_TREE_DEPTH]; - path[0] = sibling; - - let mut indices: [Field; MERKLE_TREE_DEPTH] = [0; MERKLE_TREE_DEPTH]; - indices[0] = 0; - - let root = compute_merkle_root(leaf, path, indices); - - let first_level = pedersen_hash([leaf, sibling]); - let mut expected = first_level; - for _ in 1..MERKLE_TREE_DEPTH { - expected = pedersen_hash([expected, 0]); - } - assert(root == expected); -} diff --git a/src/proof_a.nr b/src/proof_a.nr deleted file mode 100644 index f2a811b..0000000 --- a/src/proof_a.nr +++ /dev/null @@ -1,307 +0,0 @@ -/// Apertrue ProofA - Certificate Chain Verification -/// -/// This is the first half of the split-proof architecture for RSA-4096 support. -/// -/// ProofA proves: -/// 1. The leaf certificate was signed by an intermediate CA (X.509 signature) -/// 2. The leaf public key in TBS matches the key used for COSE signature (SPKI binding) -/// 3. The blinded link commitment matches (links to ProofB without revealing intermediate) -/// 4. The nullifier is correctly derived from the TBS-extracted leaf key -/// -/// PUBLIC INPUTS (shared with ProofB - must match): -/// - trust_list_root: Oracle's Merkle root (not directly used here, but part of shared inputs) -/// - content_hash: SHA256 of stripped image -/// - nullifier: pedersen_hash([content_hash, leaf_key_hash]) -/// - proof_timestamp: When proof was generated -/// - cert_not_before: Certificate validity start -/// - cert_not_after: Certificate validity end -/// - link_commit: pedersen_hash([intermediate_leaf, link_blind]) -/// -/// PRIVATE INPUTS: -/// - TBS certificate bytes and SPKI offsets -/// - Certificate signature (ECDSA, RSA-2048, or RSA-4096) -/// - Intermediate public key (for signature verification) -/// - Leaf public key extracted from TBS (for nullifier binding) -/// -/// RSA-4096 Support: -/// - Uses 35 limbs of 120 bits for 4096-bit numbers -/// - PKCS#1 v1.5 with SHA-256 for signature verification - -use std::ecdsa_secp256r1::verify_signature; -use std::hash::pedersen_hash; -use std::hash::sha256_var; - -// RSA verification from noir_rsa -use noir_rsa::rsa::verify_sha256_pkcs1v15; -use noir_rsa::types::{RBN2048, RBN4096}; -use bignum::params::BigNumParams; - -/// Maximum TBS certificate size (in bytes) -global MAX_TBS_SIZE: u32 = 2048; - -/// RSA-2048 uses 18 limbs of 120 bits -global RSA_2048_NUM_LIMBS: u32 = 18; - -/// RSA-4096 uses 35 limbs of 120 bits (4096 / 120 = 34.13, rounded up) -global RSA_4096_NUM_LIMBS: u32 = 35; - -/// Algorithm selectors for certificate signature -global CERT_ALG_ECDSA: Field = 0; -global CERT_ALG_RSA_2048: Field = 1; -global CERT_ALG_RSA_4096: Field = 2; - -/// Leaf key type selectors -global LEAF_ALG_ECDSA: Field = 0; -global LEAF_ALG_RSA: Field = 1; - -/// ProofA main entry point -fn main( - // === PUBLIC INPUTS (shared with ProofB) === - trust_list_root: pub Field, // Not directly used, but must match ProofB - content_hash: pub Field, - nullifier: pub Field, - proof_timestamp: pub Field, - cert_not_before: pub Field, - cert_not_after: pub Field, - link_commit: pub Field, - - // === PRIVATE: ALGORITHM SELECTORS === - cert_algorithm: Field, // 0 = ECDSA, 1 = RSA-2048, 2 = RSA-4096 - leaf_key_type: Field, // 0 = ECDSA, 1 = RSA - - // === PRIVATE: TBS CERTIFICATE DATA === - tbs_certificate: [u8; MAX_TBS_SIZE], - tbs_len: u32, - - // === PRIVATE: SPKI EXTRACTION OFFSETS === - spki_offset: u32, - pubkey_offset: u32, - // For RSA leaf keys - rsa_modulus_offset: u32, - rsa_modulus_len: u32, - - // === PRIVATE: ECDSA CERT SIGNATURE (when cert_algorithm == 0) === - cert_signature_ecdsa: [u8; 64], - intermediate_pubkey_x: [u8; 32], - intermediate_pubkey_y: [u8; 32], - - // === PRIVATE: RSA-2048 CERT SIGNATURE (when cert_algorithm == 1) === - cert_signature_rsa_2048_limbs: [u128; RSA_2048_NUM_LIMBS], - intermediate_rsa_2048_modulus_limbs: [u128; RSA_2048_NUM_LIMBS], - intermediate_rsa_2048_redc_limbs: [u128; RSA_2048_NUM_LIMBS], - - // === PRIVATE: RSA-4096 CERT SIGNATURE (when cert_algorithm == 2) === - cert_signature_rsa_4096_limbs: [u128; RSA_4096_NUM_LIMBS], - intermediate_rsa_4096_modulus_limbs: [u128; RSA_4096_NUM_LIMBS], - intermediate_rsa_4096_redc_limbs: [u128; RSA_4096_NUM_LIMBS], - - // === PRIVATE: LEAF KEY FROM TBS (for nullifier binding) === - // ECDSA leaf key - tbs_leaf_pubkey_x: [u8; 32], - tbs_leaf_pubkey_y: [u8; 32], - // RSA leaf key (first two limbs sufficient for hash) - tbs_leaf_rsa_modulus_limb0: u128, - tbs_leaf_rsa_modulus_limb1: u128, - - // === PRIVATE: LINKING WITNESS === - intermediate_leaf: Field, // pedersen_hash of intermediate key material - link_blind: Field // random blinding factor (same as in ProofB) -) { - // Validate algorithm selectors - assert( - (cert_algorithm == CERT_ALG_ECDSA) | - (cert_algorithm == CERT_ALG_RSA_2048) | - (cert_algorithm == CERT_ALG_RSA_4096), - "Invalid cert algorithm" - ); - assert((leaf_key_type == LEAF_ALG_ECDSA) | (leaf_key_type == LEAF_ALG_RSA), "Invalid leaf key type"); - - // ================================================================ - // STEP 1: Hash the TBS certificate - // ================================================================ - let tbs_hash: [u8; 32] = sha256_var(tbs_certificate, tbs_len as u32); - - // ================================================================ - // STEP 2: Verify certificate signature (intermediate signed leaf cert) - // ================================================================ - if cert_algorithm == CERT_ALG_ECDSA { - // ECDSA P-256 certificate signature - let cert_valid = verify_signature( - intermediate_pubkey_x, - intermediate_pubkey_y, - cert_signature_ecdsa, - tbs_hash - ); - assert(cert_valid, "Invalid ECDSA certificate signature"); - } else if cert_algorithm == CERT_ALG_RSA_2048 { - // RSA-2048 certificate signature with PKCS#1 v1.5 padding - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - intermediate_rsa_2048_modulus_limbs, - intermediate_rsa_2048_redc_limbs - ); - let signature: RBN2048 = RBN2048::from_array(params, cert_signature_rsa_2048_limbs); - let rsa_valid = verify_sha256_pkcs1v15(tbs_hash, signature, 65537); - assert(rsa_valid, "Invalid RSA-2048 certificate signature"); - } else { - // RSA-4096 certificate signature with PKCS#1 v1.5 padding - // noir_rsa's RBN4096 type uses 35 limbs of 120 bits - let params: BigNumParams<35, 4096> = BigNumParams::new( - false, - intermediate_rsa_4096_modulus_limbs, - intermediate_rsa_4096_redc_limbs - ); - let signature: RBN4096 = RBN4096::from_array(params, cert_signature_rsa_4096_limbs); - let rsa_valid = verify_sha256_pkcs1v15(tbs_hash, signature, 65537); - assert(rsa_valid, "Invalid RSA-4096 certificate signature"); - } - - // ================================================================ - // STEP 3: Validate SPKI and bind leaf pubkey from TBS - // ================================================================ - assert(spki_offset < tbs_len, "SPKI offset out of bounds"); - assert(pubkey_offset < tbs_len, "Pubkey offset out of bounds"); - assert(pubkey_offset > spki_offset, "Pubkey must be after SPKI start"); - assert(tbs_certificate[spki_offset] == 0x30, "SPKI must start with SEQUENCE"); - - if leaf_key_type == LEAF_ALG_ECDSA { - // ECDSA leaf key: Extract EC point from BIT STRING - assert(tbs_certificate[pubkey_offset] == 0x03, "Expected BIT STRING for EC pubkey"); - - // Extract pubkey from BIT STRING: tag(1) + len(1) + unused(1) + uncompressed(1) = 4 bytes header - let key_start = pubkey_offset + 4; - assert(tbs_certificate[key_start - 1] == 0x04, "Expected uncompressed EC point"); - - // Verify X coordinate matches witness - for i in 0..32 { - assert(tbs_certificate[key_start + i] == tbs_leaf_pubkey_x[i], "Leaf pubkey X mismatch"); - } - - // Verify Y coordinate matches witness - for i in 0..32 { - assert(tbs_certificate[key_start + 32 + i] == tbs_leaf_pubkey_y[i], "Leaf pubkey Y mismatch"); - } - } else { - // RSA leaf key: Verify modulus INTEGER tag - assert(rsa_modulus_offset < tbs_len, "RSA modulus offset out of bounds"); - assert(rsa_modulus_offset + rsa_modulus_len <= tbs_len, "RSA modulus extends beyond TBS"); - assert(tbs_certificate[rsa_modulus_offset] == 0x02, "Expected INTEGER for RSA modulus"); - - // The signature verification cryptographically binds the key - // We rely on the signature check + nullifier binding for security - } - - // ================================================================ - // STEP 4: Verify link commitment (binds to ProofB) - // ================================================================ - let expected_link_commit = pedersen_hash([intermediate_leaf, link_blind]); - assert(link_commit == expected_link_commit, "Link commitment mismatch"); - - // ================================================================ - // STEP 5: Verify intermediate_leaf matches intermediate key - // ================================================================ - let expected_intermediate_leaf = if cert_algorithm == CERT_ALG_ECDSA { - let x_field = bytes_to_field(intermediate_pubkey_x); - let y_field = bytes_to_field(intermediate_pubkey_y); - pedersen_hash([x_field, y_field]) - } else if cert_algorithm == CERT_ALG_RSA_2048 { - pedersen_hash([intermediate_rsa_2048_modulus_limbs[0] as Field, intermediate_rsa_2048_modulus_limbs[1] as Field]) - } else { - pedersen_hash([intermediate_rsa_4096_modulus_limbs[0] as Field, intermediate_rsa_4096_modulus_limbs[1] as Field]) - }; - assert(intermediate_leaf == expected_intermediate_leaf, "Intermediate leaf mismatch"); - - // ================================================================ - // STEP 6: Verify nullifier derivation from TBS-extracted leaf key - // ================================================================ - // This is the CRITICAL step that prevents splice attacks: - // The nullifier must be derived from the leaf key EXTRACTED from the signed TBS - // Since ProofB also proves the same nullifier with the COSE leaf key, - // both proofs must use the same leaf key. - let leaf_key_hash = if leaf_key_type == LEAF_ALG_ECDSA { - let leaf_x_field = bytes_to_field(tbs_leaf_pubkey_x); - let leaf_y_field = bytes_to_field(tbs_leaf_pubkey_y); - pedersen_hash([leaf_x_field, leaf_y_field]) - } else { - pedersen_hash([tbs_leaf_rsa_modulus_limb0 as Field, tbs_leaf_rsa_modulus_limb1 as Field]) - }; - - let expected_nullifier = pedersen_hash([content_hash, leaf_key_hash]); - assert(nullifier == expected_nullifier, "Invalid nullifier (leaf key binding failed)"); - - // ================================================================ - // STEP 7: Verify certificate validity at proof time - // ================================================================ - let ts = proof_timestamp as u64; - let not_before = cert_not_before as u64; - let not_after = cert_not_after as u64; - assert(ts >= not_before, "Certificate not yet valid at proof time"); - assert(ts <= not_after, "Certificate expired at proof time"); - - // Note: trust_list_root is a public input for consistency with ProofB - // but is not directly constrained here (Merkle membership is in ProofB) - // The verifier ensures both proofs have matching trust_list_root - let _ = trust_list_root; -} - -/// Convert 32 bytes to Field (big-endian) -fn bytes_to_field(bytes: [u8; 32]) -> Field { - let mut result: Field = 0; - for i in 0..32 { - result = result * 256 + bytes[i] as Field; - } - result -} - -// ==================================================================== -// TESTS -// ==================================================================== - -#[test] -fn test_intermediate_leaf_ecdsa() { - let x: [u8; 32] = [1; 32]; - let y: [u8; 32] = [2; 32]; - - let x_field = bytes_to_field(x); - let y_field = bytes_to_field(y); - let leaf = pedersen_hash([x_field, y_field]); - - // Verify same inputs produce same output - let leaf2 = pedersen_hash([x_field, y_field]); - assert(leaf == leaf2); -} - -#[test] -fn test_intermediate_leaf_rsa() { - let modulus_limb0: u128 = 12345678901234567890; - let modulus_limb1: u128 = 98765432109876543210; - - let leaf = pedersen_hash([modulus_limb0 as Field, modulus_limb1 as Field]); - - // Different limbs -> different leaf - let different_limb0: u128 = 11111111111111111111; - let different_leaf = pedersen_hash([different_limb0 as Field, modulus_limb1 as Field]); - assert(leaf != different_leaf); -} - -#[test] -fn test_leaf_key_binding() { - // Simulate the splice attack prevention: - // ProofA derives nullifier from TBS leaf key - // ProofB derives nullifier from COSE leaf key - // If they match, the leaf keys must be the same - - let content_hash: Field = 999; - let leaf_key_hash_a: Field = 111; - let leaf_key_hash_b: Field = 111; // Same as A - - let nullifier_a = pedersen_hash([content_hash, leaf_key_hash_a]); - let nullifier_b = pedersen_hash([content_hash, leaf_key_hash_b]); - - assert(nullifier_a == nullifier_b); - - // Different leaf key -> different nullifier (attack detected) - let attacker_leaf_key: Field = 222; - let attacker_nullifier = pedersen_hash([content_hash, attacker_leaf_key]); - assert(nullifier_a != attacker_nullifier); -} diff --git a/src/proof_b.nr b/src/proof_b.nr deleted file mode 100644 index c0987a2..0000000 --- a/src/proof_b.nr +++ /dev/null @@ -1,196 +0,0 @@ -/// Apertrue ProofB - COSE Signature + Merkle Membership -/// -/// This is the second half of the split-proof architecture for RSA-4096 support. -/// -/// ProofB proves: -/// 1. A valid COSE signature exists (ES256 or PS256) using the leaf key -/// 2. The intermediate CA is in the Oracle's promoted trust list (Merkle membership) -/// 3. The blinded link commitment matches (links to ProofA without revealing intermediate) -/// 4. The nullifier is correctly derived from the leaf key and content hash -/// 5. Certificate validity at proof time -/// -/// PUBLIC INPUTS (shared with ProofA - must match): -/// - trust_list_root: Oracle's Merkle root -/// - content_hash: SHA256 of stripped image -/// - nullifier: pedersen_hash([content_hash, leaf_key_hash]) -/// - proof_timestamp: When proof was generated -/// - cert_not_before: Certificate validity start -/// - cert_not_after: Certificate validity end -/// - link_commit: pedersen_hash([intermediate_leaf, link_blind]) -/// -/// PRIVATE INPUTS: -/// - COSE signature and leaf key (ECDSA or RSA-2048) -/// - COSE message hash (SHA256 of Sig_structure) -/// - Intermediate leaf value and link_blind -/// - Merkle path for intermediate - -use std::ecdsa_secp256r1::verify_signature; -use std::hash::pedersen_hash; - -// RSA verification from noir_rsa -use noir_rsa::rsa::verify_sha256_pkcs1v15; -use noir_rsa::types::RBN2048; -use bignum::params::BigNumParams; - -/// Maximum depth of the Merkle tree for promoted intermediates -global MERKLE_TREE_DEPTH: u32 = 8; - -/// RSA-2048 uses 18 limbs of 120 bits -global RSA_NUM_LIMBS: u32 = 18; - -/// Algorithm selectors -global ALG_ECDSA: Field = 0; -global ALG_RSA: Field = 1; - -/// ProofB main entry point -fn main( - // === PUBLIC INPUTS (shared with ProofA) === - trust_list_root: pub Field, - content_hash: pub Field, - nullifier: pub Field, - proof_timestamp: pub Field, - cert_not_before: pub Field, - cert_not_after: pub Field, - link_commit: pub Field, - - // === PRIVATE: ALGORITHM SELECTOR === - cose_algorithm: Field, // 0 = ECDSA (ES256), 1 = RSA (PS256) - - // === PRIVATE: ECDSA COSE SIGNATURE (when cose_algorithm == 0) === - cose_signature_ecdsa: [u8; 64], - leaf_pubkey_x: [u8; 32], - leaf_pubkey_y: [u8; 32], - - // === PRIVATE: RSA COSE SIGNATURE (when cose_algorithm == 1) === - cose_signature_rsa_limbs: [u128; RSA_NUM_LIMBS], - leaf_rsa_modulus_limbs: [u128; RSA_NUM_LIMBS], - leaf_rsa_redc_limbs: [u128; RSA_NUM_LIMBS], - - // === PRIVATE: COSE MESSAGE HASH === - cose_message_hash: [u8; 32], - - // === PRIVATE: LINKING WITNESS === - intermediate_leaf: Field, // pedersen_hash of intermediate key material - link_blind: Field, // random blinding factor - - // === PRIVATE: MERKLE MEMBERSHIP === - merkle_path: [Field; MERKLE_TREE_DEPTH], - merkle_indices: [Field; MERKLE_TREE_DEPTH] -) { - // Validate algorithm selector - assert((cose_algorithm == ALG_ECDSA) | (cose_algorithm == ALG_RSA), "Invalid COSE algorithm"); - - // ================================================================ - // STEP 1: Verify COSE signature (leaf key signed the C2PA claim) - // ================================================================ - if cose_algorithm == ALG_ECDSA { - // ES256: ECDSA P-256 signature - let cose_valid = verify_signature( - leaf_pubkey_x, - leaf_pubkey_y, - cose_signature_ecdsa, - cose_message_hash - ); - assert(cose_valid, "Invalid ECDSA COSE signature"); - } else { - // PS256: RSA-2048 PKCS#1 v1.5 signature - let params: BigNumParams<18, 2048> = BigNumParams::new( - false, - leaf_rsa_modulus_limbs, - leaf_rsa_redc_limbs - ); - let signature: RBN2048 = RBN2048::from_array(params, cose_signature_rsa_limbs); - let rsa_valid = verify_sha256_pkcs1v15(cose_message_hash, signature, 65537); - assert(rsa_valid, "Invalid RSA COSE signature"); - } - - // ================================================================ - // STEP 2: Verify Merkle membership for intermediate - // ================================================================ - let computed_root = compute_merkle_root(intermediate_leaf, merkle_path, merkle_indices); - assert(computed_root == trust_list_root, "Intermediate not in trust list"); - - // ================================================================ - // STEP 3: Verify link commitment (binds to ProofA) - // ================================================================ - let expected_link_commit = pedersen_hash([intermediate_leaf, link_blind]); - assert(link_commit == expected_link_commit, "Link commitment mismatch"); - - // ================================================================ - // STEP 4: Verify nullifier derivation (binds leaf key to content) - // ================================================================ - let leaf_pubkey_hash = if cose_algorithm == ALG_ECDSA { - let leaf_x_field = bytes_to_field(leaf_pubkey_x); - let leaf_y_field = bytes_to_field(leaf_pubkey_y); - pedersen_hash([leaf_x_field, leaf_y_field]) - } else { - pedersen_hash([leaf_rsa_modulus_limbs[0] as Field, leaf_rsa_modulus_limbs[1] as Field]) - }; - - let expected_nullifier = pedersen_hash([content_hash, leaf_pubkey_hash]); - assert(nullifier == expected_nullifier, "Invalid nullifier"); - - // ================================================================ - // STEP 5: Verify certificate validity at proof time - // ================================================================ - let ts = proof_timestamp as u64; - let not_before = cert_not_before as u64; - let not_after = cert_not_after as u64; - assert(ts >= not_before, "Certificate not yet valid at proof time"); - assert(ts <= not_after, "Certificate expired at proof time"); -} - -/// Convert 32 bytes to Field (big-endian) -fn bytes_to_field(bytes: [u8; 32]) -> Field { - let mut result: Field = 0; - for i in 0..32 { - result = result * 256 + bytes[i] as Field; - } - result -} - -/// Compute Merkle root from leaf and proof -fn compute_merkle_root( - leaf: Field, - path: [Field; MERKLE_TREE_DEPTH], - indices: [Field; MERKLE_TREE_DEPTH] -) -> Field { - let mut current = leaf; - - for i in 0..MERKLE_TREE_DEPTH { - let path_element = path[i]; - let is_right = indices[i]; - let left = if is_right == 0 { current } else { path_element }; - let right = if is_right == 0 { path_element } else { current }; - current = pedersen_hash([left, right]); - } - - current -} - -// ==================================================================== -// TESTS -// ==================================================================== - -#[test] -fn test_link_commitment() { - let intermediate_leaf: Field = 12345; - let link_blind: Field = 67890; - let commit = pedersen_hash([intermediate_leaf, link_blind]); - - // Verify same inputs produce same output - let commit2 = pedersen_hash([intermediate_leaf, link_blind]); - assert(commit == commit2); -} - -#[test] -fn test_nullifier_derivation() { - let content_hash: Field = 111; - let leaf_key_hash: Field = 222; - let nullifier = pedersen_hash([content_hash, leaf_key_hash]); - - // Different content hash -> different nullifier - let different_content: Field = 333; - let different_nullifier = pedersen_hash([different_content, leaf_key_hash]); - assert(nullifier != different_nullifier); -} diff --git a/vendor/noir-jwt/js/package-lock.json b/vendor/noir-jwt/js/package-lock.json deleted file mode 100644 index f011492..0000000 --- a/vendor/noir-jwt/js/package-lock.json +++ /dev/null @@ -1,745 +0,0 @@ -{ - "name": "noir-jwt", - "version": "0.4.5", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "noir-jwt", - "version": "0.4.5", - "license": "MIT", - "devDependencies": { - "@types/jsonwebtoken": "^9.0.8", - "jsonwebtoken": "^9.0.2", - "tsx": "^4.19.3", - "typescript": "^5.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz", - "integrity": "sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*", - "@types/node": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", - "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-tsconfig": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", - "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tsx": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", - "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true, - "license": "MIT" - } - } -} diff --git a/vendor/noir-jwt/js/package.json b/vendor/noir-jwt/js/package.json deleted file mode 100644 index ca3b81c..0000000 --- a/vendor/noir-jwt/js/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "noir-jwt", - "version": "0.4.5", - "description": "JavaScript library for generating inputs for the noir-jwt circuit", - "files": [ - "dist", - "src", - "package.json" - ], - "source": "src/index.ts", - "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", - "browser": "./dist/browser/index.js", - "exports": { - ".": { - "types": "./dist/types/index.d.ts", - "browser": "./dist/browser/index.js", - "import": "./dist/esm/index.js", - "require": "./dist/cjs/index.js", - "default": "./dist/esm/index.js" - } - }, - "types": "dist/types/index.d.ts", - "scripts": { - "build": "rm -rf dist && npm run build:cjs && npm run build:esm && npm run build:browser", - "build:cjs": "tsc --outDir dist/cjs --module commonjs", - "build:esm": "tsc --outDir dist/esm --module es2020", - "build:browser": "tsc --outDir dist/browser --module es2020 --target es2020", - "build:dev": "tsc --watch", - "generate-noir-test-data": "npx tsx scripts/noir-test-data.ts", - "prepublishOnly": "npm run build" - }, - "keywords": [ - "noir", - "jwt" - ], - "author": "saleel ", - "license": "MIT", - "devDependencies": { - "@types/jsonwebtoken": "^9.0.8", - "jsonwebtoken": "^9.0.2", - "tsx": "^4.19.3", - "typescript": "^5.0.0" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} diff --git a/vendor/noir-jwt/js/scripts/noir-test-data.ts b/vendor/noir-jwt/js/scripts/noir-test-data.ts deleted file mode 100644 index 08f416a..0000000 --- a/vendor/noir-jwt/js/scripts/noir-test-data.ts +++ /dev/null @@ -1,168 +0,0 @@ -// @ts-ignore -import crypto from "crypto"; -// @ts-ignore -import jsonwebtoken from "jsonwebtoken"; -import { generateInputs } from "../src/generate-inputs.js"; - -// const key = crypto.generateKeyPairSync("rsa", { -// modulusLength: 2048, -// publicExponent: 65537, -// }); - -// console.log(key.privateKey.export({ type: "pkcs8", format: "pem" })); -// console.log(key.publicKey.export({ type: "spki", format: "pem" })); - -const privateKeyPem = `-----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjm55on1OLp1Ur -4B/N4+OKz6YL22jpjUmJzC81ghS4YQg8pb+DjUR734F6LGXLHqBuLvP5cjq5zRv3 -uLWfrhj/FGDKdkk5QGRcHbF6bbwlFnfv4BpojF5Dg7SiPBa+12pva3gB99nvoT/r -q1nTGGP57DaAO7EtiFIOl+hGzPK3B3byk1xek8m4BQ9mEC/ZDrCHlDyn9wcWEsNu -vV8qlFeLbKmcWSDScKJHEFeYlyWAZGxr56hvEgA9hqomJ61VDHzqBG7kI4PYolzO -vORKnhsYTFminBnndABfnifxSFVCg+FFhLioBaAyZ452hIRX7ASQXV4L9w7ayZpI -4uNJ508fAgMBAAECggEAEc842S6uy371mIcXLzRlapDcBGJn8zR8EtH1OZ/lXYTC -fseUJ1/TWqCj2YbHteqpkBTwXfD/T4ZySu8CZlVvRyUSvDdQFTlbM2PQFAGp/2eI -usXsWgEdqb/Gg/qCh1evsF1EfQJb6Ofmq2LFrmLzTxtVe3QD/27db9U9ZaedrCqp -S6Ar7abI3Zo3bc+N6PKJEnN9Du+kj9nofi2dVjrlr/RFE+zx+7yq0aO+IpmRIP34 -WOvRzTGOWtvBYAWmy4F8E4RsDJuV/coQJZ67udu9uhbzedIlZpnpjEdGdLSFwiO0 -LPKr3BW/iNmE4kBfnWPO2XeKrz+tld7a4Q2hrvEDEQKBgQDNp3wJB+KrEb5G3io5 -mpZfLBaf1R4NE9c2QfstdiBJ3DdqjhBgpSaAQ5mKcspnqy0G1chk8UYaP++nIrZT -8+6iPDHBd8vBwW4xjsWsQ+mjJ0oxPqTLjw7YRf3vPpHK99IzROG/t7/Yb99SMnNt -9oabx1UYsUqJo/9I72H2DsRQLQKBgQDLqQ5MdIWuUTEAFD4/bi4uAvq5OpmxwWiJ -zHDTVZD6tPN4CIq1rJWdKHoJ/tcDpOBdX22cBJoI/70vOyuh0xNkFKZpWWislRWr -Xm+ZUt74fFwHNJywkfqAp/xrFKSCcfiTfxAtBAXraFo9taHHTKz0VImFfMBMdgDD -dzKZq9xf+wKBgQC/1aSZE/b3loSEvMZsl2v/eTPdgkIW9tQA88lmndL+suIqjjxu -un9QlD5MbEmsLHvC7XaR2pKG9+8IXBPx+hA226maC7JQmau9pK11xJ/TJlpJ12KH -03mIermmCxqaV1OHqZBfcvsM3UZW+WK9R4JHG8igUPjzrbv7f/lEOoAbPQKBgDw3 -GtwuI4xbwyIj2hfFCvBdvyXfFqxA5BjCEqXZickmkUnvNJvskDvsSNEFwSr5p8DT -w0O69JQukRAS7Z6mGvifRmiln9ZPKh4GCPcLUpOjqU4UFzP5pVg+0toSO2W6LuXl -TrIQm3Nz4iKWvmN/3y9Kg3KtZOn2hdlFN/fJoZnbAoGBAJaTIliqJIvO5+L3auyZ -abJ8id/nLZxAYpdCvzj1OaBHHjdrnwICTes8QNvcgcNIKdOkNjPVoGjTKXTdyBZJ -g220hxOl6PTarDEwxCAxkWEZkN/mGITN4SkLyAQe5CMKGQWczx9rsnhlcj37YLJX -KkhEi0T+msAtTMLLYFeKaEGD ------END PRIVATE KEY-----`; - -const publicKeyPem = `-----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5ueaJ9Ti6dVK+AfzePj -is+mC9to6Y1JicwvNYIUuGEIPKW/g41Ee9+Beixlyx6gbi7z+XI6uc0b97i1n64Y -/xRgynZJOUBkXB2xem28JRZ37+AaaIxeQ4O0ojwWvtdqb2t4AffZ76E/66tZ0xhj -+ew2gDuxLYhSDpfoRszytwd28pNcXpPJuAUPZhAv2Q6wh5Q8p/cHFhLDbr1fKpRX -i2ypnFkg0nCiRxBXmJclgGRsa+eobxIAPYaqJietVQx86gRu5COD2KJczrzkSp4b -GExZopwZ53QAX54n8UhVQoPhRYS4qAWgMmeOdoSEV+wEkF1eC/cO2smaSOLjSedP -HwIDAQAB ------END PUBLIC KEY-----`; - - -const nonce = "123123123"; -const email = "alice@test.com"; - -export async function createKeyAndSignData() { - // Generate a key pair using RSASSA-PKCS1-v1_5 - const privateKey = crypto.createPrivateKey({ - key: privateKeyPem, - type: "pkcs8", - format: "pem", - }); - - const publicKey = crypto.createPublicKey({ - key: publicKeyPem, - type: "spki", - format: "pem", - }); - - // Sample payload - const payload = { - iss: "http://test.com", - sub: "ABCD123123", - email_verified: true, - nonce, - email, - iat: 1737642217, - aud: "123123123.456456456", - exp: 1799999999, // 2027-01-15T07:59:59.000Z - }; - - // Sign the payload - const jwt = jsonwebtoken.sign(payload, privateKey, { - algorithm: "RS256", - }); - - // Verify the jwt - jsonwebtoken.verify(jwt, publicKey); - - // Convert public key to JWK - const pubkeyJwk = publicKey.export({ format: "jwk" }); - - return { - pubkeyJwk, - jwt, - payload, - }; -} - -async function generateNoirTestData() { - const { pubkeyJwk, jwt } = await createKeyAndSignData(); - - // Prepare inputs - const inputs = await generateInputs({ - jwt: jwt, - pubkey: pubkeyJwk as JsonWebKey, - maxSignedDataLength: 512, - }); - - return ` - let pubkey_modulus_limbs = [${inputs.pubkey_modulus_limbs.join(", ")}]; - let redc_params_limbs = [${inputs.redc_params_limbs.join(", ")}]; - let signature_limbs = [${inputs.signature_limbs.join(", ")}]; - let data: BoundedVec = BoundedVec::from_array([${inputs.data!.storage.filter(s => s !== 0).join(", ")}]); - let base64_decode_offset = ${inputs.base64_decode_offset}; - - let jwt = JWT::init( - data, - base64_decode_offset, - pubkey_modulus_limbs, - redc_params_limbs, - signature_limbs, - ); - - jwt.verify(); - ` -} - -async function generateNoirTestDataPartialHash() { - const { pubkeyJwk, jwt } = await createKeyAndSignData(); - - // Prepare inputs - const inputs = await generateInputs({ - jwt: jwt, - pubkey: pubkeyJwk as JsonWebKey, - shaPrecomputeTillKeys: ["nonce", "email"], - maxSignedDataLength: 256, - }); - - return ` - let pubkey_modulus_limbs = [${inputs.pubkey_modulus_limbs.join(", ")}]; - let redc_params_limbs = [${inputs.redc_params_limbs.join(", ")}]; - let signature_limbs = [${inputs.signature_limbs.join(", ")}]; - let partial_data: BoundedVec = BoundedVec::from_array([${inputs.partial_data!.storage.filter(s => s !== 0).join(", ")}]); - let base64_decode_offset = ${inputs.base64_decode_offset}; - let partial_hash = [${inputs.partial_hash!.join(", ")}]; - let full_data_length = ${inputs.full_data_length}; - - let jwt = JWT::init_with_partial_hash( - partial_data, - partial_hash, - full_data_length, - base64_decode_offset, - pubkey_modulus_limbs, - redc_params_limbs, - signature_limbs, - ); - - jwt.verify(); - ` -} - -generateNoirTestData().then(console.log).catch(console.error); -console.log("\n\n--------------------------------\n\n"); -generateNoirTestDataPartialHash().then(console.log).catch(console.error); - diff --git a/vendor/noir-jwt/js/src/generate-inputs.ts b/vendor/noir-jwt/js/src/generate-inputs.ts deleted file mode 100644 index 12138b7..0000000 --- a/vendor/noir-jwt/js/src/generate-inputs.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { generatePartialSHA256 } from './partial-sha'; - -type GenerateInputsParams = { - jwt: string; - pubkey: JsonWebKey; - shaPrecomputeTillKeys?: string[]; - maxSignedDataLength: number; -} - -type JWTCircuitInputs = { - data?: { - storage: number[]; - len: number; - }; - base64_decode_offset: number; - pubkey_modulus_limbs: string[]; - redc_params_limbs: string[]; - signature_limbs: string[]; - partial_data?: { - storage: number[]; - len: number; - }; - partial_hash?: number[]; - full_data_length?: number; -} - -/* -* Generates circuit inputs required for the jwt lib -* @param {Object} params - The input parameters -* @param {string} params.jwt - The JWT token to process (string) -* @param {JsonWebKey} params.pubkey - The public key to verify the signature (JsonWebKey) -* @param {string[]} params.shaPrecomputeTillKeys - (optional) Key(s) in the payload until which SHA should be precomputed -* @param {number} params.maxSignedDataLength - Maximum length of signed data (with or without partial hash) allowed by the circuit -*/ -export async function generateInputs({ - jwt, - pubkey, - shaPrecomputeTillKeys, - maxSignedDataLength, // when using partial hash, this will be the length of data after partial hash -}: GenerateInputsParams) { - // Parse token - const [headerB64, payloadB64] = jwt.split("."); - - // Extract signed data as byte array - const signedDataString = jwt.split(".").slice(0, 2).join("."); // $header.$payload - const signedData = new TextEncoder().encode(signedDataString) as Uint8Array; - - // Extract signature as bigint - const signatureBase64Url = jwt.split(".")[2]; - const signatureBase64 = signatureBase64Url - .replace(/-/g, "+") - .replace(/_/g, "/"); - - const signature = new Uint8Array( - atob(signatureBase64) - .split("") - .map((c) => c.charCodeAt(0)) - ); - - const signatureBigInt = BigInt("0x" + Array.from(signature).map(b => b.toString(16).padStart(2, '0')).join('')); - - // Extract pubkey modulus as bigint - const pubkeyBigInt = BigInt("0x" + atob(pubkey.n!.replace(/-/g, "+").replace(/_/g, "/")) - .split("") - .map(c => c.charCodeAt(0).toString(16).padStart(2, "0")) - .join("")); - const redcParam = (1n << (2n * 2048n + 4n)) / pubkeyBigInt; // something needed by the noir big-num lib - - const inputs: Partial = { - pubkey_modulus_limbs: splitBigIntToChunks(pubkeyBigInt, 120, 18).map(s => s.toString()), - redc_params_limbs: splitBigIntToChunks(redcParam, 120, 18).map(s => s.toString()), - signature_limbs: splitBigIntToChunks(signatureBigInt, 120, 18).map(s => s.toString()), - }; - - if (!shaPrecomputeTillKeys || shaPrecomputeTillKeys.length === 0) { - // No precompute selector - no need to precompute SHA256 - if (signedData.length > maxSignedDataLength) { - throw new Error("Signed data length exceeds maxSignedDataLength"); - } - const signedDataPadded = new Uint8Array(maxSignedDataLength); - signedDataPadded.set(signedData); - inputs.data = { - storage: Array.from(signedDataPadded), - len: signedData.length, - } - // entire payload is base64 decode-able when not using partial hash - // offset in signed data is the index of payload start - // this can be any multiple of 4 from payload start, if you want to skip some bytes from start - inputs.base64_decode_offset = headerB64.length + 1; - } else { - // Precompute SHA256 of the signed data - // SHA256 is done in 64 byte chunks, so we can hash upto certain portion outside of circuit to save constraints - // Signed data is $headerB64.$payloadB64 - // We need to find the index in B64 payload corresponding to min(hdIndex, nonceIndex) when decoded - // Then we find the 64 byte boundary before this index and precompute the SHA256 upto that - const payloadString = atob(payloadB64); - const indicesOfPrecomputeKeys = shaPrecomputeTillKeys.map((key) => - payloadString.indexOf(`"${key}":`) - ); - const smallerIndex = Math.min(...indicesOfPrecomputeKeys); - const smallerIndexInB64 = Math.floor((smallerIndex * 4) / 3); // 4 B64 chars = 3 bytes - - const sliceStart = headerB64.length + smallerIndexInB64 + 1; // +1 for the '.' - - // Precompute the SHA256 hash - const { partialHash, remainingData } = - await generatePartialSHA256(signedData, sliceStart); - - // Pad to the max length configured in the circuit - if (remainingData.length > maxSignedDataLength) { - throw new Error("remainingData after partial hash exceeds maxSignedDataLength"); - } - - const remainingDataPadded = new Uint8Array(maxSignedDataLength); - remainingDataPadded.set(remainingData); - - inputs.partial_data = { - storage: Array.from(remainingDataPadded), - len: remainingData.length, - }; - inputs.partial_hash = Array.from(partialHash); - inputs.full_data_length = signedData.length; - - // when using partial hash, the data after the partial hash might not be a valid base64 - // we need to find an offset (1, 2, or 3) such that the remaining payload is base64 decode-able - // this is the number that should be added to the "payload chunk that was included in SHA precompute" - // to make it a multiple of 4 - // in other words, if you trim offset number of bytes from the remaining payload, it will be base64 decode-able - const shaCutoffIndex = signedData.length - remainingData.length; - const payloadBytesInShaPrecompute = shaCutoffIndex - (headerB64.length + 1); - const offsetToMakeIt4x = 4 - (payloadBytesInShaPrecompute % 4); - inputs.base64_decode_offset = offsetToMakeIt4x; - } - - return inputs as JWTCircuitInputs; -} - - -/* -* Splits a BigInt into fixed-size chunks -* @param {bigint} bigInt - The BigInt to split -* @param {number} chunkSize - Size of each chunk in bits -* @param {number} numChunks - Number of chunks to split into -* @returns {bigint[]} Array of BigInt chunks -*/ -export function splitBigIntToChunks( - bigInt: bigint, - chunkSize: number, - numChunks: number -) { - const chunks = []; - const mask = (1n << BigInt(chunkSize)) - 1n; - for (let i = 0; i < numChunks; i++) { - const chunk = (bigInt / (1n << (BigInt(i) * BigInt(chunkSize)))) & mask; - chunks.push(chunk); - } - return chunks; -} \ No newline at end of file diff --git a/vendor/noir-jwt/js/src/index.ts b/vendor/noir-jwt/js/src/index.ts deleted file mode 100644 index 898fd6a..0000000 --- a/vendor/noir-jwt/js/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './generate-inputs.js'; -export * from './partial-sha.js'; -// Export any other necessary modules diff --git a/vendor/noir-jwt/js/src/partial-sha.ts b/vendor/noir-jwt/js/src/partial-sha.ts deleted file mode 100644 index 7e544c0..0000000 --- a/vendor/noir-jwt/js/src/partial-sha.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Returns the intermediate SHA256 hash of the data -export async function generatePartialSHA256(data: Uint8Array, hashUntilIndex: number) { - if (typeof data === 'string') { - const encoder = new TextEncoder(); - data = encoder.encode(data); // Convert string to Uint8Array - } - - const blockSize = 64; // 512 bits - const blockIndex = Math.floor(hashUntilIndex / blockSize); - const H = new Uint32Array([ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 - ]); - - for (let i = 0; i < blockIndex; i++) { - if (i * blockSize >= data.length) { - throw new Error('Block index out of range.'); - } - - const block = new Uint8Array(blockSize); - block.set(data.slice(i * blockSize, (i + 1) * blockSize)); - sha256Block(H, block); - } - - // Get the intermediate digest (this is **not** the final hash) - return { - partialHash: H, - remainingData: data.slice(blockIndex * blockSize) - } -} - -/** - * SHA-256 constants (first 32 bits of fractional parts of cube roots of primes) - */ -const K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; - -/** -* Rotate right function (SHA-256 bitwise operations) -*/ -function rotr(n: number, x: number) { - return (x >>> n) | (x << (32 - n)); -} - -/** -* SHA-256 Compression Function (Processes 64-byte blocks) -*/ -function sha256Block(H: Uint32Array, block: Uint8Array) { - let w = new Uint32Array(64); - let a = H[0], b = H[1], c = H[2], d = H[3]; - let e = H[4], f = H[5], g = H[6], h = H[7]; - - // Convert block into 32-bit words - for (let i = 0; i < 16; i++) { - w[i] = (block[i * 4] << 24) | (block[i * 4 + 1] << 16) | (block[i * 4 + 2] << 8) | block[i * 4 + 3]; - } - for (let i = 16; i < 64; i++) { - const s0 = rotr(7, w[i - 15]) ^ rotr(18, w[i - 15]) ^ (w[i - 15] >>> 3); - const s1 = rotr(17, w[i - 2]) ^ rotr(19, w[i - 2]) ^ (w[i - 2] >>> 10); - w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0; - } - - // Main compression loop - for (let i = 0; i < 64; i++) { - const S1 = rotr(6, e) ^ rotr(11, e) ^ rotr(25, e); - const ch = (e & f) ^ (~e & g); - const temp1 = (h + S1 + ch + K[i] + w[i]) >>> 0; - const S0 = rotr(2, a) ^ rotr(13, a) ^ rotr(22, a); - const maj = (a & b) ^ (a & c) ^ (b & c); - const temp2 = (S0 + maj) >>> 0; - - h = g; - g = f; - f = e; - e = (d + temp1) >>> 0; - d = c; - c = b; - b = a; - a = (temp1 + temp2) >>> 0; - } - - // Update intermediate hash values - H[0] = (H[0] + a) >>> 0; - H[1] = (H[1] + b) >>> 0; - H[2] = (H[2] + c) >>> 0; - H[3] = (H[3] + d) >>> 0; - H[4] = (H[4] + e) >>> 0; - H[5] = (H[5] + f) >>> 0; - H[6] = (H[6] + g) >>> 0; - H[7] = (H[7] + h) >>> 0; -} diff --git a/vendor/noir-jwt/js/tsconfig.json b/vendor/noir-jwt/js/tsconfig.json deleted file mode 100644 index 6100264..0000000 --- a/vendor/noir-jwt/js/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "module": "esnext", - "moduleResolution": "node", - "rootDir": "./src", - "outDir": "./dist/esm", - - "declaration": true, - "declarationMap": true, - "declarationDir": "./dist/types", - "sourceMap": true, - - "allowJs": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] -} diff --git a/vendor/noir-rsa/LICENSE b/vendor/noir-rsa/LICENSE new file mode 100644 index 0000000..4495847 --- /dev/null +++ b/vendor/noir-rsa/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 zkpassport + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/noir-rsa/VENDORED_FROM.md b/vendor/noir-rsa/VENDORED_FROM.md new file mode 100644 index 0000000..7658f53 --- /dev/null +++ b/vendor/noir-rsa/VENDORED_FROM.md @@ -0,0 +1,10 @@ +# Vendored: noir_rsa + +- **Source**: https://github.com/zkpassport/noir_rsa +- **Version**: v0.9.1 (with sha512 bumped to v0.1.1 for beta.19 compatibility) +- **License**: MIT (https://github.com/zkpassport/noir_rsa/blob/main/LICENSE) +- **Authors**: [zkpassport](https://zkpassport.id/) + +## Modifications + +- `sha512` dependency bumped from v0.1.0 to v0.1.1 to fix `std::wrapping_add` removal in nargo beta.19.