Encryption times and sizes of serialized encrypted values

Hi,

Today was released concrete-ml 0.3.0 and I would like to ask some doubts related to time execution and size of encrypted values.

First, I used the example from the Concrete-ml GitHub repository. Then, I edited the file circuit.py, specifically the encrypt_run_decrypt function like this:

def encrypt_run_decrypt(self, *args: Any) -> Any:
    """
    Encrypt inputs, run the circuit, and decrypt the outputs in one go.

    Args:
        *args (Union[int, numpy.ndarray]):
            inputs to the circuit

    Returns:
        Union[int, np.ndarray, Tuple[Union[int, np.ndarray], ...]]:
            clear result of homomorphic evaluation
    """

    if self.configuration.virtual:
        return self.graph(*args)

    print("Values:", *args)
    
    start_time_encrypt = time.time()
    public_args = self.encrypt(*args)        
    print("--- %s seconds encrypt ---" % (time.time() - start_time_encrypt))

    print("Size of encrypted values:", sys.getsizeof(public_args.serialize()))

    start_time_run = time.time()
    encrypted_result = self.run(public_args)
    print("--- %s seconds run ---" % (time.time() - start_time_run))

    start_time_decrypt = time.time()
    decrypted_result = self.decrypt(encrypted_result)
    print("--- %s seconds decrypt ---" % (time.time() - start_time_decrypt))

    return decrypted_result
    #return self.decrypt(self.run(self.encrypt(*args)))

And these are the results (Only the first three elements):

Values: [[25 25 19  9]]
--- 68.07132411003113 seconds (encrypt) ---
Size of encrypted values: 65633
--- 0.6150095462799072 seconds (run) ---
--- 0.000396728515625 seconds (decrypt) ---
Values: [[ 5  6 16 20]]
--- 0.004143953323364258 seconds (encrypt) ---
Size of encrypted values: 65633
--- 0.6125960350036621 seconds (run) ---
--- 0.0003757476806640625 seconds (decrypt) ---
Values: [[ 5 10 28  6]]
--- 0.004086494445800781 seconds (encrypt) ---
Size of encrypted values: 65633
--- 0.6059427261352539 seconds (run) ---
--- 0.0003662109375 seconds (decrypt) ---
...

Doubts:

  1. Why is the first encrytion so much longer than the rest?
  2. Why is the encrypted size the same if the values are different? What does the size depend on?
  3. Is there an error in my edited code?

Thank you very much. I greatly appreciate your effort in adding functionalities to the library.

1 Like

Hey,

you’re quite fast in adopting new releases! We haven’t even finished to polish the doc (some links will be edited tomorrow)

So:

  1. the first encryption actually hides the key generation: if you generate the key explicitly before, you’ll see that it is not negligible and that then, all the encryptions are at the same speed
  2. why would a size depend on values? I guess it is pretty expected. But however, I am not sure, 65000 (bytes?) look quite small to me for a ciphertext, we’ll check tomorrow
  3. what kind of error do you have in mind
1 Like

And you might want to look at concrete-ml/ClientServer.ipynb at release/0.3.x · zama-ai/concrete-ml · GitHub ! And Production Deployment - Concrete ML . As I told you, the link in this later file is broken, it is supposed to be the first ipynb I gave you.

Cheers!

1 Like

Hi @benoit, thank you very much for your fast anwer!

  1. Makes sense! Solved.
  2. Right. My confusion, sorry. If it may help, when I serialized encrypted values in Rust I got sizes over a single value of around 32000 bytes…
  3. Nothing in particular, but I wasn’t sure.

I’ll take a look at the notebook

Thank you!

oK then the 65000 bytes make sense!

Yes, enjoy the new features in CML. I hope you’ll remark that the doc has been greatly improved and is now much clearer and extensive.

1 Like

Great! Couldn’t agree more, the documentation now is pretty good, especially the Key Concepts section.

I’ve done a few more tests in case they are useful to you. Also I’ve tested that encryption times are the same when the keygen it is explicitly generated.

Values: [[16 15 16 16 16 17 17 19 18 14 14 17 18 17]]
--- 0.02614116668701172 seconds (encrypt) ---
Size of encrypted values: 458929
Values: [[21 15 25 16 13 19 17 18 17 13 17 14 18 17]]
--- 0.026222705841064453 seconds (encrypt) ---
Size of encrypted values: 458929
Values: [[15 15 15 16 16 16 15 15 16 17 17 17 15 15]]
--- 0.024915218353271484 seconds (encrypt) ---
Size of encrypted values: 458929

1 Like

We even improved the doc in CML 0.4, check this out: What is Concrete ML? - Concrete ML . Hopefully you’ll find it even clearer

1 Like