diff --git a/CMakeLists.txt b/CMakeLists.txt
index ab9f81bedd388dcdfbda7785899cf95174d8994c..c59e16b49a42541996247773aca2b5c1ced97e15 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,15 +6,15 @@ project(
         PPANN
         VERSION 0.1
         DESCRIPTION "This project implements the inner product revealing encryption."
-        LANGUAGES C
+        LANGUAGES CXX
 )
 
 # Set standards and include tests.
 if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
-    set(CMAKE_C_STANDARD 17)
+    set(CMAKE_CXX_STANDARD 17)
     set_property(GLOBAL PROPERTY USE_FOLDERS ON)
     include(CTest)
-endif()
+endif ()
 
 # Find the relic library.
 find_library(RELIC_LIB relic)
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 63f43d77e568953425fe69d23a691374a00edb3b..530e768631176d1fb2e02442ec81020d5db86696 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -1,3 +1,3 @@
 # Call this executable app.
-add_executable(app scheme.c)
+add_executable(app app.cpp)
 target_link_libraries(app PRIVATE ppann_lib)
\ No newline at end of file
diff --git a/apps/app.cpp b/apps/app.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..576dde40976821c80d0d4fb6eb32475f6c29102f
--- /dev/null
+++ b/apps/app.cpp
@@ -0,0 +1,7 @@
+#include <iostream>
+
+using namespace std;
+
+int main() {
+    cout << "Hello from app." << endl;
+}
\ No newline at end of file
diff --git a/apps/scheme.c b/apps/scheme.c
deleted file mode 100644
index a071ac6c876e8c41bb9d34eb20941699bfc5306d..0000000000000000000000000000000000000000
--- a/apps/scheme.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "vector.h"
-#include "matrix.h"
-
-const int B_SIZE = 6;
-
-struct key {
-    zp_mat A;
-    zp_mat B;
-    zp_mat Bi;
-    g base;
-    gt t_base;
-    bn_t modular;
-};
-
-struct ct {
-    g_vec ctx;
-    g_vec ctk;
-    g_vec ctc;
-};
-
-void initialize_relic() {
-    core_init();
-    pc_param_set_any();
-}
-
-struct key setup(int size) {
-    struct key key;
-    pc_get_ord(key.modular);
-    gen(key.base);
-    bp_map(key.base, key.base, key.t_base);
-    key.A = matrix_zp_rand(2, size, key.modular);
-    key.B = matrix_zp_rand(B_SIZE, B_SIZE, key.modular);
-    key.Bi = matrix_transpose(matrix_inverse(key.B, B_SIZE, key.modular), B_SIZE, B_SIZE);
-    return key;
-}
-
-struct ct enc(struct key key, const int *message, int size) {
-    // Declare the returned ciphertext and convert message to zp.
-    struct ct ct;
-    zp_vec x = vector_zp_from_int(message, size, key.modular);
-
-    // Helper values.
-    int one[] = {1}, zero[] = {0};
-    zp_vec one_vec = vector_zp_from_int(one, 1, key.modular);
-    zp_vec zero_vec = vector_zp_from_int(zero, 1, key.modular);
-
-    // We generate s and compute sA + x.
-    zp_vec s = vector_zp_rand(2, key.modular);
-    zp_vec sA = matrix_multiply(s, key.A, 1, 2, size, key.modular);
-    zp_vec sAx = vector_add(sA, x, size);
-    ct.ctx = vector_raise(key.base, sAx, size);
-
-    // We compute the function hiding inner product encryption key.
-    zp_mat AT = matrix_transpose(key.A, 2, size);
-    zp_vec xAT = matrix_multiply(x, AT, 1, size, 2, key.modular);
-    zp_vec xATs = vector_merge(xAT, s, 2, 2);
-    zp_vec xATs0 = vector_merge(xATs, zero_vec, 4, 1);
-    zp_vec xATs01 = vector_merge(xATs0, one_vec, 5, 1);
-    zp_vec xATs01_B = matrix_multiply(xATs01, key.B, 1, B_SIZE, B_SIZE, key.modular);
-    ct.ctc = vector_raise(key.base, xATs01_B, B_SIZE);
-
-    // We compute the function hiding inner product encryption ciphertext.
-    zp_vec sAAT = matrix_multiply(sA, AT, 1, size, 2, key.modular);
-    zp_vec xATsAAT = vector_add(xAT, sAAT, 2);
-    zp_vec sxATsAAT = vector_merge(s, xATsAAT, 2, 2);
-    zp_vec sxATsAAT1 = vector_merge(sxATsAAT, one_vec, 4, 1);
-    zp_vec sxATsAAT10 = vector_merge(sxATsAAT1, zero_vec, 5, 1);
-    zp_vec sxATsAAT10_Bi = matrix_multiply(sxATsAAT10, key.Bi, 1, B_SIZE, B_SIZE, key.modular);
-    ct.ctk = vector_raise(key.base, sxATsAAT10_Bi, B_SIZE);
-
-    return ct;
-}
-
-void eval(struct key key, struct ct x, struct ct y, int size) {
-    // Decrypt components.
-    gt xy, ct;
-    inner_product(xy, x.ctx, y.ctx, size);
-    inner_product(ct, x.ctc, y.ctk, B_SIZE);
-
-    // Decrypt final result.
-    gt_inv(ct, ct);
-    gt_mul(xy, xy, ct);
-
-    // Check correctness.
-    gt desired_output;
-    gt_exp_dig(desired_output, key.t_base, 65);
-    if (gt_cmp(desired_output, xy) == RLC_EQ) printf("Magic happened");
-}
-
-int main() {
-    // Initialize relic.
-    initialize_relic();
-    // Set x, y vectors.
-    int x[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
-    int y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-    // Initialize the scheme.
-    struct key key = setup(10);
-    // Encrypt the messages.
-    struct ct ct_x = enc(key, x, 10);
-    struct ct ct_y = enc(key, y, 10);
-    // Evaluate the two ciphertexts.
-    eval(key, ct_x, ct_y, 10);
-    return 0;
-}
\ No newline at end of file
diff --git a/include/field.h b/include/field.h
index 527654316e50511e0fd25ea2e41d77be5886dc9f..67cd008fc23253684ad7b4440ea1871252da51a1 100644
--- a/include/field.h
+++ b/include/field.h
@@ -1,35 +1,37 @@
 #ifndef PPANN_FIELD_H
 #define PPANN_FIELD_H
 
+#include <gmp.h>
+
+extern "C" {
 #include "relic/relic.h"
+}
 
 struct zp {
-    bn_t point;
-    bn_t modular;
+    bn_t point{};
+    bn_t modular{};
 };
 
-struct zp new_zp();
-
-struct zp rand_zp(bn_t modular);
+zp rand_zp(bn_t modular);
 
-struct zp zp_zero(bn_t modular);
+zp zp_zero(bn_t modular);
 
-struct zp zp_one(bn_t modular);
+zp zp_one(bn_t modular);
 
-struct zp zp_copy(struct zp x);
+zp zp_copy(zp x);
 
-struct zp zp_from_int(int x, bn_t modular);
+zp zp_from_int(int x, bn_t modular);
 
-struct zp zp_add(struct zp x, struct zp y);
+zp zp_add(zp x, zp y);
 
-struct zp zp_neg(struct zp x);
+zp zp_neg(zp x);
 
-struct zp zp_mul(struct zp x, struct zp y);
+zp zp_mul(zp x, zp y);
 
-struct zp zp_inv(struct zp x);
+zp zp_inv(zp x);
 
-int zp_cmp(struct zp x, struct zp y);
+int zp_cmp(zp x, zp y);
 
-int zp_cmp_int(struct zp x, int y);
+int zp_cmp_int(zp x, int y);
 
 #endif //PPANN_FIELD_H
\ No newline at end of file
diff --git a/include/group.h b/include/group.h
index 9a94d5943f47ffe11efe731979bebaa060f8ad0e..6b956f10e0428850acf8210710bd0f01faf79ed7 100644
--- a/include/group.h
+++ b/include/group.h
@@ -8,9 +8,9 @@ typedef gt_t gt;
 
 void gen(g x);
 
-void g_mul(g r, g x, struct zp y);
+void g_mul(g r, g x, zp y);
 
-void gt_raise(gt r, gt x, struct zp y);
+void gt_raise(gt r, gt x, zp y);
 
 void bp_map(g a, g b, gt r);
 
diff --git a/include/ipre.h b/include/ipre.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd84869bf372d929d2c8d55199a084f49510e29c
--- /dev/null
+++ b/include/ipre.h
@@ -0,0 +1,30 @@
+#ifndef PPANN_IPRE_H
+#define PPANN_IPRE_H
+
+#include "vector.h"
+#include "matrix.h"
+
+const int B_SIZE = 6;
+
+struct key {
+    zp_mat A;
+    zp_mat B;
+    zp_mat Bi;
+    g base;
+    gt t_base;
+    bn_t modular;
+};
+
+struct ct {
+    g_vec ctx;
+    g_vec ctk;
+    g_vec ctc;
+};
+
+key setup(int size);
+
+ct enc(key key, const int *message, int size);
+
+int eval(key key, ct x, ct y, int size, int bound);
+
+#endif //PPANN_IPRE_H
\ No newline at end of file
diff --git a/include/matrix.h b/include/matrix.h
index b3c8e7a8c081aa0b4cd2dc307dd5231b4ea6d347..f0f7f6d20cd7175c9242e6029e2e83d4d672b031 100644
--- a/include/matrix.h
+++ b/include/matrix.h
@@ -4,7 +4,7 @@
 #include "field.h"
 #include "group.h"
 
-typedef struct zp *zp_mat;
+typedef zp *zp_mat;
 
 zp_mat matrix_zp_from_int(const int *int_mat, int row, int col, bn_t modular);
 
diff --git a/include/vector.h b/include/vector.h
index 21e0f7c2c94ad14182fc8e303a572c6ca773ba47..355f93519603ade2c3120336e09ebedb03c9741d 100644
--- a/include/vector.h
+++ b/include/vector.h
@@ -4,7 +4,7 @@
 #include "field.h"
 #include "group.h"
 
-typedef struct zp *zp_vec;
+typedef zp *zp_vec;
 typedef g *g_vec;
 
 zp_vec vector_zp_from_int(const int *int_vec, int size, bn_t modular);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 109948d972988e2f326d4eba59959cc5c747dd44..ff0a517ba790ead1dcda9c088a4a983952adfdba 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.c group.c vector.c matrix.c ${HEADER_LIST})
+add_library(ppann_lib field.cpp group.cpp vector.cpp matrix.cpp ipre.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/field.c b/src/field.cpp
similarity index 58%
rename from src/field.c
rename to src/field.cpp
index fe727080e23220046ac5f3ce13be30b4b90b440e..21b9119920d5ee6530b2e8c3a13b7de112035e78 100644
--- a/src/field.c
+++ b/src/field.cpp
@@ -1,82 +1,75 @@
 #include "field.h"
 
-struct zp new_zp() {
-    struct zp result;
-    bn_new(result.point);
-    bn_new(result.modular);
-    return result;
-}
-
-struct zp rand_zp(bn_st *modular) {
-    struct zp result = new_zp();
+zp rand_zp(bn_st *modular) {
+    zp result;
     bn_rand_mod(result.point, modular);
     bn_copy(result.modular, modular);
     return result;
 }
 
-struct zp zp_zero(bn_st *modular) {
-    struct zp result = new_zp();
+zp zp_zero(bn_st *modular) {
+    zp result;
     bn_set_dig(result.point, 0);
     bn_copy(result.modular, modular);
     return result;
 }
 
-struct zp zp_one(bn_st *modular) {
-    struct zp result = new_zp();
+zp zp_one(bn_st *modular) {
+    zp result;
     bn_set_dig(result.point, 1);
     bn_copy(result.modular, modular);
     return result;
 }
 
-struct zp zp_copy(struct zp x) {
-    struct zp result = new_zp();
+zp zp_copy(zp x) {
+    zp result;
     bn_copy(result.point, x.point);
     bn_copy(result.modular, x.modular);
     return result;
 }
 
-struct zp zp_from_int(int x, bn_st *modular) {
-    struct zp result = new_zp();
+zp zp_from_int(int x, bn_st *modular) {
+    zp result;
     bn_set_dig(result.point, x);
     bn_copy(result.modular, modular);
     return result;
 }
 
-struct zp zp_add(struct zp x, struct zp y) {
-    struct zp result = new_zp();
+zp zp_add(zp x, zp y) {
+    zp result;
     bn_add(result.point, x.point, y.point);
     bn_mod(result.point, result.point, x.modular);
     bn_copy(result.modular, x.modular);
     return result;
 }
 
-struct zp zp_neg(struct zp x) {
-    struct zp result = new_zp();
+zp zp_neg(zp x) {
+    zp result;
     bn_neg(result.point, x.point);
     bn_mod(result.point, result.point, x.modular);
     bn_copy(result.modular, x.modular);
     return result;
 }
 
-struct zp zp_mul(struct zp x, struct zp y) {
-    struct zp result = new_zp();
+zp zp_mul(zp x, zp y) {
+    zp result;
     bn_mul(result.point, x.point, y.point);
     bn_mod(result.point, result.point, x.modular);
     bn_copy(result.modular, x.modular);
     return result;
 }
 
-struct zp zp_inv(struct zp x) {
-    struct zp result = new_zp();
+zp zp_inv(zp x) {
+    zp result;
     bn_mod_inv(result.point, x.point, x.modular);
     bn_copy(result.modular, x.modular);
     return result;
 }
 
-int zp_cmp(struct zp x, struct zp y) {
+int zp_cmp(zp x, zp y) {
     return bn_cmp(x.point, y.point) == RLC_EQ;
 }
 
-int zp_cmp_int(struct zp x, int y) {
+int zp_cmp_int(zp x, int y) {
     return bn_cmp_dig(x.point, y) == RLC_EQ;
 }
\ No newline at end of file
diff --git a/src/group.c b/src/group.cpp
similarity index 66%
rename from src/group.c
rename to src/group.cpp
index e6307a5e0f9226982e87f210a92836875bd0628b..6558d9930a812577683a7ee8590ef1513f9c5a20 100644
--- a/src/group.c
+++ b/src/group.cpp
@@ -4,11 +4,11 @@ void gen(ep_st *x) {
     g1_get_gen(x);
 }
 
-void g_mul(ep_st *r, ep_st *x, struct zp y) {
+void g_mul(ep_st *r, ep_st *x, zp y) {
     g1_mul(r, x, y.point);
 }
 
-void gt_raise(fp_t *r, fp_t *x, struct zp y) {
+void gt_raise(fp_t *r, fp_t *x, zp y) {
     gt_exp(r, x, y.point);
 }
 
diff --git a/src/matrix.c b/src/matrix.cpp
similarity index 89%
rename from src/matrix.c
rename to src/matrix.cpp
index f83056481cf4130de0812bbf9f985e2b74e37f1c..27836f19ca26bbe11ce15a926e309d7341fb87a6 100644
--- a/src/matrix.c
+++ b/src/matrix.cpp
@@ -2,7 +2,7 @@
 
 zp_mat matrix_zp_from_int(const int *int_mat, int row, int col, bn_st *modular) {
     zp_mat x;
-    x = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    x = (zp_mat) malloc(sizeof(zp) * row * col);
     for (int i = 0; i < row; i++) {
         for (int j = 0; j < col; j++) {
             x[i * col + j] = zp_from_int(int_mat[i * col + j], modular);
@@ -13,7 +13,7 @@ zp_mat matrix_zp_from_int(const int *int_mat, int row, int col, bn_st *modular)
 
 zp_mat matrix_zp_rand(int row, int col, bn_st *modular) {
     zp_mat x;
-    x = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    x = (zp_mat) malloc(sizeof(zp) * row * col);
     for (int i = 0; i < row; i++) {
         for (int j = 0; j < col; j++) {
             x[i * col + j] = rand_zp(modular);
@@ -24,7 +24,7 @@ zp_mat matrix_zp_rand(int row, int col, bn_st *modular) {
 
 zp_mat matrix_identity(int size, bn_st *modular) {
     zp_mat x;
-    x = (zp_mat) malloc(sizeof(struct zp) * size * size);
+    x = (zp_mat) malloc(sizeof(zp) * size * size);
     for (int i = 0; i < size; i++) {
         for (int j = 0; j < size; j++) {
             if (i == j) x[i * size + j] = zp_one(modular);
@@ -46,7 +46,7 @@ int matrix_is_identity(zp_mat x, int size) {
 
 zp_mat matrix_transpose(zp_mat x, int row, int col) {
     zp_mat xt;
-    xt = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    xt = (zp_mat) malloc(sizeof(zp) * row * col);
     for (int i = 0; i < row; i++) {
         for (int j = 0; j < col; j++) {
             xt[j * row + i] = zp_copy(x[i * col + j]);
@@ -57,7 +57,7 @@ zp_mat matrix_transpose(zp_mat x, int row, int col) {
 
 zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y) {
     zp_mat xy;
-    xy = (zp_mat) malloc(sizeof(struct zp) * row * (col_x + col_y));
+    xy = (zp_mat) malloc(sizeof(zp) * row * (col_x + col_y));
     for (int i = 0; i < row; i++) {
         for (int j = 0; j < col_x; j++) {
             xy[i * (col_x + col_y) + j] = zp_copy(x[i * col_x + j]);
@@ -70,7 +70,7 @@ zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y) {
 }
 
 zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y, bn_st *modular) {
-    zp_mat xy = (zp_mat) malloc(sizeof(struct zp) * row_x * col_y);
+    auto xy = (zp_mat) malloc(sizeof(zp) * row_x * col_y);
 
     for (int i = 0; i < row_x; i++) {
         for (int j = 0; j < col_y; j++) {
@@ -89,7 +89,8 @@ zp_mat matrix_inverse(zp_mat x, int size, bn_st *modular) {
     zp_mat row_echelon = matrix_merge(x, identity, size, size, size);
 
     // Declare temp value.
-    struct zp temp_multiplier, temp_neg;
+    zp temp_multiplier;
+    zp temp_neg;
 
     // Bottom left half to all zeros.
     for (int i = 0; i < size; i++) {
@@ -128,7 +129,7 @@ zp_mat matrix_inverse(zp_mat x, int size, bn_st *modular) {
 
     // Copy over the output.
     zp_mat xi;
-    xi = (zp_mat) malloc(sizeof(struct zp) * size * size);
+    xi = (zp_mat) malloc(sizeof(zp) * size * size);
     for (int i = 0; i < size; i++) {
         for (int j = 0; j < size; j++) {
             xi[i * size + j] = zp_copy(row_echelon[i * 2 * size + size + j]);
diff --git a/src/vector.c b/src/vector.cpp
similarity index 83%
rename from src/vector.c
rename to src/vector.cpp
index 24f234470b9d553a257488d0723d0d685a988b6f..33de4488d3152c641c71d2ec53ec57416b359572 100644
--- a/src/vector.c
+++ b/src/vector.cpp
@@ -2,21 +2,21 @@
 
 zp_vec vector_zp_from_int(const int *int_vec, int size, bn_st *modular) {
     zp_vec x;
-    x = (zp_vec) malloc(sizeof(struct zp) * size);
+    x = (zp_vec) malloc(sizeof(zp) * size);
     for (int i = 0; i < size; i++) x[i] = zp_from_int(int_vec[i], modular);
     return x;
 }
 
 zp_vec vector_zp_rand(int size, bn_st *modular) {
     zp_vec x;
-    x = (zp_vec) malloc(sizeof(struct zp) * size);
+    x = (zp_vec) malloc(sizeof(zp) * size);
     for (int i = 0; i < size; i++) x[i] = rand_zp(modular);
     return x;
 }
 
 zp_vec vector_merge(zp_vec a, zp_vec b, int size_a, int size_b) {
     zp_vec r;
-    r = (zp_vec) malloc(sizeof(struct zp) * (size_a + size_b));
+    r = (zp_vec) malloc(sizeof(zp) * (size_a + size_b));
     for (int i = 0; i < size_a; i++) r[i] = zp_copy(a[i]);
     for (int i = 0; i < size_b; i++) r[i + size_a] = zp_copy(b[i]);
     return r;
@@ -24,7 +24,7 @@ zp_vec vector_merge(zp_vec a, zp_vec b, int size_a, int size_b) {
 
 zp_vec vector_add(zp_vec a, zp_vec b, int size) {
     zp_vec r;
-    r = (zp_vec) malloc(sizeof(struct zp) * size);
+    r = (zp_vec) malloc(sizeof(zp) * size);
     for (int i = 0; i < size; i++) r[i] = zp_add(a[i], b[i]);
     return r;
 }
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ef1621db4e243c9ee0ecf000bd59ce3a57e0e82d..bf74047755caeac69a4d612122ce20e6e84bb361 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,17 +1,20 @@
 # Add tests as separate executables.
-add_executable(test_field test_field.c)
-add_executable(test_group test_group.c)
-add_executable(test_vector test_vector.c)
-add_executable(test_matrix test_matrix.c)
+add_executable(test_field test_field.cpp)
+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)
 
 # Link tests to the main library.
 target_link_libraries(test_field PRIVATE ppann_lib)
 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)
 
 # 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)
\ No newline at end of file
+add_test(NAME test_matrix COMMAND test_matrix)
+add_test(NAME test_ipre COMMAND test_ipre)
\ No newline at end of file
diff --git a/tests/test_field.c b/tests/test_field.cpp
similarity index 63%
rename from tests/test_field.c
rename to tests/test_field.cpp
index 8a13422c5adf726b4a9166b3bc85768af125a5ae..f5f4e3ed9380ac3e1e14c98c008fbf5eb1649f0f 100644
--- a/tests/test_field.c
+++ b/tests/test_field.cpp
@@ -1,51 +1,51 @@
 #include "field.h"
 
 int test_zp_zero(bn_st *N) {
-    struct zp x = zp_zero(N);
+    zp x = zp_zero(N);
     return zp_cmp_int(x, 0);
 }
 
 int test_zp_one(bn_st *N) {
-    struct zp x = zp_one(N);
+    zp x = zp_one(N);
     return zp_cmp_int(x, 1);
 }
 
 int test_zp_copy(bn_st *N) {
-    struct zp x = zp_from_int(10, N);
-    struct zp y = zp_copy(x);
+    zp x = zp_from_int(10, N);
+    zp y = zp_copy(x);
     return zp_cmp(x, y);
 }
 
 int test_zp_from_int(bn_st *N) {
-    struct zp x = zp_from_int(3, N);
+    zp x = zp_from_int(3, N);
     return zp_cmp_int(x, 3);
 }
 
 int test_zp_add(bn_st *N) {
-    struct zp x = zp_from_int(10, N);
-    struct zp y = zp_from_int(20, N);
-    struct zp z = zp_add(x, y);
+    zp x = zp_from_int(10, N);
+    zp y = zp_from_int(20, N);
+    zp z = zp_add(x, y);
     return zp_cmp_int(z, 30);
 }
 
 int test_zp_neg(bn_st *N) {
-    struct zp x = rand_zp(N);
-    struct zp y = zp_neg(x);
-    struct zp z = zp_add(x, y);
+    zp x = rand_zp(N);
+    zp y = zp_neg(x);
+    zp z = zp_add(x, y);
     return zp_cmp_int(z, 0);
 }
 
 int test_zp_mul(bn_st *N) {
-    struct zp x = zp_from_int(10, N);
-    struct zp y = zp_from_int(20, N);
-    struct zp z = zp_mul(x, y);
+    zp x = zp_from_int(10, N);
+    zp y = zp_from_int(20, N);
+    zp z = zp_mul(x, y);
     return zp_cmp_int(z, 200);
 }
 
 int test_zp_inv(bn_st *N) {
-    struct zp x = rand_zp(N);
-    struct zp y = zp_inv(x);
-    struct zp z = zp_mul(x, y);
+    zp x = rand_zp(N);
+    zp y = zp_inv(x);
+    zp z = zp_mul(x, y);
     return zp_cmp_int(z, 1);
 }
 
diff --git a/tests/test_group.c b/tests/test_group.cpp
similarity index 90%
rename from tests/test_group.c
rename to tests/test_group.cpp
index b3c0d220575bb794d28c6569bbb2ce99e30f559a..3905e5138853bab1cdc48b4db61ee1ae092ce962 100644
--- a/tests/test_group.c
+++ b/tests/test_group.cpp
@@ -8,8 +8,8 @@ int test_generator() {
 
 int test_all(bn_st *N) {
     // Set integers.
-    struct zp m = zp_from_int(5, N);
-    struct zp n = zp_from_int(25, N);
+    zp m = zp_from_int(5, N);
+    zp n = zp_from_int(25, N);
 
     // Declare variables.
     g a, b;
diff --git a/tests/test_matrix.c b/tests/test_matrix.cpp
similarity index 100%
rename from tests/test_matrix.c
rename to tests/test_matrix.cpp
diff --git a/tests/test_vector.c b/tests/test_vector.cpp
similarity index 100%
rename from tests/test_vector.c
rename to tests/test_vector.cpp