{"id":21388007,"url":"https://github.com/zkpersona/noir-jwt","last_synced_at":"2025-10-04T00:31:34.875Z","repository":{"id":259873973,"uuid":"875042438","full_name":"zkpersona/noir-jwt","owner":"zkpersona","description":"A JWT Verification and Claims Attestation Library for Noir.","archived":false,"fork":false,"pushed_at":"2025-04-11T08:10:01.000Z","size":143,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T09:52:18.759Z","etag":null,"topics":["hmac-sha256","jwt","jwt-verifier","library","noir-lang","rsa-sha256","zero-knowledge"],"latest_commit_sha":null,"homepage":"","language":"Noir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zkpersona.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-19T00:48:21.000Z","updated_at":"2025-04-11T08:19:29.000Z","dependencies_parsed_at":"2024-10-28T15:07:16.222Z","dependency_job_id":"37165ff6-e091-418e-82c9-1ea36d476201","html_url":"https://github.com/zkpersona/noir-jwt","commit_stats":null,"previous_names":["envoy-vc/noir_jwt","zkpersona/noir_jwt","zkpersona/noir-jwt"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/zkpersona/noir-jwt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkpersona%2Fnoir-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkpersona%2Fnoir-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkpersona%2Fnoir-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkpersona%2Fnoir-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zkpersona","download_url":"https://codeload.github.com/zkpersona/noir-jwt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkpersona%2Fnoir-jwt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278249326,"owners_count":25955834,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-03T02:00:06.070Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hmac-sha256","jwt","jwt-verifier","library","noir-lang","rsa-sha256","zero-knowledge"],"created_at":"2024-11-22T12:15:35.465Z","updated_at":"2025-10-04T00:31:34.868Z","avatar_url":"https://github.com/zkpersona.png","language":"Noir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Noir JWT\n\nA JWT Verification and Claims Attestation Library for Noir. This library provides a set of types and functions for verifying different JWT schemes. The current implementation supports the following JWT schemes:\n\n- HMAC-SHA256 (HS256)\n- RSA-SHA256 (RS256 with 2048-bit keys)\n\nJWT structure is defined in JWT struct, which is generic over the signature type, header length, payload length, and signature length. Signature type is either `BoundedVec\u003cu8, MaxSignatureLength\u003e` for HMAC or `BoundedVec\u003cField, MaxSignatureLength\u003e` for RSA.\n\n```noir\npub type Header\u003clet MaxHeaderLength: u32\u003e = BoundedVec\u003cu8, MaxHeaderLength\u003e;\npub type Payload\u003clet MaxPayloadLength: u32\u003e = BoundedVec\u003cu8, MaxPayloadLength\u003e;\npub type Signature\u003cT, let MaxSignatureLength: u32\u003e = BoundedVec\u003cT, MaxSignatureLength\u003e;\n\n\npub struct JWT\u003cT, let MaxHeaderLength: u32, let MaxPayloadLength: u32, let MaxSignatureLength: u32\u003e {\n    pub header: Header\u003cMaxHeaderLength\u003e,\n    pub payload: Payload\u003cMaxPayloadLength\u003e,\n    pub signature: Signature\u003cT, MaxSignatureLength\u003e,\n}\n```\n\n## Installation\n\nIn your _Nargo.toml_ file, add the version of this library you would like to install under dependency:\n\n```toml\n[dependencies]\nnoir_jwt = { tag = \"v0.1.0\", git = \"https://github.com/zkpersona/noir-jwt\", directory = \"lib\" }\n```\n\n## Usage\n\n### HMAC-SHA256 (HS256) Verification\n\n```noir\nuse noir_jwt::JWT_H256 as JWT;\nuse noir_jwt::types::SecretKey;\n\npub global MAX_HEADER_LENGTH: u32 = 64;\npub global MAX_PAYLOAD_LENGTH: u32 = 256;\npub global MAX_SIGNATURE_LENGTH: u32 = 43;\n\npub global MAX_SECRET_KEY_LENGTH: u32 = 64;\n\nfn main(\n    jwt: JWT\u003cMAX_HEADER_LENGTH, MAX_PAYLOAD_LENGTH, MAX_SIGNATURE_LENGTH\u003e,\n    secret_key: SecretKey\u003cMAX_SECRET_KEY_LENGTH\u003e,\n) -\u003e pub bool {\n    jwt.verify(secret_key)\n}\n```\n\n### RSA-SHA256 (RS256) Verification\n\n```noir\nuse noir_jwt::{constants::KEY_LIMBS_2048, JWT_RS256 as JWT, RSAPubkey};\n\npub global MAX_HEADER_LENGTH: u32 = 32;\npub global MAX_PAYLOAD_LENGTH: u32 = 128;\n\nfn main(\n    jwt: JWT\u003cMAX_HEADER_LENGTH, MAX_PAYLOAD_LENGTH\u003e,\n    pub_key: RSAPubkey\u003cKEY_LIMBS_2048\u003e,\n) -\u003e pub bool {\n    jwt.verify(pub_key, 65537)\n}\n```\n\n### Claim Attestation\n\n```noir\nuse base64::BASE64_URL_DECODER::decode_var;\nuse json_parser::JSON1kb;\nuse noir_jwt::JWT_H256 as JWT;\nuse noir_jwt::types::{Payload, SecretKey};\n\npub global MAX_HEADER_LENGTH: u32 = 64;\npub global MAX_PAYLOAD_LENGTH: u32 = 256;\npub global MAX_SIGNATURE_LENGTH: u32 = 43;\n\npub global MAX_SECRET_KEY_LENGTH: u32 = 64;\n\nunconstrained fn parse_json(payload: Payload\u003cMAX_PAYLOAD_LENGTH\u003e) -\u003e JSON1kb {\n    let mut decoded: BoundedVec\u003cu8, (MAX_PAYLOAD_LENGTH * 3) / 4\u003e = decode_var(payload);\n    for _i in decoded.len()..decoded.max_len() {\n        decoded.push(32); // Whitespace character\n    }\n    let json: JSON1kb = JSON1kb::parse_json(decoded.storage());\n    json\n}\n\nfn main(\n    jwt: JWT\u003cMAX_HEADER_LENGTH, MAX_PAYLOAD_LENGTH, MAX_SIGNATURE_LENGTH\u003e,\n    secret_key: SecretKey\u003cMAX_SECRET_KEY_LENGTH\u003e,\n    expected_email: BoundedVec\u003cu8, 64\u003e,\n) -\u003e pub bool {\n    let verified = jwt.verify(secret_key);\n\n    assert(verified);\n\n    /// Safety: Payload is already verified\n    let json: JSON1kb = unsafe { parse_json(jwt.payload) };\n\n    let email: BoundedVec\u003cu8, 64\u003e = json.get_string_unchecked(\"sub\".as_bytes());\n\n    println(expected_email);\n    println(email);\n\n    email == expected_email\n}\n```\n\n### Library Usage\n\nThis library provides a set of helpers functions to generate circuit inputs. To install the library, run the following command:\n\n```bash\nnpm install @zkpersona/noir-jwt\n# or\nyarn add @zkpersona/noir-jwt\n# or\npnpm add @zkpersona/noir-jwt\n# or\nbun add @zkpersona/noir-jwt\n```\n\nHere is an example of how to use the library to generate inputs for H256 proof:\n\n```typescript\nimport type { InputMap } from '@noir-lang/noir_js';\nimport { BoundedVec, U8 } from '@zkpersona/noir-helpers';\nimport { JWT } from '@zkpersona/noir-jwt';\n\nconst jwt = new JWT(\n  'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzQ0MzUxOTAzLCJleHAiOjE3NDQzNTkxMDN9.lKtDhCu1-ejUIEwrXPFWaaEvaXc5qZg1jUfxFxciQJ4'\n);\nconst jwtInputs = jwt.toCircuitInputs({\n  maxHeaderLength: 64,\n  maxPayloadLength: 256,\n  maxSignatureLength: 43,\n});\n\nconst secretKey = Uint8Array.from('secret_key');\n\nconst secretKeyArray = Array.from(secretKey).map((e) =\u003e new U8(e));\nconst secretKeyVec = new BoundedVec(64, () =\u003e new U8(0));\nsecretKeyVec.extendFromArray(secretKeyArray);\n\nconst inputs: InputMap = {\n  ...jwtInputs,\n  secret_key: secretKeyVec.toJSON(),\n};\n```\n\nAnd here is an example of how to use the library to generate inputs for RS256 proof:\n\n```typescript\nimport type { InputMap } from '@noir-lang/noir_js';\nimport { JWT, RSAPubKey } from '@zkpersona/noir-jwt';\n\nconst pubKeyPem = `-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEArlZIVMkJ+pyjixkrQiZXYd3MwbIHUzsFwSCB/rjds1FpfgXAsArG\n8EtyrKfDwZxdccLUGIlmdKO6uurL/wbcJcYxiMcJON5vPXztUAMeCNc6gvmlcsRa\n5V1cdpFcjOsGwJKp/n+iIV5VOODfRdiIcE/YKb7fhCsu8xv03SNgUSi/7cwA+0nZ\n6rzmQuWYYQ0VNMN0YJvFZe3iacjgKtQOlM79E6lD+s3noxp0N8kW+Aefv6lVxUD3\nEbXTyxPSYR8XOrud88rsQqBrKfwz8L+IEk/dx4VVC9jXQAxvJ/NMRrOs3oitq91L\n3R5k630h2aroD2sJi35ooWovymjAlLv+LwIDAQAB\n-----END RSA PUBLIC KEY-----`;\n\nconst jwt = new JWT(\n  'eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzQ0MzUyMTMyLCJleHAiOjE3NDQzNTkzMzJ9.e4wBkSuW7Xpx6oChK7dm9nZG4P6pqsibj54nqQ4Zrt5wAz0Ibeh5MRyv8YMV9TzUE5ta8n9P-EJuqwtPohL2uMuoPwnIxKWXt4qAOtxMkWFLEckHSYoHCXqvph-UyPLbGL2zTSJJP-SgTr7E9Y1bU5qM46oieDiQL0ao4CEk5pXjjH5ueAvyA5jfcNAr2kVYsZh8oFFs00VZcUPUXVyZsfjG7EvZ1O6jQ_nCgYqzpQL-kW9ZI_prSNtvDX4wK1JFMVqXHma7XNbvmZNKSvvWhKw-V-lfL3RgjcrVyZnTV-apaZTr6ihOEXlenyU-zOhRfwzAic9HdFG8DUR6_xVqHA',\n  'RS256'\n);\n\nconst pubKey = RSAPubKey.fromPem(pubKeyPem);\n\nconst jwtInputs = jwt.toCircuitInputs({\n  maxHeaderLength: 32,\n  maxPayloadLength: 128,\n  maxSignatureLength: 18,\n});\n\nconst inputs: InputMap = {\n  ...jwtInputs,\n  ...pubKey.toCircuitInputs(),\n};\n```\n\n## License\n\nThis project is licensed under the MIT License.\n\nSee the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkpersona%2Fnoir-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzkpersona%2Fnoir-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkpersona%2Fnoir-jwt/lists"}