1 // @file  simple-integers-bgvrns.cpp - Simple example for BGVrns (integer
2 // arithmetic).
3 // @author TPOC: contact@palisade-crypto.org
4 //
5 // @copyright Copyright (c) 2019, New Jersey Institute of Technology (NJIT))
6 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 // 1. Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution. THIS SOFTWARE IS
14 // PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17 // EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 #include "palisade.h"
26 
27 using namespace lbcrypto;
28 
main()29 int main() {
30   // Sample Program: Step 1 - Set CryptoContext
31 
32   // Set the main parameters
33   int plaintextModulus = 65537;
34   double sigma = 3.2;
35   SecurityLevel securityLevel = HEStd_128_classic;
36   uint32_t depth = 2;
37 
38   // Instantiate the crypto context
39   CryptoContext<DCRTPoly> cryptoContext =
40       CryptoContextFactory<DCRTPoly>::genCryptoContextBGVrns(
41           depth, plaintextModulus, securityLevel, sigma, depth, OPTIMIZED, BV);
42 
43   // Enable features that you wish to use
44   cryptoContext->Enable(ENCRYPTION);
45   cryptoContext->Enable(SHE);
46   cryptoContext->Enable(LEVELEDSHE);
47 
48   // Sample Program: Step 2 - Key Generation
49 
50   // Initialize Public Key Containers
51   LPKeyPair<DCRTPoly> keyPair;
52 
53   // Generate a public/private key pair
54   keyPair = cryptoContext->KeyGen();
55 
56   // Generate the relinearization key
57   cryptoContext->EvalMultKeyGen(keyPair.secretKey);
58 
59   // Generate the rotation evaluation keys
60   cryptoContext->EvalAtIndexKeyGen(keyPair.secretKey, {1, 2, -1, -2});
61 
62   // Sample Program: Step 3 - Encryption
63 
64   // First plaintext vector is encoded
65   std::vector<int64_t> vectorOfInts1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
66   Plaintext plaintext1 = cryptoContext->MakePackedPlaintext(vectorOfInts1);
67   // Second plaintext vector is encoded
68   std::vector<int64_t> vectorOfInts2 = {3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12};
69   Plaintext plaintext2 = cryptoContext->MakePackedPlaintext(vectorOfInts2);
70   // Third plaintext vector is encoded
71   std::vector<int64_t> vectorOfInts3 = {1, 2, 5, 2, 5, 6, 7, 8, 9, 10, 11, 12};
72   Plaintext plaintext3 = cryptoContext->MakePackedPlaintext(vectorOfInts3);
73 
74   // The encoded vectors are encrypted
75   auto ciphertext1 = cryptoContext->Encrypt(keyPair.publicKey, plaintext1);
76   auto ciphertext2 = cryptoContext->Encrypt(keyPair.publicKey, plaintext2);
77   auto ciphertext3 = cryptoContext->Encrypt(keyPair.publicKey, plaintext3);
78 
79   // Sample Program: Step 4 - Evaluation
80 
81   // Homomorphic additions
82   auto ciphertextAdd12 = cryptoContext->EvalAdd(ciphertext1, ciphertext2);
83   auto ciphertextAddResult =
84       cryptoContext->EvalAdd(ciphertextAdd12, ciphertext3);
85 
86   // Homomorphic multiplications
87   // modulus switching is done automatically because by default the modulus
88   // switching method is set to AUTO (rather than MANUAL)
89   auto ciphertextMul12 = cryptoContext->EvalMult(ciphertext1, ciphertext2);
90   auto ciphertextMultResult =
91       cryptoContext->EvalMult(ciphertextMul12, ciphertext3);
92 
93   // Homomorphic rotations
94   auto ciphertextRot1 = cryptoContext->EvalAtIndex(ciphertext1, 1);
95   auto ciphertextRot2 = cryptoContext->EvalAtIndex(ciphertext1, 2);
96   auto ciphertextRot3 = cryptoContext->EvalAtIndex(ciphertext1, -1);
97   auto ciphertextRot4 = cryptoContext->EvalAtIndex(ciphertext1, -2);
98 
99   // Sample Program: Step 5 - Decryption
100 
101   // Decrypt the result of additions
102   Plaintext plaintextAddResult;
103   cryptoContext->Decrypt(keyPair.secretKey, ciphertextAddResult,
104                          &plaintextAddResult);
105 
106   // Decrypt the result of multiplications
107   Plaintext plaintextMultResult;
108   cryptoContext->Decrypt(keyPair.secretKey, ciphertextMultResult,
109                          &plaintextMultResult);
110 
111   // Decrypt the result of rotations
112   Plaintext plaintextRot1;
113   cryptoContext->Decrypt(keyPair.secretKey, ciphertextRot1, &plaintextRot1);
114   Plaintext plaintextRot2;
115   cryptoContext->Decrypt(keyPair.secretKey, ciphertextRot2, &plaintextRot2);
116   Plaintext plaintextRot3;
117   cryptoContext->Decrypt(keyPair.secretKey, ciphertextRot3, &plaintextRot3);
118   Plaintext plaintextRot4;
119   cryptoContext->Decrypt(keyPair.secretKey, ciphertextRot4, &plaintextRot4);
120 
121   plaintextRot1->SetLength(vectorOfInts1.size());
122   plaintextRot2->SetLength(vectorOfInts1.size());
123   plaintextRot3->SetLength(vectorOfInts1.size());
124   plaintextRot4->SetLength(vectorOfInts1.size());
125 
126   std::cout << "Plaintext #1: " << plaintext1 << std::endl;
127   std::cout << "Plaintext #2: " << plaintext2 << std::endl;
128   std::cout << "Plaintext #3: " << plaintext3 << std::endl;
129 
130   // Output results
131   std::cout << "\nResults of homomorphic computations" << std::endl;
132   std::cout << "#1 + #2 + #3: " << plaintextAddResult << std::endl;
133   std::cout << "#1 * #2 * #3: " << plaintextMultResult << std::endl;
134   std::cout << "Left rotation of #1 by 1: " << plaintextRot1 << std::endl;
135   std::cout << "Left rotation of #1 by 2: " << plaintextRot2 << std::endl;
136   std::cout << "Right rotation of #1 by 1: " << plaintextRot3 << std::endl;
137   std::cout << "Right rotation of #1 by 2: " << plaintextRot4 << std::endl;
138 
139   return 0;
140 }
141