From dd034ec9acb6fcc443f58458595a25de957b3d10 Mon Sep 17 00:00:00 2001 From: Alexandra Mirzuitova Date: Fri, 22 Mar 2024 11:19:15 +0200 Subject: [PATCH 1/3] Updates for repository's README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b5a5ef0..341e192 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # FHE components library -This repository is an initial phase of building application layer FHE Components library for developers and is home to the award-winning solutions from the [FHERMA](https://fherma.io/) challenges platform. The library will be constantly extended by adding new FHE components. +This repository is an initial phase of building an application layer FHE Components library for developers and serves as the home to the award-winning solutions from the [FHERMA](https://fherma.io/) challenges platform. +The library will be constantly extended by adding new FHE components. -Initial version of the library contains results of the first challenges: +The initial version of the library contains the results of the first challenges: - [Matrix Multiplication](https://fherma.io/challenges/652bf669485c878710fd020b/overview) - [Logistic Regression Function](https://fherma.io/challenges/652bf648485c878710fd0208/overview) - [Sign Evaluation](https://fherma.io/challenges/652bf668485c878710fd020a/overview) @@ -23,14 +24,15 @@ The library is designed with flexibility in mind, ensuring it's backend-agnostic # Contributing to the Library -There are two ways to contribute to Polycircuit. You can: -- Create PR with new component or improvements for existing one; +There are two ways to contribute to Polycircuit: +- Create PR with a new component or improvements for an existing one; - Participate in the challenges on the [FHERMA platform](https://fherma.io/challenges). # Stay Connected Join our vibrant community to stay updated on the latest developments, participate in discussions, and connect with fellow FHE enthusiasts: -* Discord: Join our [Discord channel](https://discord.com/invite/NfhXwyr9M5) for real-time chat, Q&A, and community events. -* Twitter: Follow us on [Twitter](https://twitter.com/FairMath) for the latest news, updates, and interesting tidbits from the world of Fully Homomorphic Encryption. -* Visit our [Fairmath blog](https://fairmath.xyz/blog) and [FHERMA challenges wrap-ups](https://fherma.io/content) for in-depth articles, feature announcements, tutorials, and insights into the future of privacy-preserving technologies. +* Discord: Join our [Discord server](https://discord.com/invite/NfhXwyr9M5) for real-time chat, Q&A, and community events. +* Twitter: Follow us on [X](https://twitter.com/FairMath) for the latest news, updates, and interesting tidbits from the world of Fully Homomorphic Encryption. +* LinkedIn: Join our [LinkedIn group]() to stay in touch with the team and the updates. +* Visit our [Fair Math blog](https://fairmath.xyz/blog) and [FHERMA challenges wrap-ups](https://fherma.io/content) for in-depth articles, feature announcements, tutorials, and insights into the future of privacy-preserving technologies. From b209c6844dfa2dfb0af71c8bfa0a099e34d97e18 Mon Sep 17 00:00:00 2001 From: Alexandra Mirzuitova Date: Fri, 22 Mar 2024 11:19:29 +0200 Subject: [PATCH 2/3] Placeholders for new challenges --- cpp/include/cifar/README.md | 125 +++++++++++++++++++++++++++++++ cpp/include/cifar/cifar_ckks.h | 34 +++++++++ cpp/include/cifar/config.json | 13 ++++ cpp/include/parity/README.md | 97 ++++++++++++++++++++++++ cpp/include/parity/config.json | 16 ++++ cpp/include/parity/parity_ckks.h | 31 ++++++++ cpp/include/relu/README.md | 84 +++++++++++++++++++++ cpp/include/relu/relu_ckks.h | 35 +++++++++ 8 files changed, 435 insertions(+) create mode 100644 cpp/include/cifar/README.md create mode 100644 cpp/include/cifar/cifar_ckks.h create mode 100644 cpp/include/cifar/config.json create mode 100644 cpp/include/parity/README.md create mode 100644 cpp/include/parity/config.json create mode 100644 cpp/include/parity/parity_ckks.h create mode 100644 cpp/include/relu/README.md create mode 100644 cpp/include/relu/relu_ckks.h diff --git a/cpp/include/cifar/README.md b/cpp/include/cifar/README.md new file mode 100644 index 0000000..0ec6b35 --- /dev/null +++ b/cpp/include/cifar/README.md @@ -0,0 +1,125 @@ +# CIFAR-10 Image Classification component + +*This is a stub repository for the FHERMA CIFAR-10 Image Classification challenge https://fherma.io/challenges/652bf663485c878710fd0209 which is live March-Jun 2024.* + +--- + +## Overview + +[CIFAR-10](https://www.cs.toronto.edu/~kriz/cifar.html) is a widely recognized dataset comprising 60,000 color images of size 32x32 pixels, categorized into 10 classes (such as automobiles, airplanes, dogs, etc.). +This dataset serves as a standard benchmark for machine learning algorithms in computer vision. + +The goal of the challenge is to develop and implement a machine-learning model capable of efficiently classifying encrypted CIFAR-10 images without decrypting them. + +## Challenge Info: + +1. **Challenge type**: This challenge is a White Box. +The project with source code is required. +2. **Encryption Scheme**: CKKS. +3. **Supported libraries**: [OpenFHE](https://github.com/openfheorg/openfhe-development), [Lattigo](https://github.com/tuneinsight/lattigo). +4. **Input**: + - Encrypted image + - Cryptocontext + - Public key + - Multiplication key + - Galois keys +5. **Output**: Encrypted classification result. + +## How to Participate + +This is a **White Box** challenge. +We've prepared a guide on how to participate in these types of challenges, please see our [User Guide](https://fherma.io/how_it_works). + +## Encoding Technique + +We utilize the following class indexing for the CIFAR-10 dataset. + +| Index | Class| +| -------- | -------- | +| 0 | Airplane | +| 1 | Automobile | +| 2 | Bird | +| 3 | Cat | +| 4 | Deer | +| 5 | Dog | +| 6 | Frog | +| 7 | Horse | +| 8 | Ship | +| 9 | Truck | + +### Input + +Each image is encoded as a real vector with a dimension of 3072=3x1024. +The initial 1024 slots denote the red channel, the subsequent ones denote green, and the final segment denotes blue. +Each slot stores value in the range of [0, 255]. + +If you need the data to be packaged in a different way, please open an issue on the [GitHub](https://github.com/Fherma-challenges/cifar-10). + +### Output + +The outcome of the computation is governed by the initial 10 slots in the resultant ciphertext. +If the input image belongs to class "i", then within the first 10 slots of the resultant vector, the maximum value must be located in slot "i." + +## Parameters + +Parameters used to generate cryptocontext, keys and ciphertext can be changed through the `config.json` file located in the project root. +Parameters must provide security of at least 128 bits. + +## Implementation + +Your implementation could be here! + +## Test Environment + +The solution will be tested inside a docker container. +The following libraries/packages will be used in the testing environment: + - **OpenFHE**: v1.1.2 + - **OpenFHE-Python**: v0.8.4 + - **Lattigo**: v5.0.2 + +### Command-Line Interface for Application Testing + +#### OpenFHE +The application should support the following command-line interface (CLI) options: + +- **--input** [path]: Specifies the path to the file containing the encrypted test image. +- **--output** [path]: Specifies the path to the file where the result should be written. +- **--cc** [path]: Indicates the path to the Cryptocontext file serialized in **BINARY** form. +- **--key_public** [path]: Specifies the path to the Public Key file. +- **--key_mult** [path]: Specifies the path to the Evaluation (Multiplication) Key file. +- **--key_rot** [path]: Specifies the path to the Rotation Key file. + +#### Lattigo +The application should support the following command-line interface (CLI) options: + +- **--input** [path]: Specifies the path to the file containing the encrypted test image. +- **--output** [path]: Specifies the path to the file where the result should be written. +- **--cc** [path]: Indicates the path to the Cryptocontext file serialized in **BINARY** form. +- **--key_eval** [path]: defines the path to the file where `MemEvaluationKeySet` object is serialized. `MemEvaluationKeySet` contains the evaluation key and Galois keys. + +## Example + +If the input image is classified as airplane (class 0), then the following outcomes are considered correct: + +| 0.78 | 0.23 | 0.56 | 0.75 | 0 | 0.1 | 0.23 | 0.56 | 0.43 | 0.3 | ... | +|---|---|---|---|---|---|---|---|---|---|---| + +| 0.98 | 0.23 | 0.26 | 0.93 | 0 | 0.1 | 0.23 | 0.56 | 0.43 | 0.3 | ... | +|---|---|---|---|---|---|---|---|---|---|--- | + +| 0.48 | 0.23 | 0.16 | 0.17 | 0 | 0.1 | 0.23 | 0.26 | 0.43 | 0.3 | ... | +|---|---|---|---|---|---|---|---|---|---|---| + +## Useful Links + +* [OpenFHE](https://github.com/openfheorg/openfhe-development) +* [OpenFHE Python](https://github.com/openfheorg/openfhe-python) +* [Lattigo](https://github.com/tuneinsight/lattigo) + +## Help + +If you have any questions, you can: + * Contact us by email: support@fherma.io + * Ask a question in our [Discord](https://discord.gg/NfhXwyr9M5). + * Open an issue in the [GitHub Repository](https://github.com/Fherma-challenges/cifar-10). + * Use [OpenFHE Discourse](https://openfhe.discourse.group). diff --git a/cpp/include/cifar/cifar_ckks.h b/cpp/include/cifar/cifar_ckks.h new file mode 100644 index 0000000..9b2f7c9 --- /dev/null +++ b/cpp/include/cifar/cifar_ckks.h @@ -0,0 +1,34 @@ +#include "openfhe.h" + +#include "ciphertext-ser.h" +#include "cryptocontext-ser.h" +#include "key/key-ser.h" +#include "scheme/ckksrns/ckksrns-ser.h" + +using namespace lbcrypto; + +class CIFAR10CKKS { + CryptoContext m_cc; + PublicKey m_PublicKey; + Ciphertext m_InputC; + Ciphertext m_OutputC; + std::string m_PubKeyLocation; + std::string m_MultKeyLocation; + std::string m_RotKeyLocation; + std::string m_CCLocation; + std::string m_InputLocation; + std::string m_OutputLocation; + +public: + CIFAR10CKKS(std::string ccLocation, std::string pubKeyLocation, std::string multKeyLocation, + std::string rotKeyLocation, + std::string inputLocation, + std::string outputLocation); + + void initCC(); + + void eval(); + + void serializeOutput(); + +}; diff --git a/cpp/include/cifar/config.json b/cpp/include/cifar/config.json new file mode 100644 index 0000000..4435b1e --- /dev/null +++ b/cpp/include/cifar/config.json @@ -0,0 +1,13 @@ +{ + "indexes_for_rotation_key": [ + 1, + 2, + 3, + 4, + 5 + ], + "ring_dimension": 32768, + "mult_depth": 10, + "batch_size": 16384, + "scale_mod_size": 48 + } diff --git a/cpp/include/parity/README.md b/cpp/include/parity/README.md new file mode 100644 index 0000000..9d99789 --- /dev/null +++ b/cpp/include/parity/README.md @@ -0,0 +1,97 @@ +# Parity component + +*This is a stub repository for the future Parity component from the IBM challenge on FHERMA https://fherma.io/challenges/65ef8c4c5428d672bcc3977b which is live on March-Jun 2024.* + +*Link to the template repository: https://github.com/Fherma-challenges/parity* + +--- + +## Overview + +This challenge was developed by [IBM Research](https://research.ibm.com). +The objective of the challenge is to design an algorithm that evaluates the function `parity(x)` under CKKS. +The function `parity(x)` gets an integer and returns its least significant bit (LSB). In other words, + +$$parity(x) = x \mod 2,$$ + +where $x \in \mathbb{Z}.$ + +The `parity` function is closely related to the bit extraction problem, where given an integer $x$ the goal is to find its bit representation $x =\sum 2^i b_i$ which is useful in many cases, e.g., comparisons. +Thus, an efficient implementation of `parity(x)` would lead to an efficient implementation of bit extraction. + +## Challenge Info: + +1. **Challenge type:** This challenge is a White Box challenge. +Participants are required to submit the project with their source code. +2. **Encryption Scheme:** CKKS. +3. **FHE Library:** OpenFHE, Lattigo. +4. **Input Data:** Encrypted vector $x = (x_1, \ldots)$, where $x_i \in [0,255]$. +5. **Output Data:** The outcome should be an encrypted vector $parity(x)= \left(parity\left(x_1\right), \ldots\right)$. + +## How to Participate + +This is a **White Box** challenge. +We've prepared a guide on how to participate in these types of challenges, please see our [User Guide](https://fherma.io/how_it_works). + +## Parameters of the Key + +1. **Bootstrapping:** The key will support bootstrapping. +2. **Number of slots:** $2^{16}$. +3. **Multiplication depth:** 29. +4. **Fractional part precision (ScaleModSize):** 59 bits. +5. **First Module Size:** 60 bits. + +## Parameters of the input + +1. **Packing:** Each slot will contain one value $x_i$. +2. **Input range:** For each element $x_i=n_i + e_i$, where $n_i\in [0,255]$ is an integer, and $|e_i| < 10^{-5}$ is a small noise. + +## Requirements of the output + +1. **Packing:** Each slot will contain one value $y_i = parity(x_i)$, the parity of the corresponding slot in the input. +2. **Ouput range:** For each element $y_i=b_i + E_i$, where $y_i\in [0,1]$ is an integer, and $|E_i| < 10^{-2}$ is a small noise. + +## Implementation + +Your implementation could be here! + +## Test Environment + +Submissions will be evaluated on a single-core CPU. +The following libraries/packages will be used for generating test case data and for testing solutions: + +- **OpenFHE:** v1.1.4 +- **OpenFHE-Python:** v0.8.6 +- **Lattigo:** v5.0.2 +- **HElayers:** v1.5.3.1 [Download](https://ibm.github.io/helayers/ 'Download HElayers') +- **pyhelayers:** v1.5.3.1 [Download](https://ibm.github.io/helayers/ 'Download pyhelayers') + +## Example + +The executable will be run as follows: + +``` +./app --cc cc.bin --key_public pub.bin --key_mult mult.bin --input in.bin --output out.bin +``` + +An example of the message encrypted in `in.bin`: + +`Input = [203.0000005, 102.0000008, 3.0000002, 56.9999994, 77.9999993, ...]` + +An example output for this input: + +`Output = [0.995, 0.008, 1.002, 1.004, -0.003, ...]` + +## Useful Links + +* [OpenFHE](https://github.com/openfheorg/openfhe-development) +* [OpenFHE Python](https://github.com/openfheorg/openfhe-python) +* [Lattigo](https://github.com/tuneinsight/lattigo) + +## Help + +If you have any questions, you can: + * Contact us by email: support@fherma.io + * Ask a question in our [Discord](https://discord.gg/NfhXwyr9M5). + * Open an issue in the [GitHub Repository](https://github.com/Fherma-challenges/parity/issues). + * Use [OpenFHE Discourse](https://openfhe.discourse.group). diff --git a/cpp/include/parity/config.json b/cpp/include/parity/config.json new file mode 100644 index 0000000..5cad678 --- /dev/null +++ b/cpp/include/parity/config.json @@ -0,0 +1,16 @@ +{ + "indexes_for_rotation_key": [ + 1 + ], + "mult_depth": 29, + "ring_dimension": 131072, + "scale_mod_size": 59, + "first_mod_size": 60, + "batch_size": 65536, + "enable_bootstrapping": false, + "levels_available_after_bootstrap": 10, + "level_budget": [ + 4, + 4 + ] +} diff --git a/cpp/include/parity/parity_ckks.h b/cpp/include/parity/parity_ckks.h new file mode 100644 index 0000000..f536bb1 --- /dev/null +++ b/cpp/include/parity/parity_ckks.h @@ -0,0 +1,31 @@ +#include "openfhe.h" + +#include "ciphertext-ser.h" +#include "cryptocontext-ser.h" +#include "key/key-ser.h" +#include "scheme/ckksrns/ckksrns-ser.h" + +using namespace lbcrypto; + +class ParityCKKS { + CryptoContext m_cc; + PublicKey m_PublicKey; + Ciphertext m_InputC; + Ciphertext m_OutputC; + std::string m_PubKeyLocation; + std::string m_MultKeyLocation; + std::string m_RotKeyLocation; + std::string m_CCLocation; + std::string m_InputLocation; + std::string m_OutputLocation; + +public: + ParityCKKS(std::string ccLocation, std::string pubKeyLocation, std::string multKeyLocation, + std::string rotKeyLocation, std::string inputLocation, std::string outputLocation); + + void initCC(); + + void eval(); + + void serializeOutput(); +}; diff --git a/cpp/include/relu/README.md b/cpp/include/relu/README.md new file mode 100644 index 0000000..62e18c2 --- /dev/null +++ b/cpp/include/relu/README.md @@ -0,0 +1,84 @@ +# ReLU component + +*This is a stub repository for the future ReLU component from the FHERMA ReLU challenge https://fherma.io/challenges/6542c282100761da3b545c3e which is live on March-Jun 2024.* +*Link to the template repository: https://github.com/Fherma-challenges/relu* + +--- + +## Overview + +The Rectified Linear Unit (ReLU) function is a fundamental activation function used extensively in neural networks, particularly in deep learning models. +It is a simple yet powerful non-linear function that introduces non-linearity into the network, allowing it to learn complex patterns and representations in the data. + +The ReLU function is defined mathematically as: + +ReLU(x) = \max(0, x) + +The objective of the challenge is to create an algorithm capable of computing the ReLU function on data encrypted with CKKS. + +## Challenge Info: + +1. **Challenge type:** This challenge is a Black Box. +Participants are only required to submit the resultant ciphertext. +Code or implementation details are not required during the challenge. +However, the project code will be asked from the winner of the competition. +2. **Encryption Scheme**: CKKS. +3. **Supported libraries**: [OpenFHE](https://github.com/openfheorg/openfhe-development), [Lattigo](https://github.com/tuneinsight/lattigo). +4. **Input Data**: + * Encrypted vector **X** + * Cryptocontext + * Public key + * Multiplication (Relinearization) key +5. **Output Data**: The outcome should be an encrypted vector `ReLU(x)`. + +*If additional rotation keys are needed, please open an issue on [GitHub](https://github.com/Fherma-challenges/relu) and we will provide them.* + +## How to Participate + +This is a **Black Box** challenge. +We've prepared a guide on how to participate in these types of challenges, please see our [User Guide](https://fherma.io/how_it_works). + +## Encoding Technique + +By default, we pack the input vector **X** in ciphertext as follows: +| x0 | x1 | x2 | x3 |... +|---|---|---|---|--- + +The resulting **ReLU(X)** vector should be packed in the same manner: + +| ReLU(x0) | ReLU(x1) | ReLU(x2) | ReLU(x3) | ... +|---|---|---|---|--- + +*If you need the data to be packaged in a different format, please open an issue on [GitHub](https://github.com/Fherma-challenges/relu).* + +## Implementation + +Your implementation could be here! + +## Test Environment + +The following libraries/packages were used for generating test cases: + - **OpenFHE**: v1.1.2 + - **Lattigo**: v5.0.2 + +Participants can use any third-party software and libraries to solve the challenge. +The only requirement is that the ciphertext uploaded to the platform should be compatible with the OpenFHE library v1.1 or Lattigo v5.0.2. + +## Example + +Suppose we have a vector `[-0.45, 0, 0.23]`. +After applying the **ReLU** function to each element, we get the vector `[0, 0, 0.23]`. + +## Useful Links + +* [OpenFHE](https://github.com/openfheorg/openfhe-development) +* [OpenFHE Python](https://github.com/openfheorg/openfhe-python) +* [Lattigo](https://github.com/tuneinsight/lattigo) + +## Help + +If you have any questions, you can: + * Contact us by email: support@fherma.io + * Ask a question in our [Discord](https://discord.gg/NfhXwyr9M5). + * Open an issue in the [GitHub Repository](https://github.com/Fherma-challenges/relu). + * Use [OpenFHE Discourse](https://openfhe.discourse.group). diff --git a/cpp/include/relu/relu_ckks.h b/cpp/include/relu/relu_ckks.h new file mode 100644 index 0000000..23fce54 --- /dev/null +++ b/cpp/include/relu/relu_ckks.h @@ -0,0 +1,35 @@ +#include "openfhe.h" + +// header files needed for serialization +#include "ciphertext-ser.h" +#include "cryptocontext-ser.h" +#include "key/key-ser.h" +#include "scheme/ckksrns/ckksrns-ser.h" + +using namespace lbcrypto; + +class ReluCKKS +{ + CryptoContext m_cc; + PublicKey m_PublicKey; + Ciphertext m_InputC; + Ciphertext m_OutputC; + std::string m_PubKeyLocation; + std::string m_MultKeyLocation; + std::string m_RotKeyLocation; + std::string m_CCLocation; + std::string m_InputLocation; + std::string m_OutputLocation; + +public: + ReluCKKS(std::string ccLocation, std::string pubKeyLocation, std::string multKeyLocation, + std::string rotKeyLocation, + std::string inputLocation, + std::string outputLocation); + + void initCC(); + + void eval(); + + void serializeOutput(); +}; From f7b8ab362f44e50dff5a313003c3aeadf186b5c6 Mon Sep 17 00:00:00 2001 From: Alexandra Mirzuitova Date: Mon, 1 Apr 2024 15:04:26 +0300 Subject: [PATCH 3/3] Added Go template by Sergey Gomenyuk Co-authored-by: Sergey Gomenyuk --- cpp/include/cifar/lattigo/config.json | 6 + cpp/include/cifar/lattigo/go.sum | 35 +++++ .../lattigo/internal/solution/solution.go | 19 +++ cpp/include/cifar/lattigo/main.go | 128 ++++++++++++++++++ cpp/include/cifar/{ => openfhe}/cifar_ckks.h | 0 cpp/include/cifar/{ => openfhe}/config.json | 0 cpp/include/parity/lattigo/config.json | 6 + cpp/include/parity/lattigo/go.sum | 35 +++++ .../lattigo/internal/solution/solution.go | 19 +++ cpp/include/parity/lattigo/main.go | 128 ++++++++++++++++++ cpp/include/parity/{ => openfhe}/config.json | 0 .../parity/{ => openfhe}/parity_ckks.h | 0 cpp/include/relu/config.json | 9 ++ 13 files changed, 385 insertions(+) create mode 100644 cpp/include/cifar/lattigo/config.json create mode 100644 cpp/include/cifar/lattigo/go.sum create mode 100644 cpp/include/cifar/lattigo/internal/solution/solution.go create mode 100644 cpp/include/cifar/lattigo/main.go rename cpp/include/cifar/{ => openfhe}/cifar_ckks.h (100%) rename cpp/include/cifar/{ => openfhe}/config.json (100%) create mode 100644 cpp/include/parity/lattigo/config.json create mode 100644 cpp/include/parity/lattigo/go.sum create mode 100644 cpp/include/parity/lattigo/internal/solution/solution.go create mode 100644 cpp/include/parity/lattigo/main.go rename cpp/include/parity/{ => openfhe}/config.json (100%) rename cpp/include/parity/{ => openfhe}/parity_ckks.h (100%) create mode 100644 cpp/include/relu/config.json diff --git a/cpp/include/cifar/lattigo/config.json b/cpp/include/cifar/lattigo/config.json new file mode 100644 index 0000000..43d11a7 --- /dev/null +++ b/cpp/include/cifar/lattigo/config.json @@ -0,0 +1,6 @@ +{ + "log_n": 17, + "log_q": [60, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50], + "log_p": [56, 55, 55, 55], + "log_default_scale": 50 +} diff --git a/cpp/include/cifar/lattigo/go.sum b/cpp/include/cifar/lattigo/go.sum new file mode 100644 index 0000000..cc0067a --- /dev/null +++ b/cpp/include/cifar/lattigo/go.sum @@ -0,0 +1,35 @@ +github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924 h1:DG4UyTVIujioxwJc8Zj8Nabz1L1wTgQ/xNBSQDfdP3I= +github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tuneinsight/lattigo/v5 v5.0.2 h1:g+WmQK0G04nldAPnthgBFsfMtCJRLcfwME+cR9hLuIg= +github.com/tuneinsight/lattigo/v5 v5.0.2/go.mod h1:mmynIHGOeVRGYzuHRdZNbDLJWe8WHDYCgYkl9WZrHN0= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cpp/include/cifar/lattigo/internal/solution/solution.go b/cpp/include/cifar/lattigo/internal/solution/solution.go new file mode 100644 index 0000000..451ddbd --- /dev/null +++ b/cpp/include/cifar/lattigo/internal/solution/solution.go @@ -0,0 +1,19 @@ +package solution + +import ( + "io" + + "github.com/tuneinsight/lattigo/v5/core/rlwe" + "github.com/tuneinsight/lattigo/v5/he/hefloat" +) + +func SolveTestcase( + params *hefloat.Parameters, + evl *rlwe.MemEvaluationKeySet, + pk *rlwe.PublicKey, + cipher *rlwe.Ciphertext, + out io.Writer, +) (*rlwe.Ciphertext, error) { + // Put your solution here + return nil, nil +} diff --git a/cpp/include/cifar/lattigo/main.go b/cpp/include/cifar/lattigo/main.go new file mode 100644 index 0000000..ec23322 --- /dev/null +++ b/cpp/include/cifar/lattigo/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "errors" + "flag" + "io" + "log" + "os" + + "github.com/tuneinsight/lattigo/v5/core/rlwe" + "github.com/tuneinsight/lattigo/v5/he/hefloat" + + "app/internal/solution" +) + +func main() { + ccFile := flag.String("cc", "", "") + evalFile := flag.String("key_eval", "", "") + inputFile := flag.String("input", "", "") + outputFile := flag.String("output", "", "") + pkFile := flag.String("key_public", "", "") + + flag.Parse() + + params, err := readContext(ccFile) + if err != nil { + log.Fatalf("read context error: %s", err.Error()) + } + + evl, err := readEvaluationKeySet(evalFile) + if err != nil { + log.Fatalf("read evaluation key set error: %s", err.Error()) + } + + pk, err := readPublicKey(pkFile) + if err != nil { + log.Fatalf("read public key error: %s", err.Error()) + } + + in, err := readInputFile(inputFile) + if err != nil { + log.Fatalf("read input file error: %s", err.Error()) + } + + out, err := os.Create(*outputFile) + if err != nil { + log.Fatalf("create output file error: %s", err.Error()) + } + + defer out.Close() + + res, err := solution.SolveTestcase(params, evl, pk, in, out) + if err != nil { + log.Fatalf("solution error: %s", err) + } + + if _, err = res.WriteTo(out); err != nil { + log.Fatalf("can't write resulted ciphertext: %s", err.Error()) + } +} + +func readContext(ccFile *string) (*hefloat.Parameters, error) { + if ccFile == nil { + return nil, errors.New("ccFile is nil") + } + + ccData, err := os.ReadFile(*ccFile) + if err != nil { + return nil, errors.New("can't read context") + } + + params := &hefloat.Parameters{} + if err := params.UnmarshalBinary(ccData); err != nil { + return nil, errors.New("can't unmarshal context") + } + + return params, nil +} + +func readEvaluationKeySet(evalFile *string) (*rlwe.MemEvaluationKeySet, error) { + if evalFile == nil { + return nil, errors.New("evalFile is nil") + } + + evalF, err := os.Open(*evalFile) + if err != nil { + return nil, errors.New("can't open evaluation key set file") + } + defer evalF.Close() + + evl := &rlwe.MemEvaluationKeySet{} + + if _, err = evl.ReadFrom(evalF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read evaluation key set file") + } + + return evl, nil +} + +func readPublicKey(pkFile *string) (*rlwe.PublicKey, error) { + pkF, err := os.Open(*pkFile) + if err != nil { + return nil, errors.New("can't open public key file") + } + defer pkF.Close() + + pk := &rlwe.PublicKey{} + if _, err = pk.ReadFrom(pkF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read public key file") + } + + return pk, nil +} + +func readInputFile(inputFile *string) (*rlwe.Ciphertext, error) { + inputF, err := os.Open(*inputFile) + if err != nil { + return nil, errors.New("can't open input ciphertext") + } + defer inputF.Close() + + in := &rlwe.Ciphertext{} + if _, err := in.ReadFrom(inputF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read input ciphertext") + } + + return in, nil +} diff --git a/cpp/include/cifar/cifar_ckks.h b/cpp/include/cifar/openfhe/cifar_ckks.h similarity index 100% rename from cpp/include/cifar/cifar_ckks.h rename to cpp/include/cifar/openfhe/cifar_ckks.h diff --git a/cpp/include/cifar/config.json b/cpp/include/cifar/openfhe/config.json similarity index 100% rename from cpp/include/cifar/config.json rename to cpp/include/cifar/openfhe/config.json diff --git a/cpp/include/parity/lattigo/config.json b/cpp/include/parity/lattigo/config.json new file mode 100644 index 0000000..43d11a7 --- /dev/null +++ b/cpp/include/parity/lattigo/config.json @@ -0,0 +1,6 @@ +{ + "log_n": 17, + "log_q": [60, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50], + "log_p": [56, 55, 55, 55], + "log_default_scale": 50 +} diff --git a/cpp/include/parity/lattigo/go.sum b/cpp/include/parity/lattigo/go.sum new file mode 100644 index 0000000..cc0067a --- /dev/null +++ b/cpp/include/parity/lattigo/go.sum @@ -0,0 +1,35 @@ +github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924 h1:DG4UyTVIujioxwJc8Zj8Nabz1L1wTgQ/xNBSQDfdP3I= +github.com/ALTree/bigfloat v0.0.0-20220102081255-38c8b72a9924/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tuneinsight/lattigo/v5 v5.0.2 h1:g+WmQK0G04nldAPnthgBFsfMtCJRLcfwME+cR9hLuIg= +github.com/tuneinsight/lattigo/v5 v5.0.2/go.mod h1:mmynIHGOeVRGYzuHRdZNbDLJWe8WHDYCgYkl9WZrHN0= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= +golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cpp/include/parity/lattigo/internal/solution/solution.go b/cpp/include/parity/lattigo/internal/solution/solution.go new file mode 100644 index 0000000..451ddbd --- /dev/null +++ b/cpp/include/parity/lattigo/internal/solution/solution.go @@ -0,0 +1,19 @@ +package solution + +import ( + "io" + + "github.com/tuneinsight/lattigo/v5/core/rlwe" + "github.com/tuneinsight/lattigo/v5/he/hefloat" +) + +func SolveTestcase( + params *hefloat.Parameters, + evl *rlwe.MemEvaluationKeySet, + pk *rlwe.PublicKey, + cipher *rlwe.Ciphertext, + out io.Writer, +) (*rlwe.Ciphertext, error) { + // Put your solution here + return nil, nil +} diff --git a/cpp/include/parity/lattigo/main.go b/cpp/include/parity/lattigo/main.go new file mode 100644 index 0000000..ec23322 --- /dev/null +++ b/cpp/include/parity/lattigo/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "errors" + "flag" + "io" + "log" + "os" + + "github.com/tuneinsight/lattigo/v5/core/rlwe" + "github.com/tuneinsight/lattigo/v5/he/hefloat" + + "app/internal/solution" +) + +func main() { + ccFile := flag.String("cc", "", "") + evalFile := flag.String("key_eval", "", "") + inputFile := flag.String("input", "", "") + outputFile := flag.String("output", "", "") + pkFile := flag.String("key_public", "", "") + + flag.Parse() + + params, err := readContext(ccFile) + if err != nil { + log.Fatalf("read context error: %s", err.Error()) + } + + evl, err := readEvaluationKeySet(evalFile) + if err != nil { + log.Fatalf("read evaluation key set error: %s", err.Error()) + } + + pk, err := readPublicKey(pkFile) + if err != nil { + log.Fatalf("read public key error: %s", err.Error()) + } + + in, err := readInputFile(inputFile) + if err != nil { + log.Fatalf("read input file error: %s", err.Error()) + } + + out, err := os.Create(*outputFile) + if err != nil { + log.Fatalf("create output file error: %s", err.Error()) + } + + defer out.Close() + + res, err := solution.SolveTestcase(params, evl, pk, in, out) + if err != nil { + log.Fatalf("solution error: %s", err) + } + + if _, err = res.WriteTo(out); err != nil { + log.Fatalf("can't write resulted ciphertext: %s", err.Error()) + } +} + +func readContext(ccFile *string) (*hefloat.Parameters, error) { + if ccFile == nil { + return nil, errors.New("ccFile is nil") + } + + ccData, err := os.ReadFile(*ccFile) + if err != nil { + return nil, errors.New("can't read context") + } + + params := &hefloat.Parameters{} + if err := params.UnmarshalBinary(ccData); err != nil { + return nil, errors.New("can't unmarshal context") + } + + return params, nil +} + +func readEvaluationKeySet(evalFile *string) (*rlwe.MemEvaluationKeySet, error) { + if evalFile == nil { + return nil, errors.New("evalFile is nil") + } + + evalF, err := os.Open(*evalFile) + if err != nil { + return nil, errors.New("can't open evaluation key set file") + } + defer evalF.Close() + + evl := &rlwe.MemEvaluationKeySet{} + + if _, err = evl.ReadFrom(evalF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read evaluation key set file") + } + + return evl, nil +} + +func readPublicKey(pkFile *string) (*rlwe.PublicKey, error) { + pkF, err := os.Open(*pkFile) + if err != nil { + return nil, errors.New("can't open public key file") + } + defer pkF.Close() + + pk := &rlwe.PublicKey{} + if _, err = pk.ReadFrom(pkF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read public key file") + } + + return pk, nil +} + +func readInputFile(inputFile *string) (*rlwe.Ciphertext, error) { + inputF, err := os.Open(*inputFile) + if err != nil { + return nil, errors.New("can't open input ciphertext") + } + defer inputF.Close() + + in := &rlwe.Ciphertext{} + if _, err := in.ReadFrom(inputF); err != nil && !errors.Is(err, io.EOF) { + return nil, errors.New("can't read input ciphertext") + } + + return in, nil +} diff --git a/cpp/include/parity/config.json b/cpp/include/parity/openfhe/config.json similarity index 100% rename from cpp/include/parity/config.json rename to cpp/include/parity/openfhe/config.json diff --git a/cpp/include/parity/parity_ckks.h b/cpp/include/parity/openfhe/parity_ckks.h similarity index 100% rename from cpp/include/parity/parity_ckks.h rename to cpp/include/parity/openfhe/parity_ckks.h diff --git a/cpp/include/relu/config.json b/cpp/include/relu/config.json new file mode 100644 index 0000000..3106f7a --- /dev/null +++ b/cpp/include/relu/config.json @@ -0,0 +1,9 @@ +{ + "indexes_for_rotation_key": [ + 1, + 2, + 3, + 4, + 5 + ] + }