diff --git a/apps/app.cpp b/apps/app.cpp
index f4b973c076ff9e3b7f10206490cc5246847ccb20..a8235882db50b3d117950c92cd3bec2050c8ab3e 100644
--- a/apps/app.cpp
+++ b/apps/app.cpp
@@ -1,33 +1,7 @@
 #include <iostream>
-#include "ipre.h"
 
 using namespace std;
 
 int main() {
     cout << "Testing in the app." << endl;
-
-    // Init core and setup.
-    core_init();
-    pc_param_set_any();
-
-    // Testing.
-    g base, test_value;
-    gen(base);
-
-    g1_mul_dig(test_value, base, 2);
-
-    g table[200];
-    cout << RLC_EP_TABLE_MAX << endl << endl;
-
-    g1_mul_pre(table, base);
-
-    g1_print(table[0]);
-    cout << endl;
-    g1_print(table[1]);
-    cout << endl;
-    g1_print(table[2]);
-    cout << endl;
-    g1_print(test_value);
-    cout << endl;
-    cout << (g1_cmp(table[9], test_value) == RLC_EQ) << endl;
 }
\ No newline at end of file
diff --git a/data/sift_groundtruth.ivecs b/data/sift_groundtruth.ivecs
new file mode 100644
index 0000000000000000000000000000000000000000..c27b8113b7056f0698ba05b8b93be2fa13c86ee7
Binary files /dev/null and b/data/sift_groundtruth.ivecs differ
diff --git a/data/sift_query.fvecs b/data/sift_query.fvecs
new file mode 100644
index 0000000000000000000000000000000000000000..a3e55a94710c85051fa85e0f3e01a798a5569d2e
Binary files /dev/null and b/data/sift_query.fvecs differ
diff --git a/include/helper.h b/include/helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ddca45402b6dee24eb3d1a3596ed90aec3ab3f4
--- /dev/null
+++ b/include/helper.h
@@ -0,0 +1,12 @@
+#ifndef PPANN_HELPER_H
+#define PPANN_HELPER_H
+
+#include <cstdio>
+#include <cstring>
+#include <sys/stat.h>
+
+float *fvecs_read(const char *file_path, size_t *d_out, size_t *n_out);
+
+int *ivecs_read(const char *file_path, size_t *d_out, size_t *n_out);
+
+#endif //PPANN_HELPER_H
\ No newline at end of file
diff --git a/include/hnsw.h b/include/hnsw.h
new file mode 100644
index 0000000000000000000000000000000000000000..759e69a65619538c634a5fce803856c1edf3e141
--- /dev/null
+++ b/include/hnsw.h
@@ -0,0 +1,10 @@
+#ifndef PPANN_HNSW_H
+#define PPANN_HNSW_H
+
+
+class hnsw {
+
+};
+
+
+#endif //PPANN_HNSW_H
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ff0a517ba790ead1dcda9c088a4a983952adfdba..2dad76fb6d7412ec5e10f5eb3f64f58030e92044 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,7 +2,7 @@
 set(HEADER_LIST "${CMAKE_SOURCE_DIR}/include/")
 
 # Add all files to the library.
-add_library(ppann_lib field.cpp group.cpp vector.cpp matrix.cpp ipre.cpp ${HEADER_LIST})
+add_library(ppann_lib field.cpp group.cpp vector.cpp matrix.cpp ipre.cpp hnsw.cpp helper.cpp ${HEADER_LIST})
 
 # We need this directory, and users of our library will need it too
 target_include_directories(ppann_lib PUBLIC ../include)
diff --git a/src/helper.cpp b/src/helper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad4f4262a73147bd82fd6e5fa690af3ca7e6d2e7
--- /dev/null
+++ b/src/helper.cpp
@@ -0,0 +1,40 @@
+#include "helper.h"
+
+float *fvecs_read(const char *file_path, size_t *d_out, size_t *n_out) {
+    // Open up the file.
+    FILE *file = fopen(file_path, "r");
+
+    // Get the dimension.
+    int d;
+    fread(&d, 1, sizeof(int), file);
+
+    // Get the number of vectors.
+    fseek(file, 0, SEEK_SET);
+    struct stat st{};
+    fstat(fileno(file), &st);
+
+    // Compute number of vectors.
+    size_t sz = st.st_size;
+    size_t n = sz / ((d + 1) * 4);
+
+    // Update parameters.
+    *d_out = d;
+    *n_out = n;
+
+    // Save the data.
+    auto *x = new float[n * (d + 1)];
+    fread(x, sizeof(float), n * (d + 1), file);
+
+    // shift array to remove row headers
+    for (size_t i = 0; i < n; i++) memmove(x + i * d, x + 1 + i * (d + 1), d * sizeof(*x));
+
+    // Close file.
+    fclose(file);
+
+    return x;
+}
+
+int *ivecs_read(const char *file_path, size_t *d_out, size_t *n_out) {
+    // Cast the float results to integers.
+    return (int *) fvecs_read(file_path, d_out, n_out);
+}
\ No newline at end of file
diff --git a/src/hnsw.cpp b/src/hnsw.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0020eb0e41de92cdf60a3a312e51a6a0404cfe9d
--- /dev/null
+++ b/src/hnsw.cpp
@@ -0,0 +1 @@
+#include "hnsw.h"
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index bf74047755caeac69a4d612122ce20e6e84bb361..fb3fe9e4607a806f3ff1fe77afaa85f230036597 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -4,6 +4,7 @@ add_executable(test_group test_group.cpp)
 add_executable(test_vector test_vector.cpp)
 add_executable(test_matrix test_matrix.cpp)
 add_executable(test_ipre test_ipre.cpp)
+add_executable(test_helper test_helper.cpp)
 
 # Link tests to the main library.
 target_link_libraries(test_field PRIVATE ppann_lib)
@@ -11,10 +12,12 @@ target_link_libraries(test_group PRIVATE ppann_lib)
 target_link_libraries(test_vector PRIVATE ppann_lib)
 target_link_libraries(test_matrix PRIVATE ppann_lib)
 target_link_libraries(test_ipre PRIVATE ppann_lib)
+target_link_libraries(test_helper PRIVATE ppann_lib)
 
 # Register the previous tests.
 add_test(NAME test_field COMMAND test_field)
 add_test(NAME test_group COMMAND test_group)
 add_test(NAME test_vector COMMAND test_vector)
 add_test(NAME test_matrix COMMAND test_matrix)
-add_test(NAME test_ipre COMMAND test_ipre)
\ No newline at end of file
+add_test(NAME test_ipre COMMAND test_ipre)
+add_test(NAME test_helper COMMAND test_helper WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/data")
\ No newline at end of file
diff --git a/tests/test_helper.cpp b/tests/test_helper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0162cc4dba74434e392daeb6cb8ec2bef57702bb
--- /dev/null
+++ b/tests/test_helper.cpp
@@ -0,0 +1,37 @@
+#include "helper.h"
+
+int test_read_fvecs() {
+    // Set dimensions holders and get the data.
+    size_t d, n;
+    float *xd = fvecs_read("sift_query.fvecs", &d, &n);
+
+    // Check for whether the data is correct.
+    if (d != 128) return 0;
+    if (n != 10000) return 0;
+    if (xd[1] != 3) return 0;
+    if (xd[1279872] != 23) return 0;
+
+    // If everything passes, return 1.
+    return 1;
+}
+
+int test_read_ivecs() {
+    // Set dimensions holders and get the data.
+    size_t d, n;
+    int *gt = ivecs_read("sift_groundtruth.ivecs", &d, &n);
+
+    // Check for whether the data is correct.
+    if (d != 100) return 0;
+    if (n != 10000) return 0;
+    if (gt[1] != 934876) return 0;
+    if (gt[999900] != 874343) return 0;
+
+    // If everything passes, return 1.
+    return 1;
+}
+
+int main() {
+    if (test_read_fvecs() != 1) return 1;
+    if (test_read_ivecs() != 1) return 1;
+    return 0;
+}
\ No newline at end of file
diff --git a/tests/test_ipre.cpp b/tests/test_ipre.cpp
index 7e0c691c1b7f20bdf50c6e1d5ee425dcfbf9d6ec..d8d1ea886ebaa0ad8eb2a3672492f3fb23c384f1 100644
--- a/tests/test_ipre.cpp
+++ b/tests/test_ipre.cpp
@@ -3,16 +3,16 @@
 int test_scheme() {
     // Set x, y vectors.
     int x[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
-    int y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1000};
+    int y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 100};
     // Initialize the scheme.
     key key = setup(10);
     // Encrypt the messages.
     ct ct_x = enc(key, x, 10);
     ct ct_y = enc(key, y, 10);
     // Evaluate the two ciphertexts.
-    int output = eval(key, ct_x, ct_y, 10, 5000);
+    int output = eval(key, ct_x, ct_y, 10, 150);
 
-    return output == 1045;
+    return output == 145;
 }
 
 int main() {
diff --git a/tests/test_matrix.cpp b/tests/test_matrix.cpp
index 6610e354dc03e0c85db08e500aabff45babe13ec..93eca2a32281718062639aa9fece43cb1d3db0c8 100644
--- a/tests/test_matrix.cpp
+++ b/tests/test_matrix.cpp
@@ -41,7 +41,7 @@ int test_multiply_vector(bn_st *N) {
 }
 
 int test_inverse(bn_st *N) {
-    int size = 100;
+    int size = 128;
     zp_mat x = matrix_zp_rand(size, size, N);
     zp_mat xi = matrix_inverse(x, size, N);
     zp_mat r = matrix_multiply(x, xi, size, size, size, N);