{"id":15370306,"url":"https://github.com/jedisct1/zig-hpke","last_synced_at":"2025-04-15T13:54:01.303Z","repository":{"id":56735607,"uuid":"353120385","full_name":"jedisct1/zig-hpke","owner":"jedisct1","description":"HPKE implementation for Zig.","archived":false,"fork":false,"pushed_at":"2025-03-02T22:17:40.000Z","size":36,"stargazers_count":17,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-28T20:46:43.700Z","etag":null,"topics":["crypto","hpke","zig","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","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/jedisct1.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2021-03-30T19:36:34.000Z","updated_at":"2025-03-25T05:56:13.000Z","dependencies_parsed_at":"2025-03-02T23:31:21.771Z","dependency_job_id":null,"html_url":"https://github.com/jedisct1/zig-hpke","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fzig-hpke","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fzig-hpke/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fzig-hpke/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fzig-hpke/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jedisct1","download_url":"https://codeload.github.com/jedisct1/zig-hpke/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249085475,"owners_count":21210267,"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","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":["crypto","hpke","zig","zig-package"],"created_at":"2024-10-01T13:40:51.313Z","updated_at":"2025-04-15T13:54:01.279Z","avatar_url":"https://github.com/jedisct1.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HPKE for Zig\n\n`zig-hpke` is an implementation of the [Hybrid Public Key Encryption](https://www.rfc-editor.org/rfc/rfc9180.html) (HPKE) scheme.\n\n## Usage\n\n### Bounded arrays\n\nThis code heavily relies on the `std.BoundedArray` type: a type to store small, variable-sized slices whose maximum size is known.\n\nKeys are typically represented using that type, whose raw slice can be accessed with the `constSlice()` function (for a constant slice), or `slice()` (for a mutable slice).\n\n### Suite instantiation\n\n```zig\nconst suite = try Suite.init(\n    primitives.Kem.X25519HkdfSha256.id,\n    primitives.Kdf.HkdfSha256.id,\n    primitives.Aead.Aes128Gcm.id,\n);\n```\n\n### Key pair creation\n\n```zig\nconst kp = try suite.generateKeyPair();\n```\n\n### Client: creation and encapsulation of the shared secret\n\nA _client_ initiates a connexion by sending an encrypted secret; a _server_ accepts an encrypted secret from a client, and decrypts it, so that both parties can eventually agree on a shared secret.\n\n```zig\nvar client_ctx_and_encapsulated_secret =\n    try suite.createClientContext(server_kp.public_key.slice(), \"info\", null, null);\n\nvar client_ctx = client_ctx_and_encapsulated_secret.client_ctx;\n\nvar encapsulated_secret = client_ctx_and_encapsulated_secret.encapsulated_secret;\n```\n\n* `encapsulated_secret.encapsulated` needs to be sent to the server. `encapsulated_secret.encapsulated.secret` must remain secret.\n* `client_ctx` can be used to encrypt/decrypt messages exchanged with the server.\n\nTo improve misuse resistance, this implementation uses distinct types for the client and the server context: `ClientContext` for the client, and `ServerContext` for the server.\n\n### Server: decapsulation of the shared secret\n\n```zig\nvar server_ctx =\n    try suite.createServerContext(encapsulated_secret.encapsulated.constSlice(), server_kp, \"info\", null);\n```\n\n* `server_ctx` can be used to encrypt/decrypt messages exchanged with the client\n* The last parameter is an optional pre-shared key.\n\n### Encryption of a message from the client to the server\n\nA message can be encrypted by the client for the server:\n\n```zig\nclient_ctx.encryptToServer(\u0026ciphertext, message, ad);\n```\n\nNonces are automatically incremented, so it is safe to call this function multiple times within the same context.\n\nLast parameter is optional associated data.\n\nThe ciphertext is `client_ctx.tagLength()` bytes larger than the message.\n\n### Decryption of a ciphertext received by the server\n\nThe server can decrypt a ciphertext sent by the client:\n\n```zig\nvar message2: [message.len]u8 = undefined;\ntry server_ctx.decryptFromClient(\u0026message2, \u0026ciphertext, ad);\n```\n\nLast parameter is optional associated data. The message length is `server_ctx.tagLength()` bytes shorter than the ciphertext.\n\n### Encryption of a message from the server to the client\n\nA message can also be encrypted by the server for the client:\n\n```zig\nserver_ctx.encryptToClient(\u0026ciphertext, message, ad);\n```\n\nNonces are automatically incremented, so it is safe to call this function multiple times within the same context.\n\nLast parameter is optional associated data.\n\n### Decryption of a ciphertext received by the client\n\nThe client can decrypt an encrypted response from the server:\n\n```zig\ntry client_ctx.decryptFromServer(\u0026message2, \u0026ciphertext, ad);\n```\n\nLast parameter is optional associated data.\n\n## Authenticated modes\n\nAuthenticated modes, with or without a PSK are supported.\n\nSee `createAuthenticatedClientContext` and `createAuthenticatedServerContext`.\n\n### Exporter secret\n\nThe exporter secret can be obtained with the `exportedSecret()` function available both in the `ServerContext` and `ClientContext` structures:\n\n```zig\nconst exporter = client_ctx.exporterSecret().constSlice();\n```\n\n### Key derivation\n\n```zig\nconst secret1 = try client_ctx.exportSecret(\"description 1\")\nconst secret2 = try server_ctx.exportSecret(\"description 2\");\n```\n\n### Access the raw cipher interface\n\n```zig\nconst aead = suite.aead;\n```\n\n## That's it!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedisct1%2Fzig-hpke","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjedisct1%2Fzig-hpke","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedisct1%2Fzig-hpke/lists"}