[{"content":"MAYA: A Short Shuffle Argument With Fast Verification Authors: Thi Van Thao Doan, Olivier Pereira, and Thomas Peters\nAffiliation: UCLouvain, B-1348 Louvain-la-Neuve, Belgium\nPublished at: 33rd ACM Conference on Computer and Communications Security (CCS'26), to appear.\nAbstract Shuffle arguments dominate the audit data in end-to-end verifiable elections when homomorphic tallying is not applicable. Deployed mixnets in countries like Australia, Estonia, Israel, Norway, Spain, and Switzerland produce proofs that scale linearly, reaching gigabytes for millions of ciphertexts. MAYA achieves O(log n) communication complexity with a transparent setup requiring no trusted parameters.\nDownload Download PDF Citation @inproceedings{maya2026, title = {MAYA: A Short Shuffle Argument With Fast Verification}, author = {Doan, Thi Van Thao and Pereira, Olivier and Peters, Thomas}, booktitle = {Proceedings of the 2026 ACM SIGSAC Conference on Computer and Communications Security (CCS \u0026#39;26)}, publisher = {ACM}, year = {2026} } Key Contributions Computational parameter optimization (k=4 folding factor) Iterative padding with bounded overhead Aggregated argument batching (1.5x reduction in recursive prover time) Bridged consistency for aggregated commitments Production-scale evaluation on Ristretto255 and P-256 The performance figures shown on this website (see the home page) are better than those reported in the CCS \u0026lsquo;26 paper. The protocol itself is unchanged; the improvements come from implementation optimizations made after the paper was written.\n","permalink":"https://thaodoanvan.github.io/maya_website/paper/","summary":"\u003ch1 id=\"maya-a-short-shuffle-argument-with-fast-verification\"\u003eMAYA: A Short Shuffle Argument With Fast Verification\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eAuthors:\u003c/strong\u003e Thi Van Thao Doan, Olivier Pereira, and Thomas Peters\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eAffiliation:\u003c/strong\u003e UCLouvain, B-1348 Louvain-la-Neuve, Belgium\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003ePublished at:\u003c/strong\u003e 33rd ACM Conference on Computer and Communications Security\n(\u003ca href=\"https://www.sigsac.org/ccs/CCS2026/call-for/call-for-papers.html\"\u003eCCS'26\u003c/a\u003e),\nto appear.\u003c/p\u003e\n\u003ch2 id=\"abstract\"\u003eAbstract\u003c/h2\u003e\n\u003cp\u003eShuffle arguments dominate the audit data in end-to-end verifiable elections\nwhen homomorphic tallying is not applicable. Deployed mixnets in countries\nlike Australia, Estonia, Israel, Norway, Spain, and Switzerland produce\nproofs that scale linearly, reaching gigabytes for millions of ciphertexts.\nMAYA achieves O(log n) communication complexity with a transparent setup\nrequiring no trusted parameters.\u003c/p\u003e","title":"Paper"},{"content":"The MAYA Verifier Specification is a complete, language-agnostic verification procedure. Together with the election record, it enables an independent developer to write a working verifier from scratch, in any programming language, without access to the MAYA source code or the research paper.\nSpecification Documents VersionSpecificationDate 1.0 Download September 2026 The specification defines the exact binary format of all data, the deterministic derivation of public parameters, the hash-based Fiat–Shamir transcript protocol, and the step-by-step verification algorithm. What the Specification Covers Group and scalar arithmetic for Ristretto255 (Section 3) Data formats and serialization (Section 4) Deterministic generator derivation / CRS (Section 5) Hash computation and Fiat–Shamir transcript (Section 6) Challenge vector derivation (Section 7) Complete verification algorithm in 6 steps (Section 8) IPA and eCP sub-protocols (Sections 9–10) Test vectors for every intermediate computation (Section 11) Test Vectors Section 11 of the specification provides reference values for every intermediate computation a verifier performs, so that each stage can be validated independently before moving to the next. A mismatch at any stage pinpoints the module that needs fixing.\nThe reference test case is a shuffle of n = 4 ciphertexts with folding factor k = 2, recursion depth d = 2, and base-case parameter m = 1, under the permutation π = (1, 3, 0, 2). Every value is printed as 64 hexadecimal characters encoding 32 bytes in byte order. Both the transcript and the prover\u0026rsquo;s random-number generator were initialized with fixed seeds, so the values are reproducible on every run.\nStageWhat to compareSection CRS generatorsB_blinding, F, first 4 of g and h11.5–11.6 Challenge vector eFirst 4 entries11.7 Transcript challengesy, z, x, x', x_ipp, w_agg11.8 Flattened weightsw_L, w_R, w_O, w_V, w_c for n = 411.9 Proof parsingProof header, IPA and eCP sub-proofs11.10–11.12 IPA scalar expansions_g, s_h vectors11.13 eCP scalar expansionCorresponding vectors11.14 Mega-MSM result32 zero bytes (the group identity)11.17 The binary test election record is not yet published. Until it is, the hexadecimal values in Section 11 are sufficient to construct the input by hand and to check every stage of an implementation.\nByte-Level Reproducibility Two conforming implementations in different languages must produce identical accept/reject decisions on identical input bytes. Every array length is stated and must be verified; every scalar and group element is checked for canonicality. This is what makes the specification, rather than any particular codebase, the reference for what a valid MAYA proof is.\n","permalink":"https://thaodoanvan.github.io/maya_website/specification/","summary":"\u003cp\u003eThe MAYA Verifier Specification is a complete, language-agnostic verification\nprocedure. Together with the election record, it enables an independent\ndeveloper to write a working verifier from scratch, in any programming\nlanguage, without access to the MAYA source code or the research paper.\u003c/p\u003e\n\u003ch2 id=\"specification-documents\"\u003eSpecification Documents\u003c/h2\u003e\n\u003cfigure class=\"data-table simple\"\u003e\n\u003cdiv class=\"table-scroll\"\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\u003cth\u003eVersion\u003c/th\u003e\u003cth\u003eSpecification\u003c/th\u003e\u003cth\u003eDate\u003c/th\u003e\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e1.0\u003c/td\u003e\u003ctd\u003e\u003ca class=\"dl-link\" href=\"/maya_website/spec/maya_verifier_spec_v1.pdf\" download\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\u003cpath d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/\u003e\u003cpolyline points=\"7 10 12 15 17 10\"/\u003e\u003cline x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"/\u003e\u003c/svg\u003eDownload\u003c/a\u003e\n\u003c/td\u003e\u003ctd\u003eSeptember 2026\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c/figure\u003e\nThe specification defines the exact binary format of all data, the\ndeterministic derivation of public parameters, the hash-based Fiat–Shamir\ntranscript protocol, and the step-by-step verification algorithm.\n\u003ch2 id=\"what-the-specification-covers\"\u003eWhat the Specification Covers\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eGroup and scalar arithmetic for Ristretto255 (Section 3)\u003c/li\u003e\n\u003cli\u003eData formats and serialization (Section 4)\u003c/li\u003e\n\u003cli\u003eDeterministic generator derivation / CRS (Section 5)\u003c/li\u003e\n\u003cli\u003eHash computation and Fiat–Shamir transcript (Section 6)\u003c/li\u003e\n\u003cli\u003eChallenge vector derivation (Section 7)\u003c/li\u003e\n\u003cli\u003eComplete verification algorithm in 6 steps (Section 8)\u003c/li\u003e\n\u003cli\u003eIPA and eCP sub-protocols (Sections 9–10)\u003c/li\u003e\n\u003cli\u003eTest vectors for every intermediate computation (Section 11)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"test-vectors\"\u003eTest Vectors\u003c/h2\u003e\n\u003cp\u003eSection 11 of the specification provides reference values for every\nintermediate computation a verifier performs, so that each stage can be\nvalidated independently before moving to the next. A mismatch at any stage\npinpoints the module that needs fixing.\u003c/p\u003e","title":"Verifier Specification"},{"content":"Real-world election systems rarely fit the standard cryptographic model of a single list of ciphertexts encrypted under one public key. In practice, ciphertexts may need to remain grouped by precinct or municipality, different groups may use different encryption keys, and shuffling may be combined with partial decryption or secret exponentiation.\nMAYAsk — MAYA Swiss-Knife — is the extended construction that accommodates these settings while preserving the properties of the base protocol. Specifically, it gives logarithmic-size arguments for block-respecting shuffles, shuffles of ciphertexts encrypted under different public keys, shuffles combined with partial decryption using a mixer\u0026rsquo;s secret-key share, and shuffles combined with secret exponentiation of selected ciphertext components. In all cases the resulting arguments retain logarithmic size in the number of ciphertexts, require a transparent setup, and have verification dominated by a single multi-scalar multiplication.\nExtensions Block permutations. Proves that ballots are shuffled strictly within their designated blocks — municipalities, precincts, or ballot styles — without crossing boundaries. Blocks may be uniform or of differing sizes.\nMultiple keys. Supports federated settings where different districts encrypt ballots under entirely independent public keys.\nShuffle-and-exponentiate. Allows a mixer to apply a publicly anchored secret exponentiation during the shuffle, as required by oblivious PRF evaluation, plaintext-equivalence tests, and the DbleMixExp operation of recent Swiss Post proposals.\nDecryption mixnets. Enables each mix server to verifiably strip a layer of encryption while shuffling, removing the need for a separate decryption phase. Threshold key sharing is fully supported.\nAll four preserve MAYA\u0026rsquo;s $O(\\log n)$ proof size. Adding block structures or multiple keys incurs essentially zero overhead compared to the base protocol; the decryption mixnet adds about 7% to multi-threaded prover time, and shuffle-and-exponentiate carries a moderate overhead from its extra exponentiation and doubled ciphertext count.\nThe paper is not yet publicly available. It will be linked here once it is.\nPerformance ScenarionProver (s)Verifier (s) \u0026Pi;1: Uniform blocks, single key 1k \u0026times; 2020k1.3 / 3.90.33 / 0.97 1k \u0026times; 8080k5.6 / 15.41.3 / 3.9 1k \u0026times; 320320k22.2 / 62.35.1 / 14.5 10k \u0026times; 20200k13.9 / 38.43.2 / 9.7 1 \u0026times; 200k (MAYA)200k13.2 / 39.73.1 / 9.1 10k \u0026times; 80800k55.5 / 165.812.7 / 38.8 100k \u0026times; 202M138.3 / 391.531.5 / 97.1 \u0026Pi;2: Heterogeneous blocks, single key 1k \u0026times; [50, 150]200k13.5 / 44.43.1 / 9.1 20k \u0026times; [2, 3, 5]200k13.7 / 44.43.1 / 9.2 80k \u0026times; [3, 7]800k54.8 / 159.712.6 / 39.7 \u0026Pi;3: Multiple keys Key 1: 1k \u0026times; [37, 63]\nKey 2: 500 \u0026times; [149, 14, 37]200k13.2 / 38.63.2 / 10.4 Key 1: 10k \u0026times; [5]\nKey 2: 3.5k \u0026times; [3, 7, 10]\nKey 3: 20k \u0026times; [2, 2]200k13.7 / 40.233.1 / 9.75 Keys 1\u0026ndash;100: 1k \u0026times; [2]200k13.6 / 40.192.3 / 9.68 \u0026Pi;4: Decryption mixnet (one mixer) 10k \u0026times; 20200k14.9 / 45.03.1 / 9.6 \u0026Pi;5: Shuffle-and-exponentiate (DbleMixExp) 5k \u0026times; 20200k8.9 / 27.62.5 / 7.2 10k \u0026times; 20400k19.5 / 55.15.0 / 14.4 Table 1. Performance of the MAYA extensions for a shuffle of n ciphertexts. Timings are measured end-to-end and in seconds as MT / ST. B × b: B blocks (e.g., districts) of b ciphertexts each. B × [b1, b2, …]: B groups, each partitioned into sub-blocks of sizes bj. For Π3, each entry describes an entity operating under an independent key with its own block structure. For Π4, we report one mix server\u0026rsquo;s shuffle-and-partial-decryption step. For Π5, n = 2Bb since each entry produces two ciphertexts (one per key).\nAll variants were implemented in Rust on top of the MAYA reference implementation, using curve25519-dalek over Ristretto255 at 128-bit security with folding factor k=4, on the hardware described on the home page. Timings include all cryptographic operations, CRS regeneration, and disk I/O.\nThe source code for all four extensions is at uclcrypto/maya_extensions, which is also the current MAYA implementation. See the Changelog.\nProof sizes remain logarithmic across all variants. At n = 200,000 the measured sizes are 6,176 bytes for the single-key variants Π1 and Π2; 6,272 bytes for two keys, growing by 96 bytes per additional key up to 15,680 bytes for 100 keys (Π3); 6,224 bytes for Π4; and 6,320 bytes for Π5. At n = 2,000,000 the Π1 proof is 7,328 bytes.\n","permalink":"https://thaodoanvan.github.io/maya_website/mayask/","summary":"\u003cp\u003eReal-world election systems rarely fit the standard cryptographic model of a\nsingle list of ciphertexts encrypted under one public key. In practice,\nciphertexts may need to remain grouped by precinct or municipality, different\ngroups may use different encryption keys, and shuffling may be combined with\npartial decryption or secret exponentiation.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eMAYAsk\u003c/strong\u003e — MAYA Swiss-Knife — is the extended construction that accommodates\nthese settings while preserving the properties of the base protocol.\nSpecifically, it gives logarithmic-size arguments for block-respecting\nshuffles, shuffles of ciphertexts encrypted under different public keys,\nshuffles combined with partial decryption using a mixer\u0026rsquo;s secret-key share,\nand shuffles combined with secret exponentiation of selected ciphertext\ncomponents. In all cases the resulting arguments retain logarithmic size in\nthe number of ciphertexts, require a transparent setup, and have verification\ndominated by a single multi-scalar multiplication.\u003c/p\u003e","title":"MAYAsk: Swiss-Knife Extensions"},{"content":"The MAYA verifier can be built and tested incrementally. Each step below produces a testable output that can be validated against the test vectors in the specification before moving to the next. You can implement the verifier in any programming language.\nWhere the Proof Comes From A verifier reads two inputs:\nThe input ciphertexts file, taken from the bulletin board or from the previous mix layer. It carries the number of ciphertexts n, the two coordinate vectors of the input ciphertexts, and the public key (g, f, h). The proof bundle, produced by the mix server that performed the shuffle. It carries the serialized proof, the vector commitment V, and the coordinate vectors of the output ciphertexts. Both files are plain binary with the layout fixed in Section 4 of the specification, and both must have exactly the length implied by their declared counters. An implementation may read the same fields from a database or a network API instead, as long as every field is present and every structural check is applied.\nTo generate a bundle to test against, run the MAYA prover from the reference implementation. Nothing about the proof is tied to that implementation or to Rust: the verification procedure is fully deterministic, so any two conforming verifiers, in any two languages, return the same accept/reject decision on the same input bytes.\nPrerequisites The Verifier Specification document The test vectors in Section 11 of the specification A Ristretto255 library for your language: Rust: curve25519-dalek Go: filippo.io/edwards25519 Python: pysodium (libsodium bindings) JavaScript: ristretto255-js C: libsodium (Ristretto255 support since v1.0.18) An HMAC-SHA-256 implementation. This is the only hash primitive the specification uses, and it is available in the standard libraries of C (OpenSSL), Python, Go, Java 9+, and Rust. Implementation Steps Step 1: Scalar and Point I/O (Spec Sections 3, 4.1) Implement scalar encoding/decoding, point compression/decompression, and canonicality checks for Ristretto255. Test: Decode the test-vector scalars and points; confirm round-trip encoding. Step 2: CRS Generators (Spec Section 5) Implement HMAC-SHA-256 in counter mode, the FromUniformBytes hash-to-group map, and the Pedersen/Bulletproof generator derivation. Test: Compare B_blinding, F, and the first 4 entries of g and h against the test vectors in Section 11.5-11.6. Step 3: HMAC Transcript (Spec Section 6) Implement the HMAC-SHA-256 transcript state machine (init, append, challenge). Test: Replay the test-vector transcript and compare each derived challenge (y, z, x, \u0026hellip;) against Section 11.8. Step 4: Challenge Vector e (Spec Section 7) Implement the dedicated transcript and counter-mode HMAC expansion. Test: Compare the first 4 entries of e against Section 11.7. Step 5: Election Record Parser (Spec Section 4) Parse the input ciphertexts file and proof bundle. Run all structural validation checks (file lengths, n \u0026gt;= 2, k in {2,3,4,5,6,8,16}, point decompression, scalar canonicality). Test: Successfully parse the n=4 test election record. Step 6: Constraint Flattening (Spec Section 8.3) Build the permutation circuit and compute the weight vectors w_L, w_R, w_O, w_V, w_c. Test: Compare flattened weights against Section 11.9. Step 7: IPA Scalar Expansion (Spec Section 9) Implement the IPA verification-scalars function: replay the IPA sub-transcript, expand the final witness back to n dimensions. Test: Compare against Section 11.13. Step 8: eCP Scalar Expansion (Spec Section 10) Same as Step 7 for the eCP sub-protocol. Test: Compare against Section 11.14. Step 9: Mega-MSM Assembly (Spec Sections 8.5-8.6) Compute all batched scalars, assemble the point/scalar vectors, execute the MSM, and check identity. A variable-time MSM is fine here: every input to the verifier is public. Test: The Mega-MSM result must be 32 zero bytes (the Ristretto255 identity). If so, the proof is Accepted. A Note on What the Verifier Must Not Trust Every byte of the election record and the proof is treated as potentially adversarial. The verifier must recompute the CRS generators and all challenges itself, and must never accept generators, challenge vectors, or challenge scalars supplied in the input data. This is also why the specification mandates explicit bounds checks, canonical scalar checks, and decompression checks on every field.\nWhat Comes Next Once your verifier accepts the n=4 test case, we recommend trying it against larger test cases (n=100, n=1000) and against malformed proofs, which exercise the rejection paths that the n=4 case never reaches. If you complete an independent verifier, we would like to hear about it — open an issue on the repository.\n","permalink":"https://thaodoanvan.github.io/maya_website/getting-started/","summary":"\u003cp\u003eThe MAYA verifier can be built and tested incrementally. Each step below\nproduces a testable output that can be validated against the test vectors\nin the specification before moving to the next. You can implement the\nverifier in any programming language.\u003c/p\u003e\n\u003ch2 id=\"where-the-proof-comes-from\"\u003eWhere the Proof Comes From\u003c/h2\u003e\n\u003cp\u003eA verifier reads two inputs:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eThe \u003cstrong\u003einput ciphertexts file\u003c/strong\u003e, taken from the bulletin board or from the\nprevious mix layer. It carries the number of ciphertexts n, the two\ncoordinate vectors of the input ciphertexts, and the public key (g, f, h).\u003c/li\u003e\n\u003cli\u003eThe \u003cstrong\u003eproof bundle\u003c/strong\u003e, produced by the mix server that performed the\nshuffle. It carries the serialized proof, the vector commitment V, and the\ncoordinate vectors of the output ciphertexts.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eBoth files are plain binary with the layout fixed in Section 4 of the\nspecification, and both must have exactly the length implied by their declared\ncounters. An implementation may read the same fields from a database or a\nnetwork API instead, as long as every field is present and every structural\ncheck is applied.\u003c/p\u003e","title":"Getting Started: Build Your Own Verifier"},{"content":"MAYA is implemented in Rust with two curve instantiations. The source code accompanies the research paper.\nThe current artifact reproduces the performance measurements reported in the paper. A public API for allowing users to shuffle their own ciphertexts is still under development. Once available, this page will be updated with the corresponding usage instructions and commands.\nRepositories Repository Contents maya_shuffle_proof The code evaluated in the paper, as maya_ristretto (Ristretto255, curve25519-dalek) and maya_p256 (NIST P-256, arkworks) maya_extensions The current implementation, together with the MAYAsk protocols See the Changelog for what changed between them. The commands below are for maya_shuffle_proof.\nRequirements Hardware: x86-64 CPU, minimum 8 GB RAM (16 GB recommended) Software: Rust \u0026gt;= 1.81 (install via rustup.rs) Quick Start cd maya_ristretto cargo build --release --features yoloproofs,parallel QUICK=1 cargo bench --bench r1cs --features yoloproofs,parallel Reproducing the benchmarks cd maya_ristretto # Single-threaded cargo bench --bench r1cs --features yoloproofs # Multi-threaded cargo bench --bench r1cs --features yoloproofs,parallel Repository Structure maya_ristretto/ # Primary instantiation src/ # Library source benches/r1cs.rs # Benchmark maya_p256/ # Secondary instantiation src/ # Library source benches/r1cs.rs # Benchmark ","permalink":"https://thaodoanvan.github.io/maya_website/code/","summary":"\u003cp\u003eMAYA is implemented in Rust with two curve instantiations. The source code\naccompanies the research paper.\u003c/p\u003e\n\u003cp\u003eThe current artifact reproduces the performance measurements reported in the paper. A public API for allowing users to shuffle their own ciphertexts is still under development. Once available, this page will be updated with the corresponding usage instructions and commands.\u003c/p\u003e\n\u003ch2 id=\"repositories\"\u003eRepositories\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eRepository\u003c/th\u003e\n          \u003cth\u003eContents\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"https://github.com/uclcrypto/maya_shuffle_proof\"\u003emaya_shuffle_proof\u003c/a\u003e\u003c/td\u003e\n          \u003ctd\u003eThe code evaluated in the paper, as \u003ccode\u003emaya_ristretto\u003c/code\u003e (Ristretto255, curve25519-dalek) and \u003ccode\u003emaya_p256\u003c/code\u003e (NIST P-256, arkworks)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ca href=\"https://github.com/uclcrypto/maya_extensions\"\u003emaya_extensions\u003c/a\u003e\u003c/td\u003e\n          \u003ctd\u003eThe current implementation, together with the MAYAsk protocols\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eSee the \u003ca href=\"/maya_website/changelog/\"\u003eChangelog\u003c/a\u003e for what changed between\nthem. The commands below are for \u003ccode\u003emaya_shuffle_proof\u003c/code\u003e.\u003c/p\u003e","title":"Code \u0026 Repositories"},{"content":"Two versions of the MAYA implementation are public.\nVersion 2 — current (August 2026) uclcrypto/maya_extensions\nOne hash function. Version 1 used three primitives: a Merlin transcript for Fiat–Shamir, SHA3-512 for the Pedersen generators, and SHAKE256 for the Bulletproof generators. Version 2 uses HMAC-SHA-256 for all three. HMAC-SHA-256 is in the standard library of every mainstream language, so a verifier can be written in any of them without reproducing a Rust-specific transcript construction.\nExtensions. This repository also contains the five MAYAsk protocols. Plain MAYA is Π1 with a single block.\nBenchmarks. The performance table on the home page was produced by this repository, by the Π1 benchmark in pi1_pi2_pi3/benches/pi1.rs. Each configuration is a triple (k, B, b): folding factor, number of blocks, block size. The table uses a single block, so b is the number of ciphertexts. The configurations are set in the configs list in custom_benchmark:\n(4, 1, 1_000), (4, 1, 10_000), (4, 1, 100_000), (4, 1, 1_000_000) cd pi1_pi2_pi3 cargo bench --bench pi1 --features yoloproofs,parallel # multi-threaded cargo bench --bench pi1 --features yoloproofs # single-threaded Version 1 — CCS \u0026lsquo;26 artifact (May 2026) uclcrypto/maya_shuffle_proof\nThe code evaluated in the Paper. It reproduces the measurements reported there. Ristretto255 and P-256.\nWhich version to use Reproducing the paper\u0026rsquo;s tables: version 1. Blocks, multiple keys, or decryption mixnets: version 2. ","permalink":"https://thaodoanvan.github.io/maya_website/changelog/","summary":"\u003cp\u003eTwo versions of the MAYA implementation are public.\u003c/p\u003e\n\u003ch2 id=\"version-2--current-august-2026\"\u003eVersion 2 — current (August 2026)\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/uclcrypto/maya_extensions\"\u003euclcrypto/maya_extensions\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eOne hash function.\u003c/strong\u003e Version 1 used three primitives: a Merlin transcript for\nFiat–Shamir, SHA3-512 for the Pedersen generators, and SHAKE256 for the\nBulletproof generators. Version 2 uses HMAC-SHA-256 for all three. HMAC-SHA-256\nis in the standard library of every mainstream language, so a verifier can be\nwritten in any of them without reproducing a Rust-specific transcript\nconstruction.\u003c/p\u003e","title":"Changelog"},{"content":"MAYA is developed at UCLouvain (Université catholique de Louvain), Louvain-la-Neuve, Belgium.\nThi Van Thao Doan — Researcher, UCLouvain Olivier Pereira — Professor, UCLouvain Thomas Peters — Professor, UCLouvain Contact For questions about the MAYA specification, implementation, or to report issues, please open an issue on the GitHub repository or contact the team at UCLouvain.\nAcknowledgments This work has been funded in part by the Walloon Region through the project CyberExcellence (convention number 2110186).\n","permalink":"https://thaodoanvan.github.io/maya_website/team/","summary":"\u003cp\u003eMAYA is developed at UCLouvain (Université catholique de Louvain),\nLouvain-la-Neuve, Belgium.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eThi Van Thao Doan\u003c/strong\u003e — Researcher, UCLouvain\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eOlivier Pereira\u003c/strong\u003e — Professor, UCLouvain\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eThomas Peters\u003c/strong\u003e — Professor, UCLouvain\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"contact\"\u003eContact\u003c/h2\u003e\n\u003cp\u003eFor questions about the MAYA specification, implementation, or to report\nissues, please open an issue on the GitHub repository or contact the team\nat UCLouvain.\u003c/p\u003e\n\u003ch2 id=\"acknowledgments\"\u003eAcknowledgments\u003c/h2\u003e\n\u003cp\u003eThis work has been funded in part by the Walloon Region through the project\nCyberExcellence (convention number 2110186).\u003c/p\u003e","title":"Team"},{"content":"What is MAYA? MAYA is a shuffle argument with O(log n) communication complexity and a transparent setup. It proves that a mix server correctly permuted and re-randomized a list of ElGamal ciphertexts without altering, adding, or dropping any vote.\nWhat curves does MAYA support? MAYA is instantiated on two curves: Ristretto255 (Curve25519, via curve25519-dalek) and NIST P-256 (via arkworks). The protocol is algebraically generic and can be adapted to other prime-order groups.\nWhat is the trust model? MAYA uses a transparent (public-coin) setup requiring no trusted parameters. The only inputs taken on faith are the group definition and the specification itself.\nCan MAYA handle ciphertexts that carry more than one encrypted value? Yes. Some elections encrypt a whole vector of values under one randomness and several public keys at once, so that a single ciphertext is a wide row rather than a pair of group elements. MAYA generalizes to that setting: the permutation part of the argument is untouched, and only the part that ties the shuffled ciphertexts back to the permutation has to account for the extra columns. The prover sends a few more group elements up front, one per extra column, but the recursive part of the argument does not grow at all, so the proof stays logarithmic in the number of ciphertexts. See the Paper for the construction.\nCan MAYA handle non-power-of-2 ciphertext counts? Yes. MAYA uses iterative padding, which pads incrementally at each recursion level to a multiple of k, bounding total overhead to O(log_k n) additional elements regardless of how n aligns with powers of k.\nWhat folding factor should I use? k=4 is the recommended sweet spot. It reduces prover time by ~10% compared to binary folding (k=2) by halving recursion depth while avoiding the arithmetic overhead of larger radices (k \u0026gt;= 8).\nDoes checking a proof require Rust, or any particular language? No. A MAYA proof is a sequence of bytes, and verification is a deterministic computation over those bytes. The specification fixes the binary formats, the generator derivation, and the Fiat-Shamir transcript exactly, so any two conforming verifiers — whatever language they are written in — return the same accept/reject decision on the same input. The reference implementation happens to be Rust; nothing in the proof depends on that.\nCan I check a MAYA proof myself? Yes, and that is a primary design goal. Checking a proof means running a verifier over the published election record; anyone can run one, and anyone can build one. You do not have to trust the software we wrote: the Verifier Specification describes the whole procedure in plain, language-agnostic terms, with test vectors at every step, so an independent developer can write a verifier from scratch and you can compare its verdict against ours. The Getting Started page walks through that, one testable step at a time.\nWhat is out of scope for the MAYA verifier? The verifier does not cover: ElGamal key generation, plaintext vote validity, decryption of the final ciphertext list, or bulletin board consistency. A MAYA proof only shows that the output is a correct shuffle of the input for the given public key.\n","permalink":"https://thaodoanvan.github.io/maya_website/faq/","summary":"\u003ch3 id=\"what-is-maya\"\u003eWhat is MAYA?\u003c/h3\u003e\n\u003cp\u003eMAYA is a shuffle argument with O(log n) communication complexity and a\ntransparent setup. It proves that a mix server correctly permuted and\nre-randomized a list of ElGamal ciphertexts without altering, adding,\nor dropping any vote.\u003c/p\u003e\n\u003ch3 id=\"what-curves-does-maya-support\"\u003eWhat curves does MAYA support?\u003c/h3\u003e\n\u003cp\u003eMAYA is instantiated on two curves: Ristretto255 (Curve25519, via\ncurve25519-dalek) and NIST P-256 (via arkworks). The protocol is\nalgebraically generic and can be adapted to other prime-order groups.\u003c/p\u003e","title":"FAQ"}]