This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
cryptic/cryptic/protocols/pok_schnorr/hash_for_ni_proofs.c

615 lines
16 KiB
C

/* Cryptic -- Cryptographic tools and protocols
* Copyright (C) 2010 Mikaël Ates <mates@entrouvert.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <glib.h>
#include <glib-object.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include "../../errors.h"
#include "../../utils.h"
#include "hash_for_ni_proofs.h"
/*****************************************************************************/
/* private methods */
/*****************************************************************************/
static GObjectClass *parent_class = NULL;
/*****************************************************************************/
/* overridden parent class methods */
/*****************************************************************************/
static void
dispose(GObject *object)
{
CrypticHashForNiProofs *h = CRYPTIC_HASHFORNIPROOFS(object);
int i;
if(h->modulus != NULL) {
for(i=0;i<h->nb_modulus;i++){
cryptic_release_bn(h->modulus[i]);
}
}
cryptic_release(h->modulus);
if(h->bases != NULL) {
for(i=0;i<h->nb_bases;i++){
cryptic_release_bn(h->bases[i]);
}
}
cryptic_release(h->bases);
if(h->dlreps != NULL) {
for(i=0;i<h->nb_dlreps;i++){
cryptic_release_bn(h->dlreps[i]);
}
}
cryptic_release(h->dlreps);
if(h->commitments != NULL) {
for(i=0;i<h->nb_commitments;i++){
cryptic_release_bn(h->commitments[i]);
}
}
cryptic_release(h->commitments);
cryptic_release_bn(h->h_value);
G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(h));
}
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
static void
instance_init(CrypticHashForNiProofs *h)
{
h->modulus = NULL;
h->bases = NULL;
h->dlreps = NULL;
h->commitments = NULL;
h->h_value = NULL;
}
static void
class_init(CrypticHashForNiProofsClass *klass)
{
parent_class = g_type_class_peek_parent(klass);
G_OBJECT_CLASS(klass)->dispose = dispose;
}
/*****************************************************************************/
/* public methods */
/*****************************************************************************/
GType
cryptic_hash_for_ni_proofs_get_type()
{
static GType this_type = 0;
if (!this_type) {
static const GTypeInfo this_info = {
sizeof (CrypticHashForNiProofsClass),
NULL,
NULL,
(GClassInitFunc) class_init,
NULL,
NULL,
sizeof(CrypticHashForNiProofs),
0,
(GInstanceInitFunc) instance_init,
NULL
};
this_type = g_type_register_static(G_TYPE_OBJECT,
"CrypticHashForNiProofs", &this_info, 0);
}
return this_type;
}
/**
* cryptic_hash_for_ni_proofs_new:
* @size_hash: Hash size to produce.
*
* Creates a new #CrypticHashForNiProofs.
*
* Return value: a newly created #CrypticHashForNiProofs object; or NULL if an error
* occured
**/
CrypticHashForNiProofs*
cryptic_hash_for_ni_proofs_new(int size_h)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
CrypticHashForNiProofs *h;
h = g_object_new(CRYPTIC_TYPE_HASHFORNIPROOFS, NULL);
if((size_h !=256) && (size_h != 512)){
cryptic_critical("Hash size not supported.");
goto cleanup;
}
h->size_h = size_h;
h->nb_modulus = 0;
h->nb_bases = 0;
h->nb_dlreps = 0;
h->nb_commitments = 0;
cryptic_release_bn(h->h_value);
cryptic_release(h->modulus);
cryptic_release(h->bases);
cryptic_release(h->dlreps);
cryptic_release(h->commitments);
return h;
cleanup:
cryptic_release_gobject(h);
return NULL;
}
/**
* cryptic_hash_for_ni_proofs_add_modulus:
* @modulus: Value to add.
*
* Add a value to the modulus tab.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_add_proof(CrypticHashForNiProofs* h, CrypticZkpkSchnorr *shn, BIGNUM *dlrep)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
goto_cleanup_if_fail_with_rc_with_warning(dlrep != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_modulus(h,shn->modulus));
for(i=0;i<shn->nb_quantities;i++){
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_base(h,shn->bases[i]));
}
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_dlrep(h,dlrep));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,shn->commitment));
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
int
cryptic_hash_for_ni_proofs_add_proofrange_prover(CrypticHashForNiProofs* h, CrypticProofrangeQrg* pr)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_modulus(h,pr->modulus));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_base(h,pr->tabBases[0]));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_base(h,pr->tabBases[1]));
for(i=0;i<5;i++){
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_dlrep(h,pr->dlreps[i]));
}
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot1->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot2->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot3->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot4->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokDelta->commitment));
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
int
cryptic_hash_for_ni_proofs_add_proofrange_verifier(CrypticHashForNiProofs* h, CrypticProofrangeQrg* pr, BIGNUM** dlreps)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
goto_cleanup_if_fail_with_rc_with_warning(dlreps != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
for(i=0;i<5;i++){
goto_cleanup_if_fail_with_rc_with_warning(dlreps[i] != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
}
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_modulus(h,pr->modulus));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_base(h,pr->tabBases[0]));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_base(h,pr->tabBases[1]));
for(i=0;i<5;i++){
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_dlrep(h,dlreps[i]));
}
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot1->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot2->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot3->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokSqrRoot4->commitment));
cryptic_check_good_rc(cryptic_hash_for_ni_proofs_add_commitment(h,pr->pokDelta->commitment));
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
/**
* cryptic_hash_for_ni_proofs_add_modulus:
* @modulus: Value to add.
*
* Add a value to the modulus tab.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_add_modulus(CrypticHashForNiProofs* h, BIGNUM* modulus)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
goto_cleanup_if_fail_with_rc_with_warning(modulus != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
if(h->nb_modulus == 0) {
cryptic_release(h->modulus);
h->modulus = g_malloc0(sizeof (**h->modulus));
if(h->modulus == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}else{
BIGNUM **tmp = NULL;
tmp = h->modulus;
h->modulus = g_realloc(h->modulus,(h->nb_modulus+1) * sizeof (**h->modulus));
if(h->modulus == NULL){
h->modulus = tmp;
tmp = NULL;
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(h->modulus[h->nb_modulus] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(h->modulus[h->nb_modulus],modulus));
h->nb_modulus++;
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
/**
* cryptic_hash_for_ni_proofs_add_base:
* @base: Value to add.
*
* Add a value to the bases tab.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_add_base(CrypticHashForNiProofs* h, BIGNUM* base)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
goto_cleanup_if_fail_with_rc_with_warning(base != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
if(h->nb_bases == 0) {
cryptic_release(h->bases);
h->bases = g_malloc0(sizeof (**h->bases));
if(h->bases == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}else{
BIGNUM **tmp = NULL;
tmp = h->bases;
h->bases = g_realloc(h->bases,(h->nb_bases+1) * sizeof (**h->bases));
if(h->bases == NULL){
h->bases = tmp;
tmp = NULL;
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(h->bases[h->nb_bases] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(h->bases[h->nb_bases],base));
h->nb_bases++;
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
/**
* cryptic_hash_for_ni_proofs_add_dlrep:
* @dlrep: Value to add.
*
* Add a value to the dlreps tab.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_add_dlrep(CrypticHashForNiProofs* h, BIGNUM* dlrep)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
goto_cleanup_if_fail_with_rc_with_warning(dlrep != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
if(h->nb_dlreps == 0) {
cryptic_release(h->dlreps);
h->dlreps = g_malloc0(sizeof (**h->dlreps));
if(h->dlreps == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}else{
BIGNUM **tmp = NULL;
tmp = h->dlreps;
h->dlreps = g_realloc(h->dlreps,(h->nb_dlreps+1) * sizeof (**h->dlreps));
if(h->dlreps == NULL){
h->dlreps = tmp;
tmp = NULL;
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(h->dlreps[h->nb_dlreps] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(h->dlreps[h->nb_dlreps],dlrep));
h->nb_dlreps++;
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
/**
* cryptic_hash_for_ni_proofs_add_commitment:
* @commitment: Value to add.
*
* Add a value to the commitments tab.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_add_commitment(CrypticHashForNiProofs* h, BIGNUM* commitment)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
CRYPTIC_HASH_NI_PROOFS_NULL_VALUE);
if(h->nb_commitments == 0) {
cryptic_release(h->commitments);
h->commitments = g_malloc0(sizeof (**h->commitments));
if(h->commitments == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}else{
BIGNUM **tmp = NULL;
tmp = h->commitments;
h->commitments = g_realloc(h->commitments,(h->nb_commitments+1) * sizeof (**h->commitments));
if(h->commitments == NULL){
h->commitments = tmp;
tmp = NULL;
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(h->commitments[h->nb_commitments] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(h->commitments[h->nb_commitments],commitment));
h->nb_commitments++;
rc = CRYPTIC_NO_ERROR;
cleanup:
return rc;
}
/**
* cryptic_hash_for_ni_proofs_add_commitment:
*
* Compute the hash.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_hash_for_ni_proofs_compute_hash(CrypticHashForNiProofs* h)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
char *concat = NULL, *tmp = NULL;
cryptic_release_string(concat);
cryptic_release_string(tmp);
int i,j;
int s = 0;
int size = 0;
int local_size;
if(h->modulus) {
for(i=0;i<h->nb_modulus;i++){
if(BN_num_bits(h->modulus[i])%8 != 0) s++;
s += BN_num_bits(h->modulus[i])/8;
}
}
if(h->bases) {
for(i=0;i<h->nb_bases;i++){
if(BN_num_bits(h->bases[i])%8 != 0) s++;
s += BN_num_bits(h->bases[i])/8;
}
}
if(h->dlreps) {
for(i=0;i<h->nb_dlreps;i++){
if(BN_num_bits(h->dlreps[i])%8 != 0) s++;
s += BN_num_bits(h->dlreps[i])/8;
}
}
if(h->commitments) {
for(i=0;i<h->nb_commitments;i++){
if(BN_num_bits(h->commitments[i])%8 != 0) s++;
s += BN_num_bits(h->commitments[i])/8;
}
}
concat = g_malloc0(s * sizeof (char));
if(concat == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
if(h->modulus) {
for(i=0;i<h->nb_modulus;i++){
local_size = 0;
if(BN_num_bits(h->modulus[i])%8 != 0) local_size++;
local_size += BN_num_bits(h->modulus[i])/8;
tmp = g_malloc0(local_size * sizeof (char));
if(tmp == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_bn2bin(h->modulus[i],tmp));
for(j=0;j<=local_size;j++){
concat[j+size]=tmp[j];
}
size += local_size;
cryptic_release_string(tmp);
}
}
if(h->bases) {
for(i=0;i<h->nb_bases;i++){
local_size = 0;
if(BN_num_bits(h->bases[i])%8 != 0) local_size++;
local_size += BN_num_bits(h->bases[i])/8;
tmp = g_malloc0(local_size * sizeof (char));
if(tmp == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_bn2bin(h->bases[i],tmp));
for(j=0;j<=local_size;j++){
concat[j+size]=tmp[j];
}
size += local_size;
cryptic_release_string(tmp);
}
}
if(h->dlreps) {
for(i=0;i<h->nb_dlreps;i++){
local_size = 0;
if(BN_num_bits(h->dlreps[i])%8 != 0) local_size++;
local_size += BN_num_bits(h->dlreps[i])/8;
tmp = g_malloc0(local_size * sizeof (char));
if(tmp == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_bn2bin(h->dlreps[i],tmp));
for(j=0;j<=local_size;j++){
concat[j+size]=tmp[j];
}
size += local_size;
cryptic_release_string(tmp);
}
}
if(h->commitments) {
for(i=0;i<h->nb_commitments;i++){
local_size = 0;
if(BN_num_bits(h->commitments[i])%8 != 0) local_size++;
local_size += BN_num_bits(h->commitments[i])/8;
tmp = g_malloc0(local_size * sizeof (char));
if(tmp == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_bn2bin(h->commitments[i],tmp));
for(j=0;j<=local_size;j++){
concat[j+size]=tmp[j];
}
size += local_size;
cryptic_release_string(tmp);
}
}
goto_cleanup_if_fail_with_rc_with_warning(concat != NULL && concat[0] != 0,
CRYPTIC_HASH_NI_PROOFS_ERROR_COMPUTATION);
goto_cleanup_if_fail_with_rc_with_warning(s == size,
CRYPTIC_HASH_NI_PROOFS_ERROR_COMPUTATION);
tmp = g_malloc0((h->size_h/8) * sizeof (char));
if(tmp == NULL){
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
goto cleanup;
}
if(h->size_h == 256){
goto_cleanup_if_fail_with_rc_with_warning_openssl(EVP_Digest (concat,size,tmp,NULL,EVP_sha256(),NULL));
/*SHA256_CTX *c;
c = g_malloc0(sizeof (SHA256_CTX));
SHA256_Init(c);
SHA256_Update(c, concat, size);
SHA256_Final(tmp,c);
cryptic_release(c);*/
}else{
goto_cleanup_if_fail_with_rc_with_warning_openssl(EVP_Digest (concat,size,tmp,NULL,EVP_sha512(),NULL));
/*SHA512_CTX *c;
c = g_malloc0(sizeof (SHA512_CTX));
SHA512_Init(c);
SHA512_Update(c, concat, size);
SHA512_Final(tmp,c);
cryptic_release(c);*/
}
goto_cleanup_if_fail_with_rc_with_warning(tmp != NULL,
CRYPTIC_HASH_NI_PROOFS_ERROR_COMPUTATION);
cryptic_release_bn(h->h_value);
h->h_value = BN_bin2bn(tmp,h->size_h/8,NULL);
goto_cleanup_if_fail_with_rc_with_warning(h->h_value != NULL,
CRYPTIC_HASH_NI_PROOFS_ERROR_COMPUTATION);
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_string(tmp);
cryptic_release_string(concat);
return rc;
}
BIGNUM*
cryptic_hash_for_ni_proofs_get_hash(CrypticHashForNiProofs* h)
{
cryptic_return_null_if_fail(h->h_value);
return h->h_value;
}