From d9337dda7db1b3430d17914b4e290b9a200045a2 Mon Sep 17 00:00:00 2001 From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net> Date: Wed, 20 Nov 2019 18:31:39 +0700 Subject: [PATCH] [*] libdap-chain-crypto -> libdap-crypto --- include/dap_cert.h | 82 +++++ include/dap_cert_file.h | 60 +++ include/dap_hash.h | 108 ++++++ include/dap_hash_fusion.h | 25 ++ include/dap_hash_keccak.h | 35 ++ include/dap_pkey.h | 63 ++++ include/dap_sign.h | 87 +++++ src/dap_cert.c | 481 +++++++++++++++++++++++++ src/dap_cert_file.c | 230 ++++++++++++ src/dap_hash.c | 55 +++ src/dap_hash_fusion.c | 28 ++ src/dap_hash_keccak.c | 26 ++ src/dap_pkey.c | 90 +++++ src/dap_sign.c | 350 ++++++++++++++++++ test/cert/CMakeLists.txt | 18 + test/cert/dap_crypto_cert_save_tests.c | 66 ++++ test/cert/dap_crypto_cert_save_tests.h | 4 + test/cert/dap_sha3_tests.c | 211 +++++++++++ test/cert/main.c | 12 + 19 files changed, 2031 insertions(+) create mode 100755 include/dap_cert.h create mode 100755 include/dap_cert_file.h create mode 100755 include/dap_hash.h create mode 100755 include/dap_hash_fusion.h create mode 100755 include/dap_hash_keccak.h create mode 100755 include/dap_pkey.h create mode 100755 include/dap_sign.h create mode 100755 src/dap_cert.c create mode 100755 src/dap_cert_file.c create mode 100755 src/dap_hash.c create mode 100755 src/dap_hash_fusion.c create mode 100755 src/dap_hash_keccak.c create mode 100755 src/dap_pkey.c create mode 100755 src/dap_sign.c create mode 100755 test/cert/CMakeLists.txt create mode 100755 test/cert/dap_crypto_cert_save_tests.c create mode 100755 test/cert/dap_crypto_cert_save_tests.h create mode 100644 test/cert/dap_sha3_tests.c create mode 100755 test/cert/main.c diff --git a/include/dap_cert.h b/include/dap_cert.h new file mode 100755 index 0000000..16c43b9 --- /dev/null +++ b/include/dap_cert.h @@ -0,0 +1,82 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * CellFrame https://cellframe.net + * Sources https://gitlab.demlabs.net/cellframe + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of CellFrame SDK the open source project + + CellFrame SDK 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 3 of the License, or + (at your option) any later version. + + CellFrame SDK 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 any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "dap_sign.h" +#include "dap_pkey.h" + +#include "dap_enc.h" +#include "dap_enc_key.h" + +#define DAP_CERT_ITEM_NAME_MAX 40 + +typedef struct dap_cert { + dap_enc_key_t * enc_key; + char name[DAP_CERT_ITEM_NAME_MAX]; + void * _pvt; + char * metadata; +} dap_cert_t; + +int dap_cert_init(); + + +dap_cert_t * dap_cert_new(const char * a_name); + +size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs, size_t * a_certs_size); + +dap_cert_t * dap_cert_generate(const char * a_cert_name,const char * a_file_path,dap_enc_key_type_t a_key_type ); + +dap_cert_t * dap_cert_generate_mem(const char * a_cert_name, + dap_enc_key_type_t a_key_type ); + + +dap_cert_t * dap_cert_add_file(const char * a_cert_name,const char *a_folder_path); +int dap_cert_save_to_folder(dap_cert_t * a_cert, const char *a_file_dir_path); +void dap_cert_add_folder(const char *a_folder_path); +void dap_cert_dump(dap_cert_t * a_cert); +dap_pkey_t * dap_cert_to_pkey(dap_cert_t * a_cert); + +dap_cert_t * dap_cert_find_by_name(const char * a_cert_name); + +dap_sign_t * dap_cert_sign(dap_cert_t * a_cert, const void * a_data, size_t a_data_size, size_t a_output_size_wished ); + +int dap_cert_compare_with_sign (dap_cert_t * a_cert,dap_sign_t * a_sign); + + +size_t dap_cert_sign_output_size(dap_cert_t * a_cert, size_t a_size_wished); + + +//int dap_cert_sign_output(dap_cert_t * a_cert, const void * a_data, size_t a_data_size +// , void * a_output , size_t a_output_size); + + +int dap_cert_add_cert_sign(dap_cert_t * a_cert, dap_cert_t * a_cert_signer); + +size_t dap_cert_count_cert_sign(dap_cert_t * a_cert); + +void dap_cert_deinit(); + +void dap_cert_delete(dap_cert_t * a_cert); +void dap_cert_delete_by_name(const char * a_cert_name); diff --git a/include/dap_cert_file.h b/include/dap_cert_file.h new file mode 100755 index 0000000..5ba7f1f --- /dev/null +++ b/include/dap_cert_file.h @@ -0,0 +1,60 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once +#include <stdint.h> +#include "dap_common.h" +#include "dap_cert.h" + +// Magic .dapcert signature +#define dap_cert_FILE_HDR_SIGN 0x0F300C4711E29380 +#define dap_cert_FILE_VERSION 1 + +// Default certificate with private key and optionaly some signs +#define dap_cert_FILE_TYPE_PRIVATE 0x00 +// Default certificate with public key and optionaly some signs +#define dap_cert_FILE_TYPE_PUBLIC 0xf0 + + +typedef struct dap_cert_file_hdr +{ + uint64_t sign; + int version; + uint8_t type; + dap_sign_type_t sign_type; + uint64_t data_size; + uint64_t data_pvt_size; + uint64_t metadata_size; + time_t ts_last_used; +} DAP_ALIGN_PACKED dap_cert_file_hdr_t; + +typedef struct dap_cert_file{ + dap_cert_file_hdr_t hdr; + uint8_t data[]; +}DAP_ALIGN_PACKED dap_cert_file_t; + +int dap_cert_file_save(dap_cert_t * a_cert, const char * a_cert_file_path); +uint8_t* dap_cert_mem_save(dap_cert_t * a_cert, uint32_t *a_cert_size_out); + +dap_cert_t* dap_cert_file_load(const char * a_cert_file_path); +dap_cert_t* dap_cert_mem_load(void * a_data, size_t a_data_size); diff --git a/include/dap_hash.h b/include/dap_hash.h new file mode 100755 index 0000000..3d968c6 --- /dev/null +++ b/include/dap_hash.h @@ -0,0 +1,108 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * CellFrame https://cellframe.net + * Sources https://gitlab.demlabs.net/cellframe + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of CellFrame SDK the open source project + + CellFrame SDK 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 3 of the License, or + (at your option) any later version. + + CellFrame SDK 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 any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + +#include "dap_common.h" +#include "dap_hash_keccak.h" + +#include "KeccakHash.h" +#include "SimpleFIPS202.h" + +#define DAP_HASH_FAST_SIZE 32 +#define DAP_CHAIN_HASH_FAST_SIZE 32 + +typedef enum dap_hash_type { + DAP_HASH_TYPE_KECCAK = 0, + DAP_HASH_TYPE_SLOW_0 = 1, +} dap_hash_type_t; + +typedef union dap_chain_hash_fast{ + uint8_t raw[DAP_CHAIN_HASH_FAST_SIZE]; +} dap_chain_hash_fast_t; + +//size_t dap_chain_hash_fast_to_str(dap_chain_hash_fast_t * a_hash, char * a_str, size_t a_str_max); +int dap_chain_str_to_hash_fast( const char * a_hash_str, dap_chain_hash_fast_t * a_hash); + +static inline bool dap_hash_fast( const void *a_data_in, size_t a_data_in_size, dap_chain_hash_fast_t *a_hash_out ) +{ + if ( (a_data_in == NULL) || (a_data_in_size == 0) || (a_hash_out == NULL) ) + return false; + + // dap_hash_keccak( a_data_in, a_data_in_size, a_data_out, a_data_out_size ); + + SHA3_256( (unsigned char *)a_hash_out, (const unsigned char *)a_data_in, a_data_in_size ); + + //SHA3_256( (unsigned char *)a_hash_out, (const unsigned char *)a_data_in, a_data_in_size ); + + return true; +} + + +/** + * @brief dap_hash_fast_compare + * @param a_hash1 + * @param a_hash2 + * @return + */ +static inline bool dap_hash_fast_compare(dap_chain_hash_fast_t *a_hash1, dap_chain_hash_fast_t *a_hash2) +{ + if(!a_hash1 || !a_hash2) + return false; + if(!memcmp(a_hash1, a_hash2, sizeof(dap_chain_hash_fast_t))) + return true; + return false; +} + +static inline bool dap_hash_fast_is_blank( dap_chain_hash_fast_t *a_hash ) +{ + static dap_chain_hash_fast_t l_blank_hash = { 0}; +// uint8_t *l_hast_bytes = (uint8_t*) a_hash; +// for(size_t i = 0; i < sizeof(dap_chain_hash_fast_t); i++) { +// if(l_hast_bytes[i]) +// return false; +// } + return dap_hash_fast_compare( a_hash, &l_blank_hash); +} + + +DAP_STATIC_INLINE int dap_chain_hash_fast_to_str( dap_chain_hash_fast_t *a_hash, char *a_str, size_t a_str_max ) +{ + a_str[0] = '0'; + a_str[1] = 'x'; + a_str[ DAP_CHAIN_HASH_FAST_SIZE * 2 + 2 ] = 0; + dap_htoa64( (a_str + 2), a_hash->raw, DAP_CHAIN_HASH_FAST_SIZE ); + return DAP_CHAIN_HASH_FAST_SIZE * 2 + 2; +} + +static inline char *dap_chain_hash_fast_to_str_new(dap_chain_hash_fast_t * a_hash) +{ + const size_t c_hash_str_size = sizeof(*a_hash)*2 +1 /*trailing zero*/ +2 /* heading 0x */+4/*just to be sure*/ ; + char * ret = DAP_NEW_Z_SIZE(char, c_hash_str_size); + dap_chain_hash_fast_to_str( a_hash, ret, c_hash_str_size ); + return ret; +} diff --git a/include/dap_hash_fusion.h b/include/dap_hash_fusion.h new file mode 100755 index 0000000..a2d8d85 --- /dev/null +++ b/include/dap_hash_fusion.h @@ -0,0 +1,25 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <kahovski@gmail.com> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once diff --git a/include/dap_hash_keccak.h b/include/dap_hash_keccak.h new file mode 100755 index 0000000..f94db1c --- /dev/null +++ b/include/dap_hash_keccak.h @@ -0,0 +1,35 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <kahovski@gmail.com> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +/* +#include "keccak.h" + +static inline void dap_hash_keccak(const void * a_in, size_t a_in_size, void * a_out, size_t a_out_size) +{ + keccak((const uint8_t*) a_in, a_in_size, (uint8_t *) a_out,(int) a_out_size ); +}*/ + + diff --git a/include/dap_pkey.h b/include/dap_pkey.h new file mode 100755 index 0000000..af9d930 --- /dev/null +++ b/include/dap_pkey.h @@ -0,0 +1,63 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <stdint.h> +#include "dap_common.h" +#include "dap_enc_key.h" + +typedef union dap_pkey_type{ + enum { + PKEY_TYPE_NULL = 0x0000, + PKEY_TYPE_SIGN_BLISS = 0x0901, + PKEY_TYPE_SIGN_TESLA = 0x0902, + PKEY_TYPE_SIGN_DILITHIUM = 0x0903, + PKEY_TYPE_SIGN_PICNIC = 0x0102, + PKEY_TYPE_MULTI = 0xffff /// @brief Has inside subset of different keys + + } type: 16; + uint16_t raw; +} dap_pkey_type_t; +/** + * @struct dap_pkey + * @brief Public keys + */ +typedef struct dap_pkey{ + struct { + dap_pkey_type_t type; /// Pkey type + uint32_t size; /// Pkey size + } header; /// Only header's hash is used for verification + uint8_t pkey[]; /// @param pkey @brief raw pkey dat +} DAP_ALIGN_PACKED dap_pkey_t; + +static dap_pkey_t m_dap_pkey_null; // For sizeof nothing more + +dap_pkey_t *dap_pkey_from_enc_key(dap_enc_key_t *a_key); +static inline size_t dap_pkey_from_enc_key_output_calc(dap_enc_key_t *a_key) +{ + return sizeof(m_dap_pkey_null.header)+ a_key->pub_key_data_size; +} + +int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output); + diff --git a/include/dap_sign.h b/include/dap_sign.h new file mode 100755 index 0000000..8a5542e --- /dev/null +++ b/include/dap_sign.h @@ -0,0 +1,87 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> +#include "dap_common.h" +#include "dap_enc_ca.h" +#include "dap_enc_key.h" +#include "dap_pkey.h" +#include "dap_hash.h" + +typedef union dap_sign_type{ + enum { + SIG_TYPE_NULL = 0x0000, + SIG_TYPE_BLISS = 0x0001, + SIG_TYPE_DEFO = 0x0002, /// @brief key image for anonymous transaction + SIG_TYPE_TESLA = 0x0003, /// @brief + SIG_TYPE_PICNIC = 0x0101, /// @brief + SIG_TYPE_DILITHIUM = 0x0102, /// @brief + SIG_TYPE_MULTI = 0xffff /// @brief Has inside subset of different signatures and sign composed with all of them + } type: 16; + uint16_t raw; +} dap_sign_type_t; + +typedef struct dap_sign_hdr{ + dap_sign_type_t type; /// Signature type + uint8_t padding[2]; /// Padding for better aligmnent + uint16_t sign_size; /// Signature size + uint32_t sign_pkey_size; /// Signature serialized public key size +} DAP_ALIGN_PACKED dap_sign_hdr_t; + +/** + * @struct dap_sign + * @brief Chain storage format for digital signature + */ +typedef struct dap_sign +{ + dap_sign_hdr_t header; /// Only header's hash is used for verification + uint8_t pkey_n_sign[]; /// @param sig @brief raw signature data +} DAP_ALIGN_PACKED dap_sign_t; + +size_t dap_sign_get_size(dap_sign_t * a_chain_sign); + +int dap_sign_verify (dap_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size); + +dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size + , size_t a_output_wish_size ); +size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key,size_t a_output_wish_size ); +//int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size +// , void * a_output, size_t a_output_size ); + + +dap_sign_type_t dap_sign_type_from_key_type( dap_enc_key_type_t a_key_type); +dap_enc_key_type_t dap_sign_type_to_key_type(dap_sign_type_t a_chain_sign_type); + +dap_sign_type_t dap_pkey_type_from_sign( dap_pkey_type_t a_pkey_type); + +uint8_t* dap_sign_get_sign(dap_sign_t *a_sign, size_t *a_sign_out); +uint8_t* dap_sign_get_pkey(dap_sign_t *a_sign, size_t *a_pub_key_out); +bool dap_sign_get_pkey_hash(dap_sign_t *a_sign, dap_chain_hash_fast_t * a_sign_hash); + +dap_enc_key_t *dap_sign_to_enc_key(dap_sign_t * a_chain_sign); +const char * dap_sign_type_to_str(dap_sign_type_t a_chain_sign_type); +dap_sign_type_t dap_sign_type_from_str(const char * a_type_str); + diff --git a/src/dap_cert.c b/src/dap_cert.c new file mode 100755 index 0000000..e82d29d --- /dev/null +++ b/src/dap_cert.c @@ -0,0 +1,481 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <sys/types.h> +#include <dirent.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <ctype.h> + +#include "uthash.h" +#include "utlist.h" +#include "dap_common.h" +#include "dap_config.h" +#include "dap_string.h" +#include "dap_strfuncs.h" +#include "dap_cert.h" +#include "dap_cert_file.h" +//#include "dap_hash.h" +#define LOG_TAG "dap_cert" + + +typedef struct dap_sign_item +{ + dap_sign_t * sign; + struct dap_sign_item * next; + struct dap_sign_item * prev; +} dap_sign_item_t; + +typedef struct dap_cert_item +{ + char name[DAP_CERT_ITEM_NAME_MAX]; + dap_cert_t * cert; + UT_hash_handle hh; +} dap_cert_item_t; + +typedef struct dap_cert_pvt +{ + dap_sign_item_t *signs; +} dap_cert_pvt_t; + + +#define PVT(a) ( ( dap_cert_pvt_t *)((a)->_pvt) ) + +static dap_cert_item_t * s_certs = NULL; + +/** + * @brief dap_cert_init + * @return + */ +int dap_cert_init() +{ + return 0; +} + +/** + * @brief dap_cert_parse_str_list + * @param a_certs_str + * @param a_certs + * @param a_certs_size_t + * @return summary size for signatures of all certs in list + */ +size_t dap_cert_parse_str_list(const char * a_certs_str, dap_cert_t *** a_certs, size_t * a_certs_size) +{ + char * l_certs_tmp_ptrs = NULL; + char * l_certs_str_dup = strdup(a_certs_str); + char *l_cert_str = strtok_r(l_certs_str_dup, ",", &l_certs_tmp_ptrs); + + // First we just calc items + while(l_cert_str) { + l_cert_str = strtok_r(NULL, ",", &l_certs_tmp_ptrs); + (*a_certs_size)++; + } + // init certs array + dap_cert_t **l_certs; + *a_certs = l_certs = DAP_NEW_Z_SIZE(dap_cert_t*, (*a_certs_size) * sizeof(dap_cert_t*) ); + + // Second pass we parse them all + strcpy(l_certs_str_dup, a_certs_str); + l_cert_str = strtok_r(l_certs_str_dup, ",", &l_certs_tmp_ptrs); + + size_t l_certs_pos = 0; + size_t l_sign_total_size =0; + while(l_cert_str) { + // trim whitespace in certificate's name + l_cert_str = dap_strstrip(l_cert_str);// removes leading and trailing spaces + // get certificate by name + l_certs[l_certs_pos] = dap_cert_find_by_name(l_cert_str); + // if certificate is found + if(l_certs[l_certs_pos]) { + l_sign_total_size += dap_cert_sign_output_size(l_certs[l_certs_pos],0); + l_certs_pos++; + } else { + log_it(L_WARNING,"Can't load cert %s",l_cert_str); + DAP_DELETE(*a_certs); + *a_certs = NULL; + *a_certs_size = 0; + break; + } + l_cert_str = strtok_r(NULL, ",", &l_certs_tmp_ptrs); + } + free(l_certs_str_dup); + return l_sign_total_size; +} + + + +/** + * @brief dap_cert_sign_output_size + * @param a_cert + * @param a_size_wished + * @return + */ +size_t dap_cert_sign_output_size(dap_cert_t * a_cert, size_t a_size_wished) +{ + return dap_sign_create_output_unserialized_calc_size( a_cert->enc_key,a_size_wished); +} + +/** + * @brief dap_cert_sign_output + * @param a_cert + * @param a_data + * @param a_data_size + * @param a_output + * @param a_output_siz + * @return + */ +/*int dap_cert_sign_output(dap_cert_t * a_cert, const void * a_data, size_t a_data_size, + void * a_output, size_t a_output_size) +{ + return dap_sign_create_output( a_cert->enc_key,a_data,a_data_size,a_output,a_output_size); +}*/ + +/** + * @brief dap_cert_sign + * @param a_cert + * @param a_data + * @param a_data_size + * @param a_output_size_wished + * @return + */ +dap_sign_t * dap_cert_sign(dap_cert_t * a_cert, const void * a_data + , size_t a_data_size, size_t a_output_size_wished ) +{ + dap_enc_key_t * l_key = a_cert->enc_key; + dap_sign_t *l_ret = dap_sign_create(l_key, a_data, a_data_size, a_output_size_wished); + return l_ret; +} + +/** + * @brief dap_cert_add_cert_sign + * @param a_cert + * @param a_cert_signer + * @return + */ +int dap_cert_add_cert_sign(dap_cert_t * a_cert, dap_cert_t * a_cert_signer) +{ + if (a_cert->enc_key->pub_key_data_size && a_cert->enc_key->pub_key_data) { + dap_sign_item_t * l_sign_item = DAP_NEW_Z(dap_sign_item_t); + l_sign_item->sign = dap_cert_sign (a_cert_signer,a_cert->enc_key->pub_key_data,a_cert->enc_key->pub_key_data_size,0); + DL_APPEND ( PVT(a_cert)->signs, l_sign_item ); + return 0; + } else { + log_it (L_ERROR, "No public key in cert \"%s\" that we are trying to sign with \"%s\"", a_cert->name,a_cert_signer->name); + return -1; + } +} + + +/** + * @brief dap_cert_generate_mem + * @param a_cert_name + * @param a_key_type + * @return + */ +dap_cert_t * dap_cert_generate_mem(const char * a_cert_name, + dap_enc_key_type_t a_key_type ) +{ + dap_enc_key_t *l_enc_key = dap_enc_key_new_generate(a_key_type, NULL, 0, NULL, 0, 0); + if ( l_enc_key ){ + dap_cert_t * l_cert = dap_cert_new(a_cert_name); + l_cert->enc_key = l_enc_key; + log_it(L_DEBUG,"Certificate generated"); + //dap_cert_item_t * l_cert_item = DAP_NEW_Z(dap_cert_item_t); + //snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_cert_name); + //HASH_ADD_STR(s_certs,name,l_cert_item); + log_it(L_DEBUG,"Certificate name %s recorded", a_cert_name); + return l_cert; + } else { + log_it(L_ERROR,"Can't generate key in memory!"); + //dap_cert_delete(l_cert); + return NULL; + } +} + +/** + * @brief dap_cert_generate + * @param a_cert_name + * @param a_file_path + * @param a_key_type + * @return + */ +dap_cert_t * dap_cert_generate(const char * a_cert_name + , const char * a_file_path,dap_enc_key_type_t a_key_type ) +{ + dap_cert_t * l_cert = dap_cert_generate_mem(a_cert_name,a_key_type); + if ( l_cert){ + if ( dap_cert_file_save(l_cert, a_file_path) == 0 ){ + return l_cert; + } else{ + dap_cert_delete(l_cert); + log_it(L_ERROR, "Can't save certificate to the file!"); + return NULL; + } + } else { + log_it(L_ERROR,"Can't generate certificat in memory!"); + } + return NULL; +} + +/** + * @brief dap_cert_delete_by_name + * @param a_cert_name + */ +void dap_cert_delete_by_name(const char * a_cert_name) +{ + dap_cert_t * l_cert = dap_cert_find_by_name(a_cert_name); + if ( l_cert ) + dap_cert_delete( l_cert ); + else + log_it(L_WARNING,"Can't find \"%s\" certificate to delete it",a_cert_name); +} + +/** + * @brief dap_cert_find_by_name + * @param a_cert_name + * @return + */ +dap_cert_t * dap_cert_find_by_name(const char * a_cert_name) +{ + dap_cert_item_t * l_cert_item = NULL; + HASH_FIND_STR(s_certs,a_cert_name,l_cert_item); + if ( l_cert_item ){ + return l_cert_item->cert ; + } else { + dap_cert_t *l_cert = NULL; + uint16_t l_ca_folders_size = 0; + char **l_ca_folders; + char *l_cert_path = NULL; + l_ca_folders = dap_config_get_array_str(g_config, "resources", "ca_folders", &l_ca_folders_size); + for (uint16_t i = 0; i < l_ca_folders_size; ++i) { +#ifdef _WIN32 + l_cert_path = dap_strjoin("", s_sys_dir_path, l_ca_folders[i], "/", a_cert_name, ".dcert", (char*)NULL); +#else + l_cert_path = dap_strjoin("", l_ca_folders[i], "/", a_cert_name, ".dcert", (char*)NULL); +#endif + l_cert = dap_cert_file_load(l_cert_path); + if (l_cert) { + goto ret; + } + } + ret: + if (l_cert_path) + DAP_DELETE(l_cert_path); + return l_cert; + } +} + + +/** + * @brief dap_cert_new + * @param a_name + * @return + */ +dap_cert_t * dap_cert_new(const char * a_name) +{ + dap_cert_t * l_ret = DAP_NEW_Z(dap_cert_t); + l_ret->_pvt = DAP_NEW_Z(dap_cert_pvt_t); + dap_snprintf(l_ret->name,sizeof(l_ret->name),"%s",a_name); + + dap_cert_item_t * l_cert_item = DAP_NEW_Z(dap_cert_item_t); + dap_snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_name); + l_cert_item->cert = l_ret; + HASH_ADD_STR(s_certs,name,l_cert_item); + + return l_ret; +} + +/** + * @brief s_cert_delete + * @param a_cert + */ +void dap_cert_delete(dap_cert_t * a_cert) +{ + dap_cert_item_t * l_cert_item = NULL; + HASH_FIND_STR(s_certs, a_cert->name, l_cert_item); + if ( l_cert_item ){ + HASH_DEL(s_certs,l_cert_item); + DAP_DELETE (l_cert_item); + } + + if( a_cert->enc_key ) + dap_enc_key_delete (a_cert->enc_key ); + if( a_cert->metadata ) + DAP_DELETE (a_cert->metadata ); + if (a_cert->_pvt) + DAP_DELETE( a_cert->_pvt ); + DAP_DELETE (a_cert ); +} + +/** + * @brief dap_cert_add_file + * @param a_cert_name + * @param a_folder_path + * @return + */ +dap_cert_t * dap_cert_add_file(const char * a_cert_name,const char *a_folder_path) +{ + size_t l_cert_path_length = strlen(a_cert_name)+8+strlen(a_folder_path); + char * l_cert_path = DAP_NEW_Z_SIZE(char,l_cert_path_length); + dap_snprintf(l_cert_path,l_cert_path_length,"%s/%s.dcert",a_folder_path,a_cert_name); + if( access( l_cert_path, F_OK ) == -1 ) { + log_it (L_ERROR, "File %s is not exists! ", l_cert_path); + DAP_DELETE(l_cert_path); + exit(-701); + } + dap_cert_t * l_cert; + l_cert = dap_cert_file_load(l_cert_path); + if (l_cert == NULL){ + log_it (L_ERROR, "File %s is corrupted or wrong format ", l_cert_path); + } + DAP_DELETE(l_cert_path); + return l_cert; +} + +/** + * @brief dap_cert_save_to_folder + * @param a_cert + * @param a_file_dir_path + */ +int dap_cert_save_to_folder(dap_cert_t * a_cert, const char *a_file_dir_path) +{ + int ret = 0; + const char * l_cert_name = a_cert->name; + size_t l_cert_path_length = strlen(l_cert_name)+8+strlen(a_file_dir_path); + char * l_cert_path = DAP_NEW_Z_SIZE(char,l_cert_path_length); + dap_snprintf(l_cert_path,l_cert_path_length,"%s/%s.dcert",a_file_dir_path,l_cert_name); + ret = dap_cert_file_save(a_cert,l_cert_path); + DAP_DELETE( l_cert_path); + return ret; +} + +/** + * @brief dap_cert_to_pkey + * @param a_cert + * @return + */ +dap_pkey_t * dap_cert_to_pkey(dap_cert_t * a_cert) +{ + if ( a_cert ) + return dap_pkey_from_enc_key( a_cert->enc_key ); + else + return NULL; +} + +/** + * @brief dap_cert_compare_with_sign + * @param a_cert + * @param a_sign + * @return + */ +int dap_cert_compare_with_sign (dap_cert_t * a_cert,dap_sign_t * a_sign) +{ + dap_return_val_if_fail(a_cert && a_cert->enc_key && a_sign, -1); + if ( dap_sign_type_from_key_type( a_cert->enc_key->type ).type == a_sign->header.type.type ){ + int l_ret; + size_t l_pub_key_size = 0; + // serialize public key + uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_cert->enc_key, &l_pub_key_size); + if ( l_pub_key_size == a_sign->header.sign_pkey_size){ + l_ret = memcmp ( l_pub_key, a_sign->pkey_n_sign, a_sign->header.sign_pkey_size ); + }else + l_ret = -2; // Wrong pkey size + DAP_DELETE(l_pub_key); + return l_ret; + }else + return -1; // Wrong sign type +} + + + +/** + * @brief dap_cert_count_cert_sign + * @param a_cert + * @return + */ +size_t dap_cert_count_cert_sign(dap_cert_t * a_cert) +{ + size_t ret; + dap_sign_item_t * l_cert_item = NULL; + DL_COUNT( PVT(a_cert)->signs,l_cert_item,ret); + return ret > 0 ? ret : 0 ; +} + + +/** + * @brief dap_cert_dump + * @param a_cert + */ +void dap_cert_dump(dap_cert_t * a_cert) +{ + printf ("Certificate name: %s\n",a_cert->name); + printf ("Signature type: %s\n", dap_sign_type_to_str( dap_sign_type_from_key_type(a_cert->enc_key->type) ) ); + printf ("Private key size: %lu\n",a_cert->enc_key->priv_key_data_size); + printf ("Public key size: %lu\n", a_cert->enc_key->pub_key_data_size); + printf ("Metadata section size: %lu\n",a_cert->metadata?strlen(a_cert->metadata):0); + printf ("Certificates signatures chain size: %lu\n",dap_cert_count_cert_sign (a_cert)); +} + + +/** + * @brief dap_cert_add_folder + * @param a_folder_path + */ +void dap_cert_add_folder(const char *a_folder_path) +{ + DIR * l_dir = opendir(a_folder_path); + if( l_dir ) { + struct dirent * l_dir_entry; + while((l_dir_entry=readdir(l_dir))!=NULL){ + const char * l_filename = l_dir_entry->d_name; + size_t l_filename_len = strlen (l_filename); + // Check if its not special dir entries . or .. + if( strcmp(l_filename,".") && strcmp(l_filename,"..") ){ + // If not check the file's suffix + const char l_suffix[]=".dcert"; + size_t l_suffix_len = strlen(l_suffix); + if (strncmp(l_filename+ l_filename_len-l_suffix_len,l_suffix,l_suffix_len) == 0 ){ + char * l_cert_name = dap_strdup(l_filename); + l_cert_name[l_filename_len-l_suffix_len] = '\0'; // Remove suffix + // Load the cert file + //log_it(L_DEBUG,"Trying to load %s",l_filename); + dap_cert_add_file(l_cert_name,a_folder_path); + DAP_DELETE(l_cert_name); + } + } + + } + closedir(l_dir); + log_it(L_NOTICE, "Added folder %s",a_folder_path); + }else + log_it(L_WARNING, "Can't add folder %s to cert manager",a_folder_path); +} + +/** + * @brief dap_cert_deinit + */ +void dap_cert_deinit() +{ + +} diff --git a/src/dap_cert_file.c b/src/dap_cert_file.c new file mode 100755 index 0000000..f41e05e --- /dev/null +++ b/src/dap_cert_file.c @@ -0,0 +1,230 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include "dap_common.h" +#include "dap_enc.h" +#include "dap_enc_key.h" +#include "dap_cert_file.h" + +#define LOG_TAG "dap_cert_file" + +/** + * @brief dap_cert_file_save + * @param a_cert + * @param a_cert_file_path + * @return + */ +int dap_cert_file_save(dap_cert_t * a_cert, const char * a_cert_file_path) +{ + FILE * l_file = fopen(a_cert_file_path,"wb"); + if( l_file ){ + uint32_t l_data_size = 0; + void * l_data = dap_cert_mem_save(a_cert, &l_data_size); + if ( l_data ){ + size_t l_retbytes; + if ( (l_retbytes = fwrite(l_data,1,l_data_size,l_file)) != l_data_size ){ + log_it(L_ERROR, "Can't write %u bytes on disk (processed only %u)!", l_data_size,l_retbytes); + return -3; + } + fclose(l_file); + DAP_DELETE(l_data); + return 0; + }else{ + log_it(L_ERROR,"Can't serialize certificate in memory"); + fclose(l_file); + return -4; + } + }else{ + log_it(L_ERROR, "Can't open file for write: %s", strerror(errno)); + return -2; + } +} + +/** + * @brief dap_cert_file_save_to_mem + * @param a_cert + * @param a_cert_size_out + * @return + */ +uint8_t* dap_cert_mem_save(dap_cert_t * a_cert, uint32_t *a_cert_size_out) +{ + dap_cert_file_hdr_t l_hdr={0}; + uint32_t l_data_offset = 0; + dap_enc_key_t * l_key = a_cert->enc_key; + uint8_t *l_data = NULL; + + size_t l_priv_key_data_size = a_cert->enc_key->priv_key_data_size; + size_t l_pub_key_data_size = a_cert->enc_key->pub_key_data_size; + uint8_t *l_pub_key_data = a_cert->enc_key->pub_key_data_size ? + dap_enc_key_serealize_pub_key(l_key, &l_pub_key_data_size) : + NULL; + uint8_t *l_priv_key_data = a_cert->enc_key->priv_key_data ? + dap_enc_key_serealize_priv_key(l_key, &l_priv_key_data_size) : + NULL; + + l_hdr.sign = dap_cert_FILE_HDR_SIGN; + l_hdr.type = dap_cert_FILE_TYPE_PUBLIC; + if ( l_priv_key_data ){ + l_hdr.type = dap_cert_FILE_TYPE_PRIVATE; + log_it(L_DEBUG,"Private key size %u",l_priv_key_data_size); + } + if (l_pub_key_data){ + log_it(L_DEBUG,"Public key size %u",l_pub_key_data_size); + }else{ + log_it(L_ERROR,"No public or private key in certificate, nothing to save"); + goto lb_exit; + } + log_it(L_DEBUG,"Metadata size %u",l_key->_inheritor_size); + + l_hdr.version = dap_cert_FILE_VERSION; + l_hdr.data_size = l_pub_key_data_size; + l_hdr.data_pvt_size = l_priv_key_data_size; + l_hdr.metadata_size = l_key->_inheritor_size; + + l_hdr.ts_last_used = l_key->last_used_timestamp; + l_hdr.sign_type = dap_sign_type_from_key_type ( l_key->type ); + + + l_data = DAP_NEW_SIZE(void, sizeof(l_hdr) + DAP_CERT_ITEM_NAME_MAX + l_priv_key_data_size + l_pub_key_data_size + l_hdr.metadata_size); + + memcpy(l_data +l_data_offset, &l_hdr ,sizeof(l_hdr) ); + l_data_offset += sizeof(l_hdr); + + memcpy(l_data +l_data_offset, a_cert->name, DAP_CERT_ITEM_NAME_MAX );//save cert name + l_data_offset += DAP_CERT_ITEM_NAME_MAX; + + memcpy(l_data +l_data_offset, l_pub_key_data ,l_pub_key_data_size ); + l_data_offset += l_pub_key_data_size; + + if ( l_priv_key_data_size ) { + memcpy(l_data +l_data_offset, l_priv_key_data ,l_priv_key_data_size ); + l_data_offset += l_priv_key_data_size; + } + + if ( l_key->_inheritor_size ) { + memcpy(l_data +l_data_offset, l_key->_inheritor ,l_key->_inheritor_size ); + l_data_offset += l_key->_inheritor_size; + } +lb_exit: + DAP_DELETE(l_pub_key_data); + DAP_DELETE(l_priv_key_data); + if (l_data) + log_it(L_NOTICE,"Certificate \"%s\" successfully serialized",a_cert->name); + else + log_it(L_ERROR,"Certificate \"%s\" was not serialized",a_cert->name); + if(a_cert_size_out) + *a_cert_size_out = l_data_offset; + return l_data; +} + +/** + * @brief dap_cert_file_load + * @param a_cert_file_path + * @return + */ + +dap_cert_t* dap_cert_file_load(const char * a_cert_file_path) +{ + dap_cert_t * l_ret = NULL; + FILE * l_file = fopen(a_cert_file_path,"rb"); + + if( l_file ){ + fseek(l_file, 0L, SEEK_END); + uint64_t l_file_size = ftell(l_file); + rewind(l_file); + uint8_t * l_data = DAP_NEW_SIZE(uint8_t,l_file_size); + if ( fread(l_data,1,l_file_size,l_file ) != l_file_size ){ + log_it(L_ERROR, "Can't read %u bytes from the disk!", l_file_size); + DAP_DELETE (l_data); + goto lb_exit; + }else{ + l_ret = dap_cert_mem_load(l_data,l_file_size); + } + DAP_DELETE(l_data); + } +lb_exit: + if( l_file ) + fclose(l_file); + return l_ret; +} + + +/** + * @brief dap_cert_mem_load + * @param a_data + * @param a_data_size + * @return + */ +dap_cert_t* dap_cert_mem_load(void * a_data, size_t a_data_size) +{ + dap_cert_t * l_ret = NULL; + dap_cert_file_hdr_t l_hdr={0}; + uint8_t * l_data = (uint8_t *) a_data; + uint32_t l_data_offset = 0; + memcpy(&l_hdr,l_data, sizeof(l_hdr)); + l_data_offset += sizeof(l_hdr); + if (l_hdr.sign != dap_cert_FILE_HDR_SIGN ){ + log_it(L_ERROR, "Wrong cert signature, corrupted header!"); + goto l_exit; + } + if (l_hdr.version >= 1 ){ + if ( (sizeof(l_hdr) + l_hdr.data_size+l_hdr.data_pvt_size +l_hdr.metadata_size) > a_data_size ){ + log_it(L_ERROR,"Corrupted cert data, data sections size is smaller than exists on the disk! (%llu expected, %llu on disk)", + sizeof(l_hdr)+l_hdr.data_pvt_size+l_hdr.data_size+l_hdr.metadata_size, a_data_size); + goto l_exit; + } + + char l_name[DAP_CERT_ITEM_NAME_MAX]; + memcpy(l_name, l_data +l_data_offset, DAP_CERT_ITEM_NAME_MAX );//save cert name + l_data_offset += DAP_CERT_ITEM_NAME_MAX; + + //l_ret = DAP_NEW_Z(dap_cert_t); + l_ret = dap_cert_new(l_name); + l_ret->enc_key = dap_enc_key_new( dap_sign_type_to_key_type( l_hdr.sign_type )); + l_ret->enc_key->last_used_timestamp = l_hdr.ts_last_used; + + if ( l_hdr.data_size > 0 ){ + + dap_enc_key_deserealize_pub_key(l_ret->enc_key, l_data + l_data_offset, l_hdr.data_size); + l_data_offset += l_hdr.data_size; + } + if ( l_hdr.data_pvt_size > 0 ){ + + dap_enc_key_deserealize_priv_key(l_ret->enc_key, l_data + l_data_offset, l_hdr.data_pvt_size); + l_data_offset += l_hdr.data_pvt_size; + } + if(l_hdr.metadata_size > 0 && l_ret->enc_key->_inheritor && l_ret->enc_key->_inheritor_size == l_hdr.metadata_size) { + memcpy(l_ret->enc_key->_inheritor, l_data + l_data_offset, l_ret->enc_key->_inheritor_size); + } + dap_enc_key_update(l_ret->enc_key); + log_it(L_NOTICE,"Successfully loaded certificate %s", l_ret->name); + }else + log_it(L_ERROR,"Unrecognizable certificate version, corrupted file or you have too old software"); + +l_exit: + return l_ret; +} diff --git a/src/dap_hash.c b/src/dap_hash.c new file mode 100755 index 0000000..27db3c7 --- /dev/null +++ b/src/dap_hash.c @@ -0,0 +1,55 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <kahovski@gmail.com> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <stdio.h> +#include <stdlib.h> +#include "dap_common.h" +#include "dap_hash.h" + +#include "KeccakHash.h" +#include "SimpleFIPS202.h" + +#define LOG_TAG "dap_hash" + +/** + * @brief dap_chain_str_to_hash_fast_to_str + * @param a_hash_str + * @param a_hash + * @return + */ +int dap_chain_str_to_hash_fast( const char * a_hash_str, dap_chain_hash_fast_t * a_hash) +{ + const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */; + size_t l_hash_str_len = strlen( a_hash_str); + if ( l_hash_str_len + 1 == c_hash_str_size ){ + for (size_t l_offset = 2; l_offset < l_hash_str_len; l_offset+=2 ){ + if ( ( sscanf(a_hash_str+l_offset,"%02hhx",a_hash->raw+l_offset/2-1) != 1) || + ( sscanf(a_hash_str+l_offset,"%02hhX",a_hash->raw+l_offset/2-1) != 1) + ) + log_it(L_ERROR,"dap_chain_str_to_hash_fast parse error: offset=%u, hash_str_len=%u, str=\"%2s\"",l_offset, l_hash_str_len, a_hash_str+l_offset); + return -10* ((int) l_offset); // Wrong char + } + return 0; + }else // Wromg string len + return -1; +} diff --git a/src/dap_hash_fusion.c b/src/dap_hash_fusion.c new file mode 100755 index 0000000..a6e107f --- /dev/null +++ b/src/dap_hash_fusion.c @@ -0,0 +1,28 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <kahovski@gmail.com> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "dap_common.h" +#include "dap_hash_fusion.h" + +#define LOG_TAG "dap_hash_fusion" diff --git a/src/dap_hash_keccak.c b/src/dap_hash_keccak.c new file mode 100755 index 0000000..03695a7 --- /dev/null +++ b/src/dap_hash_keccak.c @@ -0,0 +1,26 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <kahovski@gmail.com> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://github.com/demlabsinc + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "dap_hash_keccak.h" + diff --git a/src/dap_pkey.c b/src/dap_pkey.c new file mode 100755 index 0000000..4a62c38 --- /dev/null +++ b/src/dap_pkey.c @@ -0,0 +1,90 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <string.h> +#include "dap_common.h" +#include "dap_pkey.h" + +#define LOG_TAG "chain_key" +//static dap_pkey_t m_dap_pkey_null={0}; // For sizeof nothing more + + +/** + * @brief dap_pkey_from_enc_key + * @param a_key + * @return + */ +dap_pkey_t* dap_pkey_from_enc_key(dap_enc_key_t *a_key) +{ + if (a_key->pub_key_data_size > 0 ){ + dap_pkey_t * l_ret = NULL; + l_ret = DAP_NEW_Z_SIZE(dap_pkey_t,dap_pkey_from_enc_key_output_calc(a_key)); + if( dap_pkey_from_enc_key_output(a_key,l_ret) != 0 ) { + DAP_DELETE(l_ret); + return NULL; + }else + return l_ret; + } + + return NULL; +} + +/** + * @brief dap_pkey_from_enc_key_output + * @param a_key + * @param a_output + * @return + */ +int dap_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output) +{ + dap_pkey_t * l_output = (dap_pkey_t *) a_output; + if (a_key->pub_key_data_size > 0 ){ + switch (a_key->type) { + case DAP_ENC_KEY_TYPE_SIG_BLISS: + l_output->header.type.type = PKEY_TYPE_SIGN_BLISS ; + break; + case DAP_ENC_KEY_TYPE_SIG_TESLA: + l_output->header.type.type = PKEY_TYPE_SIGN_TESLA ; + break; + case DAP_ENC_KEY_TYPE_SIG_PICNIC: + l_output->header.type.type = PKEY_TYPE_SIGN_PICNIC ; + break; + case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: + l_output->header.type.type = PKEY_TYPE_SIGN_DILITHIUM; + break; + + default: + log_it(L_WARNING,"No serialization preset"); + return -1; + } + l_output->header.size = a_key->pub_key_data_size; + memcpy(l_output->pkey,a_key->pub_key_data,a_key->pub_key_data_size); + return 0; + }else{ + log_it(L_WARNING, "No public key in the input enc_key object"); + return -2; + } + return -3; +} + + diff --git a/src/dap_sign.c b/src/dap_sign.c new file mode 100755 index 0000000..b7f436d --- /dev/null +++ b/src/dap_sign.c @@ -0,0 +1,350 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net https:/gitlab.com/demlabs + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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 3 of the License, or + (at your option) any later version. + + DAP 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 any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> + +#include "dap_common.h" +#include "dap_hash.h" +#include "dap_sign.h" +#include "dap_enc_bliss.h" +#include "dap_enc_tesla.h" +#include "dap_enc_picnic.h" +#include "dap_enc_dilithium.h" + +#define LOG_TAG "dap_sign" + +static dap_sign_t * s_sign_null = NULL; +static bliss_signature_t s_sign_bliss_null = {0}; + +// calc signature size +size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key, size_t a_output_wish_size ) +{ + size_t l_sign_size = 0; + switch (a_key->type){ + case DAP_ENC_KEY_TYPE_SIG_BLISS: l_sign_size = sizeof(s_sign_bliss_null); break; + case DAP_ENC_KEY_TYPE_SIG_PICNIC: l_sign_size = dap_enc_picnic_calc_signature_size(a_key); break; + case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_size = dap_enc_tesla_calc_signature_size(); break; + case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: l_sign_size = dap_enc_dilithium_calc_signature_unserialized_size(); break; + default : return 0; + + } + return l_sign_size; + //return sizeof(s_sign_null->header)+ a_key->pub_key_data_size + l_sign_size; +} + + +/** + * @brief dap_sign_type_from_key_type + * @param a_key_type + * @return + */ +dap_sign_type_t dap_sign_type_from_key_type( dap_enc_key_type_t a_key_type) +{ + dap_sign_type_t l_sign_type; + switch (a_key_type){ + case DAP_ENC_KEY_TYPE_SIG_BLISS: l_sign_type.type = SIG_TYPE_BLISS; break; + case DAP_ENC_KEY_TYPE_SIG_PICNIC: l_sign_type.type = SIG_TYPE_PICNIC; break; + case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break; + case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: l_sign_type.type = SIG_TYPE_DILITHIUM; break; + default: l_sign_type.raw = 0; + } + return l_sign_type; +} + +/** + * @brief dap_sign_type_to_key_type + * @param a_chain_sign_type + * @return + */ +dap_enc_key_type_t dap_sign_type_to_key_type(dap_sign_type_t a_chain_sign_type) +{ + switch (a_chain_sign_type.type) { + case SIG_TYPE_BLISS: return DAP_ENC_KEY_TYPE_SIG_BLISS; + case SIG_TYPE_TESLA: return DAP_ENC_KEY_TYPE_SIG_TESLA; + case SIG_TYPE_PICNIC: return DAP_ENC_KEY_TYPE_SIG_PICNIC; + case SIG_TYPE_DILITHIUM: return DAP_ENC_KEY_TYPE_SIG_DILITHIUM; + default: return DAP_ENC_KEY_TYPE_NULL; + } +} + + + +/** + * @brief dap_sign_type_to_str + * @param a_chain_sign_type + * @return + */ +const char * dap_sign_type_to_str(dap_sign_type_t a_chain_sign_type) +{ + switch (a_chain_sign_type.type) { + case SIG_TYPE_BLISS: return "sig_bliss"; + case SIG_TYPE_TESLA: return "sig_tesla"; + case SIG_TYPE_PICNIC: return "sig_picnic"; + case SIG_TYPE_DILITHIUM: return "sig_dil"; + default: return "UNDEFINED";//DAP_ENC_KEY_TYPE_NULL; + } + +} + +/** + * @brief dap_pkey_type_from_sign + * @param a_pkey_type + * @return + */ +dap_sign_type_t dap_pkey_type_from_sign( dap_pkey_type_t a_pkey_type) +{ + dap_sign_type_t l_sign_type={0}; + switch (a_pkey_type.type){ + case PKEY_TYPE_SIGN_BLISS: l_sign_type.type = SIG_TYPE_BLISS; break; + case PKEY_TYPE_SIGN_PICNIC: l_sign_type.type = SIG_TYPE_PICNIC; break; + case PKEY_TYPE_SIGN_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break; + case PKEY_TYPE_SIGN_DILITHIUM : l_sign_type.type = SIG_TYPE_DILITHIUM; break; + case PKEY_TYPE_MULTI: l_sign_type.type = SIG_TYPE_MULTI; break; + case PKEY_TYPE_NULL: l_sign_type.type = SIG_TYPE_NULL; break; + } + return l_sign_type; +} + + +/** + * @brief dap_sign_type_from_str + * @param a_type_str + * @return + */ +dap_sign_type_t dap_sign_type_from_str(const char * a_type_str) +{ + dap_sign_type_t l_sign_type = {0}; + if ( strcmp (a_type_str,"sig_bliss") == 0 ){ + l_sign_type.type = SIG_TYPE_BLISS; + } else if ( strcmp (a_type_str,"sig_tesla") == 0){ + l_sign_type.type = SIG_TYPE_TESLA; + } else if ( strcmp (a_type_str,"sig_picnic") == 0){ + l_sign_type.type = SIG_TYPE_PICNIC; + }else if ( strcmp (a_type_str,"sig_dil") == 0){ + l_sign_type.type = SIG_TYPE_DILITHIUM; + }else{ + log_it (L_WARNING, "Wrong sign type string \"%s\"",a_type_str); + } + return l_sign_type; +} + +/** + * @brief dap_sign_create_output + * @param a_key + * @param a_data + * @param a_data_size + * @param a_output [in/out] + * @return + */ +static int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, + void * a_output, size_t *a_output_size) +{ + if(!a_key || !a_key->priv_key_data || !a_key->priv_key_data_size){ + log_it (L_ERROR, "Can't find the private key to create signature"); + return -1; + } + switch (a_key->type) { + case DAP_ENC_KEY_TYPE_SIG_TESLA: + case DAP_ENC_KEY_TYPE_SIG_PICNIC: + case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: + // For PICNIC a_output_size should decrease + *a_output_size = dap_enc_sig_dilithium_get_sign(a_key,a_data,a_data_size,a_output,sizeof(dilithium_signature_t)); + // a_key->enc_na(a_key, a_data, a_data_size, a_output, *a_output_size); + return (*a_output_size > 0) ? 0 : -1; + + + case DAP_ENC_KEY_TYPE_SIG_BLISS: + return (dap_enc_sig_bliss_get_sign(a_key, a_data, a_data_size, a_output, *a_output_size) == BLISS_B_NO_ERROR) + ? 0 : -1; + default: + return -1; + } +} + +/** + * @brief dap_sign_create + * @param a_key + * @param a_data + * @param a_data_size + * @param a_output_wish_size + * @return + */ +dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data, + const size_t a_data_size, size_t a_output_wish_size) +{ + // calculate max signature size + size_t l_sign_unserialized_size = dap_sign_create_output_unserialized_calc_size(a_key, a_output_wish_size); + if(l_sign_unserialized_size > 0) { + size_t l_pub_key_size = 0; + uint8_t *l_pub_key = dap_enc_key_serealize_pub_key(a_key, &l_pub_key_size); + if(!l_pub_key) + return NULL; + uint8_t* l_sign_unserialized = DAP_NEW_Z_SIZE(uint8_t, l_sign_unserialized_size); + // calc signature [sign_size may decrease slightly] + if( dap_sign_create_output(a_key, a_data, a_data_size, + l_sign_unserialized, &l_sign_unserialized_size) != 0) { + dap_enc_key_signature_delete(a_key->type, l_sign_unserialized); + DAP_DELETE(l_pub_key); + return NULL; + } else { + size_t l_sign_ser_size = l_sign_unserialized_size; + uint8_t *l_sign_ser = dap_enc_key_serealize_sign(a_key->type, l_sign_unserialized, &l_sign_ser_size); + if ( l_sign_ser ){ + dap_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_sign_t, + sizeof(dap_sign_hdr_t) + l_sign_ser_size + l_pub_key_size); + // write serialized public key to dap_sign_t + memcpy(l_ret->pkey_n_sign, l_pub_key, l_pub_key_size); + l_ret->header.type = dap_sign_type_from_key_type(a_key->type); + // write serialized signature to dap_sign_t + memcpy(l_ret->pkey_n_sign + l_pub_key_size, l_sign_ser, l_sign_ser_size); + l_ret->header.sign_pkey_size =(uint32_t) l_pub_key_size; + l_ret->header.sign_size = (uint32_t) l_sign_ser_size; + DAP_DELETE(l_sign_ser); + dap_enc_key_signature_delete(a_key->type, l_sign_unserialized); + DAP_DELETE(l_pub_key); + return l_ret; + }else { + log_it(L_WARNING,"Can't serialize signature: NULL returned"); + return NULL; + } + } + } + return NULL; +} + +/** + * @brief dap_sign_get_sign + * @param a_sign + * @param a_sign_out + * @return + */ +uint8_t* dap_sign_get_sign(dap_sign_t *a_sign, size_t *a_sign_out) +{ + if(!a_sign) + return NULL; + if(a_sign_out) + *a_sign_out = a_sign->header.sign_size; + return a_sign->pkey_n_sign + a_sign->header.sign_pkey_size; +} + +/** + * @brief dap_sign_get_pkey + * @param a_sign + * @param a_pub_key_out + * @return + */ +uint8_t* dap_sign_get_pkey(dap_sign_t *a_sign, size_t *a_pub_key_out) +{ + if(!a_sign) + return NULL; + if(a_pub_key_out) + *a_pub_key_out = a_sign->header.sign_pkey_size; + return a_sign->pkey_n_sign; +} + +/** + * @brief dap_sign_get_pkey_hash + * @param a_sign + * @param a_sign_hash + * @return + */ +bool dap_sign_get_pkey_hash(dap_sign_t *a_sign, dap_chain_hash_fast_t * a_sign_hash) +{ + if(!a_sign){ + log_it( L_WARNING, "Sign is NULL on enter"); + return false; + } + if( ! a_sign->header.sign_pkey_size ){ + log_it( L_WARNING, "Sign public key's size is 0"); + return false; + } + return dap_hash_fast( a_sign->pkey_n_sign,a_sign->header.sign_pkey_size,a_sign_hash ); +} + + +/** + * @brief dap_sign_to_enc_key + * @param a_chain_sign + * @return + */ +dap_enc_key_t *dap_sign_to_enc_key(dap_sign_t * a_chain_sign) +{ + dap_enc_key_t * l_ret = dap_enc_key_new( dap_sign_type_to_key_type( a_chain_sign->header.type ) ); + size_t l_pkey_size = 0; + uint8_t *l_pkey = dap_sign_get_pkey(a_chain_sign, &l_pkey_size); + // deserialize public key + dap_enc_key_deserealize_pub_key(l_ret, l_pkey, l_pkey_size); + return l_ret; +} + +/** + * @brief dap_sign_verify + * @param a_chain_sign + * @param a_data + * @param a_data_size + * @return 1 valid signature, 0 invalid signature, -1 unsupported sign type + */ +int dap_sign_verify(dap_sign_t * a_chain_sign, const void * a_data, const size_t a_data_size) +{ + int l_ret; + dap_enc_key_t * l_key = dap_sign_to_enc_key(a_chain_sign); + size_t l_sign_size = a_chain_sign->header.sign_size; + size_t l_sign_ser_size; + uint8_t *l_sign_ser = dap_sign_get_sign(a_chain_sign, &l_sign_ser_size); + // deserialize signature + uint8_t * l_sign = dap_enc_key_deserealize_sign(l_key->type, l_sign_ser, &l_sign_size); + + //uint8_t * l_sign = a_chain_sign->pkey_n_sign + a_chain_sign->header.sign_pkey_size; + switch (l_key->type) { + case DAP_ENC_KEY_TYPE_SIG_TESLA: + case DAP_ENC_KEY_TYPE_SIG_PICNIC: + case DAP_ENC_KEY_TYPE_SIG_DILITHIUM: + if(l_key->dec_na(l_key, a_data, a_data_size, l_sign, l_sign_size) > 0) + l_ret = 0; + else + l_ret = 1; + break; + case DAP_ENC_KEY_TYPE_SIG_BLISS: + if(dap_enc_sig_bliss_verify_sign(l_key, a_data, a_data_size, l_sign, l_sign_size) != BLISS_B_NO_ERROR) + l_ret = 0; + else + l_ret = 1; + break; + default: + l_ret = -1; + } + dap_enc_key_signature_delete(l_key->type, l_sign); + dap_enc_key_delete(l_key); + return l_ret; +} + +/** + * Get size of struct dap_sign_t + */ +size_t dap_sign_get_size(dap_sign_t * a_chain_sign) +{ + if(!a_chain_sign) + return 0; + return (sizeof(dap_sign_t) + a_chain_sign->header.sign_size + a_chain_sign->header.sign_pkey_size); +} diff --git a/test/cert/CMakeLists.txt b/test/cert/CMakeLists.txt new file mode 100755 index 0000000..0885e42 --- /dev/null +++ b/test/cert/CMakeLists.txt @@ -0,0 +1,18 @@ +if(TARGET crypto_cert_test) + return() # The project has already been built. +endif() +project(crypto_cert_test) + +add_subdirectory(libdap-test) + +file(GLOB SOURCES *.c) +file(GLOB HEADERS *.h) + +add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) + +target_link_libraries(${PROJECT_NAME} dap_crypto dap_core dap_test) + +add_test( + NAME crypto_cert_test + COMMAND crypto_cert_test +) diff --git a/test/cert/dap_crypto_cert_save_tests.c b/test/cert/dap_crypto_cert_save_tests.c new file mode 100755 index 0000000..96a1420 --- /dev/null +++ b/test/cert/dap_crypto_cert_save_tests.c @@ -0,0 +1,66 @@ +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +#include "dap_test.h" +#include "dap_enc_key.h" +#include "dap_cert.h" +#include "dap_cert_file.h" + +#define CERT_FILE_PATH "cert_file_path.tmp" + +static void test_cert_memory_file(dap_enc_key_type_t a_key_type) +{ + uint32_t l_cert_buf_size = 0; + + dap_cert_t *l_cert = dap_cert_generate_mem("name 1", a_key_type); + dap_assert_PIF(l_cert, "Fail create cert"); + + uint8_t * l_cert_buf = dap_cert_mem_save(l_cert, &l_cert_buf_size); + dap_assert_PIF(l_cert_buf, "Fail save cert to memory"); + dap_cert_delete(l_cert); + + dap_cert_t *l_cert2 = dap_cert_mem_load(l_cert_buf, l_cert_buf_size); + dap_assert_PIF(l_cert2, "Fail read cert from memory"); + dap_cert_delete(l_cert2); + DAP_DELETE(l_cert_buf); + + dap_pass_msg("Save and load cert in memory successfully"); + + dap_cert_t *l_certf = dap_cert_generate_mem("name 2", a_key_type); + int l_res = dap_cert_file_save(l_certf, CERT_FILE_PATH); + dap_assert_PIF(!l_res, "Fail save cert to file"); + dap_cert_delete(l_certf); + + dap_cert_t *l_certf2 = dap_cert_file_load(CERT_FILE_PATH); + dap_assert_PIF(l_certf2, "Fail load cert from file"); + dap_cert_delete(l_certf2); + + // delete temp file + unlink(CERT_FILE_PATH); + + dap_pass_msg("Save and load cert in file successfully"); +} + +void init_test_case() +{ + dap_enc_key_init(); +} + +void cleanup_test_case() +{ + dap_enc_key_deinit(); +} + +void dap_crypto_cert_save_tests_run(void) +{ + dap_print_module_name("dap_cert_save"); + init_test_case(); + + test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_BLISS); + test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_TESLA); + test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_PICNIC); + test_cert_memory_file(DAP_ENC_KEY_TYPE_SIG_DILITHIUM); + + cleanup_test_case(); +} diff --git a/test/cert/dap_crypto_cert_save_tests.h b/test/cert/dap_crypto_cert_save_tests.h new file mode 100755 index 0000000..a4002ef --- /dev/null +++ b/test/cert/dap_crypto_cert_save_tests.h @@ -0,0 +1,4 @@ +#pragma once +#include "dap_test.h" + +void dap_crypto_cert_save_tests_run(void); diff --git a/test/cert/dap_sha3_tests.c b/test/cert/dap_sha3_tests.c new file mode 100644 index 0000000..7a58271 --- /dev/null +++ b/test/cert/dap_sha3_tests.c @@ -0,0 +1,211 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <memory.h> +#include <time.h> +#include <stdbool.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include <pthread.h> + +#include "dap_test.h" + +#define BUFSIZE 512 + +#ifdef _MSC_VER + #define DAP_STATIC_INLINE static __forceinline + #define DAP_INLINE __forceinline + #define DAP_ALIGNED(x) __declspec( align(x) ) +#else + #define DAP_STATIC_INLINE static __attribute__((always_inline)) inline + #define DAP_INLINE __attribute__((always_inline)) inline + #define DAP_ALIGNED(x) __attribute__ ((aligned (x))) +#endif + +uint32_t xs30_seed[4] = { 0x3D696D09, 0xCD6BEB33, 0x9D1A0022, 0x9D1B0022 }; + +static inline void zRAND_reset( void ) { + + xs30_seed[0] = 0x3D696D09; + xs30_seed[1] = 0xCD6BEB33; + xs30_seed[2] = 0x9D1A0022; + xs30_seed[3] = 0x9D1B0022; +} + +static inline uint32_t zRAND( void ) { //period 2^96-1 + + uint32_t *zseed = &xs30_seed[0]; + + uint32_t t; + + zseed[0] ^= zseed[0] << 16; + zseed[0] ^= zseed[0] >> 5; + zseed[0] ^= zseed[0] << 1; + + t = zseed[0]; + zseed[0] = zseed[1]; + zseed[1] = zseed[2]; + + zseed[2] = t ^ zseed[0] ^ zseed[1]; + + return zseed[0]; +} + +static inline uint64_t gettime64( void ) +{ + uint64_t t64; + struct timespec now; + + clock_gettime( CLOCK_MONOTONIC, &now ); + t64 = now.tv_sec; + t64 *= 1000000000; + t64 += now.tv_nsec; + + return t64; +} + +static inline double gettimefloat( void ) +{ + return (double)gettime64() / 1000000000.0; +} + +#include "keccak.h" +#include "XKCP/lib/high/Keccak/FIPS202/KeccakHash.h" +#include "fips202.h" +#include "SimpleFIPS202.h" + +#define DAP_CHAIN_HASH_FAST_SIZE 32 + +typedef union dap_chain_hash_fast{ + uint8_t raw[DAP_CHAIN_HASH_FAST_SIZE]; +} dap_chain_hash_fast_t; + +typedef enum dap_hash_type { + DAP_HASH_TYPE_KECCAK = 0, + DAP_HASH_TYPE_SLOW_0 = 1, +} dap_hash_type_t; + +static inline void dap_hash_keccak( const void * a_in, size_t a_in_size, void *a_out, size_t a_out_size ) +{ + keccak((const uint8_t*) a_in, a_in_size, (uint8_t *) a_out,(int) a_out_size ); +} + +static inline void dap_hash(const void * a_data_in, size_t a_data_in_size, + void * a_data_out, size_t a_data_out_size, + dap_hash_type_t a_type ){ + switch (a_type){ + case DAP_HASH_TYPE_KECCAK: + dap_hash_keccak(a_data_in,a_data_in_size, a_data_out,a_data_out_size); + break; +// case DAP_HASH_TYPE_SLOW_0: +// if( a_data_out_size>= dap_hash_slow_size() ){ +// dap_hash_slow(a_data_in,a_data_in_size,(char*) a_data_out); +// } +// break; + } +} + +int dap_hash_fast( const void *a_data_in, size_t a_data_in_size, dap_chain_hash_fast_t *a_hash_out ) +{ + if(!a_data_in || !a_data_in_size || !a_hash_out) + return -1; + + dap_hash( a_data_in, a_data_in_size, a_hash_out->raw, sizeof(a_hash_out->raw), + DAP_HASH_TYPE_KECCAK); + + return 1; +} + +#define DATA_SIZE 2048 + +uint8_t data[8192]; +uint8_t data2[8192]; + +Keccak_HashInstance ki0; + +#define print_hash( x ) \ + printf( " hash = " ); \ + for( int g = 0; g < 32; ++g ) \ + printf( "%02X", x[g] ); \ + printf( "\n" ); \ + +void dap_sha3_tests_run(void) +{ + dap_chain_hash_fast_t hash0; + uint64_t start; + double t; + + uint8_t hash2[32]; + + dap_print_module_name("dap_sha3_tests_run( )"); + +// printf("dap_hash_fast( ) of %u data x %u ...\n", DATA_SIZE, 65536 ); + + for (int i = 0; i < DATA_SIZE; ++ i ) { + data[i] = zRAND( ) & 255; + } + + zRAND_reset( ); + start = gettime64( ); + + for (int h = 0; h < 65536; h ++ ) { + dap_hash_fast( &data[0], DATA_SIZE, &hash0 ); + } + + t = (double)(gettime64( ) - start) / 1000000000.0; + benchmark_mgs_rate( "dap_hash_fast_sha3(monero_crypto)(2048)", 65536.0 / t ); + print_hash( hash0.raw ); + +// printf("Keccak_sha_256( ) of %u data x %u ...\n", DATA_SIZE, 65536 ); + start = gettime64( ); + + for (int h = 0; h < 65536; h ++ ) { + SHA3_256( &hash2[0], &data[0], DATA_SIZE ); + } + t = (double)(gettime64( ) - start) / 1000000000.0; + benchmark_mgs_rate( "SHA_256(XKCP)(2048)", 65536.0 / t ); + print_hash( hash2 ); + +// printf("sha3_512(dap_crypto) of %u data x %u ...\n", DATA_SIZE, 65536 ); + start = gettime64( ); + + for (int h = 0; h < 65536; h ++ ) { + sha3_256( &hash2[0], &data[0], DATA_SIZE ); + } + + t = (double)(gettime64( ) - start) / 1000000000.0; + benchmark_mgs_rate( "sha3_256(dap_crypto)(2048)", 65536.0 / t ); + + print_hash( hash2 ); + +// printf("shake256(dap_crypto) of %u data x %u ...\n", DATA_SIZE, 65536 ); + start = gettime64( ); + + for (int h = 0; h < 65536; h ++ ) { + shake256( &hash2[0], 32, &data[0], DATA_SIZE ); + } + + t = (double)(gettime64( ) - start) / 1000000000.0; + benchmark_mgs_rate( "shake256(dap_crypto)(2048)", 65536.0 / t ); + print_hash( hash2 ); + +// printf("SHAKE256 of %u data x %u ...\n", DATA_SIZE, 65536 ); + start = gettime64( ); + + for (int h = 0; h < 65536; h ++ ) { + SHAKE256( &hash2[0], 32, &data[0], DATA_SIZE ); + } + + t = (double)(gettime64( ) - start) / 1000000000.0; + benchmark_mgs_rate( "SHAKE256(XKCP)(2048)", 65536.0 / t ); + + print_hash( hash2 ); + + dap_pass_msg("dap_sha3_tests_run( )"); + + return; +} \ No newline at end of file diff --git a/test/cert/main.c b/test/cert/main.c new file mode 100755 index 0000000..0fc3c08 --- /dev/null +++ b/test/cert/main.c @@ -0,0 +1,12 @@ +#include "dap_common.h" +#include "dap_crypto_cert_save_tests.h" + +void dap_sha3_tests_run(void); + +int main(void) { + // switch off debug info from library + dap_log_level_set(L_CRITICAL); + dap_crypto_cert_save_tests_run(); + dap_sha3_tests_run(); + return 0; +} -- GitLab