Git Product home page Git Product logo

seal-embedded's Introduction

SEAL-Embedded

SEAL-Embedded is an open-source (MIT licensed) homomorphic encryption toolset for embedded devices developed by the Cryptography and Privacy Reserach Group at Microsoft. It implements the designs of CKKS-style encoding and encryption with small code and memory footprint that is published in this peer-reviewed paper. SEAL-Embedded is written in C and C++ and primarily designed for building high-level applications on Azure Sphere's ARM A7 processor. To enable wider experiments by developers and researchers, SEAL-Embedded includes configurations that target ARM M4 as well.

Acknowledgments

The majority of SEAL-Embedded was developed by Deepika Natarajan from University of Michigan during an internship at Microsoft, despite her not being present in the Git history.

Introduction

Homomorphic encryption allows for computation on encryption data without decryption. Typically, a client generates a secret key and public keys; data is encrypted with the secret key or public keys; encrypted data is sent to a untrusted server for computation; encrypted results are returned to the client who then decrypts the results. Interested users of SEAL-Embedded should read the Introduction section of Microsoft SEAL prior to using SEAL-Embedded to learn more about homomorphic encryption and the Microsoft SEAL library. SEAL-Embedded enables embedded devices to encrypt data; it does not perform key generation, computation on encrypted data, or decryption (but does include an easy-to-use adapter interface to perform key generation with Microsoft SEAL).

SEAL-Embedded consists of mainly two components: a device library (device/lib) to build an application that encrypts data, and an adapter application (adapter) for compability with Microsoft SEAL. The simplest workflow is described as follows:

  1. Run the adapter to generate a secret key and public keys
  2. Build and run an application with the device library by creating an image of the application together with the public key (for asymmetric encryption) or secret key (for symmetric encryption) for a target device
  3. Run the adapter on an remote server to receive and serialize encrypted data to Microsoft-SEAL-compatible format
  4. Build and run an application with Microsoft SEAL to compute on encrypted data
  5. Decrypt the encrypted results with Microsoft SEAL on a safe device that has the secret key

Warning

This library is research code and is not yet intended for production use. Use at your own risk. Storing a secret key on device (i.e., using symmetric encryption) can be extremely dangerous. Use public key (asymmetric encryption), or consult a security expert before creating a symmetric key deployment. See more information related to SECURITY.

Building SEAL-Embedded

On all platforms, SEAL-Embedded is built with CMake. We recommend using an out-of-source build, although in-source builds work as well. Below we give instructions for how to configure and build SEAL-Embedded components.

SEAL-Embedded Adapter

The adapter (adapter) application automatically downloads and builds Microsoft SEAL as a dependency. System requirements are listed in SEAL/README.md.

On Unix-like systems:

cd adapter
cmake -S . -B build
cmake --build build -j
./build/bin/se_adapter # run adapter

On Windows, following this guide, use Visual Studio 2019 to open adapter/CMakeLists.txt as a CMake project.

SEAL-Embedded Device Library

The device library comes with optional executables: unit tests (device/test) and benchmarks (device/bench). The library itself, unit tests, and benchmarks can be built on a native system (Linux or macOS) with the same development environment listed in SEAL-Embedded adapter.

cd device 
cmake -S . -B build -DSE_BUILD_LOCAL=ON
cmake --build build -j
./build/bin/seal_embedded_tests # run tests locally

This by default builds a library and unit tests.

To build the library and run tests for the Azure Sphere A7 target instead:

cd device 
cmake -G Ninja -S . -B build -DSE_BUILD_LOCAL=OFF
cmake --build build -j
sh ./scripts/sphere_a7_launch_cl.sh

Open another terminal and invoke gdb:

sh ./scripts/gdb_launch_sphere_a7.sh

The output should now print to the first terminal.

The following options are configurable for custom builds (default settings are in bold).

CMake option Values Information
SE_BUILD_LOCAL ON / OFF Set to OFF to target an embedded device.
SE_BUILD_M4 ON / OFF Set to ON to target ARM M4, OFF to target ARM A7 on Azure Sphere.
SE_M4_IS_SPHERE ON / OFF Set to ON to target the real-time core on Azure Sphere, OFF to target other ARM M4 processors.
CMAKE_BUILD_TYPE Debug
Release
MinSizeRel
RelWithDebInfo
Set to Release for the best run-time performance and the smallest code size.
SE_BUILD_TYPE Tests
Bench
Lib
Set to Bench to build instead the benchmark executable, to Lib to build a library only.

Note: SEAL-Embedded device code is built in Debug and Local mode by default! We recommend that all users of the library first ensure that the included tests and their target application run in Debug mode locally, for their desired memory configuration (see: user_defines.h and the SEAL-Embedded paper for more details on memory configuration options). After verifying that these tests pass, users should change CMAKE_BUILD_TYPE to Release, uncomment SE_DISABLE_TESTING_CAPABILITY in user_defines.h, and set SE_ASSERT_TYPE to 0 (None) in user_defines.h, for optimal performance. To run benchmarks, change SE_BUILD_TYPE to Bench and uncomment SE_ENABLE_TIMERS in defines.h. Users should verify that everything runs as expected in their local development environment first before targetting an embedded device.

Note: SEAL-Embedded Adapter must be built and executed first to generate required key and precomputation files. The adapter by default generates and writes files to device/adapter_output_files. If device/adapter_output_files does not exist, you should create this folder prior to running the adapter. Note that the adapter is not intended to support generation or usage of multiple parameter instances at once (i.e., using the adapter to create files for degree = 1024, then using the adapter to create files for degree = 4096, will cause some of the files generated for degree = 1024 to be overwritten).

To target an embedded device, the specific SDK for the target device is usually required. Either the unit tests or benchmarks can be built and imaged on the device. Using the Azure Sphere as an example, please follow this guide. Ultimately, users can develop their own application following this guide and statically link to the SEAL-Embedded device library.

For targeting ARM M4 on the Azure Sphere or other development boards, please follow related documents and tutorials. Note that stack size limitations may prevent certain configurations of the library to run on an Azure Sphere M4 target. For the convinience of verifying ARM M4 compatibility, we also provide device/lib/sdk_config.h for an easier deployment on Nordic Semiconductor nRF5* series devices.

Contributing

The main purpose of open sourcing SEAL-Embedded is to enable developers to build privacy-enhancing applications or services. We welcome any suggestions or contributions to improve the usebility, efficiency, and quality of SEAL-Embedded. To keep the development active, the main branch will always include the most recent changes, beyond the lastest release tag. For contributing to Microsoft SEAL, please see CONTRIBUTING.

Citing SEAL-Embedded

To cite SEAL-Embedded in academic papers, please use the following BibTeX entries.

    @Article{sealembedded,
        title = {{SEAL}-Embedded: A Homomorphic Encryption Library for the Internet of Things},
        author = {Deepika Natarajan and Wei Dai},
        journal = {{IACR} Transactions on Cryptographic Hardware and Embedded Systems},
        publisher = {Ruhr-Universit{\"a}t Bochum},
        year = 2021,
        month = jul,
        pages = {756--779},
        valume = 2021,
        number = 3,
        doi = {10.46586/tches.v2021.i3.756-779},
        issn = {2569-2925},
        note = {\url{https://tches.iacr.org/index.php/TCHES/article/view/8991}},
    }

seal-embedded's People

Contributors

dnat112 avatar florentclmichel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

seal-embedded's Issues

Problem with the asymmetric encryption

Hello,
i have an issue while trying to decode the message in asymmetric. I'm currently using this configurations:

SE_IFFT_TYPE 1 (load)
SE_NTT_TYPE 3 (load fast)
SE_INDEX_MAP_TYPE 3 (load persistent)
SE_DATA_LOAD_TYPE 1 (copy from headers)
SE_USE_MALLOC
SE_USE_COMPLEX_FUNCS
SE_MEMPOOL_ALLOC_VALUES
SE_DEFINE_PK_DATA
SE_DEFINE_SK_DATA

Basically i'm in case where i can't load data from txt files, so i used the adapter to generate headers file for index, roots and all the keys, then i added those headers to my project. When i run the test_ckks_encode_encrypt_sym() all data are loaded successfully and encode-encryption/decryption-decode occours as it is intended, with all degrees.

Now i'm trying to run the test_ckks_encode_encrypt_asym() with n = 4096, but the decryption is not working. I tried 3 different ways:

  1. In this first case i run the code setting "parms.sample_s = true" so my secret key is sampled and when the gen_pk() function occours the public keys are computed through the ckks_encode_encrypt_sym(). In this case i commented the code lines in ckks_encode_encrypt_asym() where the keys are loaded from the vectors in header files, or i'll come up with two set of public keys. But when the decryption occours the pte calculated and the pte decrypted don't match at all.

  2. In this case both the secret&public keys are loaded from headers, so i set the "parms.sample_s = false" in order to load through ckks_setup_s() the secret key. When the gen_pk() function comes the public keys are generated through the ckks_encode_encrypt_sym(), and i don't want this cause i already have them from headers, but i cannot avoid this function or the secret key is not expanded and so on. When i run the code like this i got the same error as before.

  3. In this last case i load the secret key from the file and the public keys are calculated through the gen_pk(), the load_pki() is commented this time. Now the pte match but when the decoding occours the valus decoded are totally different from the originals

values --> { 1.00, 0.00, 0.00, 0.00 ..... }
values decoded --> { -549.42, -133.81, 732.54, ...... }

Can you help me, please? How am i supposed to set everything to make the asymmetric encryption/decryption works loading the keys from header files?

Thank you!

Problem with building the library for the RISC-V target

Hi,
when I was trying to build seal embedded library for riscv target, using riscv elf toolchain, which doesn't support shared libraries such as libgcc_s.so, I got the error complaining that -lgcc_s does not exist. It seems that in the device/CMakeLists.txt the line target_link_libraries(seal_embedded_bench PRIVATE m gcc_s c seal_embedded) is trying to unconditionally link with -lgcc_s. It would be good to modify the cmake files to first check if the library exists.
Thank you!

Problem with rotation when i load a key

In the following code ,when I load a secret key and i encrypt then and i decrypt a ciphertext everything works fine. But when i try to rotate the ciphertext it outputs wrong values .Do i have to also save the gal keys .How can I fix this ;

int main(int argc, char *argv[])
{
size_t degree = 8192;
double scale = pow(2, 25);

EncryptionParameters parms(scheme_type::ckks);
seal::SEALContext context = setup_seale_prime_default(degree, parms);
KeyGenerator keygen(context);
Evaluator evaluator(context);
CKKSEncoder encoder(context);

SecretKey sk = keygen.secret_key();
RelinKeys relin_keys;
keygen.create_relin_keys(relin_keys);
GaloisKeys gal_keys;
keygen.create_galois_keys(gal_keys);
//sk_seal_save("key",sk,false);
sk_seal_load("key",context,sk);
Decryptor decryptor(context, sk);

Ciphertext ct;
PublicKey pk;
Plaintext pt;
vector res;

vector test = {1.0, 2.0, 3.0};
encoder.encode(test, scale, pt);
Encryptor encryptor(context, sk);
encryptor.encrypt_symmetric(pt, ct);

//evaluator.rotate_vector(ct,-1, gal_keys, ct);
decryptor.decrypt(ct,pt);
encoder.decode(pt,res);
for(int i = 0; i < 10; i++)
cout << res[i] << " ";

cout<<endl;
return 0;
}
In the following image the first example is with rotation and the second one is without
Screenshot from 2022-04-25 10-35-53

data processing possibilities

Hello ! i want to do some processing to the data that i collected from the SEAL embedded lib but i have some issues . I manage to write a function that multiplies a plain text vector with an encrypted matrix .With degree of 8196 it works fine but with degree 4096 it outputs the wrong answer .Is there something that i can do to fix this ? .I really want to use degree 4094 because the device is constrained

here is the code

#include
#include
#include
#include <unistd.h>
#include "seal/seal.h"
#include "utils.h"

using namespace std;
using namespace seal;

Ciphertext mul_vec(Ciphertext mat,vector mat1,EncryptionParameters params,int y,int x,int scale,GaloisKeys gal_keys){

Ciphertext res;
Plaintext pt;

SEALContext context(params);
Evaluator evaluator(context);
CKKSEncoder encoder(context);

vector<double> p(y*x);
vector<Ciphertext> ctA_result(y);

for(int i=0;i<y;i++){


      for(int ii=0;ii<y*x;ii++)
        p[ii] = 0.001 ;
    for(int ii=0;ii<x;ii++)
        p[ii] = mat1[i];
    
    evaluator.rotate_vector(mat,i*x, gal_keys,ctA_result[i]);
    encoder.encode(p,scale,pt);
    evaluator.multiply_plain(ctA_result[i],pt,ctA_result[i]);

}
evaluator.add_many(ctA_result,res);

for(int i=0;i<y*x;i++)
            p[i] = 0.0001;

for(int ii=0;ii<x;ii++)
        p[ii] =  1.0;
return res;

}

int main(){

   //  size_t degree = 1024;
  // size_t degree = 2048;
  size_t degree = 4096;
 // size_t degree = 8192;

//size_t degree = 16384;

double scale = pow(2, 25);
cout << "Parameters: degree " << degree << ", ntt_form, prime bit-lengths: {";
switch (degree)
{
    case 1024:
        cout << "27}, scale = pow(2, 20)" << endl;
        scale = pow(2, 20);
        break;
    case 2048:
        cout << "27, 27}, scale = pow(2, 25)" << endl;
        scale = pow(2, 25);
        break;

#ifdef SEALE_DEFAULT_4K_27BIT
case 4096:
cout << "27, 27, 27, 28}, scale = pow(2, 20)" << endl;
scale = pow(2, 20);
break;
#else
case 4096:
cout << "30, 30, 30, 19}, scale = pow(2, 25)" << endl;
scale = pow(2, 25);
break;
#endif
case 8192:
cout << "30 (x6), 38}, scale = pow(2, 25)" << endl;
scale = pow(2, 25);
break;
case 16384:
cout << "30 (x13), 48}, scale = pow(2, 25)" << endl;
scale = pow(2, 25);
break;
// -- 32768 is technically possible, but we do not support it
// case 32768: cout << "30 (x28), 41}, scale = pow(2, 25)" << endl;
// scale = pow(2,25);
// break;
default: cout << "Please choose a valid degree." << endl; throw;
}

EncryptionParameters params(scheme_type::ckks);
seal::SEALContext context = setup_seale_prime_default(degree, params);


KeyGenerator keygen(context);
Evaluator evaluator(context);
CKKSEncoder encoder(context);

SecretKey sk = keygen.secret_key();
Decryptor decryptor(context, sk);
PublicKey pk;
GaloisKeys gal_keys;
keygen.create_galois_keys(gal_keys);

keygen.create_public_key(pk);
Encryptor encryptor(context, pk);
Ciphertext ct,ctB;
Plaintext pt;


int y = 2;
int x = 4;
vector<double> d = {0.7,0.7};

vector<double> dw(12);
 

vector<double> mat = {0.2  ,0.2 
                      ,0.2  ,0.2  
                      ,0.2 ,0.2,
                      0.2 ,0.2};

encoder.encode(mat,scale,pt);
encryptor.encrypt(pt,ct);
cout<<"======="<<endl;
Ciphertext cp = mul_vec(ct,d,params,y,x,scale,gal_keys);

decryptor.decrypt(cp,pt);
encoder.decode(pt,dw); 

for(int i=0;i<3*4;i++)
    cout<<dw[i]<<"  "<<endl;

return 0;

}

Esp32/Arduino Support

Hello

I'm trying to use seal embedded library for an esp32 project with an arduino project but i have no idea how to include the library

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.