/greco

Primary LanguageRustMIT LicenseMIT

Greco

Warning

This is a research project and hasn't been audited. Use in production at your own risk.

Circuit for proving the correct encryption under BFV fully homomorphic encryption scheme. Note that this can be also generalized to any RLWE-based algorithms. Paper -> https://eprint.iacr.org/2024/594. The implementation manages the public inputs of the circuit in a slightly different way than the one described in the paper.

Generate Parameters

To generate the parameters for the secret key proof of encryption circuit run the following command:

python3 scripts/circuit_sk.py -n 4096 -qis '[                                      
    27424203952895201, 
    27424203952895203
]' -t 65537

Where -n is the degree of the cyclotomic polynomial that defines the ring, -qis is the list of moduli qis such that qis[i] is the modulus of the i-th CRT basis of the modulus q of the ciphertext space, -t is the plaintext modulus. The value of 𝜎 for the gaussian distribution is set to 3.2 by default.

You can modify these parameters to fit your needs. Note that the python script used to generate the inputs is largely unoptimized and can take a while to run for parameters with large n, since the polynomial multiplication is not done using NTT.

As a result:

  • A file ./src/data/sk_enc_{n}_{qis_len}x{qis_bitsize}_{t}.json is generated including the input to the circuit that can be used for testing for those specific parameters. It includes a random secret key, a random plaintext message and the corresponding ciphertext encrypted under the secret key.
  • A file ./src/data/sk_enc_{n}_{qis_len}x{qis_bitsize}_{t}_zeroes.json is generated. In this file all the coefficients of the input polynomials are set to zero. This input is used at key generation time, when the actual inputs are not known.
  • A file ./src/constants/sk_enc_constants_{n}_{qis_len}x{qis_bitsize}_{t}.rs is generated including the generic constants for the circuit. Note that we separate them from the input because these should be known at compile time.

On top of that, the console will print an estimatation of the number of advice cells needed to compile the circuit in halo2 considering a single advice column and a lookup table of size 2^8. Spoiler: around 90% of the constraints are generated by the range checks on the polynomial coefficients.

Circuit

cargo build
cargo test --release -- --nocapture

The halo2 circuit is based on a fork of axiom-eth that implements two minor changes:

  • RlcCircuit and RlcExecutor are included into a utils mod such that they can be consumed outside of the crate
  • The RlcCircuitInstructions are modified to enable equality constraints on instance column in Second Phase

Benches

To extract the benchmarks run:

cargo test --release bench_sk_enc_full_prover --features bench -- --nocapture

By default, the benchmarks are run on the input data generated by the python script described above. Namely,n = 4096 with 2 qis of 55 bits each and t = 65537. Other test vectors ara available by unzipping src/data/data.zip

To run the benchmarks on different parameters you have to:

  1. Modify the constants being imported at the top of the file. For example use crate::constants::sk_enc_constants_8192_4x55_65537::...
  2. Modify the file_path within bench_sk_enc_full_prover() function to point to the new input data file. For example let file_path = "src/data/sk_enc_8192_4x55_65537.json";

Given the same parameters, the benchmarks will run the prover and verifier for different values of k, where 2**k is the maximum number of rows in the advice columns. After setting a specific k, halo2-lib will configure the circuit accordingly. With less rows at disposal, the configuration will contain more columns, and viceversa.

More columns means more parallelism, which generally means faster proving times. Up to a point. Quoting halo2-lib docs, there is a limit to parallelism, so generally the proving time vs. number of columns plot looks parabolic: as you increase number of columns (while keeping number of cells the same), the proving time will decrease up to a point before starting to increase again.

Results

Benchmarks run on M2 Macbook Pro with 12 cores and 32GB of RAM.

The parameters have been chosen targeting 128-bit security level for different values of n. For more information on parameters choise, please check Homomorphic Encryption Standard.

Given the same parameters, the benchmarks will run the prover and verifier for different values of k, where 2**k is the maximum number of rows in the advice columns. After setting a specific k, halo2-lib will configure the circuit accordingly. With less rows at disposal, the configuration will contain more columns, and viceversa.

More columns means more parallelism, which generally means faster proving times. Up to a point. Quoting halo2-lib docs, there is a limit to parallelism, so generally the proving time vs. number of columns plot looks parabolic: as you increase number of columns (while keeping number of cells the same), the proving time will decrease up to a point before starting to increase again.

For certain parameters, low values of k might result in errors due to the lack of advice columns. That's why for certain parameters the benchmarks start at higher values of k.

N = 1024

python3 scripts/circuit_sk.py -n 1024 -qis '[                                      
    82638181
]' -t 65537
bfv params: "src/data/sk_enc_1024_1x27_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 12 | 490.086041ms       | 104.025833ms       | 805.957292ms          | 5.473208ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 13 | 425.17925ms        | 86.270958ms        | 786.931167ms          | 3.958292ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 420.792916ms       | 93.239208ms        | 836.020791ms          | 3.149542ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 405.360125ms       | 99.7695ms          | 955.489416ms          | 2.868708ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 620.653458ms       | 141.8055ms         | 1.640361125s          | 2.588709ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 907.310042ms       | 235.223167ms       | 2.67054475s           | 2.668542ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 1.641826417s       | 428.383166ms       | 5.120378208s          | 2.77925ms               |
+----+--------------------+--------------------+-----------------------+-------------------------+

N = 2048

python3 scripts/circuit_sk.py -n 2048 -qis '[                                      
    2869751532719597
]' -t 65537
bfv params: "src/data/sk_enc_2048_1x53_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 12 | 1.02548225s        | 220.633042ms       | 1.671973959s          | 8.7885ms                |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 13 | 937.555209ms       | 200.602167ms       | 1.494908333s          | 5.504542ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 826.149709ms       | 198.48025ms        | 1.475256583s          | 4.139916ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 780.143541ms       | 201.493042ms       | 1.532136625s          | 3.031834ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 820.142333ms       | 232.910583ms       | 1.97258525s           | 2.8235ms                |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 1.155686625s       | 311.328625ms       | 3.081958s             | 2.587541ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 1.702295666s       | 499.721792ms       | 5.291279833s          | 2.588834ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+

N = 4096

python3 scripts/circuit_sk.py -n 4096 -qis '[                                      
    27424203952895201, 
    27424203952895203
]' -t 65537
bfv params: "src/data/sk_enc_4096_2x55_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 12 | 3.348614875s       | 774.583583ms       | 5.161994167s          | 21.526084ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 13 | 2.906377042s       | 683.615625ms       | 4.391677667s          | 13.025541ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 2.4261365s         | 645.739291ms       | 4.09474375s           | 8.119833ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 2.269133833s       | 602.751583ms       | 3.734384125s          | 5.128375ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 2.161939667s       | 614.730875ms       | 3.86856775s           | 3.715334ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 1.983521625s       | 617.253042ms       | 4.26015725s           | 2.987833ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 2.683152334s       | 781.056125ms       | 6.43829325s           | 3.073709ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+

N = 8192

python3 scripts/circuit_sk.py -n 8192 -qis '[                                      
    33676195539292805,
    33676195539292807, 
    33676195539292809, 
    33676195539292811
]' -t 65537
bfv params: "src/data/sk_enc_8192_4x55_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 12 | 12.260128667s      | 3.215819459s       | 18.129232625s         | 81.15875ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 13 | 10.736324042s      | 2.808556291s       | 15.87686625s          | 39.417833ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 9.037218833s       | 2.484174917s       | 13.582268708s         | 22.246125ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 6.576586083s       | 2.077855666s       | 10.57232875s          | 10.488208ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 6.135039375s       | 1.919404291s       | 9.59165725s           | 7.775375ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 5.278453s          | 1.899231666s       | 9.79360175s           | 4.564875ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 5.676761667s       | 2.186588542s       | 11.418666042s         | 3.698959ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+

N = 16384

python3 scripts/circuit_sk.py -n 16384 -qis '[                                      
    12905032264241935,
    12905032264241937, 
    12905032264241939, 
    12905032264241941, 
    12905032264241947, 
    12905032264241951, 
    12905032264241953, 
    12905032264241957
]' -t 65537
bfv params: "src/data/sk_enc_16384_8x54_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 13 | 43.515304875s      | 14.407916667s      | 58.255132625s         | 166.599041ms            |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 35.551011334s      | 12.041587959s      | 50.729567334s         | 76.108667ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 28.063048833s      | 9.476986125s       | 40.625269333s         | 34.402ms                |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 24.613478458s      | 8.841772291s       | 36.525364292s         | 19.868333ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 20.710349792s      | 8.064435916s       | 33.025659s            | 10.015ms                |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 17.944376875s      | 7.127217625s       | 31.521722708s         | 7.063ms                 |
+----+--------------------+--------------------+-----------------------+-------------------------+

N = 32768

python3 scripts/circuit_sk.py -n 32768 -qis '[                                      
    477501974462976263,
    477501974462976265,
    477501974462976267,
    477501974462976269,
    477501974462976271,
    477501974462976277,
    477501974462976283,
    477501974462976289,
    477501974462976293,
    477501974462976299,
    477501974462976301,
    477501974462976307,
    477501974462976311,
    477501974462976313,
    477501974462976317
]' -t 65537
bfv params: "src/data/sk_enc_32768_15x59_65537"
+----+--------------------+--------------------+-----------------------+-------------------------+
| K  | VK Generation Time | PK Generation Time | Proof Generation Time | Proof Verification Time |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 14 | 152.501748625s     | 68.303257667s      | 188.803432959s        | 361.9965ms              |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 15 | 126.365190875s     | 53.02766575s       | 163.305771833s        | 154.303292ms            |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 16 | 102.026992625s     | 41.624153458s      | 137.814063958s        | 66.756875ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 17 | 83.088430792s      | 35.14210775s       | 119.241555167s        | 29.228375ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 18 | 69.2703075s        | 30.016031167s      | 105.986900125s        | 13.839083ms             |
+----+--------------------+--------------------+-----------------------+-------------------------+
| 19 | 65.224209125s      | 29.8882395s        | 109.52214475s         | 8.5535ms                |
+----+--------------------+--------------------+-----------------------+-------------------------+