TrustworthyComputing / REDsec

MIT License
9 stars 3 forks source link

Some errors and confusion #2

Closed p719967821 closed 3 months ago

p719967821 commented 3 months ago

hello,sir!sorry to bother you again. I have identified some issues in the code and confused about some of the content, so I am raising the following questions in the hope of receiving your answers.

  1. there is an error in the 72 line of encrypt_imagegpu.cu. it should be `pt[i-count].message = (ptxtval>>(i-count))&1; instead of pt[i-count].message = (ptxt_val>>i)&1;`

  2. I couldn't find bitsize.data in any of the folders, so executing make redcufhe_decrypt_image will result in an error.I imitated your code decrypt_image.cpp and rewrote the file. The code is as follows, but I cannot get the correct classification result. Is there a problem with my code? in nets/mnist/sign1024*3/main.cu :

    int main(void)
    {
    //dimensions
    tDimensions indim ;
    tDimensions outdim ;
    //create network
    cudaSetDevice(0);
    print_status("Instantiating network architecture...\n");
    HeBNN* network = new HeBNN() ;
    network->get_in_dims(&indim) ;
    network->get_out_dims(&outdim) ;
    
    //Results
    size_t in_size = indim.hw.h * indim.hw.w * indim.in_dep;
    tMultiBitPacked* nn_data;
    mbit_calloc_global(&nn_data, in_size, 8);
    tMultiBitPacked* nn_result ;
    mbit_calloc_global(&nn_result, 10, 1);
    
    // Read encrypted image
    for (int k = 0; k < NUM_GPUS; k++) {
      cudaSetDevice(k);
      std::ifstream input_file("../../../client/image.ctxt");
      for(uint32_t i = 0; i < in_size; i++) {
        for (uint8_t j = 0; j < 8; j++) {
          ReadCtxtFromFileRed(nn_data->enc_segs[k][i].ctxt[j], input_file);
        }
      }
      input_file.close();
    }
    
    printf("Running network...\n");
    high_resolution_clock::time_point t1 = high_resolution_clock::now();
    nn_result = network->run(nn_data);
    Synchronize();
    CuCheckError();
    high_resolution_clock::time_point t2 = high_resolution_clock::now();
    duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
    std::cout << "Inference Time: " << time_span.count() << " seconds\n";
    
    // output result to file
    for (uint8_t i = 0; i < 10; i++) { // 10 categories
      WriteCtxtToFileRed(nn_result->enc_segs[0][i].ctxt[0],"../../../client/redcufhe_network_output.ctxt");
    }
    
    printf("Result ctxts loaded into redcufhe_network_output.ctxt.\n");
    CleanUp();
    }

    in decrypt_image_gpu.cu :

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <algorithm>
#include <vector>
#include "REDcuFHE/redcufhe_gpu.cuh"

using namespace std;
using namespace redcufhe;

int num_classes = 0;
int num_bits = 0;
int msg_space = 0;

//就是一个求base^exponent的运算,只不过他优化了下,计算的更快
int pow_int(int base, int exponent) {
    if (exponent == 0)
        return 1;

    int result = pow_int(base, exponent / 2);
    result *= result;

    if (exponent & 1)
            result *= base;

    return result;
}    

int main(int argc, char** argv) {

  if (argc != 2) {
    cout << "Usage: ./decrypt.out [DATA_FORMAT]" << endl;
    return -1;
  }

  string data_fmt = argv[1];
  if (data_fmt == "MNIST" || data_fmt == "CIFAR-10") {
    num_classes = 10;
  }
  else if (data_fmt == "ImageNet") {
    num_classes = 1000;
  }
  else {
    cout << "Invalid data format!" << endl;
    return -1;
  }

  // ifstream myfile("bitsize.data");
  // int msg_bits = 0;
  // if (myfile.is_open()) {
  //   myfile >> msg_bits;
  //   myfile.close();
  // }
  // if (msg_bits < 1) {
  //   cout << "Invalid bitsize, re-run inference procedure!" << endl;
  //   return 0;
  // }
  int msg_bits = 9;
  msg_space = pow_int(2, msg_bits);

  PriKey secret_key;
  ReadPriKeyFromFile(secret_key, "secret.key");

  Ctxt* e_labels = new Ctxt[num_classes];
  int* pt_labels = new int[num_classes];
  vector<int> labels;
  std::ifstream input_file("redcufhe_network_output.ctxt");
  for (int i = 0; i < num_classes; i++) {
    ReadCtxtFromFileRed(e_labels[i], input_file);
    DecryptIntRed(pt_labels[i], e_labels[i], msg_space, secret_key);
    if (pt_labels[i] > (msg_space/2)) {
      labels.push_back(pt_labels[i] - msg_space);
    }
    else {
      labels.push_back(pt_labels[i]);
    } 
    cout << "Class " << i << ": " << labels[i] << endl;
  }

  input_file.close();

  int bestScoreIdx = std::max_element(labels.begin(),labels.end()) - labels.begin();
  cout << "Classification Result: " << bestScoreIdx << endl;

  delete [] e_labels;
  delete [] pt_labels;
}

3.Why did you encrypt integers in TFHE directly into a lweSample instead of converting each pixel into binary first, encrypting each binary into ctxt separately, and then processing it like cuFHE?

4.in IntOps_gpu.cu,Why only add the 0th bit of the ctxt array instead of adding the entire ctxt array in integer form? image

5.I tried to use all networks for inference, sign1024 3 and relu1024 3 were okay, but when I ran to binarynet and binarynet_small, an error occurred. image1

image2

cgouert commented 3 months ago

The runtime error you encountered for the CIFAR-10 networks should be resolved now in the latest commit. I will look into your questions regarding the client-side operations as soon as possible and follow up here.

p719967821 commented 3 months ago

Thanks!! In addition, CIFAR-10 network is ok.

cgouert commented 3 months ago

I have pushed changes that maintain a consistent client-side API between the GPU and CPU variants (i.e., the GPU implementation had previously supported a dynamic message space which was phased out of the CPU implementation).

p719967821 commented 3 months ago

屏幕截图 2024-08-26 135052

still something wrong

and when I removed "&",it can be worked, but 屏幕截图 2024-08-26 140057

p719967821 commented 3 months ago

image If modified in this way, there will be such a problem. If the Int type data are also placed in one ctxt ciphertext(i.e., xxxxx->enc_segs[0][i].ctxt[0]), why does the relu function still have operations such as shifting and AND each bit with opposite MSB(IntOps::relu())

cgouert commented 3 months ago

Apologies for the problem with the last commit, I have amended it.

p719967821 commented 3 months ago

hello,sir!There were no issues during this compilation and execution, but I can't get the correct decryption result.For example, I encrypted 0, but it was decrypted into 8 through the sign1024*3 neural network; I encrypted 5, but it was decrypted into 4 through the sign1024*3 neural network In addition, could you please answer the confusion I raised in my previous question?

cgouert commented 3 months ago

I am investigating the issue and will provide updates directly to this thread.

yt-candy commented 1 week ago

@p719967821 Hello, how do you solve the problem that your network decryption cannot get the correct answer? I also encountered this problem on the relu network.