From e406487051ee276df24e0aae15cee277fdcde4e6 Mon Sep 17 00:00:00 2001 From: Weiqi Feng <weltch1997@gmail.com> Date: Fri, 24 Feb 2023 19:01:53 -0500 Subject: [PATCH] Add files via upload --- CMakeLists.txt | 20 +++++++ apps/CMakeLists.txt | 2 + apps/app.c | 63 ++++++++++++++++++++++ include/field.h | 22 ++++++++ include/group.h | 19 +++++++ include/matrix.h | 25 +++++++++ include/vector.h | 22 ++++++++ src/CMakeLists.txt | 16 ++++++ src/field.c | 29 ++++++++++ src/group.c | 25 +++++++++ src/matrix.c | 122 +++++++++++++++++++++++++++++++++++++++++++ src/vector.c | 32 ++++++++++++ tests/CMakeLists.txt | 17 ++++++ tests/test_field.c | 62 ++++++++++++++++++++++ tests/test_group.c | 45 ++++++++++++++++ tests/test_matrix.c | 82 +++++++++++++++++++++++++++++ tests/test_vector.c | 63 ++++++++++++++++++++++ 17 files changed, 666 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 apps/CMakeLists.txt create mode 100644 apps/app.c create mode 100644 include/field.h create mode 100644 include/group.h create mode 100644 include/matrix.h create mode 100644 include/vector.h create mode 100644 src/CMakeLists.txt create mode 100644 src/field.c create mode 100644 src/group.c create mode 100644 src/matrix.c create mode 100644 src/vector.c create mode 100644 tests/CMakeLists.txt create mode 100644 tests/test_field.c create mode 100644 tests/test_group.c create mode 100644 tests/test_matrix.c create mode 100644 tests/test_vector.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2e5b590 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.24) +project( + PPANN + VERSION 0.1 + DESCRIPTION "Test" + LANGUAGES C +) + +if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + set(CMAKE_C_STANDARD 17) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + include(CTest) +endif() + + +find_library(RELIC_LIB relic) + +add_subdirectory(src) +add_subdirectory(apps) +add_subdirectory(tests) \ No newline at end of file diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt new file mode 100644 index 0000000..2333fb5 --- /dev/null +++ b/apps/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(app app.c) +target_link_libraries(app PRIVATE ppann_lib) \ No newline at end of file diff --git a/apps/app.c b/apps/app.c new file mode 100644 index 0000000..9508f4e --- /dev/null +++ b/apps/app.c @@ -0,0 +1,63 @@ +#include "field.h" +#include "group.h" +#include <stdio.h> +#include "relic/relic.h" + + +int main() { + core_init(); + pc_param_set_any(); + +// +// g a, b; +// gt x, y; +// +// // Get generator and map to target group, x = +// generator(a); +// map(a, a, x); +// +// +// g1_print(a); +// printf("\n"); +// gt_print(x); +// printf("\n"); +// +// // Multiply and Exp. +// zp m, n; +// zp_from_int(m, 5); +// zp_from_int(n, 5); +// +// // b = a^5, y = gt^10 +// multiply(b, a, m); +// +// g1_print(b); +// printf("\n"); +// +// exponentiation(y, x, n); +// +// gt_free(x); +// map(b, b, x); +// +// printf("Compare: %i", gt_cmp(y, x)); + + g1_t a, b; + gt_t x, y, z; + + g1_get_gen(a); + + g1_print(a); + + g1_mul_dig(b, a, 5); + + g1_print(b); + + pc_map(x, a, a); + + pc_map(y, b, b); + + gt_exp_dig(z, x, 25); + + printf("Compare: %i", gt_cmp(y, z) == RLC_EQ); + + return 0; +} \ No newline at end of file diff --git a/include/field.h b/include/field.h new file mode 100644 index 0000000..6c09690 --- /dev/null +++ b/include/field.h @@ -0,0 +1,22 @@ +#ifndef PPANN_FIELD_H +#define PPANN_FIELD_H + +#include "relic/relic.h" + +typedef fp_t zp; + +void rand_zp(zp x); + +void zp_zero(zp x); + +void zp_copy(zp x_copy, zp x); + +void zp_from_int(zp x, int x_int); + +void zp_add(zp r, zp x, zp y); + +void zp_multiply(zp p, zp x, zp y); + +void zp_inverse(zp xi, zp x); + +#endif //PPANN_FIELD_H \ No newline at end of file diff --git a/include/group.h b/include/group.h new file mode 100644 index 0000000..85c8954 --- /dev/null +++ b/include/group.h @@ -0,0 +1,19 @@ +#ifndef PPANN_GROUP_H +#define PPANN_GROUP_H + +#include "field.h" + +typedef g1_t g; +typedef gt_t gt; + +void generator(g x); + +void negate(g nx, g x); + +void multiply(g r, g x, zp y); + +void exponentiation(gt r, gt x, zp y); + +void map(g a, g b, gt r); + +#endif //PPANN_GROUP_H diff --git a/include/matrix.h b/include/matrix.h new file mode 100644 index 0000000..e13a4d2 --- /dev/null +++ b/include/matrix.h @@ -0,0 +1,25 @@ +#ifndef PPANN_MATRIX_H +#define PPANN_MATRIX_H + +#include "field.h" +#include "group.h" + +typedef zp* zp_mat; + +void matrix_zp_from_int(zp_mat x, int *int_mat, int row, int col); + +void matrix_zp_rand(zp_mat x, int row, int col); + +void matrix_identity(zp_mat x, int size); + +int matrix_is_identity(zp_mat x, int size); + +void matrix_transpose(zp_mat xt, zp_mat x, int row, int col); + +void matrix_merge(zp_mat xy, zp_mat x, zp_mat y, int row, int col_x, int col_y); + +void matrix_multiply(zp_mat xy, zp_mat x, zp_mat y, int row_x, int row_y, int col_y); + +void matrix_inverse(zp_mat xi, zp_mat x, int size); + +#endif //PPANN_MATRIX_H diff --git a/include/vector.h b/include/vector.h new file mode 100644 index 0000000..27c1c5c --- /dev/null +++ b/include/vector.h @@ -0,0 +1,22 @@ +#ifndef PPANN_VECTOR_H +#define PPANN_VECTOR_H + +#include "field.h" +#include "group.h" + +typedef zp *zp_vec; +typedef g *g_vec; + +void vector_zp_from_int(zp_vec x, int *int_vec, int length); + +void vector_zp_rand(zp_vec x, int length); + +void vector_merge(zp_vec r, zp_vec a, zp_vec b, int size_a, int size_b); + +void vector_add(zp_vec r, zp_vec a, zp_vec b, int size); + +void vector_raise(g base, zp_vec x, g_vec gx, int size); + +void inner_product(gt r, g_vec a, g_vec b, int size); + +#endif //PPANN_VECTOR_H \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..1b1c1ad --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,16 @@ +set(HEADER_LIST "${CMAKE_SOURCE_DIR}/include/") + +add_library(ppann_lib field.c group.c vector.c matrix.c ${HEADER_LIST}) + +# We need this directory, and users of our library will need it too +target_include_directories(ppann_lib PUBLIC ../include) + +# This depends on (header only) boost +target_link_libraries(ppann_lib PRIVATE ${RELIC_LIB}) + +# IDEs should put the headers in a nice place +source_group( + TREE "${PROJECT_SOURCE_DIR}/include" + PREFIX "Header Files" + FILES ${HEADER_LIST} +) diff --git a/src/field.c b/src/field.c new file mode 100644 index 0000000..82b6d37 --- /dev/null +++ b/src/field.c @@ -0,0 +1,29 @@ +#include "field.h" + +void rand_zp(dig_t *x) { + fp_rand(x); +} + +void zp_zero(dig_t *x) { + fp_zero(x); +} + +void zp_copy(dig_t *x_copy, dig_t *x) { + fp_copy(x_copy, x); +} + +void zp_from_int(dig_t *x, int y) { + fp_set_dig(x, y); +} + +void zp_add(dig_t *r, dig_t *x, dig_t *y) { + fp_add(r, x, y); +} + +void zp_multiply(dig_t *p, dig_t *x, dig_t *y) { + fp_mul(p, x, y); +} + +void zp_inverse(dig_t *xi, dig_t *x) { + fp_inv(xi, x); +} \ No newline at end of file diff --git a/src/group.c b/src/group.c new file mode 100644 index 0000000..1868a3b --- /dev/null +++ b/src/group.c @@ -0,0 +1,25 @@ +#include "group.h" + +void generator(ep_st *x) { + g1_get_gen(x); +} + +void negate(ep_st *nx, ep_st *x) { + g1_neg(nx, x); +} + +void multiply(ep_st *r, ep_st *x, dig_t *y) { + bn_t new_y; + fp_prime_back(new_y, y); + g1_mul(r, x, new_y); +} + +void exponentiation(fp_t *r, fp_t *x, dig_t *y) { + bn_t new_y; + fp_prime_back(new_y, y); + gt_exp(r, x, new_y); +} + +void map(ep_st *a, ep_st *b, fp_t *r) { + pc_map(r, a, b); +} diff --git a/src/matrix.c b/src/matrix.c new file mode 100644 index 0000000..ecc3e54 --- /dev/null +++ b/src/matrix.c @@ -0,0 +1,122 @@ +#include "matrix.h" + +void matrix_zp_from_int(zp_mat x, int *int_mat, int row, int col) { + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + zp_from_int(x[i * col + j], int_mat[i * col + j]); + } + } +} + +void matrix_zp_rand(zp_mat x, int row, int col) { + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + rand_zp(x[i * col + j]); + } + } +} + +void matrix_identity(zp_mat x, int size) { + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (i == j) zp_from_int(x[i * size + j], 1); + else zp_zero(x[i * size + j]); + } + } +} + +int matrix_is_identity(zp_mat x, int size) { + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (i == j && fp_cmp_dig(x[i * size + j], 1) != RLC_EQ) return 0; + if (i != j && fp_cmp_dig(x[i * size + j], 0) != RLC_EQ) return 0; + } + } + return 1; +} + +void matrix_transpose(zp_mat xt, zp_mat x, int row, int col) { + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + zp_copy(xt[j * row + i], x[i * col + j]); + } + } +} + +void matrix_merge(zp_mat xy, zp_mat x, zp_mat y, int row, int col_x, int col_y) { + for (int i = 0; i < row; i++) { + for (int j = 0; j < col_x; j++) { + zp_copy(xy[i * (col_x + col_y) + j], x[i * col_x + j]); + } + for (int j = 0; j < col_y; j++) { + zp_copy(xy[i * (col_x + col_y) + col_x + j], y[i * col_y + j]); + } + } +} + +void matrix_multiply(zp_mat xy, zp_mat x, zp_mat y, int row_x, int row_y, int col_y) { + zp temp; + for (int i = 0; i < row_x; i++) { + for (int j = 0; j < col_y; j++) { + zp_from_int(xy[i * row_y + j], 0); + for (int k = 0; k < row_y; k++) { + zp_multiply(temp, x[i * row_y + k], y[k * col_y + j]); + zp_add(xy[i * col_y + j], xy[i * col_y + j], temp); + } + } + } +} + +void matrix_inverse(zp_mat xi, zp_mat x, int size) { + // Declare the row echelon matrix and generate it. + zp *identity, *row_echelon; + identity = (zp *) malloc(size * size * sizeof(zp)); + row_echelon = (zp *) malloc(2 * size * size * sizeof(zp)); + matrix_identity(identity, size); + matrix_merge(row_echelon, x, identity, size, size, size); + + // Declare temp value. + zp temp_multiplier, temp_neg; + + // Bottom left half to all zeros. + for (int i = 0; i < size; i++) { + for (int j = i; j < size; j++) { + if (i == j && fp_cmp_dig(row_echelon[i * 2 * size + j], 1) != RLC_EQ) { + zp_inverse(temp_multiplier, row_echelon[i * 2 * size + i]); + for (int k = i; k < size * 2; k++) { + zp_multiply(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_multiplier); + } + } + + if (i == j && fp_cmp_dig(row_echelon[i * 2 * size + j], 0) == RLC_EQ) break; + + if (i != j) { + zp_copy(temp_multiplier, row_echelon[j * 2 * size + i]); + for (int k = i; k < size * 2; k++) { + zp_multiply(temp_neg, temp_multiplier, row_echelon[i * 2 * size + k]); + fp_neg(temp_neg, temp_neg); + zp_add(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_neg); + } + } + } + } + + // Top right half to all zeros. + for (int i = size - 1; i > 0; i--) { + for (int j = i - 1; j >= 0; j--) { + zp_copy(temp_multiplier, row_echelon[j * 2 * size + i]); + for (int k = i; k < size * 2; k++) { + zp_multiply(temp_neg, temp_multiplier, row_echelon[i * 2 * size + k]); + fp_neg(temp_neg, temp_neg); + zp_add(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_neg); + } + } + } + + // Copy over the output. + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + zp_copy(xi[i * size + j], row_echelon[i * 2 * size + size + j]); + } + } +} diff --git a/src/vector.c b/src/vector.c new file mode 100644 index 0000000..43ac6d0 --- /dev/null +++ b/src/vector.c @@ -0,0 +1,32 @@ +#include "vector.h" + +void vector_zp_from_int(zp_vec x, int *int_vec, int length) { + for (int i = 0; i < length; i++) zp_from_int(x[i], int_vec[i]); +} + +void vector_zp_rand(zp_vec x, int length) { + for (int i = 0; i < length; i++) rand_zp(x[i]); +} + +void vector_merge(zp_vec r, zp_vec a, zp_vec b, int size_a, int size_b) { + for (int i = 0; i < size_a; i++) zp_copy(r[i], a[i]); + for (int i = 0; i < size_b; i++) zp_copy(r[i + size_a], b[i]); +} + +void vector_add(zp_vec r, zp_vec a, zp_vec b, int size) { + for (int i = 0; i < size; i++) zp_add(r[i], a[i], b[i]); +} + +void vector_raise(ep_st base[1], zp_vec x, g_vec gx, int size) { + for (int i = 0; i < size; i++) multiply(gx[i], base, x[i]); +} + +void inner_product(gt r, g_vec a, g_vec b, int size) { + pc_map_sim(r, a, b, size); +} + + + + + + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..ef1621d --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,17 @@ +# 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) + +# 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) + +# 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 diff --git a/tests/test_field.c b/tests/test_field.c new file mode 100644 index 0000000..d51f818 --- /dev/null +++ b/tests/test_field.c @@ -0,0 +1,62 @@ +#include "field.h" + +int test_zp_zero() { + zp x, y; + zp_zero(x); + fp_zero(y); + return fp_cmp(x, y); +} + +int test_zp_copy() { + zp x, y; + zp_from_int(x, 3); + zp_copy(y, x); + return fp_cmp_dig(y, 3); +} + +int test_zp_from_int() { + zp x; + zp_from_int(x, 3); + return fp_cmp_dig(x, 3); +} + +int test_zp_add() { + zp x, y, r; + zp_from_int(x, 10); + zp_from_int(y, 20); + zp_add(r, x, y); + return fp_cmp_dig(r, 30); +} + +int test_zp_multiply() { + zp x, y, r; + zp_from_int(x, 10); + zp_from_int(y, 20); + zp_multiply(r, x, y); + return fp_cmp_dig(r, 200); +} + +int test_zp_inverse() { + zp x, xi, r; + rand_zp(x); + zp_inverse(xi, x); + zp_multiply(r, x, xi); + return fp_cmp_dig(r, 1); +} + + +int main() { + // Init core and setup. + core_init(); + pc_param_set_any(); + + // Perform tests. + if (test_zp_zero() != RLC_EQ) return 1; + if (test_zp_copy() != RLC_EQ) return 1; + if (test_zp_from_int() != RLC_EQ) return 1; + if (test_zp_add() != RLC_EQ) return 1; + if (test_zp_multiply() != RLC_EQ) return 1; + if (test_zp_inverse() != RLC_EQ) return 1; + + return 0; +} \ No newline at end of file diff --git a/tests/test_group.c b/tests/test_group.c new file mode 100644 index 0000000..0e6b9d1 --- /dev/null +++ b/tests/test_group.c @@ -0,0 +1,45 @@ +#include "group.h" + +int test_generator() { + g x; + generator(x); + return g1_is_valid(x); +} + +int test_all() { + // Set integers. + zp m, n; + zp_from_int(m, 5); + zp_from_int(n, 25); + + // Declare variables. + g a, b; + gt x, y, z; + + // Get generator g and find g^5. + generator(a); + multiply(b, a, m); + + // Get e(g, g) and e(g^5, g^5). + map(a, a, x); + map(b, b, y); + + // Get e(g, g)^25. + exponentiation(z, x, n); + + // Compare e(g^5, g^5) with e(g, g)^25. + return gt_cmp(y, z); +} + +int main(){ + // Init core and setup. + core_init(); + fp_prime_init(); + pc_param_set_any(); + + // Perform tests. + if (test_generator() != 1) return 1; + if (test_all() != RLC_EQ) return 1; + + return 0; +} \ No newline at end of file diff --git a/tests/test_matrix.c b/tests/test_matrix.c new file mode 100644 index 0000000..2f17074 --- /dev/null +++ b/tests/test_matrix.c @@ -0,0 +1,82 @@ +#include "matrix.h" + +int test_zp_from_int() { + int row = 3, col = 3; + zp x[row * col]; + int int_vec[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + matrix_zp_from_int(x, int_vec, 3, 3); + return fp_cmp_dig(x[2 * col + 2], 9); +} + +int test_transpose() { + int row = 3, col = 3; + zp x[row * col], xt[col * row]; + matrix_zp_rand(x, row, col); + matrix_transpose(xt, x, row, col); + return fp_cmp(xt[col - 1], x[2 * row]); +} + +int test_identity() { + int size = 1000; + zp *x; + x = (zp *) malloc(size * size * sizeof(zp)); + matrix_identity(x, size); + return matrix_is_identity(x, size); +} + +int test_merge() { + int size = 10; + zp xy[(size + size) * size], x[size * size], y[size * size]; + matrix_zp_rand(x, size, size); + matrix_identity(y, size); + matrix_merge(xy, x, y, size, size, size); + return fp_cmp(x[2 * size + 1], xy[4 * size + 1]); +} + +int test_multiply_vector() { + int int_x[5] = {1, 2, 3, 4, 5}; + int int_y[15] = {10, 20, 30, + 10, 20, 30, + 10, 20, 30, + 10, 20, 30, + 10, 20, 30}; + + zp x[5], y[15]; + matrix_zp_from_int(x, int_x, 1, 5); + matrix_zp_from_int(y, int_y, 5, 3); + + zp xy[3]; + matrix_multiply(xy, x, y, 1, 5, 3); + + return fp_cmp_dig(xy[1], 300); +} + +int test_inverse() { + int size = 100; + // Allocate space. + zp *x, *xi, *r; + x = (zp *) malloc(size * size * sizeof(zp)); + xi = (zp *) malloc(size * size * sizeof(zp)); + r = (zp *) malloc(size * size * sizeof(zp)); + matrix_zp_rand(x, size, size); + matrix_inverse(xi, x, size); + matrix_multiply(r, xi, x, size, size, size); + return matrix_is_identity(r, size); +} + + +int main() { + // Init core and setup. + core_init(); + pc_param_set_any(); + + // Perform tests. + if (test_zp_from_int() != RLC_EQ) return 1; + if (test_transpose() != RLC_EQ) return 1; + if (test_identity() != 1) return 1; + if (test_merge() != RLC_EQ) return 1; + if (test_multiply_vector() != RLC_EQ) return 1; + if (test_inverse() != 1) return 1; + + return 0; +} \ No newline at end of file diff --git a/tests/test_vector.c b/tests/test_vector.c new file mode 100644 index 0000000..91e27a7 --- /dev/null +++ b/tests/test_vector.c @@ -0,0 +1,63 @@ +#include "vector.h" + +int test_zp_from_int() { + zp x[4]; + int int_vec[4] = {1, 2, 3, 4}; + vector_zp_from_int(x, int_vec, 4); + return fp_cmp_dig(x[3], 4); +} + +int test_merge_vector() { + zp x[3], y[3], z[6]; + int int_vec_x[3] = {1, 2, 3}; + int int_vec_y[3] = {11, 22, 33}; + vector_zp_from_int(x, int_vec_x, 3); + vector_zp_from_int(y, int_vec_y, 3); + vector_merge(z, x, y, 3, 3); + return fp_cmp_dig(z[5], 33); +} + +int test_add_vector() { + zp x[3], y[3], z[3]; + int int_vec_x[3] = {1, 2, 3}; + int int_vec_y[3] = {11, 22, 33}; + vector_zp_from_int(x, int_vec_x, 3); + vector_zp_from_int(y, int_vec_y, 3); + vector_add(z, x, y, 3); + return fp_cmp_dig(z[2], 36); +} + +int test_inner_product() { + zp x[3], y[3]; + int int_vec_x[3] = {1, 2, 3}; + int int_vec_y[3] = {4, 5, 6}; + vector_zp_from_int(x, int_vec_x, 3); + vector_zp_from_int(y, int_vec_y, 3); + + g g, gx[3], gy[3]; + generator(g); + vector_raise(g, x, gx, 3); + vector_raise(g, y, gy, 3); + + gt b, r; + inner_product(r, gx, gy, 3); + map(g, g, b); + gt_exp_dig(b, b, 32); + + return gt_cmp(b, r); +} + + +int main() { + // Init core and setup. + core_init(); + pc_param_set_any(); + + // Perform tests. + if (test_zp_from_int() != RLC_EQ) return 1; + if (test_merge_vector() != RLC_EQ) return 1; + if (test_add_vector() != RLC_EQ) return 1; + if (test_inner_product() != RLC_EQ) return 1; + + return 0; +} \ No newline at end of file -- GitLab