Commit 0aa1e6a0 authored by Gerard Ryan's avatar Gerard Ryan
Browse files

Merge branch 'issue-962' into 'master'

Issue 962

Closes #962

See merge request palisade/palisade-student-edition!502
parents f11928eb 2acd1f4e
......@@ -7,7 +7,7 @@ PALISADE Lattice Cryptography Library - Demos
Document Description
===================
This document is intended to describe the demo programs included with the PALISADE lattice crypto library.
This document describes the demo programs included with the PALISADE lattice crypto library.
Demo Directory Description
==========================
......@@ -20,15 +20,16 @@ File Listing
------------
* Demo programs
- [demo_fusion_simple.cpp](src/pke/demo/demo_fusion_simple.cpp): a demo program of multiparty FHE operations built on FV.
- [demo-automorphism.cpp](src/pke/demo/demo-automorphism.cpp): demonstrates use of EvalAutomorphism for different schemes, plaintext encodings, and cyclotomic rings
- [demo-bfvrns.cpp](src/pke/demo/demo-bfvrns.cpp): demonstrates use of the BFVrns scheme for basic SHE operations
- [demo-cross-correlation.cpp](src/pke/demo/demo-cross-correlation.cpp): a demo program that demonstrates the use of serialization, DCRT, arbitrary cyclotomics, and packed encoding for an application that computes cross-correlation using inner products.
- [demo-cross-correlation-bfvrns.cpp](src/pke/demo/demo-cross-correlation-bfrns.cpp): a demo program that demonstrates the use of serialization, DCRT, power-of-two-cyclotomics, and packed encoding for an application that computes cross-correlation using inner products.
- [demo-crypt-pre-text.cpp](src/pke/demo/demo-crypt-pre-text.cpp): demonstrates use of PALISADE for encryption, re-encryption and decryption of text
- [demo-ccs-tutorial.cpp](src/pke/demo/demo-ccs-tutorial.cpp): demo from PALISADE tutorial given at ACM CCS in Toronto, CA, October 2018
- [demo-depth-bfvrns.cpp](src/pke/demo/demo-depth-bfvrns.cpp): demonstrates use of the BFVrns scheme for basic homomorphic encryption
- [demo-depth-bfvrns-b.cpp](src/pke/demo/demo-depth-bfvrns-b.cpp): demonstrates use of the BFVrnsB scheme for basic homomorphic encryption
- [demo-evalatindex.cpp](src/pke/demo/demo-evalatindex.cpp): demonstrates use of EvalAtIndex for different schemes and cyclotomic rings
- [demo-fusion-simple.cpp](src/pke/demo/demo-fusion-simple.cpp): a demo program of multiparty FHE operations built on FV.
- [demo-json.cpp](src/pke/demo/demo-json.cpp): demonstrates use of PALISADE encryption and decryption of vectors of integers, also illustrating the use of serializing information to text files
- [demo-linregress.cpp](src/pke/demo/demo-linregress.cpp): demonstrates performing linear regression on encrypted matrices
- [demo-packing.cpp](src/pke/demo/demo-packing.cpp): demonstrates inner product operations
......@@ -36,7 +37,5 @@ File Listing
- [demo-pre.cpp](src/pke/demo/demo-pre.cpp): demonstrates use of proxy re-encryption across several schemes
- [demo-she.cpp](src/pke/demo/demo-she.cpp): demonstrates SHE operations using several schemes
- [demo-timing.cpp](src/pke/demo/demo-timing.cpp): demonstrate the use of the TimingInfo feature of the CryptoContext
- [palisade.cpp](src/demo/pre/palisade.cpp): a program designed to demonstrate the key generation, evaluation key generation, encryption, re-encryption, and decryption functionality of the library. If you run the command without any parameters it generates a help message. Results are serialized into flat files, and are deserialized when needed. The program will read the crypto context parms file, or will read a file that you provide. Note you can also tell the program to figure out what crypto parameters to use based on whatever serialized object you are reading at the start of your program.
- [palisadedemo.sh](src/pke/demo/palisadedemo.sh): a shell script that runs the palisade demo
- [run-bfvrns.cpp](src/pke/demo/run-bfvrns.cpp): demonstrates benchmarking of RNS operations for BFVrns
- [run-bfvrns-b.cpp](src/pke/demo/run-bfvrns-b.cpp): demonstrates benchmarking of RNS operations for BFVrnsB
......@@ -496,19 +496,19 @@ struct {
cmdparser<DCRTPoly> dfunc;
string helpline;
} cmds[] = {
{"makekey", keymaker<Poly>, keymaker<DCRTPoly>, " [optional parms] keyname\n"
{"makekey", keymaker<Poly>, keymaker<DCRTPoly>, " [flags] keyname\n"
"\tcreate a new keypair\n\t\tsave keynamePUB, keynamePRI, keynameCTXT and keynameEMK"},
{"makerekey", rekeymaker<Poly>, rekeymaker<DCRTPoly>, " [optional parms] pubkey_file secretkey_file rekey_file\n"
{"makerekey", rekeymaker<Poly>, rekeymaker<DCRTPoly>, " [flags] pubkey_file secretkey_file rekey_file\n"
"\tcreate a re-encryption key from the contents of pubkey_file and secretkey_file\n\tsave in rekey_file"},
{"encrypt", encrypter<Poly>, encrypter<DCRTPoly>, " [optional parms] plaintext_file pubkey_file ciphertext_file\n"
{"encrypt", encrypter<Poly>, encrypter<DCRTPoly>, " [flags] plaintext_file pubkey_file ciphertext_file\n"
"\tencrypt the contents of plaintext_file using the contents of pubkey_file\n\tsave results in ciphertext_file"},
{"reencrypt", reencrypter<Poly>, reencrypter<DCRTPoly>, " [optional parms] encrypted_file rekey_file reencrypted_file\n"
{"reencrypt", reencrypter<Poly>, reencrypter<DCRTPoly>, " [flags] encrypted_file rekey_file reencrypted_file\n"
"\treencrypt the contents of encrypted_file using the contents of rekey_file\n\tsave results in reencrypted_file"},
{"decrypt", decrypter<Poly>, decrypter<DCRTPoly>, " [optional parms] ciphertext_file prikey_file cleartext_file\n"
{"decrypt", decrypter<Poly>, decrypter<DCRTPoly>, " [flags] ciphertext_file prikey_file cleartext_file\n"
"\tdecrypt the contents of ciphertext_file using the contents of prikey_file\n\tsave results in cleartext_file"},
{"evaladd", evaladder<Poly>, evaladder<DCRTPoly>, " [optional parms] ciphertext1 ciphertext2 addresult\n"
{"evaladd", evaladder<Poly>, evaladder<DCRTPoly>, " [flags] ciphertext1 ciphertext2 addresult\n"
"\teval-add both ciphertexts\n\tsave result in addresult"},
{"evalmult", evalmulter<Poly>, evalmulter<DCRTPoly>, " [optional parms] ciphertext1 ciphertext2 multresult\n"
{"evalmult", evalmulter<Poly>, evalmulter<DCRTPoly>, " [flags] ciphertext1 ciphertext2 multresult\n"
"\teval-mult both ciphertexts\n\tsave result in multresult"},
};
......@@ -524,9 +524,8 @@ usage(const string& cmd, const string& msg)
}
cerr << endl;
cerr << "[optional params] are:" << endl;
cerr << "-poly: (default) use Poly" << endl;
cerr << "-dcrt: use DCRTPoly instead of Poly" << endl;
cerr << "[flags] are:" << endl;
cerr << "-poly: (default) use Poly, -dcrt: use DCRTPoly" << endl;
cerr << "-integers: use integer plaintext with " << IntVectorLen << " integers\n\tplaintext file is ascii ints delimited by whitespace" << endl;
cerr << "-intlen N: use integer plaintext with N integers; default is " << IntVectorLen << endl;
cerr << "-list: list all the parameter sets, then exit" << endl;
......@@ -537,6 +536,20 @@ usage(const string& cmd, const string& msg)
int
main( int argc, char *argv[] )
{
// for text, ptm must be == 256, so search for valid parm sets
vector<string> textParmsets;
//map<string, map<string,string>>
for( auto mapIt = CryptoContextParameterSets.begin();
mapIt != CryptoContextParameterSets.end();
mapIt++ ) {
if( mapIt->second["plaintextModulus"] == "256" )
textParmsets.push_back(mapIt->first);
}
for( size_t i=0; i<textParmsets.size(); i++ )
cout << textParmsets[i] << endl;
if( argc < 2 ) {
usage("ALL");
return 1;
......
/*
* @file
* @author TPOC: palisade@njit.edu
*
* @copyright Copyright (c) 2017, New Jersey Institute of Technology (NJIT)
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "palisade.h"
#include "cryptocontexthelper.h"
#include "lattice/stdlatticeparms.h"
using namespace lbcrypto;
int main()
{
// Sample Program: Step 1 Set CryptoContext
//Set the main parameters
int plaintextModulus = 65537;
double sigma = 3.2;
SecurityLevel securityLevel = HEStd_128_classic;
uint32_t depth = 2;
//Instantiate the crypto context
CryptoContext<DCRTPoly> cryptoContext = CryptoContextFactory<DCRTPoly>::genCryptoContextBFVrns(
plaintextModulus, securityLevel, sigma, 0, depth, 0, OPTIMIZED);
//Enable features that you wish to use
cryptoContext->Enable(ENCRYPTION);
cryptoContext->Enable(SHE);
//Sample Program: Step 2 Key Generation
// Initialize Public Key Containers
LPKeyPair<DCRTPoly> keyPair;
// Generate a public/private key pair
keyPair = cryptoContext->KeyGen();
// Generate the relinearization key
cryptoContext->EvalMultKeyGen(keyPair.secretKey);
//Sample Program: Step 3 Encryption
// First plaintext vector is encoded
std::vector<int64_t> vectorOfInts1 = {1,2,3,4,5,6,7,8,9,10,11,12};
Plaintext plaintext1 = cryptoContext->MakePackedPlaintext(vectorOfInts1);
// Second plaintext vector is encoded
std::vector<int64_t> vectorOfInts2 = {3,2,1,4,5,6,7,8,9,10,11,12};
Plaintext plaintext2 = cryptoContext->MakePackedPlaintext(vectorOfInts2);
// Third plaintext vector is encoded
std::vector<int64_t> vectorOfInts3 = {1,2,5,2,5,6,7,8,9,10,11,12};
Plaintext plaintext3 = cryptoContext->MakePackedPlaintext(vectorOfInts3);
// The encoded vectors are encrypted
auto ciphertext1 = cryptoContext->Encrypt(keyPair.publicKey, plaintext1);
auto ciphertext2 = cryptoContext->Encrypt(keyPair.publicKey, plaintext2);
auto ciphertext3 = cryptoContext->Encrypt(keyPair.publicKey, plaintext3);
//Sample Program: Step 4 Evaluation
// Homomorphic additions
auto ciphertextAdd12 = cryptoContext->EvalAdd(ciphertext1,ciphertext2);
auto ciphertextAddResult = cryptoContext->EvalAdd(ciphertextAdd12,ciphertext3);
// Homomorphic multiplications
auto ciphertextMul12 = cryptoContext->EvalMult(ciphertext1,ciphertext2);
auto ciphertextMultResult = cryptoContext->EvalMult(ciphertextMul12,ciphertext3);
//Sample Program: Step 5 Decryption
// Decrypt the result of additions
Plaintext plaintextAddResult;
cryptoContext->Decrypt(keyPair.secretKey, ciphertextAddResult, &plaintextAddResult);
// Decrypt the result of multiplications
Plaintext plaintextMultResult;
cryptoContext->Decrypt(keyPair.secretKey, ciphertextMultResult, &plaintextMultResult);
// Output results
cout << plaintextAddResult << endl;
cout << plaintextMultResult << endl;
return 0;
}
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <random>
#include <stdio.h>
#include <unistd.h>
#include "../lib/cryptocontext.h"
#include "../lib/cryptocontexthelper.h"
#include "../lib/cryptocontexthelper-impl.cpp"
#include "../lib/utils/serializable.h"
#include "../lib/utils/serializablehelper.h"
#include "encoding/encodings.h"
#include "utils/debug.h"
#include <cstdio>
using namespace std;
using namespace lbcrypto;
using namespace rapidjson;
struct EncInfo
{
CryptoContext<Poly> cryptocontext;
LPKeyPair<Poly> keypair;
};
EncInfo info;
//const int IntVectorLen = 10;
int generate_crypto_context() {
usint m = 22;
usint p = 2069;
BigInteger modulusP(p);
BigInteger modulusQ("955263939794561");
BigInteger squareRootOfRoot("941018665059848");
BigInteger bigmodulus("80899135611688102162227204937217");
BigInteger bigroot("77936753846653065954043047918387");
auto cycloPoly = GetCyclotomicPolynomial<BigVector>(m, modulusQ);
ChineseRemainderTransformArb<BigVector>::SetCylotomicPolynomial(cycloPoly, modulusQ);
float stdDev = 4;
usint batchSize = 8;
shared_ptr<ILParams> params(new ILParams(m, modulusQ, squareRootOfRoot, bigmodulus, bigroot));
EncodingParams encodingParams(new EncodingParamsImpl(p, batchSize, PackedEncoding::GetAutomorphismGenerator(m)));
CryptoContext<Poly> cc = CryptoContextFactory<Poly>::genCryptoContextBGV(params, encodingParams, 8, stdDev);
cc->Enable(ENCRYPTION);
cc->Enable(SHE);
info.cryptocontext = cc;
PackedEncoding::SetParams(m, encodingParams);
return 1;
}
int generate_keys_and_write_to_files(){
cout << "Here is the context I am using: " << *info.cryptocontext->GetCryptoParameters() << endl;
LPKeyPair<Poly> kp = info.cryptocontext->KeyGen();
info.keypair = kp;
info.cryptocontext->EvalSumKeyGen(kp.secretKey);
info.cryptocontext->EvalMultKeyGen(kp.secretKey);
Serialized pubK, privK;
if ( kp.publicKey->Serialize(&pubK) ) {
if (!SerializableHelper::WriteSerializationToFile(pubK, "./encryption_info_pubK.txt") ) {
cerr << "Error writing serialization of public key to ./encryption_info_pubK.txt" << endl;
return 0;
}
} else {
cerr << "Error serializing public key" << endl;
return 0;
}
if ( kp.secretKey->Serialize(&privK) ) {
if (!SerializableHelper::WriteSerializationToFile(privK, "./encryption_info_priK.txt") ) {
cerr << "Error writing serialization of public key to ./encryption_info_priK.txt" << endl;
return 0;
}
} else {
cerr << "Error serializing private key" << endl;
return 0;
}
vector<int64_t> *v = new vector<int64_t>();
v->push_back(86);
cout << "Here's my vector" << *v << endl;
Ciphertext<Poly> ciphertext;
vector<int64_t> vectorOfInts = move(*v);
Plaintext intArray = info.cryptocontext->MakePackedPlaintext(vectorOfInts);
cout << "I am about to encrypt this: " << intArray << endl;
ciphertext = info.cryptocontext->Encrypt(info.keypair.publicKey, intArray);
Serialized cSer;
string str;
if ( ciphertext->Serialize(&cSer) ) {
if( !SerializableHelper::WriteSerializationToFile(cSer, "./ctxt_check.txt") ) {
cerr << "Error writing serialization of ciphertext to ctxt_check.txt" << endl;
return 0;
}
} else {
cerr << "Error serializing ciphertext" << endl;
return 0;
}
return 1;
}
int read_public_key_from_file(){
Serialized kser;
if ( SerializableHelper::ReadSerializationFromFile("./encryption_info_pubK.txt", &kser) == false ) {
cerr << "Could not read public key" << endl;
return 0;
}
LPPublicKey<Poly> pk = info.cryptocontext->deserializePublicKey(kser);
if ( !pk ) {
cerr << "Could not deserialize public key" << endl;
return 0;
}
info.keypair.publicKey = pk;
return 1;
}
int read_private_key_from_file(){
Serialized kser;
FILE* fp = fopen("./encryption_info_priK.txt", "r");
char readBuffer[65536];
FileReadStream sSK(fp, readBuffer, sizeof(readBuffer));
//SerialItem a(kArrayType);
kser.ParseStream(sSK);
fclose(fp);
info.cryptocontext = CryptoContextFactory<Poly>::DeserializeAndCreateContext(kser);
LPPrivateKey<Poly> sk = info.cryptocontext->deserializeSecretKey(kser);
info.keypair.secretKey = sk;
cout << *info.cryptocontext->GetCryptoParameters() << endl;
if ( !sk ) {
cerr << "Could not deserialize public key" << endl;
return 0;
}
Serialized cSer;
FILE* fp2 = fopen("./ctxt_check.txt", "r");
char readBuffer2[65536];
FileReadStream sCTXT(fp2, readBuffer2, sizeof(readBuffer));
cSer.ParseStream(sCTXT);
fclose(fp2);
if( SerializableHelper::ReadSerializationFromFile("./ctxt_check.txt", &cSer) == false ) {
cerr << "Could not read ciphertext" << endl;
return 0;
}
Plaintext iPlaintext;
Ciphertext<Poly> ct = info.cryptocontext->deserializeCiphertext(cSer);
if( ct == NULL ) {
cerr << "Could not deserialize ciphertext" << endl;
return 0;
}
//Ciphertext<Poly> ciphertext( { ct } );
//auto m = info.cryptocontext->GetElementParams()->GetCyclotomicOrder();
////auto modulusQ = info.cryptocontext->GetElementParams()->GetModulus();
////auto cycloPoly = GetCyclotomicPolynomial<BigVector>(m, modulusQ);
////ChineseRemainderTransformArb<BigVector>::SetCylotomicPolynomial(cycloPoly, modulusQ);
//PackedEncoding::SetParams(m, info.cryptocontext->GetEncodingParams());
info.cryptocontext->Decrypt(sk, ct, &iPlaintext);
cout << *iPlaintext << endl;
cout << iPlaintext->GetPackedValue()[0] << " is value" << endl;
if ( 86 == iPlaintext->GetPackedValue()[0] ) {
cout << "Cryptocontext generated successfully!" << endl;
cout << 1;
return 1;
} else {
cout << 0;
return 0;
}
return 1;
}
vector<uint64_t> split(const string &s, char delim) {
stringstream ss(s);
string item;
vector<uint64_t> tokens;
while (getline(ss, item, delim)) {
tokens.push_back(stod(item));
}
return tokens;
}
int encrypt_content( string& content_file ) {
ifstream file ( content_file );
string value;
vector<uint64_t> tokens;
string output_filename = content_file;
output_filename.replace(output_filename.end()-4,output_filename.end(),"_enc.txt");
ofstream enc_file( output_filename, ios::out | ios::binary );
OStreamWrapper oo(enc_file);
Writer<OStreamWrapper> ww(oo);
ww.StartArray();
// Serialized serial;
// SerialItem a(kArrayType);
// Serialized::AllocatorType& allocator = serial.GetAllocator();
if ( !file.good() ) {
cerr << "Failed to open input plaintext file" << endl;
return 0;
}
if( !enc_file.is_open() ) {
cerr << "could not open output file " << output_filename << endl;
return 0;
}
while ( file.good() ) {
vector<int64_t> *v = new vector<int64_t>();
getline ( file, value );
tokens = split(value, ',');
for ( vector<int64_t>::size_type i = 0; i != tokens.size(); i++ ) {
v->push_back(tokens[i]);
}
Ciphertext<Poly> ciphertext;
vector<int64_t> vectorOfInts = move(*v);
Plaintext intArray = info.cryptocontext->MakePackedPlaintext(vectorOfInts); // TODO INCORPORATE NEGATIVE VALUES AS WELL
ciphertext = info.cryptocontext->Encrypt(info.keypair.publicKey, intArray);
Serialized cSer;
string str;
if ( ciphertext->Serialize(&cSer) ) {
//cSer.Accept(ww);
SerializableHelper::SerializationToString(cSer,str);
ww.String(str);
// a.PushBack(cSer, allocator);
} else {
cerr << "Error serializing ciphertext" << endl;
return 0;
}
}
ww.EndArray();
file.close();
enc_file.close();
return 1;
}
bool FileExists( const string& name ) {
ifstream file(name);
if(!file) {
return false;
} else {
return true;
}
}
bool which_bool(string val) {
if (val == "0") { return false; }
return true;
}
int main(int argc, char** argv){
if (argc < 2) {
printf("ERROR IN NUMBER OF ARGUMENTS FOR ENCRYPTING CONTENT.\n");
} else {
string content_file = argv[1];
bool exists = FileExists("./encryption_info_priK.txt") and FileExists("./encryption_info_pubK.txt");
if (exists) {
if ( read_private_key_from_file() == false) {
cerr << "Failed to read private key from file" << endl;
return 0;
}
if ( read_public_key_from_file() == false ) {
cerr << "Failed to read public key from file" << endl;
}
encrypt_content(content_file);
} else {
if ( generate_crypto_context() == false) {
cerr << "Failed to generate cryptocontext" << endl;
}
cout << 1;
/*int is_written =*/ generate_keys_and_write_to_files();
encrypt_content(content_file);
}
}
return 0;
}
//make makeencryptcontent
//./encrypt_content ./Sample1_vecs.csv
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment