int BPU_gf2VecHashA(BPU_T_Vector_GF2 *out, const BPU_T_Vector_GF2 *in, int len){ //sha512 output constant - SHA512_DIGEST_LENGTH const int DIGEST_LENGTH = 512; int i, element = -1; unsigned char* hashed = (unsigned char*) malloc(DIGEST_LENGTH/8); BPU_T_Vector_GF2 hash_vector; // TODO: remove dependency if(SHA512((unsigned char*)in->elements, in->elements_in_row, hashed) == NULL){ BPU_printError("hash: SHA512"); return -1; } if (BPU_mallocVectorGF2(&hash_vector, DIGEST_LENGTH) != 0) { BPU_printError("hash: BPU_mallocVectorGF2"); return -2; } for (i = 0; i < hash_vector.len/8; i++) { if (i % (hash_vector.element_bit_size/8) == 0) element++; hash_vector.elements[element] ^= hashed[i] << ((i % (hash_vector.element_bit_size/8))*8); } BPU_gf2VecCropA(out, &hash_vector, 0, len); BPU_freeVecGF2(&hash_vector, 0); free(hashed); return 0; }
int BPU_gf2VectortoArray(BPU_T_GF2_Vector *v, char *s, int *size){ BPU_printError("s len %d\n",*size); if(v->len > *size) { BPU_printError("allocation error"); return -1; } memcpy(s,v->elements,v->len / 8); *size = v->len; BPU_printError("v len %d\n",v->len); return 0; }
int BPU_gf2ArraytoVector(BPU_T_GF2_Vector *v, const char *s){ if(v->len < strlen(s) + 1) { BPU_printError("allocation error"); return -1; } memcpy(v->elements,s,strlen(s)+1); return 0; }
int BPU_mecsPointchevalCCA2Decrypt(BPU_T_GF2_Vector * out, const BPU_T_GF2_Vector * in, const BPU_T_Mecs_Ctx * ctx) { BPU_T_GF2_Vector *z1, *z3; // n, l, l-bit BPU_T_GF2_Vector *tmp_2, *pt_cca2; BPU_T_GF2_Vector *r; // k - l BPU_T_GF2_Vector *h, *h_tmp; int rc = 0; // split ct in z1, z2, z3 BPU_gf2VecMalloc(&z1, ctx->code_ctx->code_len); // z2 is like out BPU_gf2VecMalloc(&z3, ctx->pt_len); // Split z to ( z1 , z2 , z3 ) BPU_gf2VecCrop(z1, in, 0, z1->len); BPU_gf2VecCrop(out, in, z1->len, out->len); BPU_gf2VecCrop(z3, in, z1->len + out->len, z3->len); BPU_gf2VecMalloc(&pt_cca2, ctx->code_ctx->msg_len); // decrypt z1 using basic mecs Reconstruct the CCA2-safe plaintext m′ = z1 ⊕ e if (BPU_mecsBasicDecrypt(pt_cca2, z1, ctx)) { return -1; } BPU_gf2VecFree(&z1); BPU_gf2VecMalloc(&r, ctx->code_ctx->msg_len - ctx->pt_len); BPU_gf2VecMalloc(&h, ctx->pt_len); BPU_gf2VecCrop(r, pt_cca2, 0, r->len); BPU_gf2VecCrop(h, pt_cca2, r->len, h->len); BPU_gf2VecFree(&pt_cca2); BPU_gf2VecMalloc(&h_tmp, ctx->pt_len); // Reconstruct plaintext candidate m = z2 ⊕ hash (r) BPU_gf2VecHash(h_tmp, r); BPU_gf2VecFree(&r); BPU_gf2VecXor(out, h_tmp); // Determine check value h′ = hash (m ∥ hash (e) ⊕ z3 ). BPU_gf2VecHash(h_tmp, ctx->code_ctx->e); BPU_gf2VecXor(h_tmp, z3); BPU_gf2VecFree(&z3); BPU_gf2VecMalloc(&tmp_2, ctx->pt_len * 2); BPU_gf2VecConcat(tmp_2, out, h_tmp); BPU_gf2VecHash(h_tmp, tmp_2); BPU_gf2VecFree(&tmp_2); if (BPU_gf2VecCmp(h, h_tmp)) { BPU_printError("Wrong check value."); rc = -1; } BPU_gf2VecFree(&h); BPU_gf2VecFree(&h_tmp); return rc; }
int BPU_gf2VecMalloc(BPU_T_GF2_Vector **v, int len) { *v = (BPU_T_GF2_Vector *) calloc(sizeof(BPU_T_GF2_Vector), 1); if (!*v) { BPU_printError("allocation error"); return -1; } return BPU_gf2VecMallocElements(*v, len); }
int BPU_gf2MatMalloc(BPU_T_GF2_Matrix **m, int rows, int cols) { int i; *m = (BPU_T_GF2_Matrix *) calloc(sizeof(BPU_T_GF2_Matrix), 1); if (!*m) { BPU_printError("allocation error"); return -1; } // element size (*m)->element_bit_size = sizeof(BPU_T_GF2)*8; // rows (*m)->k = rows; // cols (*m)->n = cols; // calc how many elements of set size will be in one row int modul = 0; if ( cols % (*m)->element_bit_size > 0) { modul = 1; } (*m)->elements_in_row = cols/(*m)->element_bit_size + modul; // allocate rows (*m)->elements = (BPU_T_GF2**) malloc(sizeof(BPU_T_GF2*) * (*m)->k); if (!(*m)->elements) { BPU_printError("can not allocate memory for matrix rows"); return -1; } // allocate cols for (i = 0; i < (*m)->k; i++) { (*m)->elements[i] = (BPU_T_GF2*) calloc(1, sizeof(BPU_T_GF2) * (*m)->elements_in_row); if (!(*m)->elements[i]) { BPU_printError("can not allocate memory for matrix cols"); return -2; } } return 0; }
int BPU_signatureInitCtx(BPU_T_Signature_Ctx **ctx, const BPU_T_UN_Signature_Params *params, const BPU_T_EN_Signature_Types type) { BPU_T_Signature_Ctx *ctx_p; *ctx = (BPU_T_Signature_Ctx *) calloc(1, sizeof(BPU_T_Signature_Ctx)); if (!*ctx) { BPU_printError("Cannot malloc BPU_T_Signature_Ctx"); return BPU_EC_MALLOC_ERROR; } ctx_p = *ctx; ctx_p->code_ctx = (BPU_T_Code_Ctx *) calloc(1, sizeof(BPU_T_Code_Ctx)); if (!ctx_p->code_ctx) { BPU_printError("Cannot malloc BPU_T_Code_Ctx"); return BPU_EC_MALLOC_ERROR; } ctx_p->type = type; ctx_p->code_ctx->code_spec = (BPU_T_UN_Code_Spec *) calloc(1, sizeof(BPU_T_UN_Code_Spec)); if (!ctx_p->code_ctx->code_spec) { BPU_printError("Can not malloc BPU_T_UN_Code_Spec"); return BPU_EC_MALLOC_ERROR; } ctx_p->params = params; switch (type) { case BPU_EN_SIGN_LDGM: ctx_p->code_ctx->type = BPU_EN_CODE_LDGM; ctx_p->code_ctx->t = params->ldgm->t; ctx_p->code_ctx->code_spec->ldgm = (BPU_T_LDGM_Spec*) calloc(sizeof(BPU_T_LDGM_Spec), 1); ctx_p->code_ctx->code_spec->ldgm->c = params->ldgm->c; ctx_p->_genKeyPair = BPU_ldgmGenKeyPair; ctx_p->_sign = BPU_ldgmSign; ctx_p->_verify = BPU_ldgmVerify; break; } return 0; }
int BPU_goppaInitParams(BPU_T_Goppa_Params **params, const uint16_t m, const uint16_t t, const BPU_T_GF2_16x mod) { *params = (BPU_T_Goppa_Params*) calloc(sizeof(BPU_T_Goppa_Params), 1); if (!params) { BPU_printError("Can't init Code params"); return -1; } (*params)->m = m; (*params)->t = t; (*params)->mod = mod; return 0; }
int BPU_qcmdpcInitParams(BPU_T_Qcmdpc_Params **params, const uint16_t m, const uint16_t n0, const uint16_t w, const uint16_t t) { *params = (BPU_T_Qcmdpc_Params*) calloc(sizeof(BPU_T_Qcmdpc_Params), 1); if (!params) { BPU_printError("Can't init Code params"); return -1; } (*params)->m = m; (*params)->n0 = n0; (*params)->w = w; (*params)->t = t; return 0; }
int BPU_padAdd(BPU_T_GF2_Vector *padded_message, const BPU_T_GF2_Vector *message, const uint16_t padding_len) { int i; if (message->len + padding_len != padded_message->len) { BPU_printError("Wrong message len"); return -1; } // copy message into padded message for (i = 0; i < message->elements_in_row; i++){ padded_message->elements[i] = message->elements[i]; } // add padding - first padded bit set to 1, rest keep 0 BPU_gf2VecSetBit(padded_message, message->len, 1); return 0; }
int BPU_gf2xMatPermute(BPU_T_Matrix_GF2_16x *out, const BPU_T_Matrix_GF2_16x *m, const BPU_T_Perm_Vector *permutation) { int i, j; // check if the size is correct if (m->n != permutation->size) { BPU_printError("BPU_gf2MatPermute: permutation size not correct m->n = %d, p->size = %d", m->n, permutation->size); return -1; } // permute for (j = 0; j < m->n; j++) { // column loop for (i = 0; i < m->k; i++) { // row loop out->elements[i][j] = m->elements[i][permutation->elements[j]]; // permute the columns } } return 0; }
int BPU_gf2MatCopy(BPU_T_Matrix_GF2 *out, const BPU_T_Matrix_GF2 *in) { int i, j; if (out->k != in->k || out->n != in->n) { BPU_printError("BPU_gf2MatCopy: wrong matrix size"); return -1; } // copy the matrix for (i = 0; i < in->k; i++) { for (j = 0; j < in->elements_in_row; j++) { out->elements[i][j] = in->elements[i][j]; } } return 0; }
int BPU_allocateBuffer(char **buffer, int *size ,int len){ // element size in bits int element_bit_size = sizeof(BPU_T_GF2) * 8; int elements_in_row = len / element_bit_size; if ( len % element_bit_size > 0) elements_in_row++; *buffer = (char*) calloc(1, sizeof(BPU_T_GF2) * elements_in_row); *size = sizeof(BPU_T_GF2) * elements_in_row * 8; /* for (int i = 0; i < sizeof(BPU_T_GF2) * elements_in_row + 1 ; i++) { (*buffer)[i] = '0'; } */ //*((*buffer) + sizeof(BPU_T_GF2) * elements_in_row + 1) = '\0'; BPU_printError("buff len %d\n",*size); return 0; }
int BPU_gf2VecMallocElements(BPU_T_GF2_Vector *v, int len) { // element size in bits v->element_bit_size = sizeof(BPU_T_GF2) * 8; // len v->len = len; v->elements_in_row = len / v->element_bit_size; if ( len % v->element_bit_size > 0) v->elements_in_row++; // allocate elemtens v->elements = (BPU_T_GF2*) calloc(1, sizeof(BPU_T_GF2) * v->elements_in_row); if (!v->elements) { BPU_printError("can not allocate memory for vector of len %d", len); return -1; } return 0; }
int BPU_padDel(BPU_T_GF2_Vector *message, const BPU_T_GF2_Vector *padded_message) { int i, message_size = 0; // count the message size for (i = padded_message->len-1; i >= 0; i--) { // nula - padding if (BPU_gf2VecGetBit(padded_message, i) == 1) { // ci bola aspon jedna 0 pred 1 //if (i <= padded_message->len-3) { message_size = i; break; //} // inak zly padding /*else { BPU_printError("del_padding: message padding is incorrect"); return -1; }*/ } } if (message->len < message_size) { BPU_printError("Wrong message size."); return -1; } message->len = message_size; // copy n-1 elements of padded message into message for (i = 0; i < padded_message->elements_in_row - 1; i++){ message->elements[i] = padded_message->elements[i]; } // copy the rest of message for (i = (padded_message->elements_in_row - 1) * padded_message->element_bit_size; i < message->len; i++){ BPU_gf2VecSetBit(message, i, BPU_gf2VecGetBit(padded_message, i)); } return 0; }
int BPU_gf2PolyMalloc(BPU_T_GF2_Poly *p, int len) { // element size in bits p->element_bit_size = sizeof(BPU_T_GF2) * 8; // len p->len = len; // calc how many elements of set size will be in one row int modul = 0; if ( len % p->element_bit_size > 0) { modul = 1; } p->elements_in_row = len / p->element_bit_size + modul; // allocate elemtens p->elements = (BPU_T_GF2*) calloc(1, sizeof(BPU_T_GF2) * p->elements_in_row); if (!p->elements) { BPU_printError("can not allocate memory for vector of len %d", len); return 1; } return 0; }