{"id":21527067,"url":"https://github.com/lambdaclass/aes_zero_knowledge_proof_circuit","last_synced_at":"2025-04-09T23:34:27.154Z","repository":{"id":64219944,"uuid":"573059566","full_name":"lambdaclass/AES_zero_knowledge_proof_circuit","owner":"lambdaclass","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-30T21:00:55.000Z","size":194,"stargazers_count":72,"open_issues_count":2,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-04T13:54:21.659Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/lambdaclass.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-12-01T15:59:15.000Z","updated_at":"2025-02-13T21:35:46.000Z","dependencies_parsed_at":"2023-02-17T21:31:20.639Z","dependency_job_id":null,"html_url":"https://github.com/lambdaclass/AES_zero_knowledge_proof_circuit","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2FAES_zero_knowledge_proof_circuit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2FAES_zero_knowledge_proof_circuit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2FAES_zero_knowledge_proof_circuit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2FAES_zero_knowledge_proof_circuit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lambdaclass","download_url":"https://codeload.github.com/lambdaclass/AES_zero_knowledge_proof_circuit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248130239,"owners_count":21052723,"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":[],"created_at":"2024-11-24T01:47:39.418Z","updated_at":"2025-04-09T23:34:27.117Z","avatar_url":"https://github.com/lambdaclass.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AES Encryption circuit\n\nZK-Snark circuit to prove that a given ciphertext is the correct `AES-128` encryption using a certain secret key.\n\nThis first iteration uses ECB as the mode of operation and `Marlin` as the proving system for the circuit. In the future we will support CBC and GCM as alternative modes and `Plonk` as an alternative proving system.\n\n## Circuit Inputs\n\n### Private\n\n- `message`: The message to encrypt. \n- `secret_key`: The secret key used for the AES encryption.\n\n### Public\n- `ciphertext`: The encrypted message. This is public as the entire point of the circuit is for a verifier to be assured that the ciphertext they were given is the correct one.\n\n## Usage\nYou can find an example usage under the `main.rs` module. Below is an explanation of it.\n\nFirst, the proving and verifying keys must be generated. You can generate ones for testing by calling\n\n```rust\nlet (proving_key, verifying_key) = synthesize_keys(message_length)?;\n```\n\nwhere `message_length` is the length of the message to be encrypted. Underneath, this is generating some universal SRS and then deriving the keys from it. In a real world scenario, the SRS should be generated in a secure manner through some setup using MPC.\n\nWith the proving key in hand, a prover calls\n\n```rust\nlet message = [1_u8; 16];\nlet secret_key = [0_u8; 16];\n\nlet proof = encrypt(\u0026message, \u0026secret_key, \u0026primitive_ciphertext, proving_key)?;\n```\n\nwhere `primitive_ciphertext` is a byte slice with the result of the `AES` encryption (under the example there's a helper function for it, but you can use any standard `AES` implementation).\n\nThe prover then hands the resulting proof along with the ciphertext to the verifier, who calls\n\n```rust\nlet result = verify_encryption(\n    verifying_key,\n    \u0026proof,\n    \u0026primitive_ciphertext\n)?;\n\nassert!(result);\n```\n\n## AES Flow\n\n`AES-128` consists of 11 rounds. The secret key is used to derive 11 round keys, one for each round. \n\nEach AES round then takes a message as input and performs the following steps:\n- `Add Round Key`\n- `Sub Bytes`\n- `Shift Rows`\n- `Mix Columns`\n\n## Building Blocks Required\nGiven the above, the building blocks required at the circuit level are the following:\n\n| Building Blocks | Required Primitives |\n| --------------- | ------------------- |\n| AddRoundKey     | `xor`               |\n| SubBytes        | conditional select  |\n| ShiftRows       | Row shifting        |\n| MixColumns      | `addmany`           |\n| KeyDerivation   | All of the above    |\n\n### Add RoundKey\nThis is just an xor of the input against the current round key.\n\n### Sub Bytes\nThis is the so called [Rijndael S-Box](https://en.wikipedia.org/wiki/Rijndael_S-box), a lookup table that has a pretty complicated calculation involving [Rijndael's finite field](https://cryptohack.gitbook.io/cryptobook/symmetric-cryptography/aes/rijndael-finite-field). \n\nInside the circuit, we implement it by instantiating the precomputed table as 256 constants and then using a conditional select operation to do the lookup.\n\n###  Shift Rows\nThis step simply writes the input as a byte matrix and then rotates each row.\n\n### Mix Columns\n`Mix Columns` is essentially multiplying the input by a matrix, only the multiplication is once again performed in [Rijndael's finite field](https://cryptohack.gitbook.io/cryptobook/symmetric-cryptography/aes/rijndael-finite-field).\n\n### Key Derivation\nThe key derivation is the most complex step, but it's ultimately just a combination of all the basic operations used in the four steps for every round.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Faes_zero_knowledge_proof_circuit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flambdaclass%2Faes_zero_knowledge_proof_circuit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Faes_zero_knowledge_proof_circuit/lists"}