The following methods are provided in the Paillier module
1Paillier.generateKeypair(keysize) # Returns privateKey, publicKey 2 3Paillier.encrypt(publicKey, plaintext) 4Paillier.eAdd(publicKey, cyphertext1, cyphertext2) 5Paillier.eAddConst(publicKey, cyphertext, plaintext) 6Paillier.eMulConst(publicKey, cyphertext, plaintext) 7 8Paillier.decrypt(privateKey, publicKey, cyphertext) 9 10Paillier.sign(privateKey, publicKey, data) 11Paillier.validSignature?(publicKey, data, signature) 12 13Paillier::ZKP.new(publicKey, plaintext, validMessages) 14Paillier::ZKP.verifyZKP?(publicKey, ciphertext, validMessages, commitment)
Note that public and privaye keys, signatures, and ZKP commitments have
from_s methods to make them easy to serialize and save to a file / database or send over a network.
The ZKP object has
commitment methods to extract the information that must be sent to the server.
Examples of all of the above methods are provided below.
Encryption and decryption is trivial:
Adding two encrypted numbers together is also easy:
You can also add plaintext constants to a message:
Multiplying by a constant is just as easy:
Paillier provides detached signatures, which can validate that a message has not been tampered with, and has been signed by the specified keypair.
If there are a limited number of acceptable messages then we say a ciphertext is valid if its plaintext is in the set of acceptable messages. The ZKP allows a third party to prove a ciphertext is valid, without having the private key to read the message.
To prove a ciphertext is valid, the prover must create their ciphertext and a commitment, and send it to the validator. The validator can then call verifyZKP? to ensure the message is valid. The client and server must have agreed ahead of time on a set and order of valid messages.
Note: The ciphertext must be created with the ZKP object, as parts of the encryption process are re-used to create the commitment.
Client (prover) side:
1msg = 7 2valid_messages = [1, 3, 5, 7, 9] 3 4# Create a ZKP object which will generate the commitment and ciphertext used for the proof 5zkp = Paillier::ZKP.new(pubkey, msg, valid_messages) 6 7ciphertext = zkp.ciphertext 8commitment = zkp.commitment 9# The client now sends the ciphertext and commitment to the server
Server (verifier) side:
It is often necessary to convert data into text to make it easy to send over a network, save into a database, and so on. Our Paillier library provides several methods to make this process easier.
Public key serialization:
Private key serialization:
WARNING: Serialized private keys are in plaintext! This functionality is provided so keys can be exported to another program and saved securely. Do not send your serialized private key across a network or save it in an insecure environment.
ZKP Commitment serialization: