diff options
author | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-03-03 22:07:58 +0000 |
---|---|---|
committer | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-03-03 22:07:58 +0000 |
commit | 296ae46ed8f8f6e5f986f978febad302e3df231a (patch) | |
tree | 1629164454a239308f33c9e12afb22e7f3cd8eeb /src/crypto/tree-hash.c | |
parent | changed name (diff) | |
download | monero-296ae46ed8f8f6e5f986f978febad302e3df231a.tar.xz |
moved all stuff to github
Diffstat (limited to 'src/crypto/tree-hash.c')
-rw-r--r-- | src/crypto/tree-hash.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/crypto/tree-hash.c b/src/crypto/tree-hash.c new file mode 100644 index 000000000..a2b0eeaa5 --- /dev/null +++ b/src/crypto/tree-hash.c @@ -0,0 +1,40 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <alloca.h> +#include <assert.h> +#include <stddef.h> +#include <string.h> + +#include "hash-ops.h" + +void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) { + assert(count > 0); + if (count == 1) { + memcpy(root_hash, hashes, HASH_SIZE); + } else if (count == 2) { + cn_fast_hash(hashes, 2 * HASH_SIZE, root_hash); + } else { + size_t i, j; + size_t cnt = count - 1; + char (*ints)[HASH_SIZE]; + for (i = 1; i < sizeof(size_t); i <<= 1) { + cnt |= cnt >> i; + } + cnt &= ~(cnt >> 1); + ints = alloca(cnt * HASH_SIZE); + memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE); + for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) { + cn_fast_hash(hashes[i], 64, ints[j]); + } + assert(i == count); + while (cnt > 2) { + cnt >>= 1; + for (i = 0, j = 0; j < cnt; i += 2, ++j) { + cn_fast_hash(ints[i], 64, ints[j]); + } + } + cn_fast_hash(ints[0], 64, root_hash); + } +} |