Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3 docs add placeholders of the planned components #8

Merged
merged 3 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -23,14 +24,15 @@ The library is designed with flexibility in mind, ensuring it's backend-agnostic
</picture>

# 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.
125 changes: 125 additions & 0 deletions cpp/include/cifar/README.md
Original file line number Diff line number Diff line change
@@ -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: [email protected]
* 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).
6 changes: 6 additions & 0 deletions cpp/include/cifar/lattigo/config.json
Original file line number Diff line number Diff line change
@@ -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
}
35 changes: 35 additions & 0 deletions cpp/include/cifar/lattigo/go.sum
Original file line number Diff line number Diff line change
@@ -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=
19 changes: 19 additions & 0 deletions cpp/include/cifar/lattigo/internal/solution/solution.go
Original file line number Diff line number Diff line change
@@ -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
}
128 changes: 128 additions & 0 deletions cpp/include/cifar/lattigo/main.go
Original file line number Diff line number Diff line change
@@ -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
}
34 changes: 34 additions & 0 deletions cpp/include/cifar/openfhe/cifar_ckks.h
Original file line number Diff line number Diff line change
@@ -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<DCRTPoly> m_cc;
PublicKey<DCRTPoly> m_PublicKey;
Ciphertext<DCRTPoly> m_InputC;
Ciphertext<DCRTPoly> 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();

};
13 changes: 13 additions & 0 deletions cpp/include/cifar/openfhe/config.json
Original file line number Diff line number Diff line change
@@ -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
}
Loading