From 32b3981095e97debb0a5cf4bff459deeee66c973 Mon Sep 17 00:00:00 2001 From: mlewa89 <52212310+mlewa89@users.noreply.github.com> Date: Wed, 16 Oct 2019 10:47:18 +0200 Subject: [PATCH] DIPPE scheme (#12) --- CMakeLists.txt | 3 + include/cifer/abe/dippe.h | 243 ++++++++++++++++++ include/cifer/data/mat_curve.h | 225 +++++++++++++++++ include/cifer/data/vec_curve.h | 57 +++++ include/cifer/test.h | 1 + src/abe/dippe.c | 434 +++++++++++++++++++++++++++++++++ src/data/mat_curve.c | 281 +++++++++++++++++++++ src/data/vec_curve.c | 48 ++++ test/abe/dippe.c | 255 +++++++++++++++++++ test/test.c | 1 + 10 files changed, 1548 insertions(+) create mode 100644 include/cifer/abe/dippe.h create mode 100644 include/cifer/data/mat_curve.h create mode 100644 src/abe/dippe.c create mode 100644 src/data/mat_curve.c create mode 100644 test/abe/dippe.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 99a3e7d..42f3e2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ include_directories( # Library sources set(library_SOURCES src/data/mat.c + src/data/mat_curve.c src/data/vec.c src/data/vec_float.c src/data/vec_curve.c @@ -56,6 +57,7 @@ set(library_SOURCES src/abe/policy.c src/abe/gpsw.c src/abe/fame.c + src/abe/dippe.c src/quadratic/sgp.c ) @@ -93,6 +95,7 @@ set(binary_SOURCES test/abe/policy.c test/abe/gpsw.c test/abe/fame.c + test/abe/dippe.c external/munit/munit.c test/quadratic/sgp.c ) diff --git a/include/cifer/abe/dippe.h b/include/cifer/abe/dippe.h new file mode 100644 index 0000000..ff15f03 --- /dev/null +++ b/include/cifer/abe/dippe.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2018 XLAB d.o.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CIFER_DIPPE_H +#define CIFER_DIPPE_H + +#include +#include +#include +#include + +#include "cifer/data/mat.h" +#include "cifer/data/mat_curve.h" +#include "cifer/data/vec.h" +#include "cifer/data/vec_curve.h" +#include "cifer/internal/errors.h" + +/** +* \file +* \ingroup abe +* \brief This is a decentralized inner-product predicate encryption +* scheme by Yan Michalevsky and Marc Joye: "Decentralized Policy-Hiding +* Attribute-Based Encryption with Receiver Privacy" +*/ + +/** + * cfe_dippe represents the DIPPE scheme + */ +typedef struct cfe_dippe { + size_t assump_size; + mpz_t p; + cfe_mat_G1 g1_A; + cfe_mat_G1 g1_UA; +} cfe_dippe; + +/** + * Initializes the DIPPE scheme and generates the global parameters + * + * @param dippe A pointer to a cfe_dippe struct + * @param assump_size The size of the underlying assumption + */ +void cfe_dippe_init(cfe_dippe *dippe, size_t assump_size); + +/** + * Clears the scheme and frees allocated memory + * + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_free(cfe_dippe *dippe); + +/** + * Prepares an attribute vector + * + * @param av A pointer to a cfe_vec struct; Represents the resulting attribute vector + * @param num_attrib Number of attributes + * @param pattern Array of indices to define the attribute vector + * @param pat_len Length of the pattern array + * @return Error code + */ +cfe_error cfe_dippe_attribute_vector_init(cfe_vec *av, size_t num_attrib, size_t pattern[], size_t pat_len); + +/** + * Prepares an exact threshold policy vector + * + * @param pv A pointer to a cfe_vec struct; Represents the resulting policy vector + * @param dippe A pointer to a cfe_dippe struct + * @param num_attrib Number of attributes + * @param pattern Array of indices to define the policy vector + * @param pat_len Length of the pattern array + * @param threshold Threshold value + * @return Error code + */ +cfe_error cfe_dippe_exact_threshold_policy_vector_init(cfe_vec *pv, cfe_dippe *dippe, size_t num_attrib, size_t pattern[], size_t pat_len, size_t threshold); + +/** + * Prepares a conjunction policy vector + * + * @param pv A pointer to a cfe_vec struct; Represents the resulting policy vector + * @param dippe A pointer to a cfe_dippe struct + * @param num_attrib Number of attributes + * @param pattern Array of indices to define the policy vector + * @param pat_len Length of the pattern array + * @return Error code + */ +cfe_error cfe_dippe_conjunction_policy_vector_init(cfe_vec *pv, cfe_dippe *dippe, size_t num_attrib, size_t pattern[], size_t pat_len); + +/** + * cfe_dippe_cipher represents the ciphertext of the DIPPE scheme + */ +typedef struct cfe_dippe_cipher { + FP12_BN254 C_prime; + cfe_vec_G1 C0; + cfe_mat_G1 Ci; +} cfe_dippe_cipher; + +/** + * Prepares a cipher struct + * + * @param pk A pointer to a cfe_dippe_cipher struct + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_cipher_init(cfe_dippe_cipher *cipher, cfe_dippe *dippe, size_t pol_size); + +/** + * Clears the ciphertext and frees allocated memory + * + * @param cipher A pointer to a cfe_dippe_cipher struct + */ +void cfe_dippe_cipher_free(cfe_dippe_cipher *cipher); + +/** + * cfe_dippe_pub_key represents the public key of the DIPPE scheme + */ +typedef struct cfe_dippe_pub_key { + ECP2_BN254 g2_sigma; + cfe_mat_G1 g1_W_A; + cfe_vec_GT gt_alpha_A; +} cfe_dippe_pub_key; + +/** + * Prepares a public key struct + * + * @param pk A pointer to a cfe_dippe_pub_key struct + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_pub_key_init(cfe_dippe_pub_key *pk, cfe_dippe *dippe); + +/** + * Clears the public key and frees allocated memory + * + * @param pk A pointer to a cfe_dippe_pub_key struct + */ +void cfe_dippe_pub_key_free(cfe_dippe_pub_key *pk); + +/** + * cfe_dippe_sec_key represents the secret key of the DIPPE scheme + */ +typedef struct cfe_dippe_sec_key { + mpz_t sigma; + cfe_vec alpha; + cfe_mat W; +} cfe_dippe_sec_key; + +/** + * Prepares a secret key struct + * + * @param pk A pointer to a cfe_dippe_sec_key struct + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_sec_key_init(cfe_dippe_sec_key *sk, cfe_dippe *dippe); + +/** + * Clears the secret key and frees allocated memory + * + * @param sk A pointer to a cfe_dippe_sec_key struct + */ +void cfe_dippe_sec_key_free(cfe_dippe_sec_key *sk); + +/** + * cfe_dippe_sec_key represents the user secret key of the DIPPE scheme + */ +typedef struct cfe_dippe_user_sec_key { + cfe_vec_G2 Ki; +} cfe_dippe_user_sec_key; + +/** + * Prepares a user secret key struct + * + * @param usk A pointer to a cfe_dippe_user_sec_key struct + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_user_sec_key_init(cfe_dippe_user_sec_key *usk, cfe_dippe *dippe); + +/** + * Clears the user secret key and frees allocated memory + * + * @param usk A pointer to a cfe_dippe_user_sec_key struct + */ +void cfe_dippe_user_sec_key_free(cfe_dippe_user_sec_key *usk); + +/** + * Initializes an authority and generates its public and private key + * + * @param pk A pointer to a cfe_dippe_pub_key struct; Represents the public key that is about to be populated + * @param sk A pointer to a cfe_dippe_sec_key struct; Represents the secret key that is about to be populated + * @param dippe A pointer to a cfe_dippe struct + */ +void cfe_dippe_generate_master_keys(cfe_dippe_pub_key *pk, cfe_dippe_sec_key *sk, cfe_dippe *dippe); + +/** + * Encrypts a given message under the provided policy + * + * @param cipher A pointer to a cfe_dippe_cipher struct; Represents the ciphertext that is about to be populated + * @param dippe A pointer to a cfe_dippe struct + * @param pks An array containing references to cfe_dippe_pub_key structs; + * @param pks_len Length of the public key array + * @param pv A reference to a cfe_vec struct; Represents the policy under which the message will be encrypted + * @param msg A reference to a FP12_BN254 struct; Represents the message that is about to be encrypted + * @return Error code + */ +cfe_error cfe_dippe_encrypt(cfe_dippe_cipher *cipher, cfe_dippe *dippe, cfe_dippe_pub_key *pks[], size_t pks_len, cfe_vec *pv, FP12_BN254 *msg); + +/** + * Used with an authority's secret key to create a new user secret key for a given attribute vector + * + * @param usk A pointer to a cfe_dippe_user_sec_key struct; Represents the user secret key that is about to be populated + * @param dippe A pointer to a cfe_dippe struct + * @param usk_id Index of the given attribute vector for which a user secret key will be created + * @param pks An array containing references to cfe_dippe_pub_key structs + * @param pks_len Length of the public key array + * @param av A pointer to a cfe_vec struct; Represents the attribute vector + * @param gid String that represents a unique user; Required for collusion prevention + * @return Error code + */ +cfe_error cfe_dippe_keygen(cfe_dippe_user_sec_key *usk, cfe_dippe *dippe, size_t usk_id, cfe_dippe_pub_key *pks[], size_t pks_len, cfe_dippe_sec_key *sk, cfe_vec *av, char gid[]); + +/** + * Restores the underlying message of a given ciphertext + * + * @param result A pointer to a FP12_BN254 struct; Represents the resulting message + * @param dippe A pointer to a cfe_dippe struct + * @param usks An array containing cfe_dippe_user_sec_key structs; Represents the set of user secretes key used for decryption + * @param usks_len Length of the user secret key array + * @param cipher A pointer to a cfe_dippe_cipher struct; Represents the ciphertext that is about to be decrypted + * @param av A pointer to a cfe_vec struct; Represents the attribute vector + * @param gid String that represents a unique user; Required for collusion prevention + */ +cfe_error cfe_dippe_decrypt(FP12_BN254 *result, cfe_dippe *dippe, cfe_dippe_user_sec_key *usks, size_t usks_len, cfe_dippe_cipher *cipher, cfe_vec *av, char gid[]); + +#endif diff --git a/include/cifer/data/mat_curve.h b/include/cifer/data/mat_curve.h new file mode 100644 index 0000000..40b96f8 --- /dev/null +++ b/include/cifer/data/mat_curve.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2018 XLAB d.o.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CIFER_MATRIX_CURVE_H +#define CIFER_MATRIX_CURVE_H + +#include +#include "cifer/data/mat.h" +#include "cifer/data/vec_curve.h" + +/** + * \file + * \ingroup data + * \brief Matrices of elements of an elliptic curve struct and operations on it. + */ + +/** + * Matrix of ECP_BN254 elements. + */ +typedef struct cfe_mat_G1 { + cfe_vec_G1 *mat; /** A pointer to the first element */ + size_t rows; /** The rows of the matrix */ + size_t cols; /** The cols of the matrix */ +} cfe_mat_G1; + +/** + * Matrix of ECP2_BN254 elements. + */ +typedef struct cfe_mat_G2 { + cfe_vec_G2 *mat; /** A pointer to the first element */ + size_t rows; /** The rows of the matrix */ + size_t cols; /** The cols of the matrix */ +} cfe_mat_G2; + +/** + * Matrix of FP12_BN254 elements. + */ +typedef struct cfe_mat_GT { + cfe_vec_GT *mat; /** A pointer to the first element */ + size_t rows; /** The rows of the matrix */ + size_t cols; /** The cols of the matrix */ +} cfe_mat_GT; + +/** + * Initializes a matrix of ECP_BN254 elements + * + * @param m A pointer to an uninitialized cfe_mat_G1 matrix + * @param rows The number of rows + * @param cols The number of columns + */ +void cfe_mat_G1_init(cfe_mat_G1 *m, size_t rows, size_t cols); + +/** + * Transposes the given cfe_mat_G1 matrix + * + * @param res A pointer to an initialized cfe_mat_G1 matrix + * @param m A pointer to a cfe_mat_G1 matrix + */ +void cfe_mat_G1_transpose(cfe_mat_G1 *res, cfe_mat_G1 *m); + +/** + * Creates a matrix whose i-th element equals u[i] * g, + * where g is the generator of ECP_BN254. The sizes of + * m and u must match. + * + * @param m A pointer to an initialized cfe_mat_G1 matrix + * @param u A pointer to matrix of integers + */ +void cfe_mat_mul_G1(cfe_mat_G1 *m, cfe_mat *u); + +/** + * Multiplication of a matrix of integers by a matrix of elements of G1 + * + * @param res A pointer to an initialized cfe_mat_G1 matrix + * @param mi A pointer to matrix of integers + * @param u A pointer to an initialized cfe_mat_G1 matrix + */ +void cfe_mat_mul_G1_mat(cfe_mat_G1 *res, cfe_mat *mi, cfe_mat_G1 *m); + +/** + * Multiplication of a matrix of elements of G1 by a vector of integers. + * + * @param res A pointer to an initialized cfe_vec_G1 vector + * @param m A pointer to a cfe_mat_G1 matrix + * @param u A pointer to matrix of integers + */ +void cfe_mat_G1_mul_vec(cfe_vec_G1 *res, cfe_mat_G1 *m, cfe_vec *u); + +/** + * Frees the memory occupied by the struct members. It does not free + * memory occupied by the struct itself. + * + * @param m A pointer to a matrix (*initialized* + * cfe_mat_G1 struct) + */ +void cfe_mat_G1_free(cfe_mat_G1 *m); + +/** + * Initializes a matrix of ECP2_BN254 elements + * + * @param m A pointer to an uninitialized cfe_mat_G2 matrix + * @param rows The number of rows + * @param cols The number of columns + */ +void cfe_mat_G2_init(cfe_mat_G2 *m, size_t rows, size_t cols); + +/** + * Transposes the given cfe_mat_G2 matrix. + * + * @param res A pointer to an initialized cfe_mat_G2 matrix + * @param m A pointer to a cfe_mat_G2 matrix + */ +void cfe_mat_G2_transpose(cfe_mat_G2 *res, cfe_mat_G2 *m); + +/** + * Creates a matrix whose i-th element equals u[i] * g, + * where g is the generator of ECP2_BN254. The sizes of + * m and u must match. + * + * @param m A pointer to an initialized cfe_mat_G2 matrix + * @param u A pointer to matrix of integers. + */ +void cfe_mat_mul_G2(cfe_mat_G2 *m, cfe_mat *u); + +/** + * Multiplication of a matrix of integers by a matrix of elements of G2 + * + * @param res A pointer to an initialized cfe_mat_G2 matrix + * @param mi A pointer to matrix of integers + * @param u A pointer to an initialized cfe_mat_G2 matrix + */ +void cfe_mat_mul_G2_mat(cfe_mat_G2 *res, cfe_mat *mi, cfe_mat_G2 *m); + +/** + * Multiplication of a matrix of elements of G2 by a vector of integers. + * + * @param res A pointer to an initialized cfe_vec_G2 vector + * @param m A pointer to a cfe_mat_G2 matrix + * @param u A pointer to matrix of integers. + */ +void cfe_mat_G2_mul_vec(cfe_vec_G2 *res, cfe_mat_G2 *m, cfe_vec *u); + +/** + * Frees the memory occupied by the struct members. It does not free + * memory occupied by the struct itself. + * + * @param m A pointer to a matrix (*initialized* + * cfe_mat_G2 struct) + */ +void cfe_mat_G2_free(cfe_mat_G2 *m); + +/** + * Initializes a matrix of FP12_BN254 elements + * + * @param m A pointer to an uninitialized cfe_mat_GT matrix + * @param rows The number of rows + * @param cols The number of columns + */ +void cfe_mat_GT_init(cfe_mat_GT *m, size_t rows, size_t cols); + +/** + * Transposes the given cfe_mat_GT matrix. + * + * @param res A pointer to an initialized cfe_mat_GT matrix + * @param m A pointer to a cfe_mat_GT matrix + */ +void cfe_mat_GT_transpose(cfe_mat_GT *res, cfe_mat_GT *m); + +/** + * Multiplication of a matrix of integers by a matrix of elements of GT + * + * @param res A pointer to an initialized cfe_mat_GT matrix + * @param mi A pointer to matrix of integers + * @param u A pointer to an initialized cfe_mat_GT matrix + */ +void cfe_mat_mul_GT_mat(cfe_mat_GT *res, cfe_mat *mi, cfe_mat_GT *m); + +/** + * Multiplication of a matrix of elements of GT by a vector of integers. + * + * @param res A pointer to an initialized cfe_vec_GT vector + * @param m A pointer to a cfe_mat_GT matrix + * @param u A pointer to matrix of integers. + */ +void cfe_mat_GT_mul_vec(cfe_vec_GT *res, cfe_mat_GT *m, cfe_vec *u); + +/** + * Pairs a given cfe_mat_G1 matrix with the generator of G2 + * + * @param res A pointer to an initialized cfe_vec_GT matrix + * @param m A pointer to a cfe_mat_G1 matrix + */ +void cfe_mat_GT_pair_mat_G1(cfe_mat_GT *res, cfe_mat_G1 *m); + +/** + * Pairs a given cfe_mat_G2 matrix with the generator of G1 + * + * @param res A pointer to an initialized cfe_vec_GT matrix + * @param m A pointer to a cfe_mat_G2 matrix + */ +void cfe_mat_GT_pair_mat_G2(cfe_mat_GT *res, cfe_mat_G2 *m); + +/** + * Frees the memory occupied by the struct members. It does not free + * memory occupied by the struct itself. + * + * @param m A pointer to a matrix (*initialized* + * cfe_mat_GT struct) + */ +void cfe_mat_GT_free(cfe_mat_GT *m); + +#endif diff --git a/include/cifer/data/vec_curve.h b/include/cifer/data/vec_curve.h index df14377..5de82fa 100644 --- a/include/cifer/data/vec_curve.h +++ b/include/cifer/data/vec_curve.h @@ -19,6 +19,7 @@ #include #include +#include #include "cifer/data/vec.h" /** @@ -43,6 +44,14 @@ typedef struct cfe_vec_G2 { size_t size; /** The size of the vector */ } cfe_vec_G2; +/** + * Vector of FP12_BN254 elements. + */ +typedef struct cfe_vec_GT { + FP12_BN254 *vec; /** A pointer to the first element */ + size_t size; /** The size of the vector */ +} cfe_vec_GT; + /** * Initializes a vector of ECP_BN254 elements of given size. * @@ -51,6 +60,13 @@ typedef struct cfe_vec_G2 { */ void cfe_vec_G1_init(cfe_vec_G1 *v, size_t size); +/** + * Sets all the values of a vector to the identity element. + * + * @param v A pointer to an initialized cfe_vec_G1 vector + */ +void cfe_vec_G1_inf(cfe_vec_G1 *v); + /** * Creates a vector whose i-th element equals u[i] * g, * where g is the generator of ECP2_BN254. The sizes of @@ -69,6 +85,13 @@ void cfe_vec_mul_G1(cfe_vec_G1 *v, cfe_vec *u); */ void cfe_vec_G2_init(cfe_vec_G2 *v, size_t size); +/** + * Sets all the values of a vector to the identity element. + * + * @param v A pointer to an initialized cfe_vec_G2 vector + */ +void cfe_vec_G2_inf(cfe_vec_G2 *v); + /** * Creates a vector whose i-th element equals u[i] * g, * where g is the generator of ECP2_BN254. The sizes of @@ -79,6 +102,31 @@ void cfe_vec_G2_init(cfe_vec_G2 *v, size_t size); */ void cfe_vec_mul_G2(cfe_vec_G2 *v, cfe_vec *u); +/** + * Initializes a vector of FP12_BN254 elements of given size. + * + * @param v A pointer to an uninitialized cfe_vec_GT vector + * @param size Size of the vector + */ +void cfe_vec_GT_init(cfe_vec_GT *v, size_t size); + +/** + * Sets all the values of a vector to the identity element. + * + * @param v A pointer to an initialized cfe_vec_GT vector + */ +void cfe_vec_GT_inf(cfe_vec_GT *v); + +/** + * Creates a vector whose i-th element equals u[i] * g, + * where g is the generator of FP12_BN254. The sizes of + * v and u must match. + * + * @param v A pointer to an initialized cfe_vec_GT vector + * @param u A pointer to vector of integers. + */ +void cfe_vec_mul_GT(cfe_vec_GT *v, cfe_vec *u); + /** * Frees the memory occupied by the struct members. It does not free * memory occupied by the struct itself. @@ -97,4 +145,13 @@ void cfe_vec_G1_free(cfe_vec_G1 *v); */ void cfe_vec_G2_free(cfe_vec_G2 *v); +/** + * Frees the memory occupied by the struct members. It does not free + * memory occupied by the struct itself. + * + * @param v A pointer to a vector (*initialized* + * cfe_vec_GT struct) + */ +void cfe_vec_GT_free(cfe_vec_GT *v); + #endif diff --git a/include/cifer/test.h b/include/cifer/test.h index a9409ab..c55f17d 100644 --- a/include/cifer/test.h +++ b/include/cifer/test.h @@ -41,6 +41,7 @@ MunitSuite dmcfe_suite; MunitSuite policy_suite; MunitSuite gpsw_suite; MunitSuite fame_suite; +MunitSuite dippe_suite; MunitSuite sgp_suite; #endif diff --git a/src/abe/dippe.c b/src/abe/dippe.c new file mode 100644 index 0000000..3dc79be --- /dev/null +++ b/src/abe/dippe.c @@ -0,0 +1,434 @@ + +#include +#include +#include +#include +#include + +#include "cifer/abe/dippe.h" +#include "cifer/data/mat.h" +#include "cifer/internal/big.h" +#include "cifer/internal/common.h" +#include "cifer/internal/hash.h" +#include "cifer/sample/uniform.h" + +void cfe_dippe_init(cfe_dippe *dippe, size_t assump_size) { + dippe->assump_size = assump_size; + mpz_init(dippe->p); + mpz_from_BIG_256_56(dippe->p, (int64_t *)CURVE_Order_BN254); + + // A (k+1 x k) + cfe_mat A; + cfe_mat_init(&A, (assump_size + 1), assump_size); + cfe_uniform_sample_mat(&A, dippe->p); + + // g1^A (k+1 x k) + cfe_mat_G1_init(&(dippe->g1_A), (assump_size + 1), assump_size); + cfe_mat_mul_G1(&(dippe->g1_A), &A); + + // U(T) (k+1 x k+1) + cfe_mat U; + cfe_mat_init(&U, (assump_size + 1), (assump_size + 1)); + cfe_uniform_sample_mat(&U, dippe->p); + + // U(T)A (k+1 x k) + cfe_mat UA; + cfe_mat_init(&UA, (assump_size + 1), assump_size); + cfe_mat_mul(&UA, &U, &A); + cfe_mat_mod(&UA, &UA, dippe->p); + + // g1^U(T)A (k+1 x k) + cfe_mat_G1_init(&(dippe->g1_UA), (assump_size + 1), assump_size); + cfe_mat_mul_G1(&(dippe->g1_UA), &UA); + + // cleanup + cfe_mat_free(&A); + cfe_mat_free(&U); + cfe_mat_free(&UA); +} + +void cfe_dippe_free(cfe_dippe *dippe) { + mpz_clear(dippe->p); + cfe_mat_G1_free(&(dippe->g1_A)); + cfe_mat_G1_free(&(dippe->g1_UA)); +} + +void cfe_dippe_pub_key_init(cfe_dippe_pub_key *pk, cfe_dippe *dippe) { + cfe_mat_G1_init(&(pk->g1_W_A), (dippe->assump_size + 1), dippe->assump_size); + cfe_vec_GT_init(&(pk->gt_alpha_A), dippe->assump_size); +} + +void cfe_dippe_pub_key_free(cfe_dippe_pub_key *pk) { + cfe_mat_G1_free(&(pk->g1_W_A)); + cfe_vec_GT_free(&(pk->gt_alpha_A)); +} + +void cfe_dippe_sec_key_init(cfe_dippe_sec_key *sk, cfe_dippe *dippe) { + mpz_init(sk->sigma); + cfe_vec_init(&(sk->alpha), (dippe->assump_size + 1)); + cfe_mat_init(&(sk->W), (dippe->assump_size + 1), (dippe->assump_size + 1)); +} + +void cfe_dippe_sec_key_free(cfe_dippe_sec_key *sk) { + mpz_clear(sk->sigma); + cfe_vec_free(&(sk->alpha)); + cfe_mat_free(&(sk->W)); +} + +void cfe_dippe_cipher_init(cfe_dippe_cipher *cipher, cfe_dippe *dippe, size_t pol_size) { + cfe_vec_G1_init(&(cipher->C0), (dippe->assump_size + 1)); + cfe_mat_G1_init(&(cipher->Ci), pol_size, (dippe->assump_size + 1)); +} + +void cfe_dippe_cipher_free(cfe_dippe_cipher *cipher) { + cfe_vec_G1_free(&(cipher->C0)); + cfe_mat_G1_free(&(cipher->Ci)); +} + +void cfe_dippe_user_sec_key_init(cfe_dippe_user_sec_key *usk, cfe_dippe *dippe) { + cfe_vec_G2_init(&(usk->Ki), (dippe->assump_size + 1)); +} + +void cfe_dippe_user_sec_key_free(cfe_dippe_user_sec_key *usk) { + cfe_vec_G2_free(&(usk->Ki)); +} + +void cfe_dippe_generate_master_keys(cfe_dippe_pub_key *pk, cfe_dippe_sec_key *sk, cfe_dippe *dippe) { + // temp vars + BIG_256_56 tmp_big; + cfe_mat tmp_mat; + cfe_mat_GT tmp_mat_gt; + + /////////////////////////////////////////////// + // Secret key section + /////////////////////////////////////////////// + + // sigma + cfe_uniform_sample(sk->sigma, dippe->p); + + // alpha (k+1 x 1) + cfe_uniform_sample_vec(&(sk->alpha), dippe->p); + + // W (k+1 x k+1) + cfe_uniform_sample_mat(&(sk->W), dippe->p); + + /////////////////////////////////////////////// + // Public key section + /////////////////////////////////////////////// + + // g2^sigma + ECP2_BN254_generator(&(pk->g2_sigma)); + BIG_256_56_from_mpz(tmp_big, sk->sigma); + ECP2_BN254_mul(&(pk->g2_sigma), tmp_big); + + // g1^W(T)A (k+1 x k) + cfe_mat_init(&tmp_mat, sk->W.cols, sk->W.rows); + cfe_mat_transpose(&tmp_mat, &(sk->W)); + cfe_mat_mul_G1_mat(&(pk->g1_W_A), &tmp_mat, &(dippe->g1_A)); + + // gt^A (k+1 x k) + cfe_mat_GT gt_A; + cfe_mat_GT_init(>_A, dippe->g1_A.rows, dippe->g1_A.cols); + cfe_mat_GT_pair_mat_G1(>_A, &(dippe->g1_A)); + + // gt^(alpha(T)A) (k x 1) + cfe_mat_GT_init(&tmp_mat_gt, gt_A.cols, gt_A.rows); + cfe_mat_GT_transpose(&tmp_mat_gt, >_A); + cfe_mat_GT_mul_vec(&(pk->gt_alpha_A), &tmp_mat_gt, &(sk->alpha)); + + // cleanup + cfe_mat_free(&tmp_mat); + cfe_mat_GT_free(>_A); + cfe_mat_GT_free(&tmp_mat_gt); +} + +cfe_error cfe_dippe_encrypt(cfe_dippe_cipher *cipher, cfe_dippe *dippe, cfe_dippe_pub_key *pks[], size_t pks_len, cfe_vec *pv, FP12_BN254 *msg) { + // check whether there is the same number of keys as policy vector components + if (pks_len != pv->size) { + return CFE_ERR_INSUFFICIENT_KEYS; + } + + // temp vars + BIG_256_56 tmp_big; + ECP_BN254 tmp_g1; + FP12_BN254 tmp_gt; + + // s (k x 1) + cfe_vec s; + cfe_vec_init(&s, dippe->assump_size); + cfe_uniform_sample_vec(&s, dippe->p); + + // C0 = g1^As (k+1 x 1) + cfe_mat_G1_mul_vec(&(cipher->C0), &(dippe->g1_A), &s); + + // g1^(W_A_s) (k+1 x 1) + cfe_vec_G1 g1_W_A_s; + cfe_vec_G1_init(&g1_W_A_s, (dippe->assump_size + 1)); + + // g1^(x_UA_s) (k+1 x 1) + cfe_vec_G1 g1_x_UA_s; + cfe_vec_G1_init(&g1_x_UA_s, (dippe->assump_size + 1)); + + // Ci = g1^(xU(T)+W(T))As (pol x k+1) + for (size_t m = 0; m < pks_len; m++) { + // g1^(W(T)As) + cfe_mat_G1_mul_vec(&g1_W_A_s, &(pks[m]->g1_W_A), &s); + // g1^(xU(T)As) + cfe_vec_G1_inf(&(g1_x_UA_s)); + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + for (size_t k = 0; k < dippe->assump_size; k++) { + ECP_BN254_copy(&tmp_g1, &(dippe->g1_UA.mat[i].vec[k])); + BIG_256_56_from_mpz(tmp_big, s.vec[k]); + ECP_BN254_mul(&tmp_g1, tmp_big); + ECP_BN254_add(&(g1_x_UA_s.vec[i]), &tmp_g1); + } + BIG_256_56_from_mpz(tmp_big, pv->vec[m]); + ECP_BN254_mul(&(g1_x_UA_s.vec[i]), tmp_big); + } + + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + ECP_BN254_copy(&(cipher->Ci.mat[m].vec[i]), &(g1_x_UA_s.vec[i])); + ECP_BN254_add(&(cipher->Ci.mat[m].vec[i]), &(g1_W_A_s.vec[i])); + } + } + + // C_prime = m * gt^alpha(T)As + FP12_BN254_one(&(cipher->C_prime)); + for (size_t m = 0; m < pks_len; m++) { + for (size_t k = 0; k < dippe->assump_size; k++) { + BIG_256_56_from_mpz(tmp_big, s.vec[k]); + FP12_BN254_pow(&tmp_gt, &(pks[m]->gt_alpha_A.vec[k]), tmp_big); + FP12_BN254_mul(&(cipher->C_prime), &tmp_gt); + } + } + FP12_BN254_mul(&(cipher->C_prime), msg); + + // cleanup + cfe_vec_free(&s); + cfe_vec_G1_free(&g1_W_A_s); + cfe_vec_G1_free(&g1_x_UA_s); + + return CFE_ERR_NONE; +} + +cfe_error cfe_dippe_keygen(cfe_dippe_user_sec_key *usk, cfe_dippe *dippe, size_t usk_id, cfe_dippe_pub_key *pks[], size_t pks_len, cfe_dippe_sec_key *sk, cfe_vec *av, char gid[]) { + // check whether there is the same number of keys as attribute vector components + if ((av->size != pks_len) || (pks_len <= usk_id)) { + return CFE_ERR_INSUFFICIENT_KEYS; + } + + // temp vars + BIG_256_56 tmp_big; + ECP2_BN254 tmp_g2, hashed; + char *hash_str, *str_vec, *ys_hex, *str_i; + + // attribute vector as string + str_vec = cfe_vec_to_string(av); + // y^σ + octet ys; + ys.val = (char *)cfe_malloc((4 * MODBYTES_256_56) * sizeof(char)); + ys_hex = (char *)cfe_malloc(((8 * MODBYTES_256_56) + 1) * sizeof(char)); + + // mue + cfe_vec_G2 mue; + cfe_vec_G2_init(&mue, (dippe->assump_size + 1)); + cfe_vec_G2_inf(&mue); + + for (size_t j = 0; j < pks_len; j++) { + ECP2_BN254_copy(&tmp_g2, &(pks[j]->g2_sigma)); + BIG_256_56_from_mpz(tmp_big, sk->sigma); + ECP2_BN254_mul(&tmp_g2, tmp_big); + ECP2_BN254_toOctet(&ys, &tmp_g2); + OCT_toHex(&ys, ys_hex); + + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + str_i = cfe_int_to_str((int)i); + hash_str = cfe_strings_concat(str_i, "|", ys_hex, "|", gid, "|", str_vec, NULL); + cfe_hash_G2(&hashed, hash_str); + + if (j < usk_id) { + ECP2_BN254_add(&(mue.vec[i]), &hashed); + } else if (j > usk_id) { + ECP2_BN254_sub(&(mue.vec[i]), &hashed); + } + free(str_i); + free(hash_str); + } + } + + // g2^h (k+1 x 1) + cfe_vec_G2 g2_h; + cfe_vec_G2_init(&g2_h, (dippe->assump_size + 1)); + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + str_i = cfe_int_to_str((int)i); + hash_str = cfe_strings_concat(str_i, "|", gid, "|", str_vec, NULL); + cfe_hash_G2(&(g2_h.vec[i]), hash_str); + free(str_i); + free(hash_str); + } + + // Ki = g2^(α−vWh+μ) (k+1 x 1) + cfe_vec_G2_inf(&(usk->Ki)); + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + for (size_t k = 0; k < (dippe->assump_size + 1); k++) { + ECP2_BN254_copy(&tmp_g2, &(g2_h.vec[k])); + BIG_256_56_from_mpz(tmp_big, sk->W.mat[i].vec[k]); + ECP2_BN254_mul(&tmp_g2, tmp_big); + ECP2_BN254_add(&(usk->Ki.vec[i]), &tmp_g2); + } + // add vi + BIG_256_56_from_mpz(tmp_big, av->vec[usk_id]); + ECP2_BN254_mul(&(usk->Ki.vec[i]), tmp_big); + // negate + ECP2_BN254_neg(&(usk->Ki.vec[i])); + // add alpha + BIG_256_56_from_mpz(tmp_big, sk->alpha.vec[i]); + ECP2_BN254_generator(&tmp_g2); + ECP2_BN254_mul(&tmp_g2, tmp_big); + ECP2_BN254_add(&(usk->Ki.vec[i]), &tmp_g2); + // add mue + ECP2_BN254_add(&(usk->Ki.vec[i]), &(mue.vec[i])); + } + + // cleanup + free(str_vec); + free(ys.val); + free(ys_hex); + cfe_vec_G2_free(&mue); + cfe_vec_G2_free(&g2_h); + + return CFE_ERR_NONE; +} + +cfe_error cfe_dippe_decrypt(FP12_BN254 *result, cfe_dippe *dippe, cfe_dippe_user_sec_key *usks, size_t usks_len, cfe_dippe_cipher *cipher, cfe_vec *av, char gid[]) { + // check whether there is the same number of keys as attribute vector components + if (av->size != usks_len) { + return CFE_ERR_INSUFFICIENT_KEYS; + } + + // temp vars + BIG_256_56 tmp_big; + ECP_BN254 tmp1_g1, tmp2_g1; + ECP2_BN254 tmp_g2; + FP12_BN254 tmp_gt; + char *hash_str, *str_i; + + // attribute vector as string + char *str_vec = cfe_vec_to_string(av); + + // C0_K + FP12_BN254 C0_K; + FP12_BN254_one(&C0_K); + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + ECP2_BN254_inf(&tmp_g2); + for (size_t j = 0; j < usks_len; j++) { + ECP2_BN254_add(&tmp_g2, &((usks + j)->Ki.vec[i])); + } + PAIR_BN254_ate(&tmp_gt, &tmp_g2, &(cipher->C0.vec[i])); + PAIR_BN254_fexp(&tmp_gt); + FP12_BN254_mul(&C0_K, &tmp_gt); + } + + // Ci_H + FP12_BN254 Ci_H; + FP12_BN254_one(&Ci_H); + for (size_t i = 0; i < (dippe->assump_size + 1); i++) { + ECP_BN254_inf(&tmp1_g1); + for (size_t j = 0; j < usks_len; j++) { + ECP_BN254_copy(&tmp2_g1, &(cipher->Ci.mat[j].vec[i])); + BIG_256_56_from_mpz(tmp_big, av->vec[j]); + ECP_BN254_mul(&tmp2_g1, tmp_big); + ECP_BN254_add(&tmp1_g1, &tmp2_g1); + } + str_i = cfe_int_to_str((int)i); + hash_str = cfe_strings_concat(str_i, "|", gid, "|", str_vec, NULL); + cfe_hash_G2(&tmp_g2, hash_str); + + PAIR_BN254_ate(&tmp_gt, &tmp_g2, &tmp1_g1); + PAIR_BN254_fexp(&tmp_gt); + FP12_BN254_mul(&Ci_H, &tmp_gt); + + free(str_i); + free(hash_str); + } + + // C0_K * Ci_H + FP12_BN254_copy(&tmp_gt, &C0_K); + FP12_BN254_mul(&tmp_gt, &Ci_H); + + // recover secret + FP12_BN254_inv(&tmp_gt, &tmp_gt); + FP12_BN254_copy(result, &(cipher->C_prime)); + FP12_BN254_mul(result, &tmp_gt); + + // cleanup + free(str_vec); + + return CFE_ERR_NONE; +} + +cfe_error cfe_dippe_attribute_vector_init(cfe_vec *av, size_t num_attrib, size_t pattern[], size_t pat_len) { + mpz_t zero; + mpz_init(zero); + mpz_set_ui(zero, 0); + cfe_vec_init(av, (num_attrib + 1)); + cfe_vec_set_const(av, zero); + + for (size_t i = 0; i < pat_len; i++) { + if (pattern[i] < num_attrib) { + mpz_set_ui(av->vec[pattern[i]], 1); + } else + return CFE_ERR_MALFORMED_INPUT; + } + mpz_set_ui(av->vec[num_attrib], 1); + + // cleanup + mpz_clear(zero); + + return CFE_ERR_NONE; +} + +cfe_error cfe_dippe_exact_threshold_policy_vector_init(cfe_vec *pv, cfe_dippe *dippe, size_t num_attrib, size_t pattern[], size_t pat_len, size_t threshold) { + mpz_t zero; + mpz_init(zero); + mpz_set_ui(zero, 0); + cfe_vec_init(pv, (num_attrib + 1)); + cfe_vec_set_const(pv, zero); + + for (size_t i = 0; i < pat_len; i++) { + if (pattern[i] < num_attrib) { + mpz_set_ui(pv->vec[pattern[i]], 1); + } else + return CFE_ERR_MALFORMED_INPUT; + } + mpz_set_ui(pv->vec[num_attrib], threshold); + mpz_neg(pv->vec[num_attrib], pv->vec[num_attrib]); + mpz_mod(pv->vec[num_attrib], pv->vec[num_attrib], dippe->p); + + // cleanup + mpz_clear(zero); + + return CFE_ERR_NONE; +} + +cfe_error cfe_dippe_conjunction_policy_vector_init(cfe_vec *pv, cfe_dippe *dippe, size_t num_attrib, size_t pattern[], size_t pat_len) { + mpz_t zero; + mpz_init(zero); + mpz_set_ui(zero, 0); + cfe_vec_init(pv, (num_attrib + 1)); + cfe_vec_set_const(pv, zero); + + for (size_t i = 0; i < pat_len; i++) { + if (pattern[i] < num_attrib) { + cfe_uniform_sample(pv->vec[pattern[i]], dippe->p); + mpz_sub(pv->vec[num_attrib], pv->vec[num_attrib], pv->vec[pattern[i]]); + } else + return CFE_ERR_MALFORMED_INPUT; + } + mpz_mod(pv->vec[num_attrib], pv->vec[num_attrib], dippe->p); + + // cleanup + mpz_clear(zero); + + return CFE_ERR_NONE; +} diff --git a/src/data/mat_curve.c b/src/data/mat_curve.c new file mode 100644 index 0000000..08a353c --- /dev/null +++ b/src/data/mat_curve.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2018 XLAB d.o.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cifer/data/mat_curve.h" +#include +#include +#include +#include +#include +#include "cifer/internal/big.h" +#include "cifer/internal/common.h" + +void cfe_mat_G1_init(cfe_mat_G1 *m, size_t rows, size_t cols) { + m->rows = rows; + m->cols = cols; + m->mat = (cfe_vec_G1 *)cfe_malloc(rows * sizeof(cfe_vec_G1)); + + for (size_t i = 0; i < rows; i++) { + cfe_vec_G1_init(&(m->mat[i]), cols); + } +} + +void cfe_mat_mul_G1(cfe_mat_G1 *m, cfe_mat *u) { + assert(m->cols == u->cols); + assert(m->rows == u->rows); + + BIG_256_56 x; + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + ECP_BN254_generator(&(m->mat[i].vec[j])); + BIG_256_56_from_mpz(x, u->mat[i].vec[j]); + ECP_BN254_mul(&(m->mat[i].vec[j]), x); + } + } +} + +void cfe_mat_G1_transpose(cfe_mat_G1 *res, cfe_mat_G1 *m) { + assert(res->rows == m->cols); + assert(res->cols == m->rows); + + for (size_t i = 0; i < m->rows; i++) { + for (size_t k = 0; k < m->cols; k++) { + ECP_BN254_copy(&(res->mat[k].vec[i]), &(m->mat[i].vec[k])); + } + } +} + +void cfe_mat_mul_G1_mat(cfe_mat_G1 *res, cfe_mat *mi, cfe_mat_G1 *m) { + assert(m->rows == mi->cols); + assert(res->cols == m->cols); + assert(res->rows == mi->rows); + + ECP_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + ECP_BN254_inf(&(res->mat[i].vec[j])); + for (size_t k = 0; k < m->rows; k++) { + ECP_BN254_copy(&g, &(m->mat[k].vec[j])); + BIG_256_56_from_mpz(x, mi->mat[i].vec[k]); + ECP_BN254_mul(&g, x); + ECP_BN254_add(&(res->mat[i].vec[j]), &g); + } + } + } +} + +void cfe_mat_G1_mul_vec(cfe_vec_G1 *res, cfe_mat_G1 *m, cfe_vec *u) { + assert(m->rows == res->size); + assert(m->cols == u->size); + + ECP_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + ECP_BN254_inf(&(res->vec[i])); + for (size_t k = 0; k < m->cols; k++) { + ECP_BN254_copy(&g, &(m->mat[i].vec[k])); + BIG_256_56_from_mpz(x, u->vec[k]); + ECP_BN254_mul(&g, x); + ECP_BN254_add(&(res->vec[i]), &g); + } + } +} + +void cfe_mat_G1_free(cfe_mat_G1 *m) { + for (size_t i = 0; i < m->rows; i++) { + cfe_vec_G1_free(&(m->mat[i])); + } + free(m->mat); +} + +void cfe_mat_G2_init(cfe_mat_G2 *m, size_t rows, size_t cols) { + m->rows = rows; + m->cols = cols; + m->mat = (cfe_vec_G2 *)cfe_malloc(rows * sizeof(cfe_vec_G2)); + + for (size_t i = 0; i < rows; i++) { + cfe_vec_G2_init(&(m->mat[i]), cols); + } +} + +void cfe_mat_G2_transpose(cfe_mat_G2 *res, cfe_mat_G2 *m) { + assert(res->rows == m->cols); + assert(res->cols == m->rows); + + for (size_t i = 0; i < m->rows; i++) { + for (size_t k = 0; k < m->cols; k++) { + ECP2_BN254_copy(&(res->mat[k].vec[i]), &(m->mat[i].vec[k])); + } + } +} + +void cfe_mat_mul_G2_mat(cfe_mat_G2 *res, cfe_mat *mi, cfe_mat_G2 *m) { + assert(m->rows == mi->cols); + assert(res->cols == m->cols); + assert(res->rows == mi->rows); + + ECP2_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + ECP2_BN254_inf(&(res->mat[i].vec[j])); + for (size_t k = 0; k < m->rows; k++) { + ECP2_BN254_copy(&g, &(m->mat[k].vec[j])); + BIG_256_56_from_mpz(x, mi->mat[i].vec[k]); + ECP2_BN254_mul(&g, x); + ECP2_BN254_add(&(res->mat[i].vec[j]), &g); + } + } + } +} + +void cfe_mat_G2_mul_vec(cfe_vec_G2 *res, cfe_mat_G2 *m, cfe_vec *u) { + assert(m->rows == res->size); + assert(m->cols == u->size); + + ECP2_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + ECP2_BN254_inf(&(res->vec[i])); + for (size_t k = 0; k < m->cols; k++) { + ECP2_BN254_copy(&g, &(m->mat[i].vec[k])); + BIG_256_56_from_mpz(x, u->vec[k]); + ECP2_BN254_mul(&g, x); + ECP2_BN254_add(&(res->vec[i]), &g); + } + } +} + +void cfe_mat_mul_G2(cfe_mat_G2 *m, cfe_mat *u) { + assert(m->cols == u->cols); + assert(m->rows == u->rows); + + BIG_256_56 x; + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + ECP2_BN254_generator(&(m->mat[i].vec[j])); + BIG_256_56_from_mpz(x, u->mat[i].vec[j]); + ECP2_BN254_mul(&(m->mat[i].vec[j]), x); + } + } +} + +void cfe_mat_G2_free(cfe_mat_G2 *m) { + for (size_t i = 0; i < m->rows; i++) { + cfe_vec_G2_free(&(m->mat[i])); + } + free(m->mat); +} + +void cfe_mat_GT_init(cfe_mat_GT *m, size_t rows, size_t cols) { + m->rows = rows; + m->cols = cols; + m->mat = (cfe_vec_GT *)cfe_malloc(rows * sizeof(cfe_vec_GT)); + + for (size_t i = 0; i < rows; i++) { + cfe_vec_GT_init(&(m->mat[i]), cols); + } +} + +void cfe_mat_GT_transpose(cfe_mat_GT *res, cfe_mat_GT *m) { + assert(res->rows == m->cols); + assert(res->cols == m->rows); + + for (size_t i = 0; i < m->rows; i++) { + for (size_t k = 0; k < m->cols; k++) { + FP12_BN254_copy(&(res->mat[k].vec[i]), &(m->mat[i].vec[k])); + } + } +} + +void cfe_mat_mul_GT_mat(cfe_mat_GT *res, cfe_mat *mi, cfe_mat_GT *m) { + assert(m->rows == mi->cols); + assert(res->cols == m->cols); + assert(res->rows == mi->rows); + + FP12_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + FP12_BN254_one(&(res->mat[i].vec[j])); + for (size_t k = 0; k < m->rows; k++) { + BIG_256_56_from_mpz(x, mi->mat[i].vec[k]); + FP12_BN254_pow(&g, &(m->mat[k].vec[j]), x); + FP12_BN254_mul(&(res->mat[i].vec[j]), &g); + } + } + } +} + +void cfe_mat_GT_mul_vec(cfe_vec_GT *res, cfe_mat_GT *m, cfe_vec *u) { + assert(m->rows == res->size); + assert(m->cols == u->size); + + FP12_BN254 g; + BIG_256_56 x; + + for (size_t i = 0; i < m->rows; i++) { + FP12_BN254_one(&(res->vec[i])); + for (size_t k = 0; k < m->cols; k++) { + BIG_256_56_from_mpz(x, u->vec[k]); + FP12_BN254_pow(&g, &(m->mat[i].vec[k]), x); + FP12_BN254_mul(&(res->vec[i]), &g); + } + } +} + +void cfe_mat_GT_pair_mat_G1(cfe_mat_GT *res, cfe_mat_G1 *m) { + assert(res->rows == m->rows); + assert(res->cols == m->cols); + + ECP2_BN254 g; + ECP2_BN254_generator(&g); + + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + PAIR_BN254_ate(&(res->mat[i].vec[j]), &g, &(m->mat[i].vec[j])); + PAIR_BN254_fexp(&(res->mat[i].vec[j])); + } + } +} + +void cfe_mat_GT_pair_mat_G2(cfe_mat_GT *res, cfe_mat_G2 *m) { + assert(res->rows == m->rows); + assert(res->cols == m->cols); + + ECP_BN254 g; + ECP_BN254_generator(&g); + + for (size_t i = 0; i < m->rows; i++) { + for (size_t j = 0; j < m->cols; j++) { + PAIR_BN254_ate(&(res->mat[i].vec[j]), &(m->mat[i].vec[j]), &g); + PAIR_BN254_fexp(&(res->mat[i].vec[j])); + } + } +} + +void cfe_mat_GT_free(cfe_mat_GT *m) { + for (size_t i = 0; i < m->rows; i++) { + cfe_vec_GT_free(&(m->mat[i])); + } + free(m->mat); +} diff --git a/src/data/vec_curve.c b/src/data/vec_curve.c index 58933ed..bab4e3e 100644 --- a/src/data/vec_curve.c +++ b/src/data/vec_curve.c @@ -16,6 +16,7 @@ #include #include +#include #include "cifer/internal/big.h" #include "cifer/data/vec.h" @@ -27,6 +28,12 @@ void cfe_vec_G1_init(cfe_vec_G1 *v, size_t size) { v->vec = (ECP_BN254 *) cfe_malloc(size * sizeof(ECP_BN254)); } +void cfe_vec_G1_inf(cfe_vec_G1 *v) { + for (size_t i = 0; i < v->size; i++) { + ECP_BN254_inf(&(v->vec[i])); + } +} + void cfe_vec_mul_G1(cfe_vec_G1 *v, cfe_vec *u) { assert(v->size == u->size); @@ -43,6 +50,12 @@ void cfe_vec_G2_init(cfe_vec_G2 *v, size_t size) { v->vec = (ECP2_BN254 *) cfe_malloc(size * sizeof(ECP2_BN254)); } +void cfe_vec_G2_inf(cfe_vec_G2 *v) { + for (size_t i = 0; i < v->size; i++) { + ECP2_BN254_inf(&(v->vec[i])); + } +} + void cfe_vec_mul_G2(cfe_vec_G2 *v, cfe_vec *u) { assert(v->size == u->size); BIG_256_56 x; @@ -54,6 +67,37 @@ void cfe_vec_mul_G2(cfe_vec_G2 *v, cfe_vec *u) { } } +void cfe_vec_GT_init(cfe_vec_GT *v, size_t size) { + v->size = size; + v->vec = (FP12_BN254 *) cfe_malloc(size * sizeof(FP12_BN254)); +} + +void cfe_vec_GT_inf(cfe_vec_GT *v) { + for (size_t i = 0; i < v->size; i++) { + FP12_BN254_one(&(v->vec[i])); + } +} + +void cfe_vec_mul_GT(cfe_vec_GT *v, cfe_vec *u) { + assert(v->size == u->size); + BIG_256_56 x; + + ECP_BN254 g1; + ECP_BN254_generator(&g1); + + ECP2_BN254 g2; + ECP2_BN254_generator(&g2); + + FP12_BN254 gt; + PAIR_BN254_ate(>, &g2, &g1); + PAIR_BN254_fexp(>); + + for (size_t i = 0; i < u->size; i++) { + BIG_256_56_from_mpz(x, u->vec[i]); + FP12_BN254_pow(&(v->vec[i]), >, x); + } +} + void cfe_vec_G1_free(cfe_vec_G1 *v) { free(v->vec); } @@ -61,3 +105,7 @@ void cfe_vec_G1_free(cfe_vec_G1 *v) { void cfe_vec_G2_free(cfe_vec_G2 *v) { free(v->vec); } + +void cfe_vec_GT_free(cfe_vec_GT *v) { + free(v->vec); +} diff --git a/test/abe/dippe.c b/test/abe/dippe.c new file mode 100644 index 0000000..1e809a0 --- /dev/null +++ b/test/abe/dippe.c @@ -0,0 +1,255 @@ + +#include +#include "cifer/abe/dippe.h" +#include "cifer/data/vec.h" +#include "cifer/test.h" + +MunitResult test_dippe_end_to_end_conjunction(const MunitParameter *params, void *data) { + cfe_error err; + + // Init DIPPE scheme + cfe_dippe dippe; + cfe_dippe_init(&dippe, 2); + + // Setup two Authorities + cfe_dippe_pub_key pk[2]; + cfe_dippe_sec_key sk[2]; + for (int i = 0; i < 2; i++) { + cfe_dippe_pub_key_init(&(pk[i]), &dippe); + cfe_dippe_sec_key_init(&(sk[i]), &dippe); + cfe_dippe_generate_master_keys(&(pk[i]), &(sk[i]), &dippe); + } + + // Sample message + ECP_BN254 g1; + ECP_BN254_generator(&g1); + ECP2_BN254 g2; + ECP2_BN254_generator(&g2); + FP12_BN254 msg; + PAIR_BN254_ate(&msg, &g2, &g1); + PAIR_BN254_fexp(&msg); + + // Collection of 6 public keys + // Each of them correspondents to an index of the Attribute-/ Policy-vector + cfe_dippe_pub_key *pks[] = {&(pk[0]), &(pk[1]), &(pk[0]), &(pk[1]), &(pk[0]), &(pk[1])}; + + // Length of attribute and policy vectors + size_t vlen = 6; + + // Policy vector (one additional component is added) + // ------ ----- + // Policy Attrs + // ------ ----- + // x0 1 + // x1 1 + // 0 . 0 = (x0+x1+x4-x0-x1-x4) = 0 + // 0 0 + // x4 1 + // -> x5=(-x0-x1-x4) 1 + size_t pattern[] = {0, 1, 4}; + cfe_vec pv; + err = cfe_dippe_conjunction_policy_vector_init(&pv, &dippe, (vlen - 1), pattern, (sizeof(pattern) / sizeof(size_t))); + munit_assert(err == CFE_ERR_NONE); + + // Test patterns + size_t ap0[] = {0, 1, 3, 4}; // "11011" - valid + size_t ap1[] = {0, 1, 2, 3, 4}; // "11111" - valid + size_t ap2[] = {1, 4}; // "01001" - invalid + size_t ap3[] = {0, 1, 3}; // "11010" - invalid + + size_t *aps[] = {ap0, ap1, ap2, ap3}; + size_t aps_len[] = { + sizeof(ap0) / sizeof(size_t), + sizeof(ap1) / sizeof(size_t), + sizeof(ap2) / sizeof(size_t), + sizeof(ap3) / sizeof(size_t)}; + + // Test results + int decryption_results[] = {1, 1, 0, 0}; + + cfe_dippe_cipher cipher; + cfe_dippe_cipher_init(&cipher, &dippe, pv.size); + + // Encrypt message under given policy vector + err = cfe_dippe_encrypt(&cipher, &dippe, pks, (sizeof(pks) / sizeof(cfe_dippe_pub_key *)), &pv, &msg); + munit_assert(err == CFE_ERR_NONE); + + // Decrypt message + FP12_BN254 result; + + // Collection of user secret keys + cfe_dippe_user_sec_key usks[vlen]; + for (size_t i = 0; i < vlen; i++) { + cfe_dippe_user_sec_key_init(&(usks[i]), &dippe); + } + + cfe_vec av; + char gid[9]; + + for (size_t i = 0; i < (sizeof(aps) / sizeof(size_t *)); i++) { + sprintf(gid, "TESTGID%zu", i); + + // Attribute vector + err = cfe_dippe_attribute_vector_init(&av, (vlen - 1), aps[i], aps_len[i]); + munit_assert(err == CFE_ERR_NONE); + + // User secret keys + for (size_t j = 0; j < vlen; j++) { + err = cfe_dippe_keygen(&(usks[j]), &dippe, j, pks, (sizeof(pks) / sizeof(cfe_dippe_pub_key *)), &sk[(j & 1)], &av, gid); + munit_assert(err == CFE_ERR_NONE); + } + + // Decrypt message + err = cfe_dippe_decrypt(&result, &dippe, (cfe_dippe_user_sec_key *)&usks, (sizeof(usks) / sizeof(cfe_dippe_user_sec_key)), &cipher, &av, gid); + munit_assert(err == CFE_ERR_NONE); + + // Check decryption + munit_assert(FP12_BN254_equals(&msg, &result) == decryption_results[i]); + + // Cleanup + cfe_vec_free(&av); + } + + // Cleanup + for (int i = 0; i < 2; i++) { + cfe_dippe_sec_key_free(&(sk[i])); + cfe_dippe_pub_key_free(&(pk[i])); + } + for (size_t i = 0; i < vlen; i++) { + cfe_dippe_user_sec_key_free(&(usks[i])); + } + cfe_dippe_cipher_free(&cipher); + cfe_dippe_free(&dippe); + cfe_vec_free(&pv); + + return MUNIT_OK; +} + +MunitResult test_dippe_end_to_end_threshold(const MunitParameter *params, void *data) { + cfe_error err; + + // Init DIPPE scheme + cfe_dippe dippe; + cfe_dippe_init(&dippe, 2); + + // Setup one Authority + cfe_dippe_pub_key pk0; + cfe_dippe_pub_key_init(&pk0, &dippe); + cfe_dippe_sec_key sk0; + cfe_dippe_sec_key_init(&sk0, &dippe); + cfe_dippe_generate_master_keys(&pk0, &sk0, &dippe); + + // Sample message + ECP_BN254 g1; + ECP_BN254_generator(&g1); + ECP2_BN254 g2; + ECP2_BN254_generator(&g2); + FP12_BN254 msg; + PAIR_BN254_ate(&msg, &g2, &g1); + PAIR_BN254_fexp(&msg); + + // Collection of public keys + // Each of them correspondents to an index of the Attribute-/ Policy-vector + cfe_dippe_pub_key *pks[] = {&pk0, &pk0, &pk0, &pk0, &pk0}; + + // Length of attribute and policy vectors + size_t vlen = 5; + + // Policy vector (one additional component is added) + // t is the threshold value + // ------ ----- + // Policy Attrs + // ------ ----- + // 1 1 + // 1 1 + // 0 . 0 = (1+1+0+0-t) = 0 + // 1 0 + // -> -t 1 + cfe_vec pv; + size_t pattern[] = {0, 1, 3}; + err = cfe_dippe_exact_threshold_policy_vector_init(&pv, &dippe, (vlen - 1), pattern, (sizeof(pattern) / sizeof(size_t)), 2); + munit_assert(err == CFE_ERR_NONE); + + // Test patterns + size_t ap0[] = {0, 1}; // "1100" - valid + size_t ap1[] = {0, 3}; // "1001" - valid + size_t ap2[] = {1, 3}; // "0101" - valid + size_t ap3[] = {1, 2, 3}; // "0111" - valid + size_t ap4[] = {0, 1, 3}; // "1101" - invalid + size_t ap5[] = {0, 1, 2, 3}; // "1111" - invalid + + size_t *aps[] = {ap0, ap1, ap2, ap3, ap4, ap5}; + size_t aps_len[] = { + sizeof(ap0) / sizeof(size_t), + sizeof(ap1) / sizeof(size_t), + sizeof(ap2) / sizeof(size_t), + sizeof(ap3) / sizeof(size_t), + sizeof(ap4) / sizeof(size_t), + sizeof(ap5) / sizeof(size_t)}; + + // Test results + int decryption_results[] = {1, 1, 1, 1, 0, 0}; + + cfe_dippe_cipher cipher; + cfe_dippe_cipher_init(&cipher, &dippe, pv.size); + + // Encrypt message under given policy vector + err = cfe_dippe_encrypt(&cipher, &dippe, pks, (sizeof(pks) / sizeof(cfe_dippe_pub_key *)), &pv, &msg); + munit_assert(err == CFE_ERR_NONE); + + // Decrypt message + FP12_BN254 result; + + // Collection of user secret keys + cfe_dippe_user_sec_key usks[vlen]; + for (size_t i = 0; i < vlen; i++) { + cfe_dippe_user_sec_key_init(&(usks[i]), &dippe); + } + + cfe_vec av; + char gid[9]; + + for (size_t i = 0; i < (sizeof(aps) / sizeof(size_t *)); i++) { + sprintf(gid, "TESTGID%zu", i); + + // Attribute vector + err = cfe_dippe_attribute_vector_init(&av, (vlen - 1), aps[i], aps_len[i]); + munit_assert(err == CFE_ERR_NONE); + + // User secret keys from Auth0 + for (size_t j = 0; j < vlen; j++) { + err = cfe_dippe_keygen(&(usks[j]), &dippe, j, pks, (sizeof(pks) / sizeof(cfe_dippe_pub_key *)), &sk0, &av, gid); + munit_assert(err == CFE_ERR_NONE); + } + + // Decrypt message + err = cfe_dippe_decrypt(&result, &dippe, (cfe_dippe_user_sec_key *)&usks, (sizeof(usks) / sizeof(cfe_dippe_user_sec_key)), &cipher, &av, gid); + munit_assert(err == CFE_ERR_NONE); + + // Check decryption + munit_assert(FP12_BN254_equals(&msg, &result) == decryption_results[i]); + + // Cleanup + cfe_vec_free(&av); + } + + // Cleanup + for (size_t i = 0; i < vlen; i++) { + cfe_dippe_user_sec_key_free(&(usks[i])); + } + cfe_dippe_sec_key_free(&sk0); + cfe_dippe_pub_key_free(&pk0); + cfe_dippe_cipher_free(&cipher); + cfe_dippe_free(&dippe); + cfe_vec_free(&pv); + + return MUNIT_OK; +} + +MunitTest dippe_tests[] = { + {(char *)"/end-to-end-conjunction", test_dippe_end_to_end_conjunction, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}, + {(char *)"/end-to-end-threshold", test_dippe_end_to_end_threshold, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}, + {NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}}; + +MunitSuite dippe_suite = { + (char *)"/abe/dippe", dippe_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE}; diff --git a/test/test.c b/test/test.c index 445b5fb..a121e84 100644 --- a/test/test.c +++ b/test/test.c @@ -38,6 +38,7 @@ int main(int argc, char *argv[]) { policy_suite, gpsw_suite, fame_suite, + dippe_suite, uniform_suite, normal_cumulative_suite, normal_negative_suite,