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) 910Paillier.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 keys, signatures, and ZKP commitments have `to_s`

and `from_s`

methods to make them easy to serialize and save to a file / database or send over a network.

The ZKP object has `ciphertext`

and `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:

Signature serialization:

ZKP Commitment serialization:

No such serialization methods are provided for the private key, to give developers pause before they try to send a private key in plaintext over the network.