]> git.siccegge.de Git - software/DIPE.git/commitdiff
Code drop
authorChristoph Egger <christoph@christoph-egger.org>
Mon, 6 Jan 2020 01:00:47 +0000 (02:00 +0100)
committerChristoph Egger <christoph@christoph-egger.org>
Mon, 6 Jan 2020 01:00:47 +0000 (02:00 +0100)
.gitignore [new file with mode: 0644]
CMakeLists.txt
doc/source/api.rst [new file with mode: 0644]
doc/source/index.rst
include/DIPE.h [new file with mode: 0644]
src/CMakeLists.txt
src/DIPE.cxx
tests/CMakeLists.txt [new file with mode: 0644]
tests/a.param [new file with mode: 0644]
tests/testDIPE.cpp [new file with mode: 0644]
tests/testPBC.cpp [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b25c15b
--- /dev/null
@@ -0,0 +1 @@
+*~
index 8340506b7b5b281b6f3ce9788cbd3b62de0dd6fa..823157a89e5b19e9c88029d14e6665299dcacda1 100644 (file)
@@ -1,4 +1,10 @@
 cmake_minimum_required (VERSION 2.8.11)
 project (DIPE)
 
+include(CTest)
+include(GoogleTest)
+
+set(CMAKE_VERBOSE_MAKEFILE on)
+
 add_subdirectory(src)
+add_subdirectory(tests)
diff --git a/doc/source/api.rst b/doc/source/api.rst
new file mode 100644 (file)
index 0000000..3bb3d6e
--- /dev/null
@@ -0,0 +1,57 @@
+API Documentation
+=================
+
+Types
+-----
+
+.. c:type:: dipe_param_t
+
+   Stores public parameters used in DIPE. Initialized by :c:func:`dipe_init()` and freed by :c:func:`dipe_free_param`
+                       
+.. c:type:: dipe_master_secretkey_t
+.. c:type:: dipe_master_publickey_t
+.. c:type:: dipe_secretkey_t
+.. c:type:: dipe_ctxt_t
+                       
+Functions
+---------
+
+Initialization
+~~~~~~~~~~~~~~
+
+.. c:function:: void dipe_init(FILE* configfp, dipe_param_t* param)
+
+   initializes public parameters as well as the PBC library
+
+   :param configfp: File structure holding the pairing group definition as understood by PBC
+
+Key Generation
+~~~~~~~~~~~~~~
+                                       
+.. c:function:: void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_publickey_t* pk, dipe_master_secretkey_t* sk);
+                               
+.. c:function:: void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, element_t* y, dipe_secretkey_t* sk);
+
+   :param cid: Client ID, expected to be 16 bytes
+   :param y: Policy vector for the secret key that is to be generated. Must match with the dimensions when `msk` was generated
+   :type y: Array of Zn elements
+
+En/Decryption
+~~~~~~~~~~~~~
+                       
+.. c:function:: void dipe_encrypt(dipe_param_t param, dipe_master_publickey mpk, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt)
+.. c:function:: void dipe_decrypt(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y, dipe_ctxt_t ctxt, element_t* ptxt)
+
+   :param result: It is the responsibility of the caller to initialize the element to GT and to free it after usage
+   :type result: :c:type:`element_t`
+
+Memory Management
+~~~~~~~~~~~~~~~~~
+                                
+.. c:function:: void dipe_free_param(dipe_param_t param);
+.. c:function:: void dipe_free_master_secretkey(dipe_master_secretkey_t sk);
+.. c:function:: void dipe_free_master_publickey(dipe_master_publickey_t pk);
+.. c:function:: void dipe_free_secretkey(dipe_secretkey_t sk);
+
+
+
index 765b8156b6bcb12bfb1fe95eac2f9b68d4b1052f..6e799b7069f8892cef602915c53ef57c37cf7b30 100644 (file)
@@ -10,6 +10,7 @@ Welcome to DIPE's documentation!
    :maxdepth: 2
    :caption: Contents:
 
+   api
 
 
 Indices and tables
diff --git a/include/DIPE.h b/include/DIPE.h
new file mode 100644 (file)
index 0000000..87ebab8
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <pbc/pbc.h>
+
+extern "C" {
+       typedef struct dipe_param* dipe_param_t;
+       typedef struct dipe_master_publickey* dipe_master_publickey_t;
+       typedef struct dipe_master_secretkey* dipe_master_secretkey_t;
+       typedef struct dipe_secretkey* dipe_secretkey_t;
+       typedef struct dipe_ctxt* dipe_ctxt_t;
+       
+       void dipe_init(FILE* configfp, dipe_param_t* param);
+       pairing_t* dipe_get_pairing(dipe_param_t param);
+       
+       void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_publickey_t* pk, dipe_master_secretkey_t* sk);
+       void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, element_t* y, dipe_secretkey_t* sk);
+       
+       void dipe_encrypt(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt);
+       void dipe_decrypt(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y, dipe_ctxt_t ctxt, element_t ptxt);
+
+       void dipe_free_param(dipe_param_t param);
+       void dipe_free_master_secretkey(dipe_master_secretkey_t sk);
+       void dipe_free_master_publickey(dipe_master_publickey_t pk);
+       void dipe_free_secretkey(dipe_secretkey_t sk);
+       void dipe_free_ctxt(dipe_ctxt_t ctxt);
+}
index 2d3ee8350d026445c35da078b59c1379630847d0..ce0076e1f48d2b50e18067965b447b5695fa6940 100644 (file)
@@ -1,6 +1,12 @@
 option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
 add_library (DIPE DIPE.cxx)
 
+add_definitions(-Wall -Wextra -Werror)
+
 # Make sure the compiler can find include files for our Hello library
 # when other libraries or executables link to Hello
-target_include_directories (DIPE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories (DIPE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+
+target_link_libraries(DIPE pbc)
+target_link_libraries(DIPE gmp)
+target_link_libraries(DIPE crypto)
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..321372dccd74d913c61f365b5e78af4133e3928b 100644 (file)
@@ -0,0 +1,250 @@
+#include "DIPE.h"
+#include <string.h>
+
+struct dipe_param {
+       pairing_t pairing;
+       element_t g1;
+       element_t g2;
+       element_t gt;
+};
+
+struct dipe_master_publickey {
+       size_t dimension;
+       element_t a;
+       element_t* k;
+};
+
+struct dipe_master_secretkey {
+       size_t dimension;
+       element_t a;
+       element_t* k;
+};
+
+struct dipe_secretkey {
+       size_t dimension;
+       element_t d;
+};
+
+struct dipe_ctxt {
+       size_t dimension;
+       element_t s;
+       element_t* cx;
+       element_t c;
+};
+
+
+namespace {
+       size_t dipe_h_length(element_t elem, size_t dimension) {
+               return 16 /*cid*/ + dimension * element_length_in_bytes(elem);
+       }
+       
+       void dipe_generate_h(char* cid, element_t* y, size_t dimension, unsigned char* result) {
+               memcpy(result, cid, 16);
+               unsigned char* next_element = result+16;
+               for (size_t i = 0; i < dimension; ++i) {
+                       element_to_bytes(next_element, y[i]);
+                       next_element += element_length_in_bytes(y[0]);
+               }
+       }
+}
+
+void dipe_init(FILE* configfp, dipe_param_t* param) {
+       char buffer[2<<16];
+       (*param) = (dipe_param_t)malloc(sizeof(dipe_param));
+       fread(buffer, 1, 2<<16, configfp);
+       
+       pairing_init_set_buf((*param)->pairing, buffer, 2<<16);
+
+       element_init_G1((*param)->g1, (*param)->pairing);
+       element_init_G2((*param)->g2, (*param)->pairing);
+       element_init_GT((*param)->gt, (*param)->pairing);
+       
+       element_random((*param)->g1);
+       element_random((*param)->g2);
+       pairing_apply((*param)->gt, (*param)->g1, (*param)->g2, (*param)->pairing);
+}
+
+pairing_t* dipe_get_pairing(dipe_param_t param) {
+       return &(param->pairing);
+}
+
+void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_publickey_t* pk, dipe_master_secretkey_t* sk) {
+       *pk = (dipe_master_publickey_t)malloc(sizeof(dipe_master_publickey));
+       *sk = (dipe_master_secretkey_t)malloc(sizeof(dipe_master_secretkey));
+
+       (*sk)->dimension = (*pk)->dimension = dimension;
+
+       element_init_Zr((*sk)->a, param->pairing);
+       element_init_GT((*pk)->a, param->pairing);
+       element_random((*sk)->a);
+       element_pow_zn((*pk)->a, param->gt, (*sk)->a);
+
+       (*sk)->k = (element_t*)calloc(dimension, sizeof(element_t));
+       (*pk)->k = (element_t*)calloc(dimension, sizeof(element_t));
+       for (size_t i = 0; i < dimension; ++i) {
+               element_init_Zr((*sk)->k[i], param->pairing);
+               element_init_G1((*pk)->k[i], param->pairing);
+               element_random((*sk)->k[i]);
+               element_pow_zn((*pk)->k[i], param->gt, (*sk)->k[i]);
+       }
+}
+
+void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, element_t* y, dipe_secretkey_t* sk) {
+       *sk = (dipe_secretkey_t)malloc(sizeof(dipe_secretkey));
+       (*sk)->dimension = msk->dimension;
+       element_init_G2((*sk)->d, param->pairing);
+       
+       size_t hash_input_length = dipe_h_length(y[0], msk->dimension);
+       unsigned char hash_input[hash_input_length];
+       element_t h;
+       element_init_G2(h, param->pairing);
+       
+       dipe_generate_h(cid, y, msk->dimension, hash_input);
+       element_from_hash(h, hash_input, hash_input_length);
+
+       element_t innerp;
+       element_t tmp;
+       
+       element_init_Zr(innerp, param->pairing);
+       element_init_Zr(tmp, param->pairing);
+       element_set1(innerp);
+
+       element_from_hash(h, hash_input, hash_input_length);
+       
+       for (size_t i = 0; i < msk->dimension; ++i) {
+               element_mul(tmp, y[i], msk->k[i]);
+               element_add(innerp, innerp, tmp);
+       }
+
+       element_t a2;
+       element_init_G2(a2, param->pairing);
+       element_pow_zn(h, h, innerp);
+       element_pow_zn(a2, param->g2, msk->a);
+       element_mul((*sk)->d, a2, h);
+       
+       element_clear(h);
+       element_clear(innerp);
+       element_clear(tmp);
+       element_clear(a2);
+}
+
+void dipe_encrypt(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt) {
+       *ctxt = (dipe_ctxt_t)malloc(sizeof(dipe_ctxt));
+       (*ctxt)->dimension = mpk->dimension;    
+       
+       element_t r;
+       element_t s;
+       element_init_Zr(r, param->pairing);
+       element_init_Zr(s, param->pairing);
+
+       element_random(r);
+       element_random(s);
+
+       element_init_G1((*ctxt)->s, param->pairing);
+       element_pow_zn((*ctxt)->s, param->g1, s);
+       
+       element_t k1;
+       element_t x1;
+       element_init_G1(k1, param->pairing);
+       element_init_G1(x1, param->pairing);
+       
+       (*ctxt)->cx = (element_t*)calloc(mpk->dimension, sizeof(element_t));
+       for (size_t i = 0; i < mpk->dimension; ++i){
+               element_pow_zn(x1, param->g1, x[i]);
+               element_pow_zn(x1, x1, r);
+
+               element_pow_zn(k1, mpk->k[i], s);
+               
+               element_init_G1((*ctxt)->cx[i], param->pairing);
+               element_mul((*ctxt)->cx[i], k1, x1);
+       }
+
+       element_t at;
+       element_init_GT(at, param->pairing);
+       element_pow_zn(at, mpk->a, s);
+       element_init_GT((*ctxt)->c, param->pairing);
+       element_mul((*ctxt)->c, at, ptxt);
+
+       element_clear(r);
+       element_clear(s);
+       element_clear(k1);
+       element_clear(x1);
+       element_clear(at);
+}
+
+
+void dipe_decrypt(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y, dipe_ctxt_t ctxt, element_t ptxt) {
+       size_t hash_input_length = dipe_h_length(y[0], sk->dimension);
+       unsigned char hash_input[hash_input_length];
+       element_t h;
+       element_init_G2(h, param->pairing);
+       
+       dipe_generate_h(cid, y, sk->dimension, hash_input);
+       element_from_hash(h, hash_input, hash_input_length);
+       
+       element_t tmp;
+       element_t innerp;
+       element_t hy;
+       element_init_GT(tmp, param->pairing);
+       element_init_GT(innerp, param->pairing);
+       element_init_G2(hy, param->pairing);
+
+       element_set1(innerp);   
+       for (size_t i = 0; i < sk->dimension; ++i) {
+               element_pow_zn(hy, h, y[i]);
+               pairing_apply(tmp, ctxt->cx[i], hy, param->pairing);
+               element_mul(innerp, innerp, tmp);
+       }
+
+       pairing_apply(ptxt, ctxt->s, sk->d, param->pairing);
+       element_invert(ptxt, ptxt);
+       element_mul(ptxt, ptxt, ctxt->c);
+       element_mul(ptxt, ptxt, innerp);
+
+       element_clear(h);
+       element_clear(tmp);
+       element_clear(innerp);
+       element_clear(hy);
+}
+
+
+void dipe_free_param(dipe_param_t param) {
+       element_clear(param->g1);
+       element_clear(param->g2);
+       element_clear(param->gt);
+       pairing_clear(param->pairing);
+       free(param);
+}
+
+void dipe_free_master_secretkey(dipe_master_secretkey_t sk) {
+       for (size_t i = 0; i < sk->dimension; ++i) {
+               element_clear(sk->k[i]);
+       }
+       element_clear(sk->a);
+       free(sk->k);
+       free(sk);
+}
+
+void dipe_free_master_publickey(dipe_master_publickey_t pk) {
+       for (size_t i = 0; i < pk->dimension; ++i) {
+               element_clear(pk->k[i]);
+       }
+       element_clear(pk->a);
+       free(pk->k);
+       free(pk);
+}
+
+void dipe_free_secretkey(dipe_secretkey_t sk) {
+       element_clear(sk->d);
+       free(sk);
+}
+
+void dipe_free_ctxt(dipe_ctxt_t ctxt) {
+       for (size_t i = 0; i < ctxt->dimension; ++i) {
+               element_clear(ctxt->cx[i]);
+       }
+       element_clear(ctxt->c);
+       element_clear(ctxt->s);
+       free(ctxt->cx);
+       free(ctxt);
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..288ed8c
--- /dev/null
@@ -0,0 +1,20 @@
+macro(package_add_test TESTNAME)
+    # create an exectuable in which the tests will be stored
+    add_executable(${TESTNAME} ${ARGN})
+    # link the Google test infrastructure, mocking library, and a default main fuction to
+    # the test executable.  Remove g_test_main if writing your own main function.
+    target_link_libraries(${TESTNAME} gtest gtest_main DIPE)
+    # gtest_discover_tests replaces gtest_add_tests,
+    # see https://cmake.org/cmake/help/v3.10/module/GoogleTest.html for more options to pass to it
+    gtest_discover_tests(${TESTNAME}
+        # set a working directory so your project root so that you can find test data via paths relative to the project root
+        WORKING_DIRECTORY ${PROJECT_DIR}
+        PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}"
+    )
+    set_target_properties(${TESTNAME} PROPERTIES FOLDER tests)
+endmacro()
+
+add_subdirectory(/usr/src/gtest gtest)
+
+package_add_test(testDIPE testDIPE.cpp)
+package_add_test(testPBC testPBC.cpp)
diff --git a/tests/a.param b/tests/a.param
new file mode 100644 (file)
index 0000000..cee0e9b
--- /dev/null
@@ -0,0 +1,8 @@
+type a
+q 8780710799663312522437781984754049815806883199414208211028653399266475630880222957078625179422662221423155858769582317459277713367317481324925129998224791
+h 12016012264891146079388821366740534204802954401251311822919615131047207289359704531102844802183906537786776
+r 730750818665451621361119245571504901405976559617
+exp2 159
+exp1 107
+sign1 1
+sign0 1
diff --git a/tests/testDIPE.cpp b/tests/testDIPE.cpp
new file mode 100644 (file)
index 0000000..0a3e209
--- /dev/null
@@ -0,0 +1,130 @@
+#include <gtest/gtest.h>
+#include <pbc/pbc.h>
+
+#include "DIPE.h"
+
+static dipe_param_t param;
+
+TEST(DipeTest, DipeMasterKeygen) {
+       dipe_master_publickey_t pk;
+       dipe_master_secretkey_t sk;
+
+       dipe_master_keygen(param, 12, &pk, &sk);
+
+       dipe_free_master_secretkey(sk);
+       dipe_free_master_publickey(pk);
+}
+
+TEST(DipeTest, DipeKeygen) {
+       dipe_master_publickey_t pk;
+       dipe_master_secretkey_t msk;
+       dipe_secretkey_t sk;
+       element_t y[5];
+       for (size_t i = 0; i < 5; ++i) {
+               element_init_Zr(y[i], *dipe_get_pairing(param));
+               element_random(y[i]);
+       }
+       
+       dipe_master_keygen(param, 5, &pk, &msk);
+       dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+       
+       dipe_free_master_secretkey(msk);
+       dipe_free_master_publickey(pk);
+       dipe_free_secretkey(sk);
+
+       for (size_t i = 0; i < 5; ++i) {
+               element_clear(y[i]);
+       }
+}
+
+TEST(DipeTest, DipeDecryptFail) {
+       dipe_ctxt_t ctxt;
+       dipe_master_publickey_t pk;
+       dipe_master_secretkey_t msk;
+       dipe_secretkey_t sk;
+       
+       element_t y[5];
+       for (size_t i = 0; i < 5; ++i) {
+               element_init_Zr(y[i], *dipe_get_pairing(param));
+               element_random(y[i]);
+       }
+       
+       dipe_master_keygen(param, 5, &pk, &msk);
+       dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+
+       element_t ptxt, ptxtp;
+       element_init_GT(ptxt, *dipe_get_pairing(param));
+       element_init_GT(ptxtp, *dipe_get_pairing(param));
+
+       element_random(ptxt);
+       
+       dipe_encrypt(param, pk, y, ptxt, &ctxt);
+       dipe_decrypt(param, sk, "1234567890abcdef", y, ctxt, ptxtp);
+
+       EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
+
+       for (size_t i = 0; i < 5; ++i) {
+               element_clear(y[i]);
+       }
+       
+       element_clear(ptxt);
+       element_clear(ptxtp);
+
+       dipe_free_master_secretkey(msk);
+       dipe_free_master_publickey(pk);
+       dipe_free_secretkey(sk);
+       dipe_free_ctxt(ctxt);
+}
+
+TEST(DipeTest, DipeDecryptSuccess) {
+       dipe_ctxt_t ctxt;
+       dipe_master_publickey_t pk;
+       dipe_master_secretkey_t msk;
+       dipe_secretkey_t sk;
+       
+       element_t y[5];
+       for (size_t i = 0; i < 5; ++i) {
+               element_init_Zr(y[i], *dipe_get_pairing(param));
+               element_set0(y[i]);
+       }
+       
+       dipe_master_keygen(param, 5, &pk, &msk);
+       dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
+
+       element_t ptxt, ptxtp;
+       element_init_GT(ptxt, *dipe_get_pairing(param));
+       element_init_GT(ptxtp, *dipe_get_pairing(param));
+
+       element_random(ptxt);
+       
+       dipe_encrypt(param, pk, y, ptxt, &ctxt);
+       dipe_decrypt(param, sk, "1234567890abcdef", y, ctxt, ptxtp);
+       element_printf("%B\n", ptxt);
+       element_printf("%B\n", ptxtp);
+
+       EXPECT_EQ(element_cmp(ptxt, ptxtp), 0);
+
+       for (size_t i = 0; i < 5; ++i) {
+               element_clear(y[i]);
+       }
+       
+       element_clear(ptxt);
+       element_clear(ptxtp);
+
+       dipe_free_master_secretkey(msk);
+       dipe_free_master_publickey(pk);
+       dipe_free_secretkey(sk);
+       dipe_free_ctxt(ctxt);
+}
+
+
+int main(int argc, char **argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+
+       dipe_init(fopen("../tests/a.param", "r"), &param);
+
+       int result = RUN_ALL_TESTS();
+       dipe_free_param(param);
+       return result;
+}
+
diff --git a/tests/testPBC.cpp b/tests/testPBC.cpp
new file mode 100644 (file)
index 0000000..826ec1b
--- /dev/null
@@ -0,0 +1,71 @@
+#include <gtest/gtest.h>
+#include <pbc/pbc.h>
+
+#include "DIPE.h"
+
+static pairing_t pairing;
+
+
+/* PBC is using multiplicative notion and ONE is indeed the neutral
+ * element wrt multiplication.
+ */
+TEST(PbcTest, PbcOneTest) {
+       element_t g1;
+       element_t z;
+       element_t g1z;
+
+       element_init_G1(g1, pairing);
+       element_init_Zr(z, pairing);
+       element_init_G1(g1z, pairing);
+
+       element_set1(g1);
+       element_random(z);
+       element_pow_zn(g1z, g1, z);
+
+       EXPECT_EQ(element_cmp(g1, g1z), 0);
+
+       element_clear(g1);
+       element_clear(z);
+       element_clear(g1z);
+}
+
+TEST(PbcTest, PbcFromHash) {
+       char test1[] = "pbctest1";
+       char test2[] = "pbctest2";
+       element_t a, b;
+
+       element_init_G2(a, pairing);
+       element_init_G2(b, pairing);
+
+       element_from_hash(a, test1, 8);
+       element_from_hash(b, test1, 8);
+       EXPECT_EQ(element_cmp(a, b), 0);
+
+       element_from_hash(a, test1, 8);
+       element_from_hash(b, test2, 8);
+       EXPECT_NE(element_cmp(a, b), 0);
+
+       element_clear(a);
+       element_clear(b);
+}
+
+int main(int argc, char **argv) {
+       char buffer[2<<16];
+    ::testing::InitGoogleTest(&argc, argv);
+
+       FILE *fp;
+       fp = fopen("../tests/a.param", "r");
+       if (fp == NULL) {
+               perror("Reading Pairing Parameters");
+               return 1;
+       }
+       size_t count = fread(buffer, 1, 2<<16, fp);
+
+       pairing_init_set_buf(pairing, buffer, 2<<16);
+
+       
+       int result = RUN_ALL_TESTS();
+       pairing_clear(pairing);
+       return result;
+}
+