From 181d16156ded2fd2763d95a3878f8851477e345b Mon Sep 17 00:00:00 2001 From: rishflab Date: Tue, 20 Apr 2021 15:01:34 +1000 Subject: [PATCH] Got boost compiling --- CMakeLists.txt | 7 +- monero-adaptor/build.rs | 1 + monero-adaptor/depend/hash/crypto-ops.c | 4 +- monero-adaptor/depend/hash/hash.c | 139 +----------- .../depend/hash/include/crypto-ops.h | 13 -- monero-adaptor/depend/hash/include/hash-ops.h | 124 +++++++++++ monero-adaptor/depend/hash/include/hash.h | 13 -- monero-adaptor/depend/hash/include/int-util.h | 17 -- monero-adaptor/depend/hash/include/keccak.h | 42 ++++ monero-adaptor/depend/hash/include/warnings.h | 4 +- monero-adaptor/depend/hash/keccak.c | 203 ++++++++++++++++++ monero-adaptor/src/lib.rs | 51 +++-- 12 files changed, 421 insertions(+), 197 deletions(-) create mode 100644 monero-adaptor/depend/hash/include/hash-ops.h create mode 100644 monero-adaptor/depend/hash/include/keccak.h create mode 100644 monero-adaptor/depend/hash/keccak.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 79aff8f1..054dde1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ project(xmr_btc_swap_comit C) set(CMAKE_C_STANDARD 11) +set(BOOST_ROOT "/usr/local/Cellar/boost/1.75.0_2") +include_directories(/usr/local/Cellar/boost/1.75.0_2/include) include_directories(monero-adaptor/depend/hash) add_library(xmr_btc_swap_comit @@ -11,4 +13,7 @@ add_library(xmr_btc_swap_comit monero-adaptor/depend/hash/include/int-util.h monero-adaptor/depend/hash/crypto-ops.c monero-adaptor/depend/hash/include/crypto-ops.h - monero-adaptor/depend/hash/include/warnings.h) + monero-adaptor/depend/hash/include/keccak.h + monero-adaptor/depend/hash/include/hash-ops.h + monero-adaptor/depend/hash/keccak.c + ) diff --git a/monero-adaptor/build.rs b/monero-adaptor/build.rs index 48a62f81..3b8bffe0 100644 --- a/monero-adaptor/build.rs +++ b/monero-adaptor/build.rs @@ -11,6 +11,7 @@ fn main() { base_config.include("depend/hash/include"); base_config.file("depend/hash/hash.c"); base_config.file("depend/hash/crypto-ops.c"); + base_config.file("depend/hash/keccak.c"); base_config.compile("hash"); println!("cargo:rustc-link-lib=static=hash"); diff --git a/monero-adaptor/depend/hash/crypto-ops.c b/monero-adaptor/depend/hash/crypto-ops.c index 3836e446..e08939bc 100644 --- a/monero-adaptor/depend/hash/crypto-ops.c +++ b/monero-adaptor/depend/hash/crypto-ops.c @@ -44,6 +44,8 @@ const fe fe_fffb1; const fe fe_fffb2; const fe fe_fffb3; const fe fe_fffb4; +const ge_p3 ge_p3_identity; +const ge_p3 ge_p3_H; const fe fe_sqrtm1; const fe fe_d; @@ -2552,7 +2554,7 @@ void ge_mul8(ge_p1p1 *r, const ge_p2 *t) { ge_p2_dbl(r, &u); } -void ge_fromfe_frombytes_vartime(ge_p2 *r, const unsigned char *s) { +void ge_fromfe_frombytes_vartime(ge_p2 *r, const uint8_t *s) { fe u, v, w, x, y, z; unsigned char sign; diff --git a/monero-adaptor/depend/hash/hash.c b/monero-adaptor/depend/hash/hash.c index d90e44be..132aff5e 100644 --- a/monero-adaptor/depend/hash/hash.c +++ b/monero-adaptor/depend/hash/hash.c @@ -1,149 +1,22 @@ #include -#include -#include +#include "include/keccak.h" #include "include/hash.h" -#include -#include -#include "include/int-util.h" #include "include/crypto-ops.h" -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - -static void local_abort(const char *msg) { - fprintf(stderr, "%s\n", msg); -#ifdef NDEBUG - _exit(1); -#else - abort(); -#endif -} - -typedef uint64_t state_t[25]; - -void hash_to_scalar(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) { - keccak(in, inlen, md, mdlen); +void hash_to_scalar(const uint8_t *in, uint8_t *md) { + keccak(in, 32, md, 32); sc_reduce32(md); } // Hash a key to p3 representation -void hash_to_p3(ge_p3 *hash8_p3, const uint8_t *in, size_t inlen) { +void hash_to_p3(const uint8_t *in, ge_p3 *hash8_p3) { uint8_t md[32]; - keccak(in, 32, md, inlen); + keccak(in, 32, md, 32); ge_p2 hash_p2; - ge_fromfe_frombytes_vartime(&hash_p2, in); + ge_fromfe_frombytes_vartime(&hash_p2, md); ge_p1p1 hash8_p1p1; ge_mul8(&hash8_p1p1, &hash_p2); ge_p1p1_to_p3(hash8_p3, &hash8_p1p1); } -const uint64_t keccakf_rndc[24] = - { - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, - 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, - 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, - 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, - 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, - 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 - }; - -const int keccakf_rotc[24] = - { - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 - }; - -const int keccakf_piln[24] = - { - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 - }; - - -void keccakf(uint64_t st[25], int rounds) { - int i, j, round; - uint64_t t, bc[5]; - - for (round = 0; round < rounds; round++) { - - // Theta - for (i = 0; i < 5; i++) - bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; - - for (i = 0; i < 5; i++) { - t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); - for (j = 0; j < 25; j += 5) - st[j + i] ^= t; - } - - // Rho Pi - t = st[1]; - for (i = 0; i < 24; i++) { - j = keccakf_piln[i]; - bc[0] = st[j]; - st[j] = ROTL64(t, keccakf_rotc[i]); - t = bc[0]; - } - - // Chi - for (j = 0; j < 25; j += 5) { - for (i = 0; i < 5; i++) - bc[i] = st[j + i]; - for (i = 0; i < 5; i++) - st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; - } - - // Iota - st[0] ^= keccakf_rndc[round]; - } -} - -void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) { - state_t st; - uint8_t temp[144]; - size_t i, rsiz, rsizw; - - static_assert(HASH_DATA_AREA <= sizeof(temp), "Bad keccak preconditions"); - if (mdlen <= 0 || (mdlen > 100 && sizeof(st) != (size_t) mdlen)) { - local_abort("Bad keccak use"); - } - - rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; - rsizw = rsiz / 8; - - memset(st, 0, sizeof(st)); - - for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { - for (i = 0; i < rsizw; i++) { - uint64_t ina; - memcpy(&ina, in + i * 8, 8); - st[i] ^= swap64le(ina); - } - keccakf(st, KECCAK_ROUNDS); - } - - // last block and padding - if (inlen + 1 >= sizeof(temp) || inlen > rsiz || rsiz - inlen + inlen + 1 >= sizeof(temp) || rsiz == 0 || rsiz - 1 >= sizeof(temp) || rsizw * 8 > sizeof(temp)) { - local_abort("Bad keccak use"); - } - - if (inlen > 0) - memcpy(temp, in, inlen); - temp[inlen++] = 1; - memset(temp + inlen, 0, rsiz - inlen); - temp[rsiz - 1] |= 0x80; - - for (i = 0; i < rsizw; i++) - st[i] ^= swap64le(((uint64_t *) temp)[i]); - - keccakf(st, KECCAK_ROUNDS); - - if (((size_t) mdlen % sizeof(uint64_t)) != 0) { - local_abort("Bad keccak use"); - } - memcpy_swap64le(md, st, mdlen / sizeof(uint64_t)); -} \ No newline at end of file diff --git a/monero-adaptor/depend/hash/include/crypto-ops.h b/monero-adaptor/depend/hash/include/crypto-ops.h index 02eba493..ec17d087 100644 --- a/monero-adaptor/depend/hash/include/crypto-ops.h +++ b/monero-adaptor/depend/hash/include/crypto-ops.h @@ -77,9 +77,7 @@ void ge_add(ge_p1p1 *, const ge_p3 *, const ge_cached *); typedef ge_cached ge_dsmp[8]; extern const ge_precomp ge_Bi[8]; - void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s); - void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *); void ge_triple_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const unsigned char *, const ge_dsmp, @@ -106,7 +104,6 @@ void ge_p2_dbl(ge_p1p1 *, const ge_p2 *); /* From ge_p3_to_cached.c */ extern const fe fe_d2; - void ge_p3_to_cached(ge_cached *, const ge_p3 *); /* From ge_p3_to_p2.c */ @@ -120,7 +117,6 @@ void ge_p3_tobytes(unsigned char *, const ge_p3 *); /* From ge_scalarmult_base.c */ extern const ge_precomp ge_base[32][8]; - void ge_scalarmult_base(ge_p3 *, const unsigned char *); /* From ge_tobytes.c */ @@ -151,9 +147,6 @@ void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, co void ge_mul8(ge_p1p1 *, const ge_p2 *); -extern const ge_p3 ge_p3_identity; -extern const ge_p3 ge_p3_H; - void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); void sc_0(unsigned char *); @@ -171,20 +164,14 @@ void sc_mul(unsigned char *, const unsigned char *, const unsigned char *); void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); int sc_check(const unsigned char *); - int sc_isnonzero(const unsigned char *); /* Doesn't normalize */ // internal uint64_t load_3(const unsigned char *in); - uint64_t load_4(const unsigned char *in); - void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); - void fe_add(fe h, const fe f, const fe g); - void fe_tobytes(unsigned char *, const fe); - void fe_invert(fe out, const fe z); int ge_p3_is_point_at_infinity(const ge_p3 *p); diff --git a/monero-adaptor/depend/hash/include/hash-ops.h b/monero-adaptor/depend/hash/include/hash-ops.h new file mode 100644 index 00000000..6b65c2a1 --- /dev/null +++ b/monero-adaptor/depend/hash/include/hash-ops.h @@ -0,0 +1,124 @@ +// Copyright (c) 2014-2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +#if !defined(__cplusplus) + +#include +#include +#include +#include + +#include "int-util.h" +#include "warnings.h" + +static inline void *padd(void *p, size_t i) { + return (char *) p + i; +} + +static inline const void *cpadd(const void *p, size_t i) { + return (const char *) p + i; +} + +PUSH_WARNINGS +DISABLE_VS_WARNINGS(4267) +static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t must be 4 or 8 bytes long"); + +static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length) { + if (sizeof(size_t) == 4) { + *(uint32_t *) padd(buffer, bufsize - 4) = swap32be(length); + } else { + *(uint64_t *) padd(buffer, bufsize - 8) = swap64be(length); + } +} + +POP_WARNINGS + +#pragma pack(push, 1) +union hash_state { + uint8_t b[200]; + uint64_t w[25]; +}; +#pragma pack(pop) +static_assert(sizeof(union hash_state) == 200, "Invalid structure size"); + +void hash_permutation(union hash_state *state); + +void hash_process(union hash_state *state, const uint8_t *buf, size_t count); + +#endif + +enum { + HASH_SIZE = 32, + HASH_DATA_AREA = 136 +}; + +void cn_fast_hash(const void *data, size_t length, char *hash); + +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); + +void hash_extra_blake(const void *data, size_t length, char *hash); + +void hash_extra_groestl(const void *data, size_t length, char *hash); + +void hash_extra_jh(const void *data, size_t length, char *hash); + +void hash_extra_skein(const void *data, size_t length, char *hash); + +void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash); + +bool tree_path(size_t count, size_t idx, uint32_t *path); + +bool +tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash, char (*branch)[HASH_SIZE], size_t *depth, + uint32_t *path); + +bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, + char root[HASH_SIZE]); + +bool +is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, + uint32_t path); + +#define RX_BLOCK_VERSION 12 + +void rx_slow_hash_allocate_state(void); + +void rx_slow_hash_free_state(void); + +uint64_t rx_seedheight(const uint64_t height); + +void rx_seedheights(const uint64_t height, uint64_t *seed_height, uint64_t *next_height); + +void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, + size_t length, char *hash, int miners, int is_alt); + +void rx_reorg(const uint64_t split_height); diff --git a/monero-adaptor/depend/hash/include/hash.h b/monero-adaptor/depend/hash/include/hash.h index c6d42810..1cb58fae 100644 --- a/monero-adaptor/depend/hash/include/hash.h +++ b/monero-adaptor/depend/hash/include/hash.h @@ -8,17 +8,4 @@ #ifndef XMR_BTC_SWAP_COMIT_HASH_H #define XMR_BTC_SWAP_COMIT_HASH_H -#ifndef KECCAK_ROUNDS -#define KECCAK_ROUNDS 24 -#endif - -enum { - HASH_SIZE = 32, - HASH_DATA_AREA = 136 -}; - - -void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen); -void sc_reduce32(unsigned char *); - #endif //XMR_BTC_SWAP_COMIT_HASH_H diff --git a/monero-adaptor/depend/hash/include/int-util.h b/monero-adaptor/depend/hash/include/int-util.h index 92e2ccf7..7239c80c 100644 --- a/monero-adaptor/depend/hash/include/int-util.h +++ b/monero-adaptor/depend/hash/include/int-util.h @@ -36,9 +36,7 @@ #include #ifndef _MSC_VER - #include - #endif #if defined(__ANDROID__) @@ -172,41 +170,33 @@ static inline void sub64clamp(uint64_t *value, uint64_t sub) { (((uint64_t) (x) & 0xff00000000000000) >> 56)) static inline uint16_t ident16(uint16_t x) { return x; } - static inline uint32_t ident32(uint32_t x) { return x; } - static inline uint64_t ident64(uint64_t x) { return x; } #ifndef __OpenBSD__ # if defined(__ANDROID__) && defined(__swap16) && !defined(swap16) # define swap16 __swap16 # elif !defined(swap16) - static inline uint16_t swap16(uint16_t x) { return ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8); } - # endif # if defined(__ANDROID__) && defined(__swap32) && !defined(swap32) # define swap32 __swap32 # elif !defined(swap32) - static inline uint32_t swap32(uint32_t x) { x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); return (x << 16) | (x >> 16); } - # endif # if defined(__ANDROID__) && defined(__swap64) && !defined(swap64) # define swap64 __swap64 # elif !defined(swap64) - static inline uint64_t swap64(uint64_t x) { x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); return (x << 32) | (x >> 32); } - # endif #endif /* __OpenBSD__ */ @@ -217,7 +207,6 @@ static inline uint64_t swap64(uint64_t x) { #endif static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) {} - #undef UNUSED static inline void mem_inplace_swap16(void *mem, size_t n) { @@ -226,14 +215,12 @@ static inline void mem_inplace_swap16(void *mem, size_t n) { ((uint16_t *) mem)[i] = swap16(((const uint16_t *) mem)[i]); } } - static inline void mem_inplace_swap32(void *mem, size_t n) { size_t i; for (i = 0; i < n; i++) { ((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]); } } - static inline void mem_inplace_swap64(void *mem, size_t n) { size_t i; for (i = 0; i < n; i++) { @@ -244,11 +231,9 @@ static inline void mem_inplace_swap64(void *mem, size_t n) { static inline void memcpy_ident16(void *dst, const void *src, size_t n) { memcpy(dst, src, 2 * n); } - static inline void memcpy_ident32(void *dst, const void *src, size_t n) { memcpy(dst, src, 4 * n); } - static inline void memcpy_ident64(void *dst, const void *src, size_t n) { memcpy(dst, src, 8 * n); } @@ -259,14 +244,12 @@ static inline void memcpy_swap16(void *dst, const void *src, size_t n) { ((uint16_t *) dst)[i] = swap16(((const uint16_t *) src)[i]); } } - static inline void memcpy_swap32(void *dst, const void *src, size_t n) { size_t i; for (i = 0; i < n; i++) { ((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]); } } - static inline void memcpy_swap64(void *dst, const void *src, size_t n) { size_t i; for (i = 0; i < n; i++) { diff --git a/monero-adaptor/depend/hash/include/keccak.h b/monero-adaptor/depend/hash/include/keccak.h new file mode 100644 index 00000000..dddc2f57 --- /dev/null +++ b/monero-adaptor/depend/hash/include/keccak.h @@ -0,0 +1,42 @@ +// keccak.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef KECCAK_H +#define KECCAK_H + +#include +#include + +#ifndef KECCAK_ROUNDS +#define KECCAK_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// SHA3 Algorithm context. +typedef struct KECCAK_CTX { + // 1600 bits algorithm hashing state + uint64_t hash[25]; + // 1088-bit buffer for leftovers, block size = 136 B for 256-bit keccak + uint64_t message[17]; + // count of bytes in the message[] buffer + size_t rest; +} KECCAK_CTX; + +// compute a keccak hash (md) of given byte length from "in" +void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen); + +// update the state +void keccakf(uint64_t st[25], int norounds); + +void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md); + +void keccak_init(KECCAK_CTX *ctx); + +void keccak_update(KECCAK_CTX *ctx, const uint8_t *in, size_t inlen); + +void keccak_finish(KECCAK_CTX *ctx, uint8_t *md); + +#endif diff --git a/monero-adaptor/depend/hash/include/warnings.h b/monero-adaptor/depend/hash/include/warnings.h index e1ff2946..df5c7d1d 100644 --- a/monero-adaptor/depend/hash/include/warnings.h +++ b/monero-adaptor/depend/hash/include/warnings.h @@ -11,7 +11,7 @@ #else -//#include +#include #define PUSH_WARNINGS _Pragma("GCC diagnostic push") #define POP_WARNINGS _Pragma("GCC diagnostic pop") @@ -25,6 +25,6 @@ #define DISABLE_CLANG_WARNING(w) #endif -//#define DISABLE_GCC_AND_CLANG_WARNING(w) _Pragma(BOOST_PP_STRINGIZE(GCC diagnostic ignored BOOST_PP_STRINGIZE(-W##w))) +#define DISABLE_GCC_AND_CLANG_WARNING(w) _Pragma(BOOST_PP_STRINGIZE(GCC diagnostic ignored BOOST_PP_STRINGIZE(-W##w))) #endif diff --git a/monero-adaptor/depend/hash/keccak.c b/monero-adaptor/depend/hash/keccak.c new file mode 100644 index 00000000..35b487d3 --- /dev/null +++ b/monero-adaptor/depend/hash/keccak.c @@ -0,0 +1,203 @@ +// keccak.c +// 19-Nov-11 Markku-Juhani O. Saarinen +// A baseline Keccak (3rd round) implementation. + +#include +#include +#include +#include "include/int-util.h" +#include "include/hash-ops.h" +#include "include/keccak.h" + +static void local_abort(const char *msg) { + fprintf(stderr, "%s\n", msg); +#ifdef NDEBUG + _exit(1); +#else + abort(); +#endif +} + +const uint64_t keccakf_rndc[24] = + { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 + }; + +const int keccakf_rotc[24] = + { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + }; + +const int keccakf_piln[24] = + { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + }; + +// update the state with given number of rounds + +void keccakf(uint64_t st[25], int rounds) { + int i, j, round; + uint64_t t, bc[5]; + + for (round = 0; round < rounds; round++) { + + // Theta + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + // Rho Pi + t = st[1]; + for (i = 0; i < 24; i++) { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + // Iota + st[0] ^= keccakf_rndc[round]; + } +} + +// compute a keccak hash (md) of given byte length from "in" +typedef uint64_t state_t[25]; + +void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) { + state_t st; + uint8_t temp[144]; + size_t i, rsiz, rsizw; + + static_assert(HASH_DATA_AREA <= sizeof(temp), "Bad keccak preconditions"); + if (mdlen <= 0 || (mdlen > 100 && sizeof(st) != (size_t) mdlen)) { + local_abort("Bad keccak use"); + } + + rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; + rsizw = rsiz / 8; + + memset(st, 0, sizeof(st)); + + for (; inlen >= rsiz; inlen -= rsiz, in += rsiz) { + for (i = 0; i < rsizw; i++) { + uint64_t ina; + memcpy(&ina, in + i * 8, 8); + st[i] ^= swap64le(ina); + } + keccakf(st, KECCAK_ROUNDS); + } + + // last block and padding + if (inlen + 1 >= sizeof(temp) || inlen > rsiz || rsiz - inlen + inlen + 1 >= sizeof(temp) || rsiz == 0 || + rsiz - 1 >= sizeof(temp) || rsizw * 8 > sizeof(temp)) { + local_abort("Bad keccak use"); + } + + if (inlen > 0) + memcpy(temp, in, inlen); + temp[inlen++] = 1; + memset(temp + inlen, 0, rsiz - inlen); + temp[rsiz - 1] |= 0x80; + + for (i = 0; i < rsizw; i++) + st[i] ^= swap64le(((uint64_t *) temp)[i]); + + keccakf(st, KECCAK_ROUNDS); + + if (((size_t) mdlen % sizeof(uint64_t)) != 0) { + local_abort("Bad keccak use"); + } + memcpy_swap64le(md, st, mdlen / sizeof(uint64_t)); +} + +void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md) { + keccak(in, inlen, md, sizeof(state_t)); +} + +#define KECCAK_FINALIZED 0x80000000 +#define KECCAK_BLOCKLEN 136 +#define KECCAK_WORDS 17 +#define KECCAK_DIGESTSIZE 32 +#define KECCAK_PROCESS_BLOCK(st, block) { \ + for (int i_ = 0; i_ < KECCAK_WORDS; i_++){ \ + ((st))[i_] ^= swap64le(((block))[i_]); \ + }; \ + keccakf(st, KECCAK_ROUNDS); } + + +void keccak_init(KECCAK_CTX *ctx) { + memset(ctx, 0, sizeof(KECCAK_CTX)); +} + +void keccak_update(KECCAK_CTX *ctx, const uint8_t *in, size_t inlen) { + if (ctx->rest & KECCAK_FINALIZED) { + local_abort("Bad keccak use"); + } + + const size_t idx = ctx->rest; + ctx->rest = (ctx->rest + inlen) % KECCAK_BLOCKLEN; + + // fill partial block + if (idx) { + size_t left = KECCAK_BLOCKLEN - idx; + memcpy((char *) ctx->message + idx, in, (inlen < left ? inlen : left)); + if (inlen < left) return; + + KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message); + + in += left; + inlen -= left; + } + + while (inlen >= KECCAK_BLOCKLEN) { + memcpy(ctx->message, in, KECCAK_BLOCKLEN); + + KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message); + in += KECCAK_BLOCKLEN; + inlen -= KECCAK_BLOCKLEN; + } + if (inlen) { + memcpy(ctx->message, in, inlen); + } +} + +void keccak_finish(KECCAK_CTX *ctx, uint8_t *md) { + if (!(ctx->rest & KECCAK_FINALIZED)) { + // clear the rest of the data queue + memset((char *) ctx->message + ctx->rest, 0, KECCAK_BLOCKLEN - ctx->rest); + ((char *) ctx->message)[ctx->rest] |= 0x01; + ((char *) ctx->message)[KECCAK_BLOCKLEN - 1] |= 0x80; + + // process final block + KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message); + ctx->rest = KECCAK_FINALIZED; // mark context as finalized + } + + static_assert(KECCAK_BLOCKLEN > KECCAK_DIGESTSIZE, ""); + static_assert(KECCAK_DIGESTSIZE % sizeof(uint64_t) == 0, ""); + if (md) { + memcpy_swap64le(md, ctx->hash, KECCAK_DIGESTSIZE / sizeof(uint64_t)); + } +} diff --git a/monero-adaptor/src/lib.rs b/monero-adaptor/src/lib.rs index 30c0ce1e..e81eaa64 100644 --- a/monero-adaptor/src/lib.rs +++ b/monero-adaptor/src/lib.rs @@ -5,8 +5,9 @@ // include!(concat!(env!("OUT_DIR"), "/bindings.rs")); extern "C" { - fn hash_to_scalar(hash: *const u8, hash_len: usize, scalar: *mut u8, scalar_len: usize); - fn hash_to_p3(hash8_p3: *mut ge_p3, hash: *const u8, hash_len: usize); + fn hash_to_scalar(hash: *const u8, scalar: *mut u8); + fn hash_to_p3(hash: *const u8, p3: *mut ge_p3); + fn ge_p3_tobytes(bytes: *mut u8, hash8_p3: *const ge_p3); } use anyhow::{bail, Result}; @@ -25,10 +26,10 @@ const DOMAIN_TAG: &str = "CSLAG_c"; #[repr(C)] #[derive(Debug)] struct ge_p3 { - X: [u32; 10], - Y: [u32; 10], - Z: [u32; 10], - T: [u32; 10], + X: [i32; 10], + Y: [i32; 10], + Z: [i32; 10], + T: [i32; 10], } fn challenge( @@ -708,6 +709,7 @@ mod tests { #[cfg(test)] mod tests2 { use super::*; + use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint}; #[test] fn test_hash_to_scalar() { @@ -716,14 +718,7 @@ mod tests2 { let input = "0b6a0ae839214674e9b275aa1986c6352ec7ec6c4ae583ab5a62b947a9dee972"; let decoded_input = hex::decode(input).unwrap(); - unsafe { - hash_to_scalar( - decoded_input.as_ptr() as *const u8, - 32, - &mut scalar as *mut u8, - 32, - ) - }; + unsafe { hash_to_scalar(decoded_input.as_ptr() as *const u8, &mut scalar as *mut u8) }; let scalar = Scalar::from_bytes_mod_order(scalar); let scalar_hex = hex::encode(scalar.as_bytes()); @@ -736,7 +731,12 @@ mod tests2 { #[test] fn test_hash_to_p3() { - let input = "0b6a0ae839214674e9b275aa1986c6352ec7ec6c4ae583ab5a62b947a9dee972"; + // not zero assertion fails + // let input = + // "83efb774657700e37291f4b8dd10c839d1c739fd135c07a2fd7382334dafdd6a"; + // let decoded_input = hex::decode(input).unwrap(); + + let input = "e4bfca0ffc308fc7c344654307a32ab3008bcf5070523133093d4387341ce4d9"; let decoded_input = hex::decode(input).unwrap(); let mut p3 = ge_p3 { @@ -746,8 +746,25 @@ mod tests2 { T: [0; 10], }; - unsafe { hash_to_p3(&mut p3, decoded_input.as_ptr() as *const u8, 32) }; + let mut compressed = [0u8; 32]; - dbg!(p3); + unsafe { + hash_to_p3(decoded_input.as_ptr() as *const u8, &mut p3); + + dbg!(&p3); + // dbg!(&compressed); + // ge_p3_tobytes(&mut compressed as *mut u8, &p3); + }; + + // let actual = CompressedEdwardsY::from_slice(&compressed[..]); + // + // let decoded = hex::decode( + // " + // 2789ecbaf36e4fcb41c6157228001538b40ca379464b718d830c58caae7ea4ca", + // ) + // .unwrap(); + // let expected = CompressedEdwardsY::from_slice(decoded.as_slice()); + // + // assert_eq!(expected, actual); } }