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