Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: adds chacha20 and fast_random_context #210

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ TARGET_SOURCES(${LIBDOGECOIN_NAME} PRIVATE
src/bip44.c
src/block.c
src/buffer.c
src/chacha20.c
src/cstr.c
src/ctaes.c
src/ecc.c
Expand Down Expand Up @@ -259,6 +260,7 @@ IF(USE_TESTS)
test/bip44_tests.c
test/block_tests.c
test/buffer_tests.c
test/chacha20_tests.c
test/cstr_tests.c
test/ecc_tests.c
test/hash_tests.c
Expand Down
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ noinst_HEADERS = \
include/dogecoin/blockchain.h \
include/dogecoin/buffer.h \
include/dogecoin/byteswap.h \
include/dogecoin/chacha20.h \
include/dogecoin/chainparams.h \
include/dogecoin/common.h \
include/dogecoin/cstr.h \
Expand Down Expand Up @@ -81,6 +82,7 @@ libdogecoin_la_SOURCES = \
src/bip44.c \
src/block.c \
src/buffer.c \
src/chacha20.c \
src/chainparams.c \
src/cstr.c \
src/ctaes.c \
Expand Down Expand Up @@ -131,6 +133,7 @@ tests_SOURCES = \
test/bip44_tests.c \
test/block_tests.c \
test/buffer_tests.c \
test/chacha20_tests.c \
test/cstr_tests.c \
test/ecc_tests.c \
test/hash_tests.c \
Expand Down
52 changes: 49 additions & 3 deletions include/dogecoin/byteswap.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2014-2016 The Bitcoin Core developers
// Copyright (c) 2023 bluezr
// Copyright (c) 2023 edtubbs
// Copyright (c) 2023 The Dogecoin Foundation
// Copyright (c) 2024 bluezr
// Copyright (c) 2024 edtubbs
// Copyright (c) 2024 The Dogecoin Foundation
//
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
Expand All @@ -23,6 +23,52 @@ LIBDOGECOIN_BEGIN_DECL

#include <stdint.h>

static unsigned char bit_swap_table[256] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};

#if HAVE_DECL_BSWAP_8 == 0
DISABLE_WARNING_PUSH
DISABLE_WARNING(-Wunused-function)
LIBDOGECOIN_API static uint8_t bswap_8(uint8_t x)
{
return bit_swap_table[x];
}
DISABLE_WARNING_POP
#endif

#if defined(__APPLE__)

#if !defined(bswap_16)
Expand Down
54 changes: 54 additions & 0 deletions include/dogecoin/chacha20.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*

The MIT License (MIT)

Copyright (c) 2017 The Bitcoin Core developers
Copyright (c) 2024 bluezr
Copyright (c) 2024 The Dogecoin Foundation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef __LIBDOGECOIN_CHACHA20_H__
#define __LIBDOGECOIN_CHACHA20_H__

#include <dogecoin/dogecoin.h>

LIBDOGECOIN_BEGIN_DECL

typedef struct chacha20 {
uint32_t input[16];
void (*setkey)(struct chacha20* this, const unsigned char* key, size_t keylen);
void (*setiv)(struct chacha20* this, uint64_t iv);
void (*seek)(struct chacha20* this, uint64_t pos);
void (*output)(struct chacha20* this, unsigned char* c, size_t bytes);
} chacha20;

struct chacha20* chacha20_new();
struct chacha20* chacha20_init(const unsigned char* key, size_t keylen);
void chacha20_set_key(struct chacha20* this, const unsigned char* key, size_t keylen);
void chacha20_set_iv(struct chacha20* this, uint64_t iv);
void chacha20_seek(struct chacha20* this, uint64_t pos);
void chacha20_output(struct chacha20* this, unsigned char* c, size_t bytes);
void chacha20_free(struct chacha20* this);

LIBDOGECOIN_END_DECL

#endif // __LIBDOGECOIN_CHACHA20_H__
32 changes: 30 additions & 2 deletions include/dogecoin/common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2023 bluezr
// Copyright (c) 2023 The Dogecoin Foundation
// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2024 bluezr
// Copyright (c) 2024 The Dogecoin Foundation
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -41,6 +42,12 @@ LIBDOGECOIN_API static inline uint64_t read_le64(const unsigned char* ptr)
return le64toh(x);
}

LIBDOGECOIN_API static inline void write_le8(unsigned char* ptr, uint8_t x)
{
uint8_t v = htole8(x);
memcpy_safe(ptr, (char*)&v, 1);
}

LIBDOGECOIN_API static inline void write_le16(unsigned char* ptr, uint16_t x)
{
uint16_t v = htole16(x);
Expand Down Expand Up @@ -85,6 +92,27 @@ LIBDOGECOIN_API static inline void write_be64(unsigned char* ptr, uint64_t x)
memcpy_safe(ptr, (char*)&v, 8);
}

/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */
LIBDOGECOIN_API static inline uint64_t count_bits(uint64_t x)
{
#if HAVE_BUILTIN_CLZL
if (sizeof(unsigned long) >= sizeof(uint64_t)) {
return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0;
}
#endif
#if HAVE_BUILTIN_CLZLL
if (sizeof(unsigned long long) >= sizeof(uint64_t)) {
return x ? 8 * sizeof(unsigned long long) - __builtin_clzll(x) : 0;
}
#endif
int ret = 0;
while (x) {
x >>= 1;
++ret;
}
return ret;
}

LIBDOGECOIN_END_DECL

#endif // __LIBDOGECOIN_COMMON_H__
8 changes: 8 additions & 0 deletions include/dogecoin/portable_endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@

LIBDOGECOIN_BEGIN_DECL

# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htole8(x) (x)
# elif __BYTE_ORDER == __BIG_ENDIAN
# define htole8(x) bswap_8(x)
#else
#error UNKNOWN BYTE ORDER
#endif

#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)

#define __WINDOWS__
Expand Down
33 changes: 31 additions & 2 deletions include/dogecoin/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
The MIT License (MIT)

Copyright (c) 2015 Douglas J. Bakkum
Copyright (c) 2022 bluezr
Copyright (c) 2022 The Dogecoin Foundation
Copyright (c) 2024 bluezr
Copyright (c) 2024 The Dogecoin Foundation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -33,6 +33,35 @@

LIBDOGECOIN_BEGIN_DECL

#include <dogecoin/chacha20.h>
#include <stdint.h>

typedef struct fast_random_context {
dogecoin_bool requires_seed;
chacha20* rng;
unsigned char bytebuf[64];
int bytebuf_size;
uint64_t bitbuf;
int bitbuf_size;
void (*random_seed)(struct fast_random_context* this);
void (*fill_byte_buffer)(struct fast_random_context* this);
void (*fill_bit_buffer)(struct fast_random_context* this);
uint256* (*rand256)(struct fast_random_context* this);
uint64_t (*rand64)(struct fast_random_context* this);
uint64_t (*randbits)(struct fast_random_context* this, int bits);
uint32_t (*rand32)(struct fast_random_context* this);
dogecoin_bool (*randbool)(struct fast_random_context* this);
} fast_random_context;

struct fast_random_context* init_fast_random_context(dogecoin_bool f_deterministic, const uint256* seed);
uint256* rand256(struct fast_random_context* this);
uint64_t rand64(struct fast_random_context* this);
void free_fast_random_context(struct fast_random_context* this);

static const ssize_t NUM_OS_RANDOM_BYTES = 32;
void get_os_rand(unsigned char* ent32);
void random_sanity_check();

typedef struct dogecoin_rnd_mapper_ {
void (*dogecoin_random_init)(void);
dogecoin_bool (*dogecoin_random_bytes)(uint8_t* buf, uint32_t len, const uint8_t update_seed);
Expand Down
54 changes: 50 additions & 4 deletions include/test/utest.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*

Copyright (c) 2015 Douglas J. Bakkum
Copyright (c) 2023 bluezr
Copyright (c) 2023 The Dogecoin Foundation
Copyright (c) 2024 bluezr
Copyright (c) 2024 The Dogecoin Foundation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -125,6 +125,21 @@
} while (0); \
}

#define u_assert_uint32_not_eq(R, E) \
{ \
uint64_t r_ = (R); \
uint64_t e_ = (E); \
do { \
if (r_ == e_) { \
printf("FAILED - %s() - Line %d\n", __func__, __LINE__); \
printf("\tExpect: \t%" PRIu64 "\n", e_); \
printf("\tReceive:\t%" PRIu64 "\n", r_); \
U_TESTS_FAIL++; \
return; \
}; \
} while (0); \
}

#define u_assert_uint64_eq(R, E) \
{ \
uint64_t r_ = (R); \
Expand All @@ -140,6 +155,21 @@
} while (0); \
}

#define u_assert_uint64_not_eq(R, E) \
{ \
uint64_t r_ = (R); \
uint64_t e_ = (E); \
do { \
if (r_ == e_) { \
printf("FAILED - %s() - Line %d\n", __func__, __LINE__); \
printf("\tExpect: \t%" PRIu64 "\n", e_); \
printf("\tReceive:\t%" PRIu64 "\n", r_); \
U_TESTS_FAIL++; \
return; \
}; \
} while (0); \
}

#define u_assert_long_double_eq(R, E) \
{ \
long double r_ = (R); \
Expand All @@ -157,8 +187,8 @@

#define u_assert_double_eq(R, E) \
{ \
double r_ = (R); \
double e_ = (E); \
double r_ = (R); \
double e_ = (E); \
do { \
if (r_ != e_) { \
printf("FAILED - %s() - Line %d\n", __func__, __LINE__); \
Expand Down Expand Up @@ -246,6 +276,22 @@
} while (0); \
}

#define u_assert_mem_not_eq(R, E, L) \
{ \
const void* r_ = (R); \
const void* e_ = (E); \
size_t l_ = (L); \
do { \
if (!memcmp(r_, e_, l_)) { \
printf("FAILED - %s() - Line %d\n", __func__, __LINE__); \
printf("\tExpect: \t%s\n", utils_uint8_to_hex(e_, l_)); \
printf("\tReceive:\t%s\n", utils_uint8_to_hex(r_, l_)); \
U_TESTS_FAIL++; \
return; \
}; \
} while (0); \
}

#define u_assert_is_null(R) \
{ \
const void* r_ = (R); \
Expand Down
Loading