Package: damgard-jurik
Damgard-JurikAn implementation of the threshold variant of theDamgard-Jurikhomomorphic encryption cryptosystem.Table of ContentsInstallationPublic and Private KeysKey GenerationEncryption and DecryptionHomomorphic OperationsInstallationRequires Python 3.6+.pipinstalldamgard-jurikAlternatively, the code can be cloned and installed locally as follows.gitclonehttps://github.com/cryptovoting/damgard-jurik.gitcddamgard-jurik
pipinstall-e.Note that the-eflag will instruct pip to install the package as "editable". That is, when changes are made to any part of the package during development, those changes will immediately be available system-wide on the activated python environment.All requirements for this package should be added tosetup.py.Public and Private KeysIn the threshold variant of Damgard-Jurik implemented in this repository, a key pair consists of single public key along with a private key that has been split into multiple components usingShamir's secret sharing. The public key encrypts messages while the shares of the private key all contribute a portion of the decryption without ever requiring reconstruction of the private key. Thus, trust is distributed among the holders of the private key shares.In this implementation, the public key is aPublicKeyobject with an encrypt function while the private key shares arePrivateKeyShareobjects with a decrypt function that performs a partial decryption using that share of the private key. APrivateKeyRingobject holds a set ofPrivateKeyShares and contains a decrypt function that calls eachPrivateKeyShare's decrypt function and combines the results to obtain the final decryption.Key GenerationTo generate aPublicKeyand the correspondingPrivateKeyRing, run the following commands:fromdamgard_jurikimportkeygenpublic_key,private_key_ring=keygen(n_bits=64,s=1,threshold=3,n_shares=3)The parameters tokeygenare as follows:n_bits: The number of bits of encryption used in the public key and private key shares.s: The exponent to which the public key parameternis raised (wheren = p * qis the product of twon_bits-bit primespandq.). Plaintexts are integers in the spaceZ_n^s = {0, 1, ..., n^s - 1}.threshold: The minimum number of private key shares needed to decrypt an encrypted message.n_shares: The number of private key shares to generate.Encryption and DecryptionEncryption and decryption are implemented as methods of thePublicKeyandPrivateKeyRingclasses, respectively.For example:m=42c=public_key.encrypt(m)m_prime=private_key_ring.decrypt(c)# m_prime = 42Plaintexts likemare simply Python integers while ciphertexts (encrypted plaintexts) likecare instances of theEncryptedNumberclass.EncryptedNumberobjects contain an encryption of the plaintext along with a reference to thePublicKeyused to encrypt the plaintext.Additionally, thePublicKeyandPrivateKingRingclasses have a convenience method for encrypting and decrypting lists of integers, as shown below.m_list=[42,33,100]c_list=public_key.encrypt_list(m_list)m_prime_list=private_key_ring.decrypt_list(c_list)# m_prime_list = [42, 33, 100]Homomorphic OperationsDue to the additively homomorphic nature of the Damgard-Jurik cryptosystem, ciphertexts can be combined in such a way as to obtain an encryption of the sum of the associated plaintexts. Futhermore, ciphertexts can be combined with un-encrypted integers in such a way as to obtain the product of the associated plaintext and the un-encrypted integer. For convenience, theEncryptedNumberclass has overridden the+,-,*, and/operators to implement these operations.For example:m_1,m_2=42,33c_1,c_2=public_key.encrypt(m_1),public_key.encrypt(m_2)c=c_1+c_2m_prime=private_key_ring.decrypt(c)# m_prime = 75 = 42 + 33m,s=42,2c=public_key.encrypt(m)c_prime=c*sm_prime=private_key_ring.decrypt(c_prime)# m_prime = 84 = 42 * 2