Skip to content

Commit

Permalink
Merge pull request #4 from fairmath/minor_improvements
Browse files Browse the repository at this point in the history
Minor improvements
  • Loading branch information
g-arakelov authored Nov 28, 2024
2 parents c752daf + 65955f0 commit 34645d3
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 86 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
shell: bash

- name: Release Build - Run build
run: cmake --build .build/rel
run: cmake --build BUILD/rel
shell: bash

- name: Debug Build - Run CMake with vcpkg.json manifest
Expand All @@ -93,5 +93,5 @@ jobs:
shell: bash

- name: Debug Build - Run build
run: cmake --build .build/deb
run: cmake --build BUILD/deb
shell: bash
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ jobs:
shell: bash

- name: Run build
run: cmake --build .build/rel
run: cmake --build BUILD/rel
shell: bash

- name: Run install
run: cmake --install .build/rel
run: cmake --install BUILD/rel
shell: bash

- name: 'Upload Artifact'
uses: actions/upload-artifact@v4
with:
name: fairmath-cli-${{matrix.platform}}
path: .build/install
path: BUILD/install
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
BUILD
.build
CMakeUserPresets.json
CMakeUserPresets.json
6 changes: 3 additions & 3 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"name": "base",
"displayName": "Unix Makefiles",
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/.build/$env{BIN_DIR}",
"binaryDir": "${sourceDir}/BUILD/$env{BIN_DIR}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"CMAKE_BUILD_TYPE": "$env{BUILD_TYPE}",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/.build"
"CMAKE_INSTALL_PREFIX": "${sourceDir}/BUILD"
}
}
]
}
}
9 changes: 0 additions & 9 deletions example/run_ciphertext_decryption.sh

This file was deleted.

8 changes: 0 additions & 8 deletions example/run_config_processing.sh

This file was deleted.

4 changes: 4 additions & 0 deletions example/run_decrypt_mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

../BUILD/install/fairmath-cli decrypt --cc ./cryptocontext_name --key ./private_key_name --output ./decrypted.txt ./ciphertext_1

4 changes: 4 additions & 0 deletions example/run_generate_mode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

../BUILD/install/fairmath-cli generate --input_cfg ./input.json --output_cfg ./output.json

12 changes: 6 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ $ git clone https://github.com/fairmath/fairmath-cli
```
* Configure cmake and build the project. You should specify vcpkg path, build type and directory for cmake generated file.
```shell
$ VCPKG_ROOT=/path/to/cloned/vcpkg/repo BUILD_TYPE=Release BIN_DIR=rel cmake --preset=base && cmake --build .build/rel
$ VCPKG_ROOT=/path/to/cloned/vcpkg/repo BUILD_TYPE=Release BIN_DIR=rel cmake --preset=base && cmake --build BUILD/rel
```
All files will be located in `.build` directory. You can omit VCPKG_ROOT variable if the one was defined previously(e.g. in the `.bashrc` file)
All files will be located in `BUILD` directory. You can omit VCPKG_ROOT variable if the one was defined previously(e.g. in the `.bashrc` file)
Also it is possible to create user defined presets for CMake.
Just create the following file in the root of the repository
CMakeUserPresets.json:
Expand Down Expand Up @@ -59,15 +59,15 @@ CMakeUserPresets.json:
```
Since that you are able to run the following command to build release configuration
```shell
$ cmake --preset=rel && cmake --build .build/rel
$ cmake --preset=rel && cmake --build BUILD/rel
```
Change rel to dbg to build a debug configuration.

The very first build could take a time because of vcpkg will build 3rd party libraries for this project. NExt builds will be mush faster since 3rd party libraries will be already built and cached.
The very first build could take a time because of vcpkg will build 3rd party libraries for this project. Next builds will be mush faster since 3rd party libraries will be already built and cached.

* Installation
Run cmake install to gather all binary files related to the build.
```shell
$ cmake --install .build/rel
$ cmake --install BUILD/rel
```
If you are using provided `CMakeUserPresets.json` then build will be installed to the `.build/install` directory.
If you are using provided `CMakeUserPresets.json` then build will be installed to the `BUILD/install` directory.
110 changes: 57 additions & 53 deletions src/fairmathCli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,95 +8,99 @@ namespace po = boost::program_options;

int main(int argc, char *argv[]) try
{
po::options_description desc("Allowed parameters");
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("help", "produce help message")

("working_mode", po::value<std::string>(), "set working_mode (config_processing or ciphertext_decryption)")
("mode", po::value<std::string>(), "mode specifies cli working mode (generate or decrypt)")

("input_config_location", po::value<std::string>(), "set input_config_location (config_processing)")
("output_crypto_objects_directory", po::value<std::string>(), "set output_crypto_objects_directory (config_processing)")
("output_config_location", po::value<std::string>(), "set output_config_location (config_processing)")
("output_config_json_indent", po::value<std::string>(), "set output_config_json_indent (config_processing)")
("input_cfg", po::value<std::string>(), "input_cfg specifies input config location (mode: generate)")
("output_cfg", po::value<std::string>(), "output_cfg specifies output config location (mode: generate)")
("workdir", po::value<std::string>()->default_value("."), "workdir specifies the directory in which to generate crypto objects (mode: generate)")
("json_indent", po::value<int>()->default_value(-1), "json_indent specifies indent for output config (mode: generate)")

("output_decryption_location", po::value<std::string>(), "set output_decryption_location (ciphertext_decryption)")
("decryption_cryptocontext_location", po::value<std::string>(), "set decryption_cryptocontext_location (ciphertext_decryption)")
("ciphertext_location", po::value<std::string>(), "set ciphertext_location (ciphertext_decryption)")
("decryption_key_location", po::value<std::string>(), "set decryption_key_location (ciphertext_decryption)")
("plaintext_length", po::value<std::string>(), "set plaintext_length (ciphertext_decryption)");
("cc", po::value<std::string>(), "cc specifies cryptocontext location (mode: decrypt)")
("key", po::value<std::string>(), "key specifies decryption key location (mode: decrypt)")
("slots", po::value<int>()->default_value(10), "slots specifies plaintext length (mode: decrypt)")
("output", po::value<std::string>(), "output specifies decrypted result location (mode: decrypt)")
("input", po::value<std::string>(), "input specifies input ciphertext location (mode: decrypt)");

po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
po::positional_options_description p;
p.add("mode", 1);
p.add("input", 1);

if (vm.count("help")) { std::cout << desc << '\n'; return EXIT_SUCCESS; }
if (!vm.count("working_mode")) { throw std::runtime_error("working_mode is not specified"); }
const std::string& workingMode = vm["working_mode"].as<const std::string&>();
po::variables_map variablesMap;
const auto& parsed = po::command_line_parser(argc, argv).options(desc).positional(p).run();
po::store(parsed, variablesMap);
po::notify(variablesMap);

if (workingMode == "config_processing")
if (variablesMap.count("help")) { std::cout << desc << '\n'; return EXIT_SUCCESS; }

if (!variablesMap.count("mode")) { throw std::runtime_error("Mode is not specified"); }
if (std::find_if(parsed.options.begin(), parsed.options.end(),
[](const po::option& option) { return option.string_key == "mode"; })
!= parsed.options.begin())
{
// config_processing
if (vm.count("output_decryption_location") || vm.count("decryption_cryptocontext_location") ||
vm.count("ciphertext_location") || vm.count("decryption_key_location") || vm.count("plaintext_length"))
{
throw std::runtime_error("ciphertext_decryption working_mode argument(s) were provided for config_processing working_mode");
}
if (!vm.count("input_config_location")) { throw std::runtime_error("input_config_location is not specified"); }
if (!vm.count("output_crypto_objects_directory")) { throw std::runtime_error("output_crypto_objects_directory is not specified"); }
if (!vm.count("output_config_location")) { throw std::runtime_error("output_config_location is not specified"); }
if (!vm.count("output_config_json_indent")) { throw std::runtime_error("output_config_json_indent is not specified"); }
throw std::runtime_error("Mode must be at the beginning");
}

const std::string& mode = variablesMap["mode"].as<const std::string&>();
if (mode == "generate")
{
if (!variablesMap.count("input_cfg")) { throw std::runtime_error("Input config location is not specified"); }
if (!variablesMap.count("output_cfg")) { throw std::runtime_error("Output config location is not specified"); }

std::ifstream ifsInputConfigJson(vm["input_config_location"].as<const std::string&>(), std::ios::in);
if (!ifsInputConfigJson.is_open()) { throw std::runtime_error("Unable to open " + vm["input_config_location"].as<const std::string&>()); }
std::ifstream ifsInputConfigJson(variablesMap["input_cfg"].as<const std::string&>(), std::ios::in);
if (!ifsInputConfigJson.is_open()) { throw std::runtime_error("Unable to open " + variablesMap["input_cfg"].as<const std::string&>()); }
nlohmann::json configJson = nlohmann::json::parse(ifsInputConfigJson);
ifsInputConfigJson.close();

std::string outputCryptoObjectsDirectory = vm["output_crypto_objects_directory"].as<std::string>();
std::string outputCryptoObjectsDirectory = variablesMap["workdir"].as<std::string>();
if (outputCryptoObjectsDirectory.back() != '/') { outputCryptoObjectsDirectory.push_back('/'); }

cli::ConfigProcessor(
std::move(configJson),
std::move(outputCryptoObjectsDirectory),
vm["output_config_location"].as<std::string>(),
std::stoi(vm["output_config_json_indent"].as<const std::string&>())
variablesMap["output_cfg"].as<std::string>(),
variablesMap["json_indent"].as<int>()
).generateOutputConfig();
}
else if (workingMode == "ciphertext_decryption")
else if (mode == "decrypt")
{
// ciphertext_decryption
if (vm.count("input_config_location") || vm.count("output_crypto_objects_directory") ||
vm.count("output_config_location") || vm.count("output_config_json_indent"))
if (!variablesMap.count("cc")) { throw std::runtime_error("Cryptocontext location is not specified"); }
if (!variablesMap.count("key")) { throw std::runtime_error("Decryption key location is not specified"); }
if (!variablesMap.count("output")) { throw std::runtime_error("Output decrypted result location is not specified"); }
if (!variablesMap.count("input")) { throw std::runtime_error("Input ciphertext location is not specified"); }

if (std::find_if(parsed.options.begin(), parsed.options.end(),
[](const po::option& option) { return option.string_key == "input"; })
!= std::prev(parsed.options.end()))
{
throw std::runtime_error("config_processing working_mode argument(s) were provided for ciphertext_decryption working_mode");
throw std::runtime_error("Input must be at the end");
}

if (!vm.count("output_decryption_location")) { throw std::runtime_error("output_decryption_location is not specified"); }
if (!vm.count("decryption_cryptocontext_location")) { throw std::runtime_error("decryption_cryptocontext_location is not specified"); }
if (!vm.count("ciphertext_location")) { throw std::runtime_error("ciphertext_location is not specified"); }
if (!vm.count("decryption_key_location")) { throw std::runtime_error("decryption_key_location is not specified"); }

std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>> cc;
cli::utils::deserialize(vm["decryption_cryptocontext_location"].as<const std::string&>(), cc);

std::shared_ptr<lbcrypto::CiphertextImpl<lbcrypto::DCRTPoly>> ciphertext;
cli::utils::deserialize(vm["ciphertext_location"].as<const std::string&>(), ciphertext);
cli::utils::deserialize(variablesMap["cc"].as<const std::string&>(), cc);

std::shared_ptr<lbcrypto::PrivateKeyImpl<lbcrypto::DCRTPoly>> privateKey;
cli::utils::deserialize(vm["decryption_key_location"].as<const std::string&>(), privateKey);
cli::utils::deserialize(variablesMap["key"].as<const std::string&>(), privateKey);

std::shared_ptr<lbcrypto::CiphertextImpl<lbcrypto::DCRTPoly>> ciphertext;
cli::utils::deserialize(variablesMap["input"].as<const std::string&>(), ciphertext);

std::shared_ptr<lbcrypto::PlaintextImpl> plaintext;
cc->Decrypt(ciphertext, privateKey, &plaintext);

if (vm.count("plaintext_length")) { plaintext->SetLength(std::stoull(vm["plaintext_length"].as<const std::string&>())); }
plaintext->SetLength(variablesMap["slots"].as<int>());

std::ofstream ofsOutputDecryption(vm["output_decryption_location"].as<const std::string&>(), std::ios::out);
if (!ofsOutputDecryption.is_open()) { throw std::runtime_error("Unable to open" + vm["output_decryption_location"].as<const std::string&>()); }
std::ofstream ofsOutputDecryption(variablesMap["output"].as<const std::string&>(), std::ios::out);
if (!ofsOutputDecryption.is_open()) { throw std::runtime_error("Unable to open" + variablesMap["output"].as<const std::string&>()); }
ofsOutputDecryption << plaintext;
ofsOutputDecryption.close();
}
else
{
throw std::runtime_error("Supported working_modes are: config_processing and ciphertext_decryption");
throw std::runtime_error("Supported modes are: generate and decrypt");
}

return EXIT_SUCCESS;
Expand Down

0 comments on commit 34645d3

Please sign in to comment.