diff --git a/cnutil/CMakeLists.txt b/cnutil/CMakeLists.txt index 6d97dc3..ad3791e 100644 --- a/cnutil/CMakeLists.txt +++ b/cnutil/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories("src/external/easylogging++") include_directories("src/external/unbound") # Build library -add_library(${CXXLIB} SHARED src/main.cc src/cryptonote_basic/cryptonote_format_utils.cpp +add_library(${CXXLIB} SHARED src/cnutil.cpp src/cryptonote_basic/cryptonote_format_utils.cpp src/crypto/tree-hash.c src/crypto/crypto.cpp src/crypto/crypto-ops.c src/crypto/crypto-ops-data.c src/crypto/hash.c src/crypto/slow-hash.c src/crypto/oaes_lib.c src/crypto/aesb.c diff --git a/cnutil/cnutil.go b/cnutil/cnutil.go index 6326954..ab3d819 100644 --- a/cnutil/cnutil.go +++ b/cnutil/cnutil.go @@ -3,6 +3,7 @@ package cnutil // #cgo CFLAGS: -std=c11 -D_GNU_SOURCE // #cgo LDFLAGS: -L${SRCDIR} -Wl,-rpath=\$ORIGIN/cnutil -lcnutil -Wl,-rpath ${SRCDIR} -lstdc++ // #include +// #include // #include "src/cnutil.h" import "C" import "unsafe" @@ -18,6 +19,18 @@ func ConvertBlob(blob []byte) []byte { return output } +func GenerateAuxBlob(blob []byte) []byte { + input := (*C.char)(unsafe.Pointer(&blob[0])) + + size := (C.uint32_t)(len(blob)) + var out *C.char + blobSize := C.convert_blob_to_auxpow_blob(input, size, &out) + defer C.free(unsafe.Pointer(out)) + output := make([]byte, blobSize) + C.memcpy(unsafe.Pointer(&output[0]), unsafe.Pointer(out), (C.size_t)(blobSize)) + return output +} + func ValidateAddress(addr string) bool { input := C.CString(addr) defer C.free(unsafe.Pointer(input)) diff --git a/cnutil/src/cnutil.cpp b/cnutil/src/cnutil.cpp index 462d2db..e7a04fe 100644 --- a/cnutil/src/cnutil.cpp +++ b/cnutil/src/cnutil.cpp @@ -1,11 +1,193 @@ +#include #include #include +#include +#include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" +#include "cryptonote_basic/blobdatatype.h" +#include "crypto/crypto.h" +#include "crypto/hash.h" #include "common/base58.h" +#include "serialization/binary_utils.h" using namespace cryptonote; -extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) { +#define HASH_SIZE 32 + +/*******************************************************************************************/ +/* Helper functions for merged mining - for merkle tree branch compuation. */ + +static size_t tree_depth(size_t count) +{ + size_t i; + size_t depth = 0; + assert(count > 0); + for (i = sizeof(size_t) << 2; i > 0; i >>= 1) + { + if (count >> i > 0) + { + count >>= i; + depth += i; + } + } + return depth; +} + +static void tree_branch(const char (*hashes)[HASH_SIZE], size_t count, char (*branch)[HASH_SIZE]) +{ + size_t i, j; + size_t cnt = 1; + size_t depth = 0; + char (*ints)[HASH_SIZE]; + assert(count > 0); + for (i = sizeof(size_t) << 2; i > 0; i >>= 1) + { + if (cnt << i <= count) + { + cnt <<= i; + depth += i; + } + } + assert(cnt == 1ULL << depth); + assert(depth == tree_depth(count)); + ints = reinterpret_cast(alloca((cnt - 1) * HASH_SIZE)); + memcpy(ints, hashes + 1, (2 * cnt - count - 1) * HASH_SIZE); + for (i = 2 * cnt - count, j = 2 * cnt - count - 1; j < cnt - 1; i += 2, ++j) + { + crypto::cn_fast_hash(hashes[i], 2 * HASH_SIZE, ints[j]); + } + assert(i == count); + while (depth > 0) + { + assert(cnt == 1ULL << depth); + cnt >>= 1; + --depth; + memcpy(branch[depth], ints[0], HASH_SIZE); + for (i = 1, j = 0; j < cnt - 1; i += 2, ++j) + { + crypto::cn_fast_hash(ints[i], 2 * HASH_SIZE, ints[j]); + } + } +} + +static void tree_hash_from_branch(const char (*branch)[HASH_SIZE], size_t depth, const char* leaf, const void* path, char* root_hash) +{ + if (depth == 0) + { + memcpy(root_hash, leaf, HASH_SIZE); + } + else + { + char buffer[2][HASH_SIZE]; + int from_leaf = 1; + char *leaf_path, *branch_path; + while (depth > 0) + { + --depth; + if (path && (((const char*) path)[depth >> 3] & (1 << (depth & 7))) != 0) + { + leaf_path = buffer[1]; + branch_path = buffer[0]; + } + else + { + leaf_path = buffer[0]; + branch_path = buffer[1]; + } + if (from_leaf) + { + memcpy(leaf_path, leaf, HASH_SIZE); + from_leaf = 0; + } + else + { + crypto::cn_fast_hash(buffer, 2 * HASH_SIZE, leaf_path); + } + memcpy(branch_path, branch[depth], HASH_SIZE); + } + crypto::cn_fast_hash(buffer, 2 * HASH_SIZE, root_hash); + } +} + + +#if 0 +class CAuxPow +{ +public: + // Cryptnote coinbase tx, which contains the block hash of kevacoin block. + cryptonote::transaction miner_tx; + + // Merkle branch is used to establish that miner_tx is part of the + // merkel tree whose root is merkle_root. + std::vector merkle_branch; + + // load + template