Serialisation of the private/public key
YannisDuhamelle opened this issue · comments
I would like to serialize the private and public key to save them inside a file. I would like to serialize directly the python object generated by phe.generate_paillier_keypair()
, but apparently (according to the doc) there is no way to do it like this.
So, I tried to use the command line to use public/private key saved in JSON file. But the problem with this method is that is not handling well encryption of negative number. For example, with this simple code:
import os
os.system("pheutil genpkey --keysize 1024 example_private_key.json")
os.system("pheutil extract example_private_key.json example_public_key.json")
# Generation of the plaintext
m_plaintext = -2
print("m = ",m_plaintext)
# Encryption of the plaintext
os.system("pheutil encrypt example_public_key.json --output test.enc "+str(m_plaintext))
I obtain the following result:
Generating a paillier keypair with keysize of 1024
Keys generated
Private key written to example_private_key.json
Loading paillier keypair
Public key written to example_public_key.json
m = -2
Usage: pheutil encrypt [OPTIONS] PUBLIC PLAINTEXT
Try 'pheutil encrypt --help' for help.
Error: no such option: -2
What can I do to fix my problem ?
Thanks
The help from the encrypt option describes the problem (see the note paragraph before the "Options" section)
$ pheutil encrypt --help
Usage: pheutil encrypt [OPTIONS] PUBLIC PLAINTEXT
Encrypt a number with public key.
The PLAINTEXT input will be interpreted as a floating point number.
Output will be a JSON object with a "v" attribute containing the
ciphertext as a string, and "e" the exponent as a Number, where possible
fixed at -32.
Note if you are passing a negative number to encrypt, you will need to
include a "--" between the public key and your plaintext.
Options:
--output FILENAME Save to file instead of stdout
--help Show this message and exit.
Thus running the following works:
os.system("pheutil encrypt example_public_key.json --output test.enc -- "+str(m_plaintext))
E.g. (after having run the previous command to create the keys):
$ pheutil encrypt example_public_key.json --output test.enc -- -2
Loading public key
Encrypting: -2.0000000000000000
Note that adding "--" before a positive number also works.
Perhaps worth taking a step back.
I would like to serialize the private and public key to save them inside a file. I would like to serialize directly the python object generated by phe.generate_paillier_keypair(), but apparently (according to the doc) there is no way to do it like this.
Where do the docs say there is no way to do this? You get a PaillierPrivateKey
instance back from generate_paillier_keypair
which is just a standard Python object - you can serialize the attributes into a file.
Also there is almost certainly no need to "shell out" in order to do anything with python-paillier from Python. Each time you spawn a new process it will add quite a bit of overhead.
Yes, I'm sorry I think I misunderstood a little bit the documentation, but I remember that I had an error when I tried to do that...
Anyway, I found a solution later by just using a bit of your code from the phe.command_line in my code to serialize (maybe it is too much for what I want to do but it worked).
I put here my code if someone has the same problem than me
def serialization_paillier_keys(pub, priv, name_public, name_private):
date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
jwk_public = {
'kty': "DAJ",
'alg': "PAI-GN1",
"key_ops": ["encrypt"],
'n': phe.util.int_to_base64(pub.n),
'kid': "Paillier public key generated by pheutil on {}".format(date)
}
jwk_private = {
'kty': "DAJ",
'key_ops': ["decrypt"],
'p': phe.util.int_to_base64(priv.p),
'q': phe.util.int_to_base64(priv.q),
'pub': jwk_public,
'kid': "Paillier private key generated by pheutil on {}".format(date)
}
with open(name_public,"w") as f:
json.dump(jwk_public, f)
f.write('\n')
with open(name_private,"w") as f:
json.dump(jwk_private, f)
f.write('\n')
pki, ski = paillier.generate_paillier_keypair()
serialization_paillier_keys(pki, ski, "pki.json", "ski.json")
Thanks for your response anyway!