您现在的位置是:首页 >技术交流 >The Stage Test for My MAPLE-ORAM project网站首页技术交流

The Stage Test for My MAPLE-ORAM project

Drscq 2024-07-01 11:59:45
简介The Stage Test for My MAPLE-ORAM project

The Aim is to check whether the two integers replace each other successfully

The Test code (Read the outputs from the files)

#include <iostream>
#include "MAPLE.hpp"
#include "config.hpp"
#include <fstream>
#include <cstring>

void readDataFromFile(const std::string& filename) {
    TYPE_SIZE DB_SIZE = 1024 * 1024;
    TYPE_SIZE BLOCK_SIZE = 1024;
    TYPE_SIZE dataChunks = BLOCK_SIZE / sizeof(TYPE_DATA);
    TYPE_SIZE realNumBlocks = DB_SIZE % BLOCK_SIZE == 0 ? DB_SIZE / BLOCK_SIZE : DB_SIZE / BLOCK_SIZE + 1;
    TYPE_SIZE lenNumBlocks = static_cast<TYPE_SIZE>(ceil(sqrt(realNumBlocks)));
    int cnt = 2;
    TYPE_DATA** dbShares = new TYPE_DATA*[NUM_SERVERS];
    for (int i = 0; i < NUM_SERVERS; i++) {
        dbShares[i] = new TYPE_DATA[cnt * lenNumBlocks];
    }

    std::cout << "The value of lenNumBlocks is " << lenNumBlocks << std::endl;
    for (int i = 0; i < NUM_SERVERS; i++) {
        std::string fileToRead = "../build/"+ filename + std::to_string(i) + ".txt";
        std::ifstream file(fileToRead);
        if (file.is_open()) {
            file.read(reinterpret_cast<char*>(dbShares[i]), lenNumBlocks * sizeof(TYPE_DATA));
            file.seekg(dataChunks * lenNumBlocks * sizeof(TYPE_DATA), std::ios::beg);
            file.read(reinterpret_cast<char*>(dbShares[i] + lenNumBlocks), lenNumBlocks * sizeof(TYPE_DATA));
        }
        file.close();
    }

    // for (int i = 0; i < NUM_SERVERS; i++) {
    //     for (int j = 0; j < cnt; j++) {
    //         std::cout << "The Part " << i << " of the dbShares is " << std::endl;
    //         for (int k = 0; k < lenNumBlocks; k++) {
    //             std::cout << dbShares[i][j * lenNumBlocks + k] << " ";
    //         }
    //         std::cout << std::endl;
    //     }
    //     std::cout << std::endl;
    // }

    TYPE_DATA* result = new TYPE_DATA[cnt * lenNumBlocks];
    std::memset(result, 0, cnt * lenNumBlocks * sizeof(TYPE_DATA));
    MAPLE maple;
    maple.simpleRecover(dbShares, result, cnt * lenNumBlocks);

    for (int i = 0; i < cnt; i++) {
        std::cout << "The result of the " << i << "th part is " << std::endl;
        for (int j = 0; j < lenNumBlocks; j++) {
            std::cout << result[i * lenNumBlocks + j] << " ";
        }
        std::cout << std::endl;
    }

    std::cout << std::endl;

    delete[] result;
    for (int i = 0; i < NUM_SERVERS; i++) {
        delete[] dbShares[i];
    }
    delete[] dbShares;
}
int main()
{
    std::cout << "The decryption of dot_product_vector_copy is " << std::endl;
    std::string name = "dot_product_vector_copy";
    readDataFromFile(name);
    std::cout << "The decryption of dot_product_vector_copy_updated is " << std::endl;
    name = "dot_product_vector_copy_updated";
    readDataFromFile(name);
    return 0;
}

The Running Command

g++ FindPosBug.cpp MAPLE.cpp Utils.cpp -std=c++17 -lstdc++fs -lntl -lgmp -lgmpxx

The Running Results

The decryption of dot_product_vector_copy is 
The value of lenNumBlocks is 32
        [MAPLE] Recovery is Done
The result of the 0th part is 
121 695 783 670 596 631 699 26 434 177 419 95 632 68 795 852 4 124 593 950 519 508 759 14 700 606 722 81 598 784 951 966 
The result of the 1th part is 
310 245 574 757 589 968 861 278 473 320 185 562 991 767 191 386 712 852 977 139 503 117 938 721 538 817 314 44 509 823 1004 665 

The decryption of dot_product_vector_copy_updated is 
The value of lenNumBlocks is 32
        [MAPLE] Recovery is Done
The result of the 0th part is 
121 695 783 670 596 631 699 26 434 177 419 95 632 68 795 852 574 124 593 950 519 508 759 14 700 606 722 81 598 784 951 966 
The result of the 1th part is 
310 245 4 757 589 968 861 278 473 320 185 562 991 767 191 386 712 852 977 139 503 117 938 721 538 817 314 44 509 823 1004 665 

From the results, we can see that the integers of “4” and “574” have changed position successfully.

The Explainations for reinterpret_cast<char *>

The reinterpret_cast operator in C++ is used to convert one pointer type to another, even if the types are unrelated. It allows you to reinterpret the underlying binary data of an object without changing its actual representation. The reinterpret_cast is a powerful tool, but it should be used with caution since it bypasses type safety checks and can lead to undefined behavior if used incorrectly.

To provide you with a vivid example, let’s imagine a scenario where you have a binary file containing raw pixel data for an image. Each pixel consists of three color components: red, green, and blue. The file contains consecutive bytes representing these color components.

Now, let’s say you want to read the pixel data from the file and interpret it as a Pixel struct in your C++ program. Here’s how you can use reinterpret_cast to achieve this:

#include <iostream>
#include <fstream>

struct Pixel {
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

int main() {
    std::ifstream file("image.bin", std::ios::binary);
    if (file) {
        // Determine the file size
        file.seekg(0, std::ios::end);
        std::streampos fileSize = file.tellg();
        file.seekg(0, std::ios::beg);

        // Read the file contents into a buffer
        char* buffer = new char[fileSize];
        file.read(buffer, fileSize);
        file.close();

        // Interpret the buffer as an array of Pixels using reinterpret_cast
        Pixel* pixels = reinterpret_cast<Pixel*>(buffer);
        
        // Access individual pixels
        std::cout << "Pixel at index 0: " << static_cast<int>(pixels[0].red) << ", "
                  << static_cast<int>(pixels[0].green) << ", " << static_cast<int>(pixels[0].blue) << std::endl;
        
        // Remember to delete the buffer when done
        delete[] buffer;
    } else {
        std::cout << "Failed to open file." << std::endl;
    }

    return 0;
}

In this example, we read the contents of the binary file into a buffer of characters (char* buffer). Then, using reinterpret_cast, we interpret the buffer as an array of Pixel structs (Pixel* pixels). By doing so, we can access individual pixels as if they were stored in the Pixel struct format.

Please note that this example demonstrates the usage of reinterpret_cast for illustrative purposes. When working with raw memory and casting pointers, it’s important to ensure that the underlying data being cast matches the target type to avoid undefined behavior and alignment issues.
reinterpret_cast是C++中的一种类型转换运算符,它用于将一个指针或引用类型转换为另一个指针或引用类型,即改变指针或引用的类型而不改变指针或引用所指向的对象。使用reinterpret_cast需要注意以下几点:

  1. reinterpret_cast只能用于指针或引用类型之间的转换,不能用于其他类型之间的转换。

  2. 只有当两种类型是布局兼容的时候,才可以使用reinterpret_cast进行转换。布局兼容指的是两种类型的内存布局像素,即它们的成员变量的类型、顺序和对齐方式相同。

  3. 由于reinterpret_cast可以将一个指针类型转换为另一个指针类型,因此在使用时需要注意指针的有效性和安全性。

示例:

int i = 10;
char* p = reinterpret_cast<char*>(&i); // 将int类型的指针p转换为char类型的指针

std::cout << *p << *(p+1) << *(p+2) << *(p+3) << std::endl; // 输出 i 的字节表示

int* ip = reinterpret_cast<int*>(p); // 将char类型的指针p转换为int类型的指针

std::cout << *ip << std::endl; //输出i的值

在上面的示例中,我们使用reinterpret_cast将一个整型指针转换为char类型指针,然后输出了整型的字节表示。接着我们又将char类型指针转换为int类型指针,并输出了整型的值。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。