├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── post.js ├── src ├── common │ ├── int-util.h │ └── pod-class.h ├── contrib │ └── epee │ │ └── include │ │ ├── hex.h │ │ └── span.h ├── crypto │ ├── CryptonightR_JIT.c │ ├── CryptonightR_JIT.h │ ├── CryptonightR_template.S │ ├── CryptonightR_template.h │ ├── aesb.c │ ├── blake256.c │ ├── blake256.h │ ├── chacha.c │ ├── chacha.h │ ├── crypto-ops-data.c │ ├── crypto-ops.c │ ├── crypto-ops.h │ ├── generic-ops.h │ ├── groestl.c │ ├── groestl.h │ ├── groestl_tables.h │ ├── hash-extra-blake.c │ ├── hash-extra-groestl.c │ ├── hash-extra-jh.c │ ├── hash-extra-skein.c │ ├── hash-ops.h │ ├── hash.c │ ├── hash.h │ ├── initializer.h │ ├── jh.c │ ├── jh.h │ ├── keccak.c │ ├── keccak.h │ ├── oaes_config.h │ ├── oaes_lib.c │ ├── oaes_lib.h │ ├── random.c │ ├── random.h │ ├── skein.c │ ├── skein.h │ ├── skein_port.h │ ├── slow-hash.c │ ├── tree-hash.c │ ├── variant2_int_sqrt.h │ ├── variant4_random_math.h │ └── warnings.h ├── main.cpp └── main.h └── template.html /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, Jethro Grassie 2 | Copyright (c) 2014-2018, The Monero Project 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its contributors 17 | may be used to endorse or promote products derived from this software without 18 | specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | Parts of the project are originally copyright (c) 2012-2013 The Cryptonote 32 | developers 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = miner 2 | TYPE = debug 3 | 4 | DIRS = src \ 5 | src/crypto \ 6 | src/common \ 7 | src/contrib/epee/include 8 | 9 | CPPDEFS = 10 | CCPARAM = -s WASM=1 11 | CXXFLAGS = -std=c++11 12 | 13 | ifeq ($(TYPE),debug) 14 | CCPARAM += -g 15 | CPPDEFS += DEBUG 16 | endif 17 | 18 | ifeq ($(TYPE), release) 19 | CCPARAM += -O2 20 | endif 21 | 22 | LDPARAM += $(LDFLAGS) -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' --proxy-to-worker --shell-file template.html --post-js post.js 23 | 24 | INCPATH := $(DIRS) /opt/local/include 25 | 26 | LIBPATH := /opt/local/lib/ /usr/local/lib 27 | 28 | EXTRA_FILES = Makefile 29 | 30 | C++ = emcc 31 | 32 | STORE = build/$(TYPE) 33 | SOURCE := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.cpp)) 34 | CSOURCE := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.c)) 35 | HEADERS := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.h)) 36 | OBJECTS := $(addprefix $(STORE)/, $(SOURCE:.cpp=.bc)) 37 | COBJECTS := $(addprefix $(STORE)/, $(CSOURCE:.c=.bc)) 38 | 39 | .PHONY: clean backup dirs 40 | 41 | $(TARGET): dirs $(OBJECTS) $(COBJECTS) 42 | @echo Linking $(OBJECTS)... 43 | $(C++) $(CCPARAM) $(OBJECTS) $(COBJECTS) $(LDPARAM) -o $(STORE)/$(TARGET).html 44 | 45 | 46 | $(STORE)/%.bc: %.cpp 47 | @echo Creating object file for $*... 48 | $(C++) $(CCPARAM) $(CXXFLAGS) $(foreach INC,$(INCPATH),-I$(INC)) \ 49 | $(foreach CPPDEF,$(CPPDEFS),-D$(CPPDEF)) $< -o $@ 50 | 51 | $(STORE)/%.bc: %.c 52 | @echo Creating object file for $*... 53 | $(C++) $(CCPARAM) $(foreach INC,$(INCPATH),-I$(INC)) \ 54 | $(foreach CPPDEF,$(CPPDEFS),-D$(CPPDEF)) $< -o $@ 55 | 56 | %.h: ; 57 | 58 | clean: 59 | @echo Making clean. 60 | @-rm -rf $(STORE) 61 | 62 | backup: 63 | @-if [ ! -e build/backup ]; then mkdir -p build/backup; fi; 64 | @zip build/backup/backup_`date +%d-%m-%y_%H.%M`.zip $(SOURCE) $(HEADERS) $(EXTRA_FILES) 65 | 66 | dirs: 67 | @-if [ ! -e $(STORE) ]; then mkdir -p $(STORE); fi; 68 | @-$(foreach DIR,$(DIRS), if [ ! -e $(STORE)/$(DIR) ]; then mkdir -p $(STORE)/$(DIR); fi; ) 69 | 70 | run: $(TARGET) 71 | emrun --no_browser --no_emrun_detect --port 8080 $(STORE)/$(TARGET).html 72 | 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Monero WebAssembly based miner 2 | 3 | The core aim of this project is to provide a completely open source, browser based, Monero miner. It has a companion project, [my fork](https://github.com/jtgrassie/xmr-node-proxy) of Snipa's **xmr-node-proxy** which adds a WebSocket based branch for allowing this miner to connect through to various mining pools. 4 | 5 | Whilst browser mining can be used maliciously, there are many non-malicious use-cases, such as charitable donations (the very reason this project started). A defining aspect to whether web mining is done in a fair way is that of user consent. My recommendation is therefore to ensure the end-user knows the page will be mining and offer them controls such as starting and stopping, and options for how much processing time the mining should use. 6 | 7 | 8 | ## Compiling 9 | 10 | To compile, you first need a working setup of the WebAssembly toolchain. Follow instructions at [webassembly.org](http://webassembly.org/getting-started/developers-guide/). 11 | 12 | Then simply run `make` in the root directory of this repository. This will output to the build/debug folder. 13 | 14 | For an optimized release version, just run `make TYPE=release`. 15 | 16 | To test locally, just tack `run` onto the end of the above commands, which will start a local server for testing (required to load the WebAssembly module). 17 | 18 | ## License 19 | 20 | Please see [LICENSE](LICENSE) 21 | 22 | 23 | -------------------------------------------------------------------------------- /post.js: -------------------------------------------------------------------------------- 1 | var login = { 2 | "method":"login", 3 | "params": { 4 | "login":"wallet_address", 5 | "pass":"x", 6 | "rigid":"", 7 | "agent":"xmr-wasm/0.1" 8 | }, 9 | "id":1 10 | }; 11 | var login_id; 12 | var socket; 13 | var miner_percentage = 1; 14 | var worked_ms = 0; 15 | var loaded_at = Date.now(); 16 | 17 | var cn_hash = Module.cwrap('hash', 'number', ['array', 'number', 'number', 'number', 'number']); 18 | var cn_allocate_state = Module.cwrap('allocate_state'); 19 | var cn_free_state = Module.cwrap('free_state'); 20 | 21 | function init_socket() { 22 | var proto = 'ws' + (location.protocol.substr(-2,1) == 's' ? 's://' : '://'); 23 | var port = ':8081'; 24 | socket = new WebSocket(proto + location.hostname + port); 25 | socket.addEventListener('open', function(event) { 26 | console.log('WebSocket opened: ' + event); 27 | socket.send(JSON.stringify(login)); 28 | }); 29 | socket.addEventListener('message', function(event) { 30 | console.log('WebSocket message: ' + event.data); 31 | var data = JSON.parse(event.data); 32 | if(data.error) { 33 | console.log('Error: ' + data.error.code + ' ' + data.error.message); 34 | return; 35 | } 36 | if(data.result && data.result.status) { 37 | console.log('Result status: ' + data.result.status); 38 | } 39 | if(data.result && data.result.job) { 40 | login_id = data.result.id; 41 | do_work(data.result.job, socket); 42 | } else if(data.method && data.method == 'job' && login_id != null) { 43 | do_work(data.params, socket); 44 | } 45 | }); 46 | socket.addEventListener('error', function(event) { 47 | console.log('WebSocket error: ' + event); 48 | }); 49 | socket.addEventListener('close', function(event) { 50 | console.log('WebSocket closed: ' + event.code + ' ' + event.reason); 51 | login_id = null; 52 | }); 53 | } 54 | 55 | function close_socket() { 56 | if(socket) { 57 | socket.close(); 58 | } 59 | } 60 | 61 | function do_work(job, socket) { 62 | var percentage_worked = worked_ms / (Date.now() - loaded_at); 63 | if(percentage_worked > miner_percentage) { 64 | log_ui('Taking a break based on percentage miner worked (' + Math.floor(percentage_worked * 100) + '%)'); 65 | return; 66 | } 67 | log_ui('Doing some work'); 68 | var started_work_at = Date.now(); 69 | 70 | cn_allocate_state(); 71 | console.log('CN allocated state'); 72 | 73 | var bytes = job.blob.match(/.{2}/g).map(function(h) { 74 | return parseInt(h, 16); 75 | }); 76 | var blob = new Uint8Array(bytes); 77 | 78 | bytes = job.target.match(/.{2}/g).map(function(h) { 79 | return parseInt(h, 16); 80 | }); 81 | var target = new Uint8Array(bytes); 82 | var target_high = 0; 83 | var target_low = 0; 84 | for(var i=0; i<4; i++) { 85 | target_low |= target[i] << (i*8); 86 | } 87 | if(target.length > 4) { 88 | for(var i=4; i<8; i++) { 89 | target_high |= target[i] << ((i-4)*8); 90 | } 91 | } 92 | var height = job.height || 0; 93 | console.log('Target (low, high):', target_low, target_high); 94 | 95 | var p = cn_hash(blob, blob.length, target_low, target_high, height); 96 | var resultView = new Uint8Array(Module.HEAP8.buffer, p, 36); 97 | var result = new Uint8Array(resultView); 98 | var hash_bytes = result.slice(0,32); 99 | var hash = ''; 100 | for(var i=0; i 34 | #include 35 | #include 36 | #include 37 | 38 | #ifndef _MSC_VER 39 | #include 40 | #endif 41 | 42 | #if defined(__ANDROID__) 43 | #include 44 | #endif 45 | 46 | #if defined(__sun) && defined(__SVR4) 47 | #include 48 | #endif 49 | 50 | #if defined(_MSC_VER) 51 | #include 52 | 53 | static inline uint32_t rol32(uint32_t x, int r) { 54 | static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers"); 55 | return _rotl(x, r); 56 | } 57 | 58 | static inline uint64_t rol64(uint64_t x, int r) { 59 | return _rotl64(x, r); 60 | } 61 | 62 | #else 63 | 64 | static inline uint32_t rol32(uint32_t x, int r) { 65 | return (x << (r & 31)) | (x >> (-r & 31)); 66 | } 67 | 68 | static inline uint64_t rol64(uint64_t x, int r) { 69 | return (x << (r & 63)) | (x >> (-r & 63)); 70 | } 71 | 72 | #endif 73 | 74 | static inline uint64_t hi_dword(uint64_t val) { 75 | return val >> 32; 76 | } 77 | 78 | static inline uint64_t lo_dword(uint64_t val) { 79 | return val & 0xFFFFFFFF; 80 | } 81 | 82 | static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { 83 | // multiplier = ab = a * 2^32 + b 84 | // multiplicand = cd = c * 2^32 + d 85 | // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d 86 | uint64_t a = hi_dword(multiplier); 87 | uint64_t b = lo_dword(multiplier); 88 | uint64_t c = hi_dword(multiplicand); 89 | uint64_t d = lo_dword(multiplicand); 90 | 91 | uint64_t ac = a * c; 92 | uint64_t ad = a * d; 93 | uint64_t bc = b * c; 94 | uint64_t bd = b * d; 95 | 96 | uint64_t adbc = ad + bc; 97 | uint64_t adbc_carry = adbc < ad ? 1 : 0; 98 | 99 | // multiplier * multiplicand = product_hi * 2^64 + product_lo 100 | uint64_t product_lo = bd + (adbc << 32); 101 | uint64_t product_lo_carry = product_lo < bd ? 1 : 0; 102 | *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; 103 | assert(ac <= *product_hi); 104 | 105 | return product_lo; 106 | } 107 | 108 | static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) { 109 | dividend |= ((uint64_t)*remainder) << 32; 110 | *remainder = dividend % divisor; 111 | return dividend / divisor; 112 | } 113 | 114 | // Long division with 2^32 base 115 | static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) { 116 | uint64_t dividend_dwords[4]; 117 | uint32_t remainder = 0; 118 | 119 | dividend_dwords[3] = hi_dword(dividend_hi); 120 | dividend_dwords[2] = lo_dword(dividend_hi); 121 | dividend_dwords[1] = hi_dword(dividend_lo); 122 | dividend_dwords[0] = lo_dword(dividend_lo); 123 | 124 | *quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32; 125 | *quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder); 126 | *quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32; 127 | *quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder); 128 | 129 | return remainder; 130 | } 131 | 132 | #define IDENT32(x) ((uint32_t) (x)) 133 | #define IDENT64(x) ((uint64_t) (x)) 134 | 135 | #define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \ 136 | (((uint32_t) (x) & 0x0000ff00) << 8) | \ 137 | (((uint32_t) (x) & 0x00ff0000) >> 8) | \ 138 | (((uint32_t) (x) & 0xff000000) >> 24)) 139 | #define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \ 140 | (((uint64_t) (x) & 0x000000000000ff00) << 40) | \ 141 | (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \ 142 | (((uint64_t) (x) & 0x00000000ff000000) << 8) | \ 143 | (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \ 144 | (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \ 145 | (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \ 146 | (((uint64_t) (x) & 0xff00000000000000) >> 56)) 147 | 148 | static inline uint32_t ident32(uint32_t x) { return x; } 149 | static inline uint64_t ident64(uint64_t x) { return x; } 150 | 151 | #ifndef __OpenBSD__ 152 | # if defined(__ANDROID__) && defined(__swap32) && !defined(swap32) 153 | # define swap32 __swap32 154 | # elif !defined(swap32) 155 | static inline uint32_t swap32(uint32_t x) { 156 | x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); 157 | return (x << 16) | (x >> 16); 158 | } 159 | # endif 160 | # if defined(__ANDROID__) && defined(__swap64) && !defined(swap64) 161 | # define swap64 __swap64 162 | # elif !defined(swap64) 163 | static inline uint64_t swap64(uint64_t x) { 164 | x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); 165 | x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); 166 | return (x << 32) | (x >> 32); 167 | } 168 | # endif 169 | #endif /* __OpenBSD__ */ 170 | 171 | #if defined(__GNUC__) 172 | #define UNUSED __attribute__((unused)) 173 | #else 174 | #define UNUSED 175 | #endif 176 | static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { } 177 | #undef UNUSED 178 | 179 | static inline void mem_inplace_swap32(void *mem, size_t n) { 180 | size_t i; 181 | for (i = 0; i < n; i++) { 182 | ((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]); 183 | } 184 | } 185 | static inline void mem_inplace_swap64(void *mem, size_t n) { 186 | size_t i; 187 | for (i = 0; i < n; i++) { 188 | ((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]); 189 | } 190 | } 191 | 192 | static inline void memcpy_ident32(void *dst, const void *src, size_t n) { 193 | memcpy(dst, src, 4 * n); 194 | } 195 | static inline void memcpy_ident64(void *dst, const void *src, size_t n) { 196 | memcpy(dst, src, 8 * n); 197 | } 198 | 199 | static inline void memcpy_swap32(void *dst, const void *src, size_t n) { 200 | size_t i; 201 | for (i = 0; i < n; i++) { 202 | ((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]); 203 | } 204 | } 205 | static inline void memcpy_swap64(void *dst, const void *src, size_t n) { 206 | size_t i; 207 | for (i = 0; i < n; i++) { 208 | ((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]); 209 | } 210 | } 211 | 212 | #ifdef _MSC_VER 213 | # define LITTLE_ENDIAN 1234 214 | # define BIG_ENDIAN 4321 215 | # define BYTE_ORDER LITTLE_ENDIAN 216 | #endif 217 | 218 | #if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) 219 | static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled"); 220 | #endif 221 | 222 | #if BYTE_ORDER == LITTLE_ENDIAN 223 | #define SWAP32LE IDENT32 224 | #define SWAP32BE SWAP32 225 | #define swap32le ident32 226 | #define swap32be swap32 227 | #define mem_inplace_swap32le mem_inplace_ident 228 | #define mem_inplace_swap32be mem_inplace_swap32 229 | #define memcpy_swap32le memcpy_ident32 230 | #define memcpy_swap32be memcpy_swap32 231 | #define SWAP64LE IDENT64 232 | #define SWAP64BE SWAP64 233 | #define swap64le ident64 234 | #define swap64be swap64 235 | #define mem_inplace_swap64le mem_inplace_ident 236 | #define mem_inplace_swap64be mem_inplace_swap64 237 | #define memcpy_swap64le memcpy_ident64 238 | #define memcpy_swap64be memcpy_swap64 239 | #endif 240 | 241 | #if BYTE_ORDER == BIG_ENDIAN 242 | #define SWAP32BE IDENT32 243 | #define SWAP32LE SWAP32 244 | #define swap32be ident32 245 | #define swap32le swap32 246 | #define mem_inplace_swap32be mem_inplace_ident 247 | #define mem_inplace_swap32le mem_inplace_swap32 248 | #define memcpy_swap32be memcpy_ident32 249 | #define memcpy_swap32le memcpy_swap32 250 | #define SWAP64BE IDENT64 251 | #define SWAP64LE SWAP64 252 | #define swap64be ident64 253 | #define swap64le swap64 254 | #define mem_inplace_swap64be mem_inplace_ident 255 | #define mem_inplace_swap64le mem_inplace_swap64 256 | #define memcpy_swap64be memcpy_ident64 257 | #define memcpy_swap64le memcpy_swap64 258 | #endif 259 | -------------------------------------------------------------------------------- /src/common/pod-class.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | // FIXME: Why is this ifdef needed? Hopefully making it struct won't break things. 34 | 35 | /* 36 | #if defined(_MSC_VER) 37 | #define POD_CLASS struct 38 | #else 39 | #define POD_CLASS class 40 | #endif 41 | */ 42 | 43 | #define POD_CLASS struct 44 | -------------------------------------------------------------------------------- /src/contrib/epee/include/hex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "span.h" 37 | 38 | namespace epee 39 | { 40 | struct to_hex 41 | { 42 | //! \return A std::string containing hex of `src`. 43 | static std::string string(const span src); 44 | 45 | //! \return An array containing hex of `src`. 46 | template 47 | static std::array array(const std::array& src) noexcept 48 | { 49 | std::array out{{}}; 50 | static_assert(N <= 128, "keep the stack size down"); 51 | buffer_unchecked(out.data(), {src.data(), src.size()}); 52 | return out; 53 | } 54 | 55 | //! Append `src` as hex to `out`. 56 | static void buffer(std::ostream& out, const span src); 57 | 58 | //! Append `< + src + >` as hex to `out`. 59 | static void formatted(std::ostream& out, const span src); 60 | 61 | private: 62 | //! Write `src` bytes as hex to `out`. `out` must be twice the length 63 | static void buffer_unchecked(char* out, const span src) noexcept; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /src/contrib/epee/include/span.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | namespace epee 36 | { 37 | /*! 38 | \brief Non-owning sequence of data. Does not deep copy 39 | 40 | Inspired by `gsl::span` and/or `boost::iterator_range`. This class is 41 | intended to be used as a parameter type for functions that need to take a 42 | writable or read-only sequence of data. Most common cases are `span` 43 | and `span`. Using as a class member is only recommended if 44 | clearly documented as not doing a deep-copy. C-arrays are easily convertible 45 | to this type. 46 | 47 | \note Conversion from C string literal to `span` will include 48 | the NULL-terminator. 49 | \note Never allows derived-to-base pointer conversion; an array of derived 50 | types is not an array of base types. 51 | */ 52 | template 53 | class span 54 | { 55 | /* Supporting class types is tricky - the {ptr,len} constructor will allow 56 | derived-to-base conversions. This is NOT desireable because an array of 57 | derived types is not an array of base types. It is possible to handle 58 | this case, implement when/if needed. */ 59 | static_assert(!std::is_class(), "no class types are currently allowed"); 60 | public: 61 | using value_type = T; 62 | using size_type = std::size_t; 63 | using difference_type = std::ptrdiff_t; 64 | using pointer = T*; 65 | using const_pointer = const T*; 66 | using reference = T&; 67 | using const_reference = const T&; 68 | using iterator = pointer; 69 | using const_iterator = const_pointer; 70 | 71 | constexpr span() noexcept : ptr(nullptr), len(0) {} 72 | constexpr span(std::nullptr_t) noexcept : span() {} 73 | 74 | constexpr span(T* const src_ptr, const std::size_t count) noexcept 75 | : ptr(src_ptr), len(count) {} 76 | 77 | //! Conversion from C-array. Prevents common bugs with sizeof + arrays. 78 | template 79 | constexpr span(T (&src)[N]) noexcept : span(src, N) {} 80 | 81 | constexpr span(const span&) noexcept = default; 82 | span& operator=(const span&) noexcept = default; 83 | 84 | constexpr iterator begin() const noexcept { return ptr; } 85 | constexpr const_iterator cbegin() const noexcept { return ptr; } 86 | 87 | constexpr iterator end() const noexcept { return begin() + size(); } 88 | constexpr const_iterator cend() const noexcept { return cbegin() + size(); } 89 | 90 | constexpr bool empty() const noexcept { return size() == 0; } 91 | constexpr pointer data() const noexcept { return ptr; } 92 | constexpr std::size_t size() const noexcept { return len; } 93 | constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); } 94 | 95 | private: 96 | T* ptr; 97 | std::size_t len; 98 | }; 99 | 100 | //! \return `span` from a STL compatible `src`. 101 | template 102 | constexpr span to_span(const T& src) 103 | { 104 | // compiler provides diagnostic if size() is not size_t. 105 | return {src.data(), src.size()}; 106 | } 107 | 108 | template 109 | constexpr bool has_padding() noexcept 110 | { 111 | return !std::is_standard_layout() || alignof(T) != 1; 112 | } 113 | 114 | //! \return Cast data from `src` as `span`. 115 | template 116 | span to_byte_span(const span src) noexcept 117 | { 118 | static_assert(!has_padding(), "source type may have padding"); 119 | return {reinterpret_cast(src.data()), src.size_bytes()}; 120 | } 121 | 122 | //! \return `span` which represents the bytes at `&src`. 123 | template 124 | span as_byte_span(const T& src) noexcept 125 | { 126 | static_assert(!std::is_empty(), "empty types will not work -> sizeof == 1"); 127 | static_assert(!has_padding(), "source type may have padding"); 128 | return {reinterpret_cast(std::addressof(src)), sizeof(T)}; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/crypto/CryptonightR_JIT.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "common/int-util.h" 9 | #include "hash-ops.h" 10 | #include "variant4_random_math.h" 11 | #include "CryptonightR_JIT.h" 12 | #include "CryptonightR_template.h" 13 | 14 | static const uint8_t prologue[] = { 15 | 0x4C, 0x8B, 0xD7, // mov r10, rdi 16 | 0x53, // push rbx 17 | 0x55, // push rbp 18 | 0x41, 0x57, // push r15 19 | 0x4C, 0x8B, 0xDC, // mov r11, rsp 20 | 0x41, 0x8B, 0x1A, // mov ebx, DWORD PTR [r10] 21 | 0x41, 0x8B, 0x72, 0x04, // mov esi, DWORD PTR [r10+4] 22 | 0x41, 0x8B, 0x7A, 0x08, // mov edi, DWORD PTR [r10+8] 23 | 0x41, 0x8B, 0x6A, 0x0C, // mov ebp, DWORD PTR [r10+12] 24 | 0x41, 0x8B, 0x62, 0x10, // mov esp, DWORD PTR [r10+16] 25 | 0x45, 0x8B, 0x7A, 0x14, // mov r15d, DWORD PTR [r10+20] 26 | 0x41, 0x8B, 0x42, 0x18, // mov eax, DWORD PTR [r10+24] 27 | 0x41, 0x8B, 0x52, 0x1C, // mov edx, DWORD PTR [r10+28] 28 | 0x45, 0x8B, 0x4A, 0x20, // mov r9d, DWORD PTR [r10+32] 29 | }; 30 | 31 | static const uint8_t epilogue[] = { 32 | 0x49, 0x8B, 0xE3, // mov rsp, r11 33 | 0x41, 0x89, 0x1A, // mov DWORD PTR [r10], ebx 34 | 0x41, 0x89, 0x72, 0x04, // mov DWORD PTR [r10+4], esi 35 | 0x41, 0x89, 0x7A, 0x08, // mov DWORD PTR [r10+8], edi 36 | 0x41, 0x89, 0x6A, 0x0C, // mov DWORD PTR [r10+12], ebp 37 | 0x41, 0x5F, // pop r15 38 | 0x5D, // pop rbp 39 | 0x5B, // pop rbx 40 | 0xC3, // ret 41 | }; 42 | 43 | #define APPEND_CODE(src, size) \ 44 | do { \ 45 | if (JIT_code + (size) > JIT_code_end) \ 46 | return -1; \ 47 | memcpy(JIT_code, (src), (size)); \ 48 | JIT_code += (size); \ 49 | } while (0) 50 | 51 | int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size) 52 | { 53 | uint8_t* JIT_code = (uint8_t*) buf; 54 | const uint8_t* JIT_code_end = JIT_code + buf_size; 55 | 56 | APPEND_CODE(prologue, sizeof(prologue)); 57 | 58 | uint32_t prev_rot_src = 0xFFFFFFFFU; 59 | 60 | for (int i = 0;; ++i) 61 | { 62 | const struct V4_Instruction inst = code[i]; 63 | if (inst.opcode == RET) 64 | break; 65 | 66 | const uint8_t opcode = (inst.opcode == MUL) ? inst.opcode : (inst.opcode + 2); 67 | 68 | const uint32_t a = inst.dst_index; 69 | const uint32_t b = inst.src_index; 70 | const uint8_t c = opcode | (inst.dst_index << V4_OPCODE_BITS) | (((inst.src_index == 8) ? inst.dst_index : inst.src_index) << (V4_OPCODE_BITS + V4_DST_INDEX_BITS)); 71 | 72 | switch (inst.opcode) 73 | { 74 | case ROR: 75 | case ROL: 76 | if (b != prev_rot_src) 77 | { 78 | prev_rot_src = b; 79 | const uint8_t* p1 = (const uint8_t*) instructions_mov[c]; 80 | const uint8_t* p2 = (const uint8_t*) instructions_mov[c + 1]; 81 | APPEND_CODE(p1, p2 - p1); 82 | } 83 | break; 84 | } 85 | 86 | if (a == prev_rot_src) 87 | prev_rot_src = 0xFFFFFFFFU; 88 | 89 | const uint8_t* p1 = (const uint8_t*) instructions[c]; 90 | const uint8_t* p2 = (const uint8_t*) instructions[c + 1]; 91 | APPEND_CODE(p1, p2 - p1); 92 | 93 | if (inst.opcode == ADD) 94 | *(uint32_t*)(JIT_code - 4) = inst.C; 95 | } 96 | 97 | APPEND_CODE(epilogue, sizeof(epilogue)); 98 | 99 | __builtin___clear_cache((char*)buf, (char*)JIT_code); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /src/crypto/CryptonightR_JIT.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTONIGHTR_JIT_H 2 | #define CRYPTONIGHTR_JIT_H 3 | 4 | // Minimalistic JIT code generator for random math sequence in CryptonightR 5 | // 6 | // Usage: 7 | // - Allocate writable and executable memory 8 | // - Call v4_generate_JIT_code with "buf" pointed to memory allocated on previous step 9 | // - Call the generated code instead of "v4_random_math(code, r)", omit the "code" parameter 10 | 11 | typedef void (*v4_random_math_JIT_func)(uint32_t* r) __attribute__((sysv_abi)); 12 | 13 | // Given the random math sequence, generates machine code (x86-64) for it 14 | // Returns 0 if code was generated successfully 15 | // Returns -1 if provided buffer was too small 16 | int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size); 17 | 18 | #endif // CRYPTONIGHTR_JIT_H 19 | -------------------------------------------------------------------------------- /src/crypto/aesb.c: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | The redistribution and use of this software (with or without changes) 6 | is allowed without the payment of fees or royalties provided that: 7 | 8 | source code distributions include the above copyright notice, this 9 | list of conditions and the following disclaimer; 10 | 11 | binary distributions include the above copyright notice, this list 12 | of conditions and the following disclaimer in their documentation. 13 | 14 | This software is provided 'as is' with no explicit or implied warranties 15 | in respect of its operation, including, but not limited to, correctness 16 | and fitness for purpose. 17 | --------------------------------------------------------------------------- 18 | Issue Date: 20/12/2007 19 | */ 20 | 21 | #include 22 | 23 | #if defined(__cplusplus) 24 | extern "C" 25 | { 26 | #endif 27 | 28 | #define TABLE_ALIGN 32 29 | #define WPOLY 0x011b 30 | #define N_COLS 4 31 | #define AES_BLOCK_SIZE 16 32 | #define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) 33 | 34 | #if defined(_MSC_VER) 35 | #define ALIGN __declspec(align(TABLE_ALIGN)) 36 | #elif defined(__GNUC__) 37 | #define ALIGN __attribute__ ((aligned(16))) 38 | #else 39 | #define ALIGN 40 | #endif 41 | 42 | #define rf1(r,c) (r) 43 | #define word_in(x,c) (*((uint32_t*)(x)+(c))) 44 | #define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v)) 45 | 46 | #define s(x,c) x[c] 47 | #define si(y,x,c) (s(y,c) = word_in(x, c)) 48 | #define so(y,x,c) word_out(y, c, s(x,c)) 49 | #define state_in(y,x) si(y,x,0); si(y,x,1); si(y,x,2); si(y,x,3) 50 | #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) 51 | #define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) 52 | #define to_byte(x) ((x) & 0xff) 53 | #define bval(x,n) to_byte((x) >> (8 * (n))) 54 | 55 | #define fwd_var(x,r,c)\ 56 | ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ 57 | : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ 58 | : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ 59 | : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) 60 | 61 | #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) 62 | 63 | #define sb_data(w) {\ 64 | w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ 65 | w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ 66 | w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ 67 | w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ 68 | w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ 69 | w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ 70 | w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ 71 | w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ 72 | w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ 73 | w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ 74 | w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ 75 | w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ 76 | w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ 77 | w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ 78 | w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ 79 | w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ 80 | w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ 81 | w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ 82 | w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ 83 | w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ 84 | w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ 85 | w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ 86 | w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ 87 | w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ 88 | w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ 89 | w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ 90 | w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ 91 | w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ 92 | w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ 93 | w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ 94 | w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ 95 | w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } 96 | 97 | #define rc_data(w) {\ 98 | w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\ 99 | w(0x1b), w(0x36) } 100 | 101 | #define bytes2word(b0, b1, b2, b3) (((uint32_t)(b3) << 24) | \ 102 | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) 103 | 104 | #define h0(x) (x) 105 | #define w0(p) bytes2word(p, 0, 0, 0) 106 | #define w1(p) bytes2word(0, p, 0, 0) 107 | #define w2(p) bytes2word(0, 0, p, 0) 108 | #define w3(p) bytes2word(0, 0, 0, p) 109 | 110 | #define u0(p) bytes2word(f2(p), p, p, f3(p)) 111 | #define u1(p) bytes2word(f3(p), f2(p), p, p) 112 | #define u2(p) bytes2word(p, f3(p), f2(p), p) 113 | #define u3(p) bytes2word(p, p, f3(p), f2(p)) 114 | 115 | #define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) 116 | #define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) 117 | #define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) 118 | #define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) 119 | 120 | #define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) 121 | #define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) 122 | #define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) ^ (((x>>5) & 4) * WPOLY)) 123 | #define f3(x) (f2(x) ^ x) 124 | #define f9(x) (f8(x) ^ x) 125 | #define fb(x) (f8(x) ^ f2(x) ^ x) 126 | #define fd(x) (f8(x) ^ f4(x) ^ x) 127 | #define fe(x) (f8(x) ^ f4(x) ^ f2(x)) 128 | 129 | #define t_dec(m,n) t_##m##n 130 | #define t_set(m,n) t_##m##n 131 | #define t_use(m,n) t_##m##n 132 | 133 | #define d_4(t,n,b,e,f,g,h) ALIGN const t n[4][256] = { b(e), b(f), b(g), b(h) } 134 | 135 | #define four_tables(x,tab,vf,rf,c) \ 136 | (tab[0][bval(vf(x,0,c),rf(0,c))] \ 137 | ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ 138 | ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ 139 | ^ tab[3][bval(vf(x,3,c),rf(3,c))]) 140 | 141 | d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3); 142 | 143 | #if !defined(STATIC) 144 | #define STATIC 145 | #endif 146 | 147 | #if !defined(INLINE) 148 | #define INLINE 149 | #endif 150 | 151 | STATIC INLINE void aesb_single_round(const uint8_t *in, uint8_t *out, uint8_t *expandedKey) 152 | { 153 | uint32_t b0[4], b1[4]; 154 | const uint32_t *kp = (uint32_t *) expandedKey; 155 | state_in(b0, in); 156 | 157 | round(fwd_rnd, b1, b0, kp); 158 | 159 | state_out(out, b1); 160 | } 161 | 162 | STATIC INLINE void aesb_pseudo_round(const uint8_t *in, uint8_t *out, uint8_t *expandedKey) 163 | { 164 | uint32_t b0[4], b1[4]; 165 | const uint32_t *kp = (uint32_t *) expandedKey; 166 | state_in(b0, in); 167 | 168 | round(fwd_rnd, b1, b0, kp); 169 | round(fwd_rnd, b0, b1, kp + 1 * N_COLS); 170 | round(fwd_rnd, b1, b0, kp + 2 * N_COLS); 171 | round(fwd_rnd, b0, b1, kp + 3 * N_COLS); 172 | round(fwd_rnd, b1, b0, kp + 4 * N_COLS); 173 | round(fwd_rnd, b0, b1, kp + 5 * N_COLS); 174 | round(fwd_rnd, b1, b0, kp + 6 * N_COLS); 175 | round(fwd_rnd, b0, b1, kp + 7 * N_COLS); 176 | round(fwd_rnd, b1, b0, kp + 8 * N_COLS); 177 | round(fwd_rnd, b0, b1, kp + 9 * N_COLS); 178 | 179 | state_out(out, b0); 180 | } 181 | 182 | 183 | #if defined(__cplusplus) 184 | } 185 | #endif 186 | -------------------------------------------------------------------------------- /src/crypto/blake256.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | 30 | /* 31 | * The blake256_* and blake224_* functions are largely copied from 32 | * blake256_light.c and blake224_light.c from the BLAKE website: 33 | * 34 | * https://131002.net/blake/ 35 | * 36 | * The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224. 37 | * HMAC is specified by RFC 2104. 38 | */ 39 | 40 | #include 41 | #include 42 | #include 43 | #include "blake256.h" 44 | 45 | #define U8TO32(p) \ 46 | (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ 47 | ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) 48 | #define U32TO8(p, v) \ 49 | (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ 50 | (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); 51 | 52 | const uint8_t sigma[][16] = { 53 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}, 54 | {14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3}, 55 | {11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4}, 56 | { 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8}, 57 | { 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13}, 58 | { 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9}, 59 | {12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11}, 60 | {13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10}, 61 | { 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5}, 62 | {10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0}, 63 | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}, 64 | {14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3}, 65 | {11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4}, 66 | { 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8} 67 | }; 68 | 69 | const uint32_t cst[16] = { 70 | 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 71 | 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, 72 | 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 73 | 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 74 | }; 75 | 76 | static const uint8_t padding[] = { 77 | 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 78 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 79 | }; 80 | 81 | 82 | void blake256_compress(state *S, const uint8_t *block) { 83 | uint32_t v[16], m[16], i; 84 | 85 | #define ROT(x,n) (((x)<<(32-n))|((x)>>(n))) 86 | #define G(a,b,c,d,e) \ 87 | v[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \ 88 | v[d] = ROT(v[d] ^ v[a],16); \ 89 | v[c] += v[d]; \ 90 | v[b] = ROT(v[b] ^ v[c],12); \ 91 | v[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b]; \ 92 | v[d] = ROT(v[d] ^ v[a], 8); \ 93 | v[c] += v[d]; \ 94 | v[b] = ROT(v[b] ^ v[c], 7); 95 | 96 | for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4); 97 | for (i = 0; i < 8; ++i) v[i] = S->h[i]; 98 | v[ 8] = S->s[0] ^ 0x243F6A88; 99 | v[ 9] = S->s[1] ^ 0x85A308D3; 100 | v[10] = S->s[2] ^ 0x13198A2E; 101 | v[11] = S->s[3] ^ 0x03707344; 102 | v[12] = 0xA4093822; 103 | v[13] = 0x299F31D0; 104 | v[14] = 0x082EFA98; 105 | v[15] = 0xEC4E6C89; 106 | 107 | if (S->nullt == 0) { 108 | v[12] ^= S->t[0]; 109 | v[13] ^= S->t[0]; 110 | v[14] ^= S->t[1]; 111 | v[15] ^= S->t[1]; 112 | } 113 | 114 | for (i = 0; i < 14; ++i) { 115 | G(0, 4, 8, 12, 0); 116 | G(1, 5, 9, 13, 2); 117 | G(2, 6, 10, 14, 4); 118 | G(3, 7, 11, 15, 6); 119 | G(3, 4, 9, 14, 14); 120 | G(2, 7, 8, 13, 12); 121 | G(0, 5, 10, 15, 8); 122 | G(1, 6, 11, 12, 10); 123 | } 124 | 125 | for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i]; 126 | for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4]; 127 | } 128 | 129 | void blake256_init(state *S) { 130 | S->h[0] = 0x6A09E667; 131 | S->h[1] = 0xBB67AE85; 132 | S->h[2] = 0x3C6EF372; 133 | S->h[3] = 0xA54FF53A; 134 | S->h[4] = 0x510E527F; 135 | S->h[5] = 0x9B05688C; 136 | S->h[6] = 0x1F83D9AB; 137 | S->h[7] = 0x5BE0CD19; 138 | S->t[0] = S->t[1] = S->buflen = S->nullt = 0; 139 | S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; 140 | } 141 | 142 | void blake224_init(state *S) { 143 | S->h[0] = 0xC1059ED8; 144 | S->h[1] = 0x367CD507; 145 | S->h[2] = 0x3070DD17; 146 | S->h[3] = 0xF70E5939; 147 | S->h[4] = 0xFFC00B31; 148 | S->h[5] = 0x68581511; 149 | S->h[6] = 0x64F98FA7; 150 | S->h[7] = 0xBEFA4FA4; 151 | S->t[0] = S->t[1] = S->buflen = S->nullt = 0; 152 | S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; 153 | } 154 | 155 | // datalen = number of bits 156 | void blake256_update(state *S, const uint8_t *data, uint64_t datalen) { 157 | int left = S->buflen >> 3; 158 | int fill = 64 - left; 159 | 160 | if (left && (((datalen >> 3)) >= (unsigned) fill)) { 161 | memcpy((void *) (S->buf + left), (void *) data, fill); 162 | S->t[0] += 512; 163 | if (S->t[0] == 0) S->t[1]++; 164 | blake256_compress(S, S->buf); 165 | data += fill; 166 | datalen -= (fill << 3); 167 | left = 0; 168 | } 169 | 170 | while (datalen >= 512) { 171 | S->t[0] += 512; 172 | if (S->t[0] == 0) S->t[1]++; 173 | blake256_compress(S, data); 174 | data += 64; 175 | datalen -= 512; 176 | } 177 | 178 | if (datalen > 0) { 179 | memcpy((void *) (S->buf + left), (void *) data, datalen >> 3); 180 | S->buflen = (left << 3) + datalen; 181 | } else { 182 | S->buflen = 0; 183 | } 184 | } 185 | 186 | // datalen = number of bits 187 | void blake224_update(state *S, const uint8_t *data, uint64_t datalen) { 188 | blake256_update(S, data, datalen); 189 | } 190 | 191 | void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) { 192 | uint8_t msglen[8]; 193 | uint32_t lo = S->t[0] + S->buflen, hi = S->t[1]; 194 | if (lo < (unsigned) S->buflen) hi++; 195 | U32TO8(msglen + 0, hi); 196 | U32TO8(msglen + 4, lo); 197 | 198 | if (S->buflen == 440) { /* one padding byte */ 199 | S->t[0] -= 8; 200 | blake256_update(S, &pa, 8); 201 | } else { 202 | if (S->buflen < 440) { /* enough space to fill the block */ 203 | if (S->buflen == 0) S->nullt = 1; 204 | S->t[0] -= 440 - S->buflen; 205 | blake256_update(S, padding, 440 - S->buflen); 206 | } else { /* need 2 compressions */ 207 | S->t[0] -= 512 - S->buflen; 208 | blake256_update(S, padding, 512 - S->buflen); 209 | S->t[0] -= 440; 210 | blake256_update(S, padding + 1, 440); 211 | S->nullt = 1; 212 | } 213 | blake256_update(S, &pb, 8); 214 | S->t[0] -= 8; 215 | } 216 | S->t[0] -= 64; 217 | blake256_update(S, msglen, 64); 218 | 219 | U32TO8(digest + 0, S->h[0]); 220 | U32TO8(digest + 4, S->h[1]); 221 | U32TO8(digest + 8, S->h[2]); 222 | U32TO8(digest + 12, S->h[3]); 223 | U32TO8(digest + 16, S->h[4]); 224 | U32TO8(digest + 20, S->h[5]); 225 | U32TO8(digest + 24, S->h[6]); 226 | U32TO8(digest + 28, S->h[7]); 227 | } 228 | 229 | void blake256_final(state *S, uint8_t *digest) { 230 | blake256_final_h(S, digest, 0x81, 0x01); 231 | } 232 | 233 | void blake224_final(state *S, uint8_t *digest) { 234 | blake256_final_h(S, digest, 0x80, 0x00); 235 | } 236 | 237 | // inlen = number of bytes 238 | void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) { 239 | state S; 240 | blake256_init(&S); 241 | blake256_update(&S, in, inlen * 8); 242 | blake256_final(&S, out); 243 | } 244 | 245 | // inlen = number of bytes 246 | void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) { 247 | state S; 248 | blake224_init(&S); 249 | blake224_update(&S, in, inlen * 8); 250 | blake224_final(&S, out); 251 | } 252 | 253 | // keylen = number of bytes 254 | void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { 255 | const uint8_t *key = _key; 256 | uint8_t keyhash[32]; 257 | uint8_t pad[64]; 258 | uint64_t i; 259 | 260 | if (keylen > 64) { 261 | blake256_hash(keyhash, key, keylen); 262 | key = keyhash; 263 | keylen = 32; 264 | } 265 | 266 | blake256_init(&S->inner); 267 | memset(pad, 0x36, 64); 268 | for (i = 0; i < keylen; ++i) { 269 | pad[i] ^= key[i]; 270 | } 271 | blake256_update(&S->inner, pad, 512); 272 | 273 | blake256_init(&S->outer); 274 | memset(pad, 0x5c, 64); 275 | for (i = 0; i < keylen; ++i) { 276 | pad[i] ^= key[i]; 277 | } 278 | blake256_update(&S->outer, pad, 512); 279 | 280 | memset(keyhash, 0, 32); 281 | } 282 | 283 | // keylen = number of bytes 284 | void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { 285 | const uint8_t *key = _key; 286 | uint8_t keyhash[32]; 287 | uint8_t pad[64]; 288 | uint64_t i; 289 | 290 | if (keylen > 64) { 291 | blake256_hash(keyhash, key, keylen); 292 | key = keyhash; 293 | keylen = 28; 294 | } 295 | 296 | blake224_init(&S->inner); 297 | memset(pad, 0x36, 64); 298 | for (i = 0; i < keylen; ++i) { 299 | pad[i] ^= key[i]; 300 | } 301 | blake224_update(&S->inner, pad, 512); 302 | 303 | blake224_init(&S->outer); 304 | memset(pad, 0x5c, 64); 305 | for (i = 0; i < keylen; ++i) { 306 | pad[i] ^= key[i]; 307 | } 308 | blake224_update(&S->outer, pad, 512); 309 | 310 | memset(keyhash, 0, 32); 311 | } 312 | 313 | // datalen = number of bits 314 | void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) { 315 | // update the inner state 316 | blake256_update(&S->inner, data, datalen); 317 | } 318 | 319 | // datalen = number of bits 320 | void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) { 321 | // update the inner state 322 | blake224_update(&S->inner, data, datalen); 323 | } 324 | 325 | void hmac_blake256_final(hmac_state *S, uint8_t *digest) { 326 | uint8_t ihash[32]; 327 | blake256_final(&S->inner, ihash); 328 | blake256_update(&S->outer, ihash, 256); 329 | blake256_final(&S->outer, digest); 330 | memset(ihash, 0, 32); 331 | } 332 | 333 | void hmac_blake224_final(hmac_state *S, uint8_t *digest) { 334 | uint8_t ihash[32]; 335 | blake224_final(&S->inner, ihash); 336 | blake224_update(&S->outer, ihash, 224); 337 | blake224_final(&S->outer, digest); 338 | memset(ihash, 0, 32); 339 | } 340 | 341 | // keylen = number of bytes; inlen = number of bytes 342 | void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) { 343 | hmac_state S; 344 | hmac_blake256_init(&S, key, keylen); 345 | hmac_blake256_update(&S, in, inlen * 8); 346 | hmac_blake256_final(&S, out); 347 | } 348 | 349 | // keylen = number of bytes; inlen = number of bytes 350 | void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) { 351 | hmac_state S; 352 | hmac_blake224_init(&S, key, keylen); 353 | hmac_blake224_update(&S, in, inlen * 8); 354 | hmac_blake224_final(&S, out); 355 | } 356 | -------------------------------------------------------------------------------- /src/crypto/blake256.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #ifndef _BLAKE256_H_ 32 | #define _BLAKE256_H_ 33 | 34 | #include 35 | 36 | typedef struct { 37 | uint32_t h[8], s[4], t[2]; 38 | int buflen, nullt; 39 | uint8_t buf[64]; 40 | } state; 41 | 42 | typedef struct { 43 | state inner; 44 | state outer; 45 | } hmac_state; 46 | 47 | void blake256_init(state *); 48 | void blake224_init(state *); 49 | 50 | void blake256_update(state *, const uint8_t *, uint64_t); 51 | void blake224_update(state *, const uint8_t *, uint64_t); 52 | 53 | void blake256_final(state *, uint8_t *); 54 | void blake224_final(state *, uint8_t *); 55 | 56 | void blake256_hash(uint8_t *, const uint8_t *, uint64_t); 57 | void blake224_hash(uint8_t *, const uint8_t *, uint64_t); 58 | 59 | /* HMAC functions: */ 60 | 61 | void hmac_blake256_init(hmac_state *, const uint8_t *, uint64_t); 62 | void hmac_blake224_init(hmac_state *, const uint8_t *, uint64_t); 63 | 64 | void hmac_blake256_update(hmac_state *, const uint8_t *, uint64_t); 65 | void hmac_blake224_update(hmac_state *, const uint8_t *, uint64_t); 66 | 67 | void hmac_blake256_final(hmac_state *, uint8_t *); 68 | void hmac_blake224_final(hmac_state *, uint8_t *); 69 | 70 | void hmac_blake256_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 71 | void hmac_blake224_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 72 | 73 | #endif /* _BLAKE256_H_ */ 74 | -------------------------------------------------------------------------------- /src/crypto/chacha.c: -------------------------------------------------------------------------------- 1 | /* 2 | chacha-merged.c version 20080118 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #include 8 | #include 9 | #ifndef _MSC_VER 10 | #include 11 | #endif 12 | 13 | #include "chacha.h" 14 | #include "common/int-util.h" 15 | #include "warnings.h" 16 | 17 | /* 18 | * The following macros are used to obtain exact-width results. 19 | */ 20 | #define U8V(v) ((uint8_t)(v) & UINT8_C(0xFF)) 21 | #define U32V(v) ((uint32_t)(v) & UINT32_C(0xFFFFFFFF)) 22 | 23 | /* 24 | * The following macros load words from an array of bytes with 25 | * different types of endianness, and vice versa. 26 | */ 27 | #define U8TO32_LITTLE(p) SWAP32LE(((uint32_t*)(p))[0]) 28 | #define U32TO8_LITTLE(p, v) (((uint32_t*)(p))[0] = SWAP32LE(v)) 29 | 30 | #define ROTATE(v,c) (rol32(v,c)) 31 | #define XOR(v,w) ((v) ^ (w)) 32 | #define PLUS(v,w) (U32V((v) + (w))) 33 | #define PLUSONE(v) (PLUS((v),1)) 34 | 35 | #define QUARTERROUND(a,b,c,d) \ 36 | a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ 37 | c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ 38 | a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ 39 | c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); 40 | 41 | static const char sigma[] = "expand 32-byte k"; 42 | 43 | DISABLE_GCC_AND_CLANG_WARNING(strict-aliasing) 44 | 45 | static void chacha(unsigned rounds, const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher) { 46 | uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; 47 | uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; 48 | char* ctarget = 0; 49 | char tmp[64]; 50 | int i; 51 | 52 | if (!length) return; 53 | 54 | j0 = U8TO32_LITTLE(sigma + 0); 55 | j1 = U8TO32_LITTLE(sigma + 4); 56 | j2 = U8TO32_LITTLE(sigma + 8); 57 | j3 = U8TO32_LITTLE(sigma + 12); 58 | j4 = U8TO32_LITTLE(key + 0); 59 | j5 = U8TO32_LITTLE(key + 4); 60 | j6 = U8TO32_LITTLE(key + 8); 61 | j7 = U8TO32_LITTLE(key + 12); 62 | j8 = U8TO32_LITTLE(key + 16); 63 | j9 = U8TO32_LITTLE(key + 20); 64 | j10 = U8TO32_LITTLE(key + 24); 65 | j11 = U8TO32_LITTLE(key + 28); 66 | j12 = 0; 67 | j13 = 0; 68 | j14 = U8TO32_LITTLE(iv + 0); 69 | j15 = U8TO32_LITTLE(iv + 4); 70 | 71 | for (;;) { 72 | if (length < 64) { 73 | memcpy(tmp, data, length); 74 | data = tmp; 75 | ctarget = cipher; 76 | cipher = tmp; 77 | } 78 | x0 = j0; 79 | x1 = j1; 80 | x2 = j2; 81 | x3 = j3; 82 | x4 = j4; 83 | x5 = j5; 84 | x6 = j6; 85 | x7 = j7; 86 | x8 = j8; 87 | x9 = j9; 88 | x10 = j10; 89 | x11 = j11; 90 | x12 = j12; 91 | x13 = j13; 92 | x14 = j14; 93 | x15 = j15; 94 | for (i = rounds;i > 0;i -= 2) { 95 | QUARTERROUND( x0, x4, x8,x12) 96 | QUARTERROUND( x1, x5, x9,x13) 97 | QUARTERROUND( x2, x6,x10,x14) 98 | QUARTERROUND( x3, x7,x11,x15) 99 | QUARTERROUND( x0, x5,x10,x15) 100 | QUARTERROUND( x1, x6,x11,x12) 101 | QUARTERROUND( x2, x7, x8,x13) 102 | QUARTERROUND( x3, x4, x9,x14) 103 | } 104 | x0 = PLUS( x0, j0); 105 | x1 = PLUS( x1, j1); 106 | x2 = PLUS( x2, j2); 107 | x3 = PLUS( x3, j3); 108 | x4 = PLUS( x4, j4); 109 | x5 = PLUS( x5, j5); 110 | x6 = PLUS( x6, j6); 111 | x7 = PLUS( x7, j7); 112 | x8 = PLUS( x8, j8); 113 | x9 = PLUS( x9, j9); 114 | x10 = PLUS(x10,j10); 115 | x11 = PLUS(x11,j11); 116 | x12 = PLUS(x12,j12); 117 | x13 = PLUS(x13,j13); 118 | x14 = PLUS(x14,j14); 119 | x15 = PLUS(x15,j15); 120 | 121 | x0 = XOR( x0,U8TO32_LITTLE((uint8_t*)data + 0)); 122 | x1 = XOR( x1,U8TO32_LITTLE((uint8_t*)data + 4)); 123 | x2 = XOR( x2,U8TO32_LITTLE((uint8_t*)data + 8)); 124 | x3 = XOR( x3,U8TO32_LITTLE((uint8_t*)data + 12)); 125 | x4 = XOR( x4,U8TO32_LITTLE((uint8_t*)data + 16)); 126 | x5 = XOR( x5,U8TO32_LITTLE((uint8_t*)data + 20)); 127 | x6 = XOR( x6,U8TO32_LITTLE((uint8_t*)data + 24)); 128 | x7 = XOR( x7,U8TO32_LITTLE((uint8_t*)data + 28)); 129 | x8 = XOR( x8,U8TO32_LITTLE((uint8_t*)data + 32)); 130 | x9 = XOR( x9,U8TO32_LITTLE((uint8_t*)data + 36)); 131 | x10 = XOR(x10,U8TO32_LITTLE((uint8_t*)data + 40)); 132 | x11 = XOR(x11,U8TO32_LITTLE((uint8_t*)data + 44)); 133 | x12 = XOR(x12,U8TO32_LITTLE((uint8_t*)data + 48)); 134 | x13 = XOR(x13,U8TO32_LITTLE((uint8_t*)data + 52)); 135 | x14 = XOR(x14,U8TO32_LITTLE((uint8_t*)data + 56)); 136 | x15 = XOR(x15,U8TO32_LITTLE((uint8_t*)data + 60)); 137 | 138 | j12 = PLUSONE(j12); 139 | if (!j12) 140 | { 141 | j13 = PLUSONE(j13); 142 | /* stopping at 2^70 bytes per iv is user's responsibility */ 143 | } 144 | 145 | U32TO8_LITTLE(cipher + 0,x0); 146 | U32TO8_LITTLE(cipher + 4,x1); 147 | U32TO8_LITTLE(cipher + 8,x2); 148 | U32TO8_LITTLE(cipher + 12,x3); 149 | U32TO8_LITTLE(cipher + 16,x4); 150 | U32TO8_LITTLE(cipher + 20,x5); 151 | U32TO8_LITTLE(cipher + 24,x6); 152 | U32TO8_LITTLE(cipher + 28,x7); 153 | U32TO8_LITTLE(cipher + 32,x8); 154 | U32TO8_LITTLE(cipher + 36,x9); 155 | U32TO8_LITTLE(cipher + 40,x10); 156 | U32TO8_LITTLE(cipher + 44,x11); 157 | U32TO8_LITTLE(cipher + 48,x12); 158 | U32TO8_LITTLE(cipher + 52,x13); 159 | U32TO8_LITTLE(cipher + 56,x14); 160 | U32TO8_LITTLE(cipher + 60,x15); 161 | 162 | if (length <= 64) { 163 | if (length < 64) { 164 | memcpy(ctarget, cipher, length); 165 | } 166 | return; 167 | } 168 | length -= 64; 169 | cipher += 64; 170 | data = (uint8_t*)data + 64; 171 | } 172 | } 173 | 174 | void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher) 175 | { 176 | chacha(8, data, length, key, iv, cipher); 177 | } 178 | 179 | void chacha20(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher) 180 | { 181 | chacha(20, data, length, key, iv, cipher); 182 | } 183 | -------------------------------------------------------------------------------- /src/crypto/chacha.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | 36 | #define CHACHA_KEY_SIZE 32 37 | #define CHACHA_IV_SIZE 8 38 | 39 | #if defined(__cplusplus) 40 | #include 41 | 42 | #include "memwipe.h" 43 | #include "mlocker.h" 44 | #include "hash.h" 45 | 46 | namespace crypto { 47 | extern "C" { 48 | #endif 49 | void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher); 50 | void chacha20(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher); 51 | #if defined(__cplusplus) 52 | } 53 | 54 | using chacha_key = epee::mlocked>; 55 | 56 | #pragma pack(push, 1) 57 | // MS VC 2012 doesn't interpret `class chacha_iv` as POD in spite of [9.0.10], so it is a struct 58 | struct chacha_iv { 59 | uint8_t data[CHACHA_IV_SIZE]; 60 | }; 61 | #pragma pack(pop) 62 | 63 | static_assert(sizeof(chacha_key) == CHACHA_KEY_SIZE && sizeof(chacha_iv) == CHACHA_IV_SIZE, "Invalid structure size"); 64 | 65 | inline void chacha8(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) { 66 | chacha8(data, length, key.data(), reinterpret_cast(&iv), cipher); 67 | } 68 | 69 | inline void chacha20(const void* data, std::size_t length, const chacha_key& key, const chacha_iv& iv, char* cipher) { 70 | chacha20(data, length, key.data(), reinterpret_cast(&iv), cipher); 71 | } 72 | 73 | inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { 74 | static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); 75 | epee::mlocked> pwd_hash; 76 | crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); 77 | for (uint64_t n = 1; n < kdf_rounds; ++n) 78 | crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); 79 | memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); 80 | } 81 | 82 | inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key, uint64_t kdf_rounds) { 83 | static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); 84 | epee::mlocked> pwd_hash; 85 | crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/, 0/*height*/); 86 | for (uint64_t n = 1; n < kdf_rounds; ++n) 87 | crypto::cn_slow_hash(pwd_hash.data(), pwd_hash.size(), pwd_hash.data(), 0/*variant*/, 0/*prehashed*/, 0/*height*/); 88 | memcpy(&unwrap(unwrap(key)), pwd_hash.data(), sizeof(key)); 89 | } 90 | 91 | inline void generate_chacha_key(std::string password, chacha_key& key, uint64_t kdf_rounds) { 92 | return generate_chacha_key(password.data(), password.size(), key, kdf_rounds); 93 | } 94 | } 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/crypto/crypto-ops.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | /* From fe.h */ 34 | 35 | typedef int32_t fe[10]; 36 | 37 | /* From ge.h */ 38 | 39 | typedef struct { 40 | fe X; 41 | fe Y; 42 | fe Z; 43 | } ge_p2; 44 | 45 | typedef struct { 46 | fe X; 47 | fe Y; 48 | fe Z; 49 | fe T; 50 | } ge_p3; 51 | 52 | typedef struct { 53 | fe X; 54 | fe Y; 55 | fe Z; 56 | fe T; 57 | } ge_p1p1; 58 | 59 | typedef struct { 60 | fe yplusx; 61 | fe yminusx; 62 | fe xy2d; 63 | } ge_precomp; 64 | 65 | typedef struct { 66 | fe YplusX; 67 | fe YminusX; 68 | fe Z; 69 | fe T2d; 70 | } ge_cached; 71 | 72 | /* From ge_add.c */ 73 | 74 | void ge_add(ge_p1p1 *, const ge_p3 *, const ge_cached *); 75 | 76 | /* From ge_double_scalarmult.c, modified */ 77 | 78 | typedef ge_cached ge_dsmp[8]; 79 | extern const ge_precomp ge_Bi[8]; 80 | void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s); 81 | void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *); 82 | void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *); 83 | 84 | /* From ge_frombytes.c, modified */ 85 | 86 | extern const fe fe_sqrtm1; 87 | extern const fe fe_d; 88 | int ge_frombytes_vartime(ge_p3 *, const unsigned char *); 89 | 90 | /* From ge_p1p1_to_p2.c */ 91 | 92 | void ge_p1p1_to_p2(ge_p2 *, const ge_p1p1 *); 93 | 94 | /* From ge_p1p1_to_p3.c */ 95 | 96 | void ge_p1p1_to_p3(ge_p3 *, const ge_p1p1 *); 97 | 98 | /* From ge_p2_dbl.c */ 99 | 100 | void ge_p2_dbl(ge_p1p1 *, const ge_p2 *); 101 | 102 | /* From ge_p3_to_cached.c */ 103 | 104 | extern const fe fe_d2; 105 | void ge_p3_to_cached(ge_cached *, const ge_p3 *); 106 | 107 | /* From ge_p3_to_p2.c */ 108 | 109 | void ge_p3_to_p2(ge_p2 *, const ge_p3 *); 110 | 111 | /* From ge_p3_tobytes.c */ 112 | 113 | void ge_p3_tobytes(unsigned char *, const ge_p3 *); 114 | 115 | /* From ge_scalarmult_base.c */ 116 | 117 | extern const ge_precomp ge_base[32][8]; 118 | void ge_scalarmult_base(ge_p3 *, const unsigned char *); 119 | 120 | /* From ge_tobytes.c */ 121 | 122 | void ge_tobytes(unsigned char *, const ge_p2 *); 123 | 124 | /* From sc_reduce.c */ 125 | 126 | void sc_reduce(unsigned char *); 127 | 128 | /* New code */ 129 | 130 | void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *); 131 | void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *); 132 | void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp); 133 | void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); 134 | void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); 135 | void ge_mul8(ge_p1p1 *, const ge_p2 *); 136 | extern const fe fe_ma2; 137 | extern const fe fe_ma; 138 | extern const fe fe_fffb1; 139 | extern const fe fe_fffb2; 140 | extern const fe fe_fffb3; 141 | extern const fe fe_fffb4; 142 | extern const ge_p3 ge_p3_identity; 143 | extern const ge_p3 ge_p3_H; 144 | void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); 145 | void sc_0(unsigned char *); 146 | void sc_reduce32(unsigned char *); 147 | void sc_add(unsigned char *, const unsigned char *, const unsigned char *); 148 | void sc_sub(unsigned char *, const unsigned char *, const unsigned char *); 149 | void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *); 150 | void sc_mul(unsigned char *, const unsigned char *, const unsigned char *); 151 | void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); 152 | int sc_check(const unsigned char *); 153 | int sc_isnonzero(const unsigned char *); /* Doesn't normalize */ 154 | 155 | // internal 156 | uint64_t load_3(const unsigned char *in); 157 | uint64_t load_4(const unsigned char *in); 158 | void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); 159 | void fe_add(fe h, const fe f, const fe g); 160 | void fe_tobytes(unsigned char *, const fe); 161 | void fe_invert(fe out, const fe z); 162 | 163 | int ge_p3_is_point_at_infinity(const ge_p3 *p); 164 | -------------------------------------------------------------------------------- /src/crypto/generic-ops.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #define CRYPTO_MAKE_COMPARABLE(type) \ 39 | namespace crypto { \ 40 | inline bool operator==(const type &_v1, const type &_v2) { \ 41 | return !memcmp(&_v1, &_v2, sizeof(_v1)); \ 42 | } \ 43 | inline bool operator!=(const type &_v1, const type &_v2) { \ 44 | return !operator==(_v1, _v2); \ 45 | } \ 46 | } 47 | 48 | #define CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \ 49 | namespace crypto { \ 50 | inline bool operator==(const type &_v1, const type &_v2) { \ 51 | static_assert(sizeof(_v1) == 32, "constant time comparison is only implenmted for 32 bytes"); \ 52 | return crypto_verify_32((const unsigned char*)&_v1, (const unsigned char*)&_v2) == 0; \ 53 | } \ 54 | inline bool operator!=(const type &_v1, const type &_v2) { \ 55 | return !operator==(_v1, _v2); \ 56 | } \ 57 | } 58 | 59 | #define CRYPTO_DEFINE_HASH_FUNCTIONS(type) \ 60 | namespace crypto { \ 61 | static_assert(sizeof(std::size_t) <= sizeof(type), "Size of " #type " must be at least that of size_t"); \ 62 | inline std::size_t hash_value(const type &_v) { \ 63 | return reinterpret_cast(_v); \ 64 | } \ 65 | } \ 66 | namespace std { \ 67 | template<> \ 68 | struct hash { \ 69 | std::size_t operator()(const crypto::type &_v) const { \ 70 | return reinterpret_cast(_v); \ 71 | } \ 72 | }; \ 73 | } 74 | 75 | #define CRYPTO_MAKE_HASHABLE(type) \ 76 | CRYPTO_MAKE_COMPARABLE(type) \ 77 | CRYPTO_DEFINE_HASH_FUNCTIONS(type) 78 | 79 | #define CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(type) \ 80 | CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \ 81 | CRYPTO_DEFINE_HASH_FUNCTIONS(type) 82 | 83 | -------------------------------------------------------------------------------- /src/crypto/groestl.c: -------------------------------------------------------------------------------- 1 | /* hash.c April 2012 2 | * Groestl ANSI C code optimised for 32-bit machines 3 | * Author: Thomas Krinninger 4 | * 5 | * This work is based on the implementation of 6 | * Soeren S. Thomsen and Krystian Matusiewicz 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include "groestl.h" 13 | #include "groestl_tables.h" 14 | 15 | #define P_TYPE 0 16 | #define Q_TYPE 1 17 | 18 | const uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}}; 19 | 20 | const uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6}; 21 | 22 | 23 | #define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \ 24 | v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \ 25 | v1 = temp_var;} 26 | 27 | 28 | #define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t) \ 29 | tu = T[2*(uint32_t)x[4*c0+0]]; \ 30 | tl = T[2*(uint32_t)x[4*c0+0]+1]; \ 31 | tv1 = T[2*(uint32_t)x[4*c1+1]]; \ 32 | tv2 = T[2*(uint32_t)x[4*c1+1]+1]; \ 33 | ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ 34 | tu ^= tv1; \ 35 | tl ^= tv2; \ 36 | tv1 = T[2*(uint32_t)x[4*c2+2]]; \ 37 | tv2 = T[2*(uint32_t)x[4*c2+2]+1]; \ 38 | ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ 39 | tu ^= tv1; \ 40 | tl ^= tv2; \ 41 | tv1 = T[2*(uint32_t)x[4*c3+3]]; \ 42 | tv2 = T[2*(uint32_t)x[4*c3+3]+1]; \ 43 | ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ 44 | tu ^= tv1; \ 45 | tl ^= tv2; \ 46 | tl ^= T[2*(uint32_t)x[4*c4+0]]; \ 47 | tu ^= T[2*(uint32_t)x[4*c4+0]+1]; \ 48 | tv1 = T[2*(uint32_t)x[4*c5+1]]; \ 49 | tv2 = T[2*(uint32_t)x[4*c5+1]+1]; \ 50 | ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ 51 | tl ^= tv1; \ 52 | tu ^= tv2; \ 53 | tv1 = T[2*(uint32_t)x[4*c6+2]]; \ 54 | tv2 = T[2*(uint32_t)x[4*c6+2]+1]; \ 55 | ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ 56 | tl ^= tv1; \ 57 | tu ^= tv2; \ 58 | tv1 = T[2*(uint32_t)x[4*c7+3]]; \ 59 | tv2 = T[2*(uint32_t)x[4*c7+3]+1]; \ 60 | ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ 61 | tl ^= tv1; \ 62 | tu ^= tv2; \ 63 | y[i] = tu; \ 64 | y[i+1] = tl; 65 | 66 | 67 | /* compute one round of P (short variants) */ 68 | static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) { 69 | uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; 70 | uint32_t* x32 = (uint32_t*)x; 71 | x32[ 0] ^= 0x00000000^r; 72 | x32[ 2] ^= 0x00000010^r; 73 | x32[ 4] ^= 0x00000020^r; 74 | x32[ 6] ^= 0x00000030^r; 75 | x32[ 8] ^= 0x00000040^r; 76 | x32[10] ^= 0x00000050^r; 77 | x32[12] ^= 0x00000060^r; 78 | x32[14] ^= 0x00000070^r; 79 | COLUMN(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 80 | COLUMN(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 81 | COLUMN(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 82 | COLUMN(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 83 | COLUMN(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 84 | COLUMN(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 85 | COLUMN(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 86 | COLUMN(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 87 | } 88 | 89 | /* compute one round of Q (short variants) */ 90 | static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) { 91 | uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; 92 | uint32_t* x32 = (uint32_t*)x; 93 | x32[ 0] = ~x32[ 0]; 94 | x32[ 1] ^= 0xffffffff^r; 95 | x32[ 2] = ~x32[ 2]; 96 | x32[ 3] ^= 0xefffffff^r; 97 | x32[ 4] = ~x32[ 4]; 98 | x32[ 5] ^= 0xdfffffff^r; 99 | x32[ 6] = ~x32[ 6]; 100 | x32[ 7] ^= 0xcfffffff^r; 101 | x32[ 8] = ~x32[ 8]; 102 | x32[ 9] ^= 0xbfffffff^r; 103 | x32[10] = ~x32[10]; 104 | x32[11] ^= 0xafffffff^r; 105 | x32[12] = ~x32[12]; 106 | x32[13] ^= 0x9fffffff^r; 107 | x32[14] = ~x32[14]; 108 | x32[15] ^= 0x8fffffff^r; 109 | COLUMN(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 110 | COLUMN(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 111 | COLUMN(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 112 | COLUMN(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 113 | COLUMN(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 114 | COLUMN(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 115 | COLUMN(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 116 | COLUMN(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); 117 | } 118 | 119 | /* compute compression function (short variants) */ 120 | static void F512(uint32_t *h, const uint32_t *m) { 121 | int i; 122 | uint32_t Ptmp[2*COLS512]; 123 | uint32_t Qtmp[2*COLS512]; 124 | uint32_t y[2*COLS512]; 125 | uint32_t z[2*COLS512]; 126 | 127 | for (i = 0; i < 2*COLS512; i++) { 128 | z[i] = m[i]; 129 | Ptmp[i] = h[i]^m[i]; 130 | } 131 | 132 | /* compute Q(m) */ 133 | RND512Q((uint8_t*)z, y, 0x00000000); 134 | RND512Q((uint8_t*)y, z, 0x01000000); 135 | RND512Q((uint8_t*)z, y, 0x02000000); 136 | RND512Q((uint8_t*)y, z, 0x03000000); 137 | RND512Q((uint8_t*)z, y, 0x04000000); 138 | RND512Q((uint8_t*)y, z, 0x05000000); 139 | RND512Q((uint8_t*)z, y, 0x06000000); 140 | RND512Q((uint8_t*)y, z, 0x07000000); 141 | RND512Q((uint8_t*)z, y, 0x08000000); 142 | RND512Q((uint8_t*)y, Qtmp, 0x09000000); 143 | 144 | /* compute P(h+m) */ 145 | RND512P((uint8_t*)Ptmp, y, 0x00000000); 146 | RND512P((uint8_t*)y, z, 0x00000001); 147 | RND512P((uint8_t*)z, y, 0x00000002); 148 | RND512P((uint8_t*)y, z, 0x00000003); 149 | RND512P((uint8_t*)z, y, 0x00000004); 150 | RND512P((uint8_t*)y, z, 0x00000005); 151 | RND512P((uint8_t*)z, y, 0x00000006); 152 | RND512P((uint8_t*)y, z, 0x00000007); 153 | RND512P((uint8_t*)z, y, 0x00000008); 154 | RND512P((uint8_t*)y, Ptmp, 0x00000009); 155 | 156 | /* compute P(h+m) + Q(m) + h */ 157 | for (i = 0; i < 2*COLS512; i++) { 158 | h[i] ^= Ptmp[i]^Qtmp[i]; 159 | } 160 | } 161 | 162 | 163 | /* digest up to msglen bytes of input (full blocks only) */ 164 | static void Transform(hashState *ctx, 165 | const uint8_t *input, 166 | int msglen) { 167 | 168 | /* digest message, one block at a time */ 169 | for (; msglen >= SIZE512; 170 | msglen -= SIZE512, input += SIZE512) { 171 | F512(ctx->chaining,(uint32_t*)input); 172 | 173 | /* increment block counter */ 174 | ctx->block_counter1++; 175 | if (ctx->block_counter1 == 0) ctx->block_counter2++; 176 | } 177 | } 178 | 179 | /* given state h, do h <- P(h)+h */ 180 | static void OutputTransformation(hashState *ctx) { 181 | int j; 182 | uint32_t temp[2*COLS512]; 183 | uint32_t y[2*COLS512]; 184 | uint32_t z[2*COLS512]; 185 | 186 | 187 | 188 | for (j = 0; j < 2*COLS512; j++) { 189 | temp[j] = ctx->chaining[j]; 190 | } 191 | RND512P((uint8_t*)temp, y, 0x00000000); 192 | RND512P((uint8_t*)y, z, 0x00000001); 193 | RND512P((uint8_t*)z, y, 0x00000002); 194 | RND512P((uint8_t*)y, z, 0x00000003); 195 | RND512P((uint8_t*)z, y, 0x00000004); 196 | RND512P((uint8_t*)y, z, 0x00000005); 197 | RND512P((uint8_t*)z, y, 0x00000006); 198 | RND512P((uint8_t*)y, z, 0x00000007); 199 | RND512P((uint8_t*)z, y, 0x00000008); 200 | RND512P((uint8_t*)y, temp, 0x00000009); 201 | for (j = 0; j < 2*COLS512; j++) { 202 | ctx->chaining[j] ^= temp[j]; 203 | } 204 | } 205 | 206 | /* initialise context */ 207 | static void Init(hashState* ctx) { 208 | /* allocate memory for state and data buffer */ 209 | 210 | for(size_t i = 0; i < (SIZE512/sizeof(uint32_t)); i++) 211 | { 212 | ctx->chaining[i] = 0; 213 | } 214 | 215 | /* set initial value */ 216 | ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN); 217 | 218 | /* set other variables */ 219 | ctx->buf_ptr = 0; 220 | ctx->block_counter1 = 0; 221 | ctx->block_counter2 = 0; 222 | ctx->bits_in_last_byte = 0; 223 | } 224 | 225 | /* update state with databitlen bits of input */ 226 | static void Update(hashState* ctx, 227 | const BitSequence* input, 228 | DataLength databitlen) { 229 | int index = 0; 230 | int msglen = (int)(databitlen/8); 231 | int rem = (int)(databitlen%8); 232 | 233 | /* if the buffer contains data that has not yet been digested, first 234 | add data to buffer until full */ 235 | if (ctx->buf_ptr) { 236 | while (ctx->buf_ptr < SIZE512 && index < msglen) { 237 | ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; 238 | } 239 | if (ctx->buf_ptr < SIZE512) { 240 | /* buffer still not full, return */ 241 | if (rem) { 242 | ctx->bits_in_last_byte = rem; 243 | ctx->buffer[(int)ctx->buf_ptr++] = input[index]; 244 | } 245 | return; 246 | } 247 | 248 | /* digest buffer */ 249 | ctx->buf_ptr = 0; 250 | Transform(ctx, ctx->buffer, SIZE512); 251 | } 252 | 253 | /* digest bulk of message */ 254 | Transform(ctx, input+index, msglen-index); 255 | index += ((msglen-index)/SIZE512)*SIZE512; 256 | 257 | /* store remaining data in buffer */ 258 | while (index < msglen) { 259 | ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; 260 | } 261 | 262 | /* if non-integral number of bytes have been supplied, store 263 | remaining bits in last byte, together with information about 264 | number of bits */ 265 | if (rem) { 266 | ctx->bits_in_last_byte = rem; 267 | ctx->buffer[(int)ctx->buf_ptr++] = input[index]; 268 | } 269 | } 270 | 271 | #define BILB ctx->bits_in_last_byte 272 | 273 | /* finalise: process remaining data (including padding), perform 274 | output transformation, and write hash result to 'output' */ 275 | static void Final(hashState* ctx, 276 | BitSequence* output) { 277 | int i, j = 0, hashbytelen = HASH_BIT_LEN/8; 278 | uint8_t *s = (BitSequence*)ctx->chaining; 279 | 280 | /* pad with '1'-bit and first few '0'-bits */ 281 | if (BILB) { 282 | ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB); 284 | BILB = 0; 285 | } 286 | else ctx->buffer[(int)ctx->buf_ptr++] = 0x80; 287 | 288 | /* pad with '0'-bits */ 289 | if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) { 290 | /* padding requires two blocks */ 291 | while (ctx->buf_ptr < SIZE512) { 292 | ctx->buffer[(int)ctx->buf_ptr++] = 0; 293 | } 294 | /* digest first padding block */ 295 | Transform(ctx, ctx->buffer, SIZE512); 296 | ctx->buf_ptr = 0; 297 | } 298 | while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) { 299 | ctx->buffer[(int)ctx->buf_ptr++] = 0; 300 | } 301 | 302 | /* length padding */ 303 | ctx->block_counter1++; 304 | if (ctx->block_counter1 == 0) ctx->block_counter2++; 305 | ctx->buf_ptr = SIZE512; 306 | 307 | while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) { 308 | ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1; 309 | ctx->block_counter1 >>= 8; 310 | } 311 | while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) { 312 | ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2; 313 | ctx->block_counter2 >>= 8; 314 | } 315 | /* digest final padding block */ 316 | Transform(ctx, ctx->buffer, SIZE512); 317 | /* perform output transformation */ 318 | OutputTransformation(ctx); 319 | 320 | /* store hash result in output */ 321 | for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) { 322 | output[j] = s[i]; 323 | } 324 | 325 | /* zeroise relevant variables and deallocate memory */ 326 | for (i = 0; i < COLS512; i++) { 327 | ctx->chaining[i] = 0; 328 | } 329 | for (i = 0; i < SIZE512; i++) { 330 | ctx->buffer[i] = 0; 331 | } 332 | } 333 | 334 | /* hash bit sequence */ 335 | void groestl(const BitSequence* data, 336 | DataLength databitlen, 337 | BitSequence* hashval) { 338 | 339 | hashState context; 340 | 341 | /* initialise */ 342 | Init(&context); 343 | 344 | 345 | /* process message */ 346 | Update(&context, data, databitlen); 347 | 348 | /* finalise */ 349 | Final(&context, hashval); 350 | } 351 | /* 352 | static int crypto_hash(unsigned char *out, 353 | const unsigned char *in, 354 | unsigned long long len) 355 | { 356 | groestl(in, 8*len, out); 357 | return 0; 358 | } 359 | 360 | */ 361 | -------------------------------------------------------------------------------- /src/crypto/groestl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef __hash_h 30 | #define __hash_h 31 | /* 32 | #include "crypto_uint8.h" 33 | #include "crypto_uint32.h" 34 | #include "crypto_uint64.h" 35 | #include "crypto_hash.h" 36 | 37 | typedef crypto_uint8 uint8_t; 38 | typedef crypto_uint32 uint32_t; 39 | typedef crypto_uint64 uint64_t; 40 | */ 41 | #include 42 | 43 | /* some sizes (number of bytes) */ 44 | #define ROWS 8 45 | #define LENGTHFIELDLEN ROWS 46 | #define COLS512 8 47 | 48 | #define SIZE512 (ROWS*COLS512) 49 | 50 | #define ROUNDS512 10 51 | #define HASH_BIT_LEN 256 52 | 53 | #define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff)) 54 | 55 | 56 | #define li_32(h) 0x##h##u 57 | #define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n))) 58 | #define u32BIG(a) \ 59 | ((ROTL32(a,8) & li_32(00FF00FF)) | \ 60 | (ROTL32(a,24) & li_32(FF00FF00))) 61 | 62 | 63 | /* NIST API begin */ 64 | typedef unsigned char BitSequence; 65 | typedef unsigned long long DataLength; 66 | typedef struct { 67 | uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */ 68 | uint32_t block_counter1, 69 | block_counter2; /* message block counter(s) */ 70 | BitSequence buffer[SIZE512]; /* data buffer */ 71 | int buf_ptr; /* data buffer pointer */ 72 | int bits_in_last_byte; /* no. of message bits in last byte of 73 | data buffer */ 74 | } hashState; 75 | 76 | /*void Init(hashState*); 77 | void Update(hashState*, const BitSequence*, DataLength); 78 | void Final(hashState*, BitSequence*); */ 79 | void groestl(const BitSequence*, DataLength, BitSequence*); 80 | /* NIST API end */ 81 | 82 | /* 83 | int crypto_hash(unsigned char *out, 84 | const unsigned char *in, 85 | unsigned long long len); 86 | */ 87 | 88 | #endif /* __hash_h */ 89 | -------------------------------------------------------------------------------- /src/crypto/groestl_tables.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef __tables_h 30 | #define __tables_h 31 | 32 | 33 | const uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc 34 | , 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5 35 | , 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d 36 | , 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded 37 | , 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1 38 | , 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441 39 | , 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4 40 | , 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba 41 | , 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616 42 | , 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2 43 | , 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c 44 | , 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de 45 | , 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7 46 | , 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e 47 | , 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c 48 | , 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7 49 | , 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b 50 | , 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4 51 | , 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e 52 | , 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a 53 | , 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37 54 | , 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86 55 | , 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b 56 | , 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028 57 | , 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3 58 | , 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94 59 | , 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836 60 | , 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0 61 | , 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2 62 | , 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e 63 | , 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3 64 | , 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e}; 65 | 66 | #endif /* __tables_h */ 67 | -------------------------------------------------------------------------------- /src/crypto/hash-extra-blake.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #include "blake256.h" 35 | 36 | void hash_extra_blake(const void *data, size_t length, char *hash) { 37 | blake256_hash((uint8_t*)hash, data, length); 38 | } 39 | -------------------------------------------------------------------------------- /src/crypto/hash-extra-groestl.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #include "groestl.h" 35 | 36 | void hash_extra_groestl(const void *data, size_t length, char *hash) { 37 | groestl(data, length * 8, (uint8_t*)hash); 38 | } 39 | -------------------------------------------------------------------------------- /src/crypto/hash-extra-jh.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "jh.h" 37 | #include "hash-ops.h" 38 | 39 | void hash_extra_jh(const void *data, size_t length, char *hash) { 40 | int r = jh_hash(HASH_SIZE * 8, data, 8 * length, (uint8_t*)hash); 41 | assert(SUCCESS == r); 42 | } 43 | -------------------------------------------------------------------------------- /src/crypto/hash-extra-skein.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #include "hash-ops.h" 35 | #include "skein.h" 36 | 37 | void hash_extra_skein(const void *data, size_t length, char *hash) { 38 | int r = skein_hash(8 * HASH_SIZE, data, 8 * length, (uint8_t*)hash); 39 | assert(SKEIN_SUCCESS == r); 40 | } 41 | -------------------------------------------------------------------------------- /src/crypto/hash-ops.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #if !defined(__cplusplus) 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "common/int-util.h" 41 | #include "warnings.h" 42 | 43 | static inline void *padd(void *p, size_t i) { 44 | return (char *) p + i; 45 | } 46 | 47 | static inline const void *cpadd(const void *p, size_t i) { 48 | return (const char *) p + i; 49 | } 50 | 51 | PUSH_WARNINGS 52 | DISABLE_VS_WARNINGS(4267) 53 | static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t must be 4 or 8 bytes long"); 54 | static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length) { 55 | if (sizeof(size_t) == 4) { 56 | *(uint32_t *) padd(buffer, bufsize - 4) = swap32be(length); 57 | } else { 58 | *(uint64_t *) padd(buffer, bufsize - 8) = swap64be(length); 59 | } 60 | } 61 | POP_WARNINGS 62 | 63 | #pragma pack(push, 1) 64 | union hash_state { 65 | uint8_t b[200]; 66 | uint64_t w[25]; 67 | }; 68 | #pragma pack(pop) 69 | static_assert(sizeof(union hash_state) == 200, "Invalid structure size"); 70 | 71 | void hash_permutation(union hash_state *state); 72 | void hash_process(union hash_state *state, const uint8_t *buf, size_t count); 73 | 74 | #endif 75 | 76 | enum { 77 | HASH_SIZE = 32, 78 | HASH_DATA_AREA = 136 79 | }; 80 | 81 | void cn_fast_hash(const void *data, size_t length, char *hash); 82 | void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); 83 | 84 | void hash_extra_blake(const void *data, size_t length, char *hash); 85 | void hash_extra_groestl(const void *data, size_t length, char *hash); 86 | void hash_extra_jh(const void *data, size_t length, char *hash); 87 | void hash_extra_skein(const void *data, size_t length, char *hash); 88 | 89 | void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash); 90 | -------------------------------------------------------------------------------- /src/crypto/hash.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "hash-ops.h" 36 | #include "keccak.h" 37 | 38 | void hash_permutation(union hash_state *state) { 39 | keccakf((uint64_t*)state, 24); 40 | } 41 | 42 | void hash_process(union hash_state *state, const uint8_t *buf, size_t count) { 43 | keccak1600(buf, count, (uint8_t*)state); 44 | } 45 | 46 | void cn_fast_hash(const void *data, size_t length, char *hash) { 47 | union hash_state state; 48 | hash_process(&state, data, length); 49 | memcpy(hash, &state, HASH_SIZE); 50 | } 51 | -------------------------------------------------------------------------------- /src/crypto/hash.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include "common/pod-class.h" 38 | #include "generic-ops.h" 39 | #include "hex.h" 40 | #include "span.h" 41 | 42 | namespace crypto { 43 | 44 | extern "C" { 45 | #include "hash-ops.h" 46 | } 47 | 48 | #pragma pack(push, 1) 49 | POD_CLASS hash { 50 | char data[HASH_SIZE]; 51 | }; 52 | POD_CLASS hash8 { 53 | char data[8]; 54 | }; 55 | #pragma pack(pop) 56 | 57 | static_assert(sizeof(hash) == HASH_SIZE, "Invalid structure size"); 58 | static_assert(sizeof(hash8) == 8, "Invalid structure size"); 59 | 60 | /* 61 | Cryptonight hash functions 62 | */ 63 | 64 | inline void cn_fast_hash(const void *data, std::size_t length, hash &hash) { 65 | cn_fast_hash(data, length, reinterpret_cast(&hash)); 66 | } 67 | 68 | inline hash cn_fast_hash(const void *data, std::size_t length) { 69 | hash h; 70 | cn_fast_hash(data, length, reinterpret_cast(&h)); 71 | return h; 72 | } 73 | 74 | inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { 75 | cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/, height); 76 | } 77 | 78 | inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { 79 | cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/, height); 80 | } 81 | 82 | inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { 83 | tree_hash(reinterpret_cast(hashes), count, reinterpret_cast(&root_hash)); 84 | } 85 | 86 | inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { 87 | epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; 88 | } 89 | inline std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { 90 | epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; 91 | } 92 | 93 | const static crypto::hash null_hash = boost::value_initialized(); 94 | const static crypto::hash8 null_hash8 = boost::value_initialized(); 95 | } 96 | 97 | CRYPTO_MAKE_HASHABLE(hash) 98 | CRYPTO_MAKE_COMPARABLE(hash8) 99 | -------------------------------------------------------------------------------- /src/crypto/initializer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #if defined(__GNUC__) 34 | #if defined(__sun) && defined(__SVR4) 35 | #define INITIALIZER(name) __attribute__((constructor)) static void name(void) 36 | #define FINALIZER(name) __attribute__((destructor)) static void name(void) 37 | #else 38 | #define INITIALIZER(name) __attribute__((constructor(101))) static void name(void) 39 | #define FINALIZER(name) __attribute__((destructor(101))) static void name(void) 40 | #endif 41 | #define REGISTER_FINALIZER(name) ((void) 0) 42 | 43 | #elif defined(_MSC_VER) 44 | #include 45 | #include 46 | // https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc 47 | // https://msdn.microsoft.com/en-us/library/bb918180.aspx 48 | #pragma section(".CRT$XCT", read) 49 | #define INITIALIZER(name) \ 50 | static void __cdecl name(void); \ 51 | __declspec(allocate(".CRT$XCT")) void (__cdecl *const _##name)(void) = &name; \ 52 | static void __cdecl name(void) 53 | #define FINALIZER(name) \ 54 | static void __cdecl name(void) 55 | #define REGISTER_FINALIZER(name) \ 56 | do { \ 57 | int _res = atexit(name); \ 58 | assert(_res == 0); \ 59 | } while (0); 60 | 61 | #else 62 | #error Unsupported compiler 63 | #endif 64 | -------------------------------------------------------------------------------- /src/crypto/jh.c: -------------------------------------------------------------------------------- 1 | /*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C 2 | 3 | -------------------------------- 4 | Performance 5 | 6 | Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz) 7 | Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic) 8 | Speed for long message: 9 | 1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2 10 | 2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3 11 | 12 | -------------------------------- 13 | Last Modified: January 16, 2011 14 | */ 15 | 16 | #include "jh.h" 17 | 18 | #include 19 | #include 20 | 21 | /*typedef unsigned long long uint64;*/ 22 | typedef uint64_t uint64; 23 | 24 | /*define data alignment for different C compilers*/ 25 | #if defined(__GNUC__) 26 | #define DATA_ALIGN16(x) x __attribute__ ((aligned(16))) 27 | #else 28 | #define DATA_ALIGN16(x) __declspec(align(16)) x 29 | #endif 30 | 31 | 32 | typedef struct { 33 | int hashbitlen; /*the message digest size*/ 34 | unsigned long long databitlen; /*the message size in bits*/ 35 | unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/ 36 | DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/ 37 | unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/ 38 | } hashState; 39 | 40 | 41 | /*The initial hash value H(0)*/ 42 | const unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e}; 43 | const unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69}; 44 | const unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f}; 45 | const unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b}; 46 | 47 | /*42 round constants, each round constant is 32-byte (256-bit)*/ 48 | const unsigned char E8_bitslice_roundconstant[42][32]={ 49 | {0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40}, 50 | {0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31}, 51 | {0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc}, 52 | {0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3}, 53 | {0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23}, 54 | {0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97}, 55 | {0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14}, 56 | {0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4}, 57 | {0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36}, 58 | {0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f}, 59 | {0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b}, 60 | {0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62}, 61 | {0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5}, 62 | {0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f}, 63 | {0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a}, 64 | {0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf}, 65 | {0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0}, 66 | {0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a}, 67 | {0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6}, 68 | {0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67}, 69 | {0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18}, 70 | {0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e}, 71 | {0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1}, 72 | {0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83}, 73 | {0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef}, 74 | {0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65}, 75 | {0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c}, 76 | {0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71}, 77 | {0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0}, 78 | {0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f}, 79 | {0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad}, 80 | {0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6}, 81 | {0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63}, 82 | {0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f}, 83 | {0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a}, 84 | {0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5}, 85 | {0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48}, 86 | {0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e}, 87 | {0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7}, 88 | {0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde}, 89 | {0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a}, 90 | {0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}}; 91 | 92 | 93 | static void E8(hashState *state); /*The bijective function E8, in bitslice form*/ 94 | static void F8(hashState *state); /*The compression function F8 */ 95 | 96 | /*The API functions*/ 97 | static HashReturn Init(hashState *state, int hashbitlen); 98 | static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); 99 | static HashReturn Final(hashState *state, BitSequence *hashval); 100 | HashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval); 101 | 102 | /*swapping bit 2i with bit 2i+1 of 64-bit x*/ 103 | #define SWAP1(x) (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1)); 104 | /*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/ 105 | #define SWAP2(x) (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2)); 106 | /*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/ 107 | #define SWAP4(x) (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4)); 108 | /*swapping bits 16i||16i+1||......||16i+7 with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/ 109 | #define SWAP8(x) (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8)); 110 | /*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/ 111 | #define SWAP16(x) (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16)); 112 | /*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/ 113 | #define SWAP32(x) (x) = (((x) << 32) | ((x) >> 32)); 114 | 115 | /*The MDS transform*/ 116 | #define L(m0,m1,m2,m3,m4,m5,m6,m7) \ 117 | (m4) ^= (m1); \ 118 | (m5) ^= (m2); \ 119 | (m6) ^= (m0) ^ (m3); \ 120 | (m7) ^= (m0); \ 121 | (m0) ^= (m5); \ 122 | (m1) ^= (m6); \ 123 | (m2) ^= (m4) ^ (m7); \ 124 | (m3) ^= (m4); 125 | 126 | /*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/ 127 | /*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/ 128 | #define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1) \ 129 | m3 = ~(m3); \ 130 | m7 = ~(m7); \ 131 | m0 ^= ((~(m2)) & (cc0)); \ 132 | m4 ^= ((~(m6)) & (cc1)); \ 133 | temp0 = (cc0) ^ ((m0) & (m1));\ 134 | temp1 = (cc1) ^ ((m4) & (m5));\ 135 | m0 ^= ((m2) & (m3)); \ 136 | m4 ^= ((m6) & (m7)); \ 137 | m3 ^= ((~(m1)) & (m2)); \ 138 | m7 ^= ((~(m5)) & (m6)); \ 139 | m1 ^= ((m0) & (m2)); \ 140 | m5 ^= ((m4) & (m6)); \ 141 | m2 ^= ((m0) & (~(m3))); \ 142 | m6 ^= ((m4) & (~(m7))); \ 143 | m0 ^= ((m1) | (m3)); \ 144 | m4 ^= ((m5) | (m7)); \ 145 | m3 ^= ((m1) & (m2)); \ 146 | m7 ^= ((m5) & (m6)); \ 147 | m1 ^= (temp0 & (m0)); \ 148 | m5 ^= (temp1 & (m4)); \ 149 | m2 ^= temp0; \ 150 | m6 ^= temp1; 151 | 152 | /*The bijective function E8, in bitslice form*/ 153 | static void E8(hashState *state) 154 | { 155 | uint64 i,roundnumber,temp0,temp1; 156 | 157 | for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) { 158 | /*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/ 159 | for (i = 0; i < 2; i++) { 160 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] ); 161 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 162 | SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]); 163 | } 164 | 165 | /*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/ 166 | for (i = 0; i < 2; i++) { 167 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] ); 168 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 169 | SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]); 170 | } 171 | 172 | /*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/ 173 | for (i = 0; i < 2; i++) { 174 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] ); 175 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 176 | SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]); 177 | } 178 | 179 | /*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/ 180 | for (i = 0; i < 2; i++) { 181 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] ); 182 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 183 | SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]); 184 | } 185 | 186 | /*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/ 187 | for (i = 0; i < 2; i++) { 188 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] ); 189 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 190 | SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]); 191 | } 192 | 193 | /*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/ 194 | for (i = 0; i < 2; i++) { 195 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] ); 196 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 197 | SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]); 198 | } 199 | 200 | /*round 7*roundnumber+6: Sbox and MDS layers*/ 201 | for (i = 0; i < 2; i++) { 202 | SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] ); 203 | L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); 204 | } 205 | /*round 7*roundnumber+6: swapping layer*/ 206 | for (i = 1; i < 8; i = i+2) { 207 | temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0; 208 | } 209 | } 210 | 211 | } 212 | 213 | /*The compression function F8 */ 214 | static void F8(hashState *state) 215 | { 216 | uint64 i; 217 | 218 | /*xor the 512-bit message with the fist half of the 1024-bit hash state*/ 219 | for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i]; 220 | 221 | /*the bijective function E8 */ 222 | E8(state); 223 | 224 | /*xor the 512-bit message with the second half of the 1024-bit hash state*/ 225 | for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i]; 226 | } 227 | 228 | /*before hashing a message, initialize the hash state as H0 */ 229 | static HashReturn Init(hashState *state, int hashbitlen) 230 | { 231 | state->databitlen = 0; 232 | state->datasize_in_buffer = 0; 233 | 234 | /*initialize the initial hash value of JH*/ 235 | state->hashbitlen = hashbitlen; 236 | 237 | /*load the intital hash value into state*/ 238 | switch (hashbitlen) 239 | { 240 | case 224: memcpy(state->x,JH224_H0,128); break; 241 | case 256: memcpy(state->x,JH256_H0,128); break; 242 | case 384: memcpy(state->x,JH384_H0,128); break; 243 | case 512: memcpy(state->x,JH512_H0,128); break; 244 | } 245 | 246 | return(SUCCESS); 247 | } 248 | 249 | 250 | /*hash each 512-bit message block, except the last partial block*/ 251 | static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) 252 | { 253 | DataLength index; /*the starting address of the data to be compressed*/ 254 | 255 | state->databitlen += databitlen; 256 | index = 0; 257 | 258 | /*if there is remaining data in the buffer, fill it to a full message block first*/ 259 | /*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/ 260 | 261 | /*There is data in the buffer, but the incoming data is insufficient for a full block*/ 262 | if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512) ) { 263 | if ( (databitlen & 7) == 0 ) { 264 | memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ; 265 | } 266 | else memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ; 267 | state->datasize_in_buffer += databitlen; 268 | databitlen = 0; 269 | } 270 | 271 | /*There is data in the buffer, and the incoming data is sufficient for a full block*/ 272 | if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512) ) { 273 | memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ; 274 | index = 64-(state->datasize_in_buffer >> 3); 275 | databitlen = databitlen - (512 - state->datasize_in_buffer); 276 | F8(state); 277 | state->datasize_in_buffer = 0; 278 | } 279 | 280 | /*hash the remaining full message blocks*/ 281 | for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) { 282 | memcpy(state->buffer, data+index, 64); 283 | F8(state); 284 | } 285 | 286 | /*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/ 287 | if ( databitlen > 0) { 288 | if ((databitlen & 7) == 0) 289 | memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3); 290 | else 291 | memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1); 292 | state->datasize_in_buffer = databitlen; 293 | } 294 | 295 | return(SUCCESS); 296 | } 297 | 298 | /*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/ 299 | static HashReturn Final(hashState *state, BitSequence *hashval) 300 | { 301 | unsigned int i; 302 | 303 | if ( (state->databitlen & 0x1ff) == 0 ) { 304 | /*pad the message when databitlen is multiple of 512 bits, then process the padded block*/ 305 | memset(state->buffer, 0, 64); 306 | state->buffer[0] = 0x80; 307 | state->buffer[63] = state->databitlen & 0xff; 308 | state->buffer[62] = (state->databitlen >> 8) & 0xff; 309 | state->buffer[61] = (state->databitlen >> 16) & 0xff; 310 | state->buffer[60] = (state->databitlen >> 24) & 0xff; 311 | state->buffer[59] = (state->databitlen >> 32) & 0xff; 312 | state->buffer[58] = (state->databitlen >> 40) & 0xff; 313 | state->buffer[57] = (state->databitlen >> 48) & 0xff; 314 | state->buffer[56] = (state->databitlen >> 56) & 0xff; 315 | F8(state); 316 | } 317 | else { 318 | /*set the rest of the bytes in the buffer to 0*/ 319 | if ( (state->datasize_in_buffer & 7) == 0) 320 | for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++) state->buffer[i] = 0; 321 | else 322 | for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++) state->buffer[i] = 0; 323 | 324 | /*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/ 325 | state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7)); 326 | 327 | F8(state); 328 | memset(state->buffer, 0, 64); 329 | state->buffer[63] = state->databitlen & 0xff; 330 | state->buffer[62] = (state->databitlen >> 8) & 0xff; 331 | state->buffer[61] = (state->databitlen >> 16) & 0xff; 332 | state->buffer[60] = (state->databitlen >> 24) & 0xff; 333 | state->buffer[59] = (state->databitlen >> 32) & 0xff; 334 | state->buffer[58] = (state->databitlen >> 40) & 0xff; 335 | state->buffer[57] = (state->databitlen >> 48) & 0xff; 336 | state->buffer[56] = (state->databitlen >> 56) & 0xff; 337 | F8(state); 338 | } 339 | 340 | /*truncating the final hash value to generate the message digest*/ 341 | switch(state->hashbitlen) { 342 | case 224: memcpy(hashval,(unsigned char*)state->x+64+36,28); break; 343 | case 256: memcpy(hashval,(unsigned char*)state->x+64+32,32); break; 344 | case 384: memcpy(hashval,(unsigned char*)state->x+64+16,48); break; 345 | case 512: memcpy(hashval,(unsigned char*)state->x+64,64); break; 346 | } 347 | 348 | return(SUCCESS); 349 | } 350 | 351 | /* hash a message, 352 | three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen) 353 | one output: message digest (hashval) 354 | */ 355 | HashReturn jh_hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval) 356 | { 357 | hashState state; 358 | 359 | if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) { 360 | Init(&state, hashbitlen); 361 | Update(&state, data, databitlen); 362 | Final(&state, hashval); 363 | return SUCCESS; 364 | } 365 | else 366 | return(BAD_HASHLEN); 367 | } 368 | -------------------------------------------------------------------------------- /src/crypto/jh.h: -------------------------------------------------------------------------------- 1 | /*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C 2 | 3 | -------------------------------- 4 | Performance 5 | 6 | Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz) 7 | Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic) 8 | Speed for long message: 9 | 1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2 10 | 2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3 11 | 12 | -------------------------------- 13 | Last Modified: January 16, 2011 14 | */ 15 | #pragma once 16 | 17 | typedef unsigned char BitSequence; 18 | typedef unsigned long long DataLength; 19 | typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn; 20 | 21 | HashReturn jh_hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); 22 | -------------------------------------------------------------------------------- /src/crypto/keccak.c: -------------------------------------------------------------------------------- 1 | // keccak.c 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | // A baseline Keccak (3rd round) implementation. 4 | 5 | #include 6 | #include 7 | #include 8 | #include "common/int-util.h" 9 | #include "hash-ops.h" 10 | #include "keccak.h" 11 | 12 | static void local_abort(const char *msg) 13 | { 14 | fprintf(stderr, "%s\n", msg); 15 | #ifdef NDEBUG 16 | _exit(1); 17 | #else 18 | abort(); 19 | #endif 20 | } 21 | 22 | const uint64_t keccakf_rndc[24] = 23 | { 24 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 25 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, 26 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 27 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, 28 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 29 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 30 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, 31 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 32 | }; 33 | 34 | const int keccakf_rotc[24] = 35 | { 36 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 37 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 38 | }; 39 | 40 | const int keccakf_piln[24] = 41 | { 42 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 43 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 44 | }; 45 | 46 | // update the state with given number of rounds 47 | 48 | void keccakf(uint64_t st[25], int rounds) 49 | { 50 | int i, j, round; 51 | uint64_t t, bc[5]; 52 | 53 | for (round = 0; round < rounds; round++) { 54 | 55 | // Theta 56 | for (i = 0; i < 5; i++) 57 | bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; 58 | 59 | for (i = 0; i < 5; i++) { 60 | t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); 61 | for (j = 0; j < 25; j += 5) 62 | st[j + i] ^= t; 63 | } 64 | 65 | // Rho Pi 66 | t = st[1]; 67 | for (i = 0; i < 24; i++) { 68 | j = keccakf_piln[i]; 69 | bc[0] = st[j]; 70 | st[j] = ROTL64(t, keccakf_rotc[i]); 71 | t = bc[0]; 72 | } 73 | 74 | // Chi 75 | for (j = 0; j < 25; j += 5) { 76 | for (i = 0; i < 5; i++) 77 | bc[i] = st[j + i]; 78 | for (i = 0; i < 5; i++) 79 | st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; 80 | } 81 | 82 | // Iota 83 | st[0] ^= keccakf_rndc[round]; 84 | } 85 | } 86 | 87 | // compute a keccak hash (md) of given byte length from "in" 88 | typedef uint64_t state_t[25]; 89 | 90 | void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) 91 | { 92 | state_t st; 93 | uint8_t temp[144]; 94 | size_t i, rsiz, rsizw; 95 | 96 | static_assert(HASH_DATA_AREA <= sizeof(temp), "Bad keccak preconditions"); 97 | if (mdlen <= 0 || (mdlen > 100 && sizeof(st) != (size_t)mdlen)) 98 | { 99 | local_abort("Bad keccak use"); 100 | } 101 | 102 | rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; 103 | rsizw = rsiz / 8; 104 | 105 | memset(st, 0, sizeof(st)); 106 | 107 | for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { 108 | for (i = 0; i < rsizw; i++) 109 | st[i] ^= swap64le(((uint64_t *) in)[i]); 110 | keccakf(st, KECCAK_ROUNDS); 111 | } 112 | 113 | // last block and padding 114 | if (inlen + 1 >= sizeof(temp) || inlen > rsiz || rsiz - inlen + inlen + 1 >= sizeof(temp) || rsiz == 0 || rsiz - 1 >= sizeof(temp) || rsizw * 8 > sizeof(temp)) 115 | { 116 | local_abort("Bad keccak use"); 117 | } 118 | 119 | memcpy(temp, in, inlen); 120 | temp[inlen++] = 1; 121 | memset(temp + inlen, 0, rsiz - inlen); 122 | temp[rsiz - 1] |= 0x80; 123 | 124 | for (i = 0; i < rsizw; i++) 125 | st[i] ^= swap64le(((uint64_t *) temp)[i]); 126 | 127 | keccakf(st, KECCAK_ROUNDS); 128 | 129 | if (((size_t)mdlen % sizeof(uint64_t)) != 0) 130 | { 131 | local_abort("Bad keccak use"); 132 | } 133 | memcpy_swap64le(md, st, mdlen/sizeof(uint64_t)); 134 | } 135 | 136 | void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md) 137 | { 138 | keccak(in, inlen, md, sizeof(state_t)); 139 | } 140 | 141 | #define KECCAK_FINALIZED 0x80000000 142 | #define KECCAK_BLOCKLEN 136 143 | #define KECCAK_WORDS 17 144 | #define KECCAK_DIGESTSIZE 32 145 | #define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0))) 146 | #define KECCAK_PROCESS_BLOCK(st, block) { \ 147 | for (int i_ = 0; i_ < KECCAK_WORDS; i_++){ \ 148 | ((st))[i_] ^= ((block))[i_]; \ 149 | }; \ 150 | keccakf(st, KECCAK_ROUNDS); } 151 | 152 | 153 | void keccak_init(KECCAK_CTX * ctx){ 154 | memset(ctx, 0, sizeof(KECCAK_CTX)); 155 | } 156 | 157 | void keccak_update(KECCAK_CTX * ctx, const uint8_t *in, size_t inlen){ 158 | if (ctx->rest & KECCAK_FINALIZED) { 159 | local_abort("Bad keccak use"); 160 | } 161 | 162 | const size_t idx = ctx->rest; 163 | ctx->rest = (ctx->rest + inlen) % KECCAK_BLOCKLEN; 164 | 165 | // fill partial block 166 | if (idx) { 167 | size_t left = KECCAK_BLOCKLEN - idx; 168 | memcpy((char*)ctx->message + idx, in, (inlen < left ? inlen : left)); 169 | if (inlen < left) return; 170 | 171 | KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message); 172 | 173 | in += left; 174 | inlen -= left; 175 | } 176 | 177 | const bool is_aligned = IS_ALIGNED_64(in); 178 | while (inlen >= KECCAK_BLOCKLEN) { 179 | const uint64_t* aligned_message_block; 180 | if (is_aligned) { 181 | aligned_message_block = (uint64_t*)in; 182 | } else { 183 | memcpy(ctx->message, in, KECCAK_BLOCKLEN); 184 | aligned_message_block = ctx->message; 185 | } 186 | 187 | KECCAK_PROCESS_BLOCK(ctx->hash, aligned_message_block); 188 | in += KECCAK_BLOCKLEN; 189 | inlen -= KECCAK_BLOCKLEN; 190 | } 191 | if (inlen) { 192 | memcpy(ctx->message, in, inlen); 193 | } 194 | } 195 | 196 | void keccak_finish(KECCAK_CTX * ctx, uint8_t *md){ 197 | if (!(ctx->rest & KECCAK_FINALIZED)) 198 | { 199 | // clear the rest of the data queue 200 | memset((char*)ctx->message + ctx->rest, 0, KECCAK_BLOCKLEN - ctx->rest); 201 | ((char*)ctx->message)[ctx->rest] |= 0x01; 202 | ((char*)ctx->message)[KECCAK_BLOCKLEN - 1] |= 0x80; 203 | 204 | // process final block 205 | KECCAK_PROCESS_BLOCK(ctx->hash, ctx->message); 206 | ctx->rest = KECCAK_FINALIZED; // mark context as finalized 207 | } 208 | 209 | static_assert(KECCAK_BLOCKLEN > KECCAK_DIGESTSIZE, ""); 210 | if (md) { 211 | memcpy(md, ctx->hash, KECCAK_DIGESTSIZE); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/crypto/keccak.h: -------------------------------------------------------------------------------- 1 | // keccak.h 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | 4 | #ifndef KECCAK_H 5 | #define KECCAK_H 6 | 7 | #include 8 | #include 9 | 10 | #ifndef KECCAK_ROUNDS 11 | #define KECCAK_ROUNDS 24 12 | #endif 13 | 14 | #ifndef ROTL64 15 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 16 | #endif 17 | 18 | // SHA3 Algorithm context. 19 | typedef struct KECCAK_CTX 20 | { 21 | // 1600 bits algorithm hashing state 22 | uint64_t hash[25]; 23 | // 1088-bit buffer for leftovers, block size = 136 B for 256-bit keccak 24 | uint64_t message[17]; 25 | // count of bytes in the message[] buffer 26 | size_t rest; 27 | } KECCAK_CTX; 28 | 29 | // compute a keccak hash (md) of given byte length from "in" 30 | void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen); 31 | 32 | // update the state 33 | void keccakf(uint64_t st[25], int norounds); 34 | 35 | void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md); 36 | 37 | void keccak_init(KECCAK_CTX * ctx); 38 | void keccak_update(KECCAK_CTX * ctx, const uint8_t *in, size_t inlen); 39 | void keccak_finish(KECCAK_CTX * ctx, uint8_t *md); 40 | #endif 41 | -------------------------------------------------------------------------------- /src/crypto/oaes_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * --------------------------------------------------------------------------- 3 | * OpenAES License 4 | * --------------------------------------------------------------------------- 5 | * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * - Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * - Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * --------------------------------------------------------------------------- 29 | */ 30 | 31 | #ifndef _OAES_CONFIG_H 32 | #define _OAES_CONFIG_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | //#ifndef OAES_HAVE_ISAAC 39 | //#define OAES_HAVE_ISAAC 1 40 | //#endif // OAES_HAVE_ISAAC 41 | 42 | //#ifndef OAES_DEBUG 43 | //#define OAES_DEBUG 0 44 | //#endif // OAES_DEBUG 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif // _OAES_CONFIG_H 51 | -------------------------------------------------------------------------------- /src/crypto/oaes_lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * --------------------------------------------------------------------------- 3 | * OpenAES License 4 | * --------------------------------------------------------------------------- 5 | * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * - Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * - Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * --------------------------------------------------------------------------- 29 | */ 30 | 31 | #ifndef _OAES_LIB_H 32 | #define _OAES_LIB_H 33 | 34 | #include 35 | #include 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | #ifdef _WIN32 42 | # ifdef OAES_SHARED 43 | # ifdef oaes_lib_EXPORTS 44 | # define OAES_API __declspec(dllexport) 45 | # else 46 | # define OAES_API __declspec(dllimport) 47 | # endif 48 | # else 49 | # define OAES_API 50 | # endif 51 | #else 52 | # define OAES_API 53 | #endif // WIN32 54 | 55 | #define OAES_VERSION "0.8.1" 56 | #define OAES_BLOCK_SIZE 16 57 | 58 | typedef void OAES_CTX; 59 | 60 | typedef enum 61 | { 62 | OAES_RET_FIRST = 0, 63 | OAES_RET_SUCCESS = 0, 64 | OAES_RET_UNKNOWN, 65 | OAES_RET_ARG1, 66 | OAES_RET_ARG2, 67 | OAES_RET_ARG3, 68 | OAES_RET_ARG4, 69 | OAES_RET_ARG5, 70 | OAES_RET_NOKEY, 71 | OAES_RET_MEM, 72 | OAES_RET_BUF, 73 | OAES_RET_HEADER, 74 | OAES_RET_COUNT 75 | } OAES_RET; 76 | 77 | /* 78 | * oaes_set_option() takes one of these values for its [option] parameter 79 | * some options accept either an optional or a required [value] parameter 80 | */ 81 | // no option 82 | #define OAES_OPTION_NONE 0 83 | // enable ECB mode, disable CBC mode 84 | #define OAES_OPTION_ECB 1 85 | // enable CBC mode, disable ECB mode 86 | // value is optional, may pass uint8_t iv[OAES_BLOCK_SIZE] to specify 87 | // the value of the initialization vector, iv 88 | #define OAES_OPTION_CBC 2 89 | 90 | #ifdef OAES_DEBUG 91 | typedef int ( * oaes_step_cb ) ( 92 | const uint8_t state[OAES_BLOCK_SIZE], 93 | const char * step_name, 94 | int step_count, 95 | void * user_data ); 96 | // enable state stepping mode 97 | // value is required, must pass oaes_step_cb to receive the state at each step 98 | #define OAES_OPTION_STEP_ON 4 99 | // disable state stepping mode 100 | #define OAES_OPTION_STEP_OFF 8 101 | #endif // OAES_DEBUG 102 | 103 | typedef uint16_t OAES_OPTION; 104 | 105 | typedef struct _oaes_key 106 | { 107 | size_t data_len; 108 | uint8_t *data; 109 | size_t exp_data_len; 110 | uint8_t *exp_data; 111 | size_t num_keys; 112 | size_t key_base; 113 | } oaes_key; 114 | 115 | typedef struct _oaes_ctx 116 | { 117 | #ifdef OAES_HAVE_ISAAC 118 | randctx * rctx; 119 | #endif // OAES_HAVE_ISAAC 120 | 121 | #ifdef OAES_DEBUG 122 | oaes_step_cb step_cb; 123 | #endif // OAES_DEBUG 124 | 125 | oaes_key * key; 126 | OAES_OPTION options; 127 | uint8_t iv[OAES_BLOCK_SIZE]; 128 | } oaes_ctx; 129 | /* 130 | * // usage: 131 | * 132 | * OAES_CTX * ctx = oaes_alloc(); 133 | * . 134 | * . 135 | * . 136 | * { 137 | * oaes_gen_key_xxx( ctx ); 138 | * { 139 | * oaes_key_export( ctx, _buf, &_buf_len ); 140 | * // or 141 | * oaes_key_export_data( ctx, _buf, &_buf_len );\ 142 | * } 143 | * } 144 | * // or 145 | * { 146 | * oaes_key_import( ctx, _buf, _buf_len ); 147 | * // or 148 | * oaes_key_import_data( ctx, _buf, _buf_len ); 149 | * } 150 | * . 151 | * . 152 | * . 153 | * oaes_encrypt( ctx, m, m_len, c, &c_len ); 154 | * . 155 | * . 156 | * . 157 | * oaes_decrypt( ctx, c, c_len, m, &m_len ); 158 | * . 159 | * . 160 | * . 161 | * oaes_free( &ctx ); 162 | */ 163 | 164 | OAES_API OAES_CTX * oaes_alloc(void); 165 | 166 | OAES_API OAES_RET oaes_free( OAES_CTX ** ctx ); 167 | 168 | OAES_API OAES_RET oaes_set_option( OAES_CTX * ctx, 169 | OAES_OPTION option, const void * value ); 170 | 171 | OAES_API OAES_RET oaes_key_gen_128( OAES_CTX * ctx ); 172 | 173 | OAES_API OAES_RET oaes_key_gen_192( OAES_CTX * ctx ); 174 | 175 | OAES_API OAES_RET oaes_key_gen_256( OAES_CTX * ctx ); 176 | 177 | // export key with header information 178 | // set data == NULL to get the required data_len 179 | OAES_API OAES_RET oaes_key_export( OAES_CTX * ctx, 180 | uint8_t * data, size_t * data_len ); 181 | 182 | // directly export the data from key 183 | // set data == NULL to get the required data_len 184 | OAES_API OAES_RET oaes_key_export_data( OAES_CTX * ctx, 185 | uint8_t * data, size_t * data_len ); 186 | 187 | // import key with header information 188 | OAES_API OAES_RET oaes_key_import( OAES_CTX * ctx, 189 | const uint8_t * data, size_t data_len ); 190 | 191 | // directly import data into key 192 | OAES_API OAES_RET oaes_key_import_data( OAES_CTX * ctx, 193 | const uint8_t * data, size_t data_len ); 194 | 195 | // set c == NULL to get the required c_len 196 | OAES_API OAES_RET oaes_encrypt( OAES_CTX * ctx, 197 | const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len ); 198 | 199 | // set m == NULL to get the required m_len 200 | OAES_API OAES_RET oaes_decrypt( OAES_CTX * ctx, 201 | const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len ); 202 | 203 | // set buf == NULL to get the required buf_len 204 | OAES_API OAES_RET oaes_sprintf( 205 | char * buf, size_t * buf_len, const uint8_t * data, size_t data_len ); 206 | 207 | OAES_API OAES_RET oaes_encryption_round( const uint8_t * key, uint8_t * c ); 208 | 209 | OAES_API OAES_RET oaes_pseudo_encrypt_ecb( OAES_CTX * ctx, uint8_t * c ); 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif 214 | 215 | #endif // _OAES_LIB_H 216 | -------------------------------------------------------------------------------- /src/crypto/random.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "hash-ops.h" 36 | #include "initializer.h" 37 | #include "random.h" 38 | 39 | static void generate_system_random_bytes(size_t n, void *result); 40 | 41 | #if defined(_WIN32) 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | static void generate_system_random_bytes(size_t n, void *result) { 48 | HCRYPTPROV prov; 49 | #ifdef NDEBUG 50 | #define must_succeed(x) do if (!(x)) { fprintf(stderr, "Failed: " #x); _exit(1); } while (0) 51 | #else 52 | #define must_succeed(x) do if (!(x)) abort(); while (0) 53 | #endif 54 | must_succeed(CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)); 55 | must_succeed(CryptGenRandom(prov, (DWORD)n, result)); 56 | must_succeed(CryptReleaseContext(prov, 0)); 57 | #undef must_succeed 58 | } 59 | 60 | #else 61 | 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | 70 | static void generate_system_random_bytes(size_t n, void *result) { 71 | int fd; 72 | if ((fd = open("/dev/urandom", O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0) { 73 | err(EXIT_FAILURE, "open /dev/urandom"); 74 | } 75 | for (;;) { 76 | ssize_t res = read(fd, result, n); 77 | if ((size_t) res == n) { 78 | break; 79 | } 80 | if (res < 0) { 81 | if (errno != EINTR) { 82 | err(EXIT_FAILURE, "read /dev/urandom"); 83 | } 84 | } else if (res == 0) { 85 | errx(EXIT_FAILURE, "read /dev/urandom: end of file"); 86 | } else { 87 | result = padd(result, (size_t) res); 88 | n -= (size_t) res; 89 | } 90 | } 91 | if (close(fd) < 0) { 92 | err(EXIT_FAILURE, "close /dev/urandom"); 93 | } 94 | } 95 | 96 | #endif 97 | 98 | static union hash_state state; 99 | 100 | #if !defined(NDEBUG) 101 | static volatile int curstate; /* To catch thread safety problems. */ 102 | #endif 103 | 104 | FINALIZER(deinit_random) { 105 | #if !defined(NDEBUG) 106 | assert(curstate == 1); 107 | curstate = 0; 108 | #endif 109 | memset(&state, 0, sizeof(union hash_state)); 110 | } 111 | 112 | INITIALIZER(init_random) { 113 | generate_system_random_bytes(32, &state); 114 | REGISTER_FINALIZER(deinit_random); 115 | #if !defined(NDEBUG) 116 | assert(curstate == 0); 117 | curstate = 1; 118 | #endif 119 | } 120 | 121 | void generate_random_bytes_not_thread_safe(size_t n, void *result) { 122 | #if !defined(NDEBUG) 123 | assert(curstate == 1); 124 | curstate = 2; 125 | #endif 126 | if (n == 0) { 127 | #if !defined(NDEBUG) 128 | assert(curstate == 2); 129 | curstate = 1; 130 | #endif 131 | return; 132 | } 133 | for (;;) { 134 | hash_permutation(&state); 135 | if (n <= HASH_DATA_AREA) { 136 | memcpy(result, &state, n); 137 | #if !defined(NDEBUG) 138 | assert(curstate == 2); 139 | curstate = 1; 140 | #endif 141 | return; 142 | } else { 143 | memcpy(result, &state, HASH_DATA_AREA); 144 | result = padd(result, HASH_DATA_AREA); 145 | n -= HASH_DATA_AREA; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/crypto/random.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | void generate_random_bytes_not_thread_safe(size_t n, void *result); 36 | -------------------------------------------------------------------------------- /src/crypto/skein.h: -------------------------------------------------------------------------------- 1 | #ifndef _SKEIN_H_ 2 | #define _SKEIN_H_ 1 3 | /************************************************************************** 4 | ** 5 | ** Interface declarations and internal definitions for Skein hashing. 6 | ** 7 | ** Source code author: Doug Whiting, 2008. 8 | ** 9 | ** This algorithm and source code is released to the public domain. 10 | ** 11 | *************************************************************************** 12 | ** 13 | ** The following compile-time switches may be defined to control some 14 | ** tradeoffs between speed, code size, error checking, and security. 15 | ** 16 | ** The "default" note explains what happens when the switch is not defined. 17 | ** 18 | ** SKEIN_DEBUG -- make callouts from inside Skein code 19 | ** to examine/display intermediate values. 20 | ** [default: no callouts (no overhead)] 21 | ** 22 | ** SKEIN_ERR_CHECK -- how error checking is handled inside Skein 23 | ** code. If not defined, most error checking 24 | ** is disabled (for performance). Otherwise, 25 | ** the switch value is interpreted as: 26 | ** 0: use assert() to flag errors 27 | ** 1: return SKEIN_FAIL to flag errors 28 | ** 29 | ***************************************************************************/ 30 | #include "skein_port.h" /* get platform-specific definitions */ 31 | 32 | typedef enum 33 | { 34 | SKEIN_SUCCESS = 0, /* return codes from Skein calls */ 35 | SKEIN_FAIL = 1, 36 | SKEIN_BAD_HASHLEN = 2 37 | } 38 | HashReturn; 39 | 40 | typedef size_t DataLength; /* bit count type */ 41 | typedef u08b_t BitSequence; /* bit stream type */ 42 | 43 | /* "all-in-one" call */ 44 | HashReturn skein_hash(int hashbitlen, const BitSequence *data, 45 | DataLength databitlen, BitSequence *hashval); 46 | 47 | #endif /* ifndef _SKEIN_H_ */ 48 | -------------------------------------------------------------------------------- /src/crypto/skein_port.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef _SKEIN_PORT_H_ 30 | #define _SKEIN_PORT_H_ 31 | 32 | #include 33 | #include 34 | 35 | #ifndef RETURN_VALUES 36 | # define RETURN_VALUES 37 | # if defined( DLL_EXPORT ) 38 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 39 | # define VOID_RETURN __declspec( dllexport ) void __stdcall 40 | # define INT_RETURN __declspec( dllexport ) int __stdcall 41 | # elif defined( __GNUC__ ) 42 | # define VOID_RETURN __declspec( __dllexport__ ) void 43 | # define INT_RETURN __declspec( __dllexport__ ) int 44 | # else 45 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 46 | # endif 47 | # elif defined( DLL_IMPORT ) 48 | # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) 49 | # define VOID_RETURN __declspec( dllimport ) void __stdcall 50 | # define INT_RETURN __declspec( dllimport ) int __stdcall 51 | # elif defined( __GNUC__ ) 52 | # define VOID_RETURN __declspec( __dllimport__ ) void 53 | # define INT_RETURN __declspec( __dllimport__ ) int 54 | # else 55 | # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers 56 | # endif 57 | # elif defined( __WATCOMC__ ) 58 | # define VOID_RETURN void __cdecl 59 | # define INT_RETURN int __cdecl 60 | # else 61 | # define VOID_RETURN void 62 | # define INT_RETURN int 63 | # endif 64 | #endif 65 | 66 | /* These defines are used to declare buffers in a way that allows 67 | faster operations on longer variables to be used. In all these 68 | defines 'size' must be a power of 2 and >= 8 69 | 70 | dec_unit_type(size,x) declares a variable 'x' of length 71 | 'size' bits 72 | 73 | dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize' 74 | bytes defined as an array of variables 75 | each of 'size' bits (bsize must be a 76 | multiple of size / 8) 77 | 78 | ptr_cast(x,size) casts a pointer to a pointer to a 79 | varaiable of length 'size' bits 80 | */ 81 | 82 | #define ui_type(size) uint##size##_t 83 | #define dec_unit_type(size,x) typedef ui_type(size) x 84 | #define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)] 85 | #define ptr_cast(x,size) ((ui_type(size)*)(x)) 86 | 87 | typedef unsigned int uint_t; /* native unsigned integer */ 88 | typedef uint8_t u08b_t; /* 8-bit unsigned integer */ 89 | typedef uint64_t u64b_t; /* 64-bit unsigned integer */ 90 | 91 | #ifndef RotL_64 92 | #define RotL_64(x,N) (((x) << (N)) | ((x) >> (64-(N)))) 93 | #endif 94 | 95 | /* 96 | * Skein is "natively" little-endian (unlike SHA-xxx), for optimal 97 | * performance on x86 CPUs. The Skein code requires the following 98 | * definitions for dealing with endianness: 99 | * 100 | * SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian 101 | * Skein_Put64_LSB_First 102 | * Skein_Get64_LSB_First 103 | * Skein_Swap64 104 | * 105 | * If SKEIN_NEED_SWAP is defined at compile time, it is used here 106 | * along with the portable versions of Put64/Get64/Swap64, which 107 | * are slow in general. 108 | * 109 | * Otherwise, an "auto-detect" of endianness is attempted below. 110 | * If the default handling doesn't work well, the user may insert 111 | * platform-specific code instead (e.g., for big-endian CPUs). 112 | * 113 | */ 114 | #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */ 115 | 116 | 117 | #include "common/int-util.h" 118 | 119 | #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ 120 | #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ 121 | 122 | #if BYTE_ORDER == LITTLE_ENDIAN 123 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 124 | #endif 125 | 126 | #if BYTE_ORDER == BIG_ENDIAN 127 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 128 | #endif 129 | 130 | /* special handler for IA64, which may be either endianness (?) */ 131 | /* here we assume little-endian, but this may need to be changed */ 132 | #if defined(__ia64) || defined(__ia64__) || defined(_M_IA64) 133 | # define PLATFORM_MUST_ALIGN (1) 134 | #ifndef PLATFORM_BYTE_ORDER 135 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 136 | #endif 137 | #endif 138 | 139 | #ifndef PLATFORM_MUST_ALIGN 140 | # define PLATFORM_MUST_ALIGN (0) 141 | #endif 142 | 143 | 144 | #if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN 145 | /* here for big-endian CPUs */ 146 | #define SKEIN_NEED_SWAP (1) 147 | #elif PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN 148 | /* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */ 149 | #define SKEIN_NEED_SWAP (0) 150 | #if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */ 151 | #define Skein_Put64_LSB_First(dst08,src64,bCnt) memcpy(dst08,src64,bCnt) 152 | #define Skein_Get64_LSB_First(dst64,src08,wCnt) memcpy(dst64,src08,8*(wCnt)) 153 | #endif 154 | #else 155 | #error "Skein needs endianness setting!" 156 | #endif 157 | 158 | #endif /* ifndef SKEIN_NEED_SWAP */ 159 | 160 | /* 161 | ****************************************************************** 162 | * Provide any definitions still needed. 163 | ****************************************************************** 164 | */ 165 | #ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */ 166 | #if SKEIN_NEED_SWAP 167 | #define Skein_Swap64(w64) \ 168 | ( (( ((u64b_t)(w64)) & 0xFF) << 56) | \ 169 | (((((u64b_t)(w64)) >> 8) & 0xFF) << 48) | \ 170 | (((((u64b_t)(w64)) >>16) & 0xFF) << 40) | \ 171 | (((((u64b_t)(w64)) >>24) & 0xFF) << 32) | \ 172 | (((((u64b_t)(w64)) >>32) & 0xFF) << 24) | \ 173 | (((((u64b_t)(w64)) >>40) & 0xFF) << 16) | \ 174 | (((((u64b_t)(w64)) >>48) & 0xFF) << 8) | \ 175 | (((((u64b_t)(w64)) >>56) & 0xFF) ) ) 176 | #else 177 | #define Skein_Swap64(w64) (w64) 178 | #endif 179 | #endif /* ifndef Skein_Swap64 */ 180 | 181 | 182 | #ifndef Skein_Put64_LSB_First 183 | void Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt) 184 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ 185 | { /* this version is fully portable (big-endian or little-endian), but slow */ 186 | size_t n; 187 | 188 | for (n=0;n>3] >> (8*(n&7))); 190 | } 191 | #else 192 | ; /* output only the function prototype */ 193 | #endif 194 | #endif /* ifndef Skein_Put64_LSB_First */ 195 | 196 | 197 | #ifndef Skein_Get64_LSB_First 198 | void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt) 199 | #ifdef SKEIN_PORT_CODE /* instantiate the function code here? */ 200 | { /* this version is fully portable (big-endian or little-endian), but slow */ 201 | size_t n; 202 | 203 | for (n=0;n<8*wCnt;n+=8) 204 | dst[n/8] = (((u64b_t) src[n ]) ) + 205 | (((u64b_t) src[n+1]) << 8) + 206 | (((u64b_t) src[n+2]) << 16) + 207 | (((u64b_t) src[n+3]) << 24) + 208 | (((u64b_t) src[n+4]) << 32) + 209 | (((u64b_t) src[n+5]) << 40) + 210 | (((u64b_t) src[n+6]) << 48) + 211 | (((u64b_t) src[n+7]) << 56) ; 212 | } 213 | #else 214 | ; /* output only the function prototype */ 215 | #endif 216 | #endif /* ifndef Skein_Get64_LSB_First */ 217 | 218 | #endif /* ifndef _SKEIN_PORT_H_ */ 219 | -------------------------------------------------------------------------------- /src/crypto/tree-hash.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2018, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "hash-ops.h" 36 | 37 | #ifdef _MSC_VER 38 | #include 39 | #elif !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) \ 40 | && !defined(__NetBSD__) 41 | #include 42 | #else 43 | #include 44 | #endif 45 | 46 | /*** 47 | * Round to power of two, for count>=3 and for count being not too large (as reasonable for tree hash calculations) 48 | */ 49 | size_t tree_hash_cnt(size_t count) { 50 | // This algo has some bad history but all we are doing is 1 << floor(log2(count)) 51 | // There are _many_ ways to do log2, for some reason the one selected was the most obscure one, 52 | // and fixing it made it even more obscure. 53 | // 54 | // Iterative method implemented below aims for clarity over speed, if performance is needed 55 | // then my advice is to use the BSR instruction on x86 56 | // 57 | // All the paranoid asserts have been removed since it is trivial to mathematically prove that 58 | // the return will always be a power of 2. 59 | // Problem space has been defined as 3 <= count <= 2^28. Of course quarter of a billion transactions 60 | // is not a sane upper limit for a block, so there will be tighter limits in other parts of the code 61 | 62 | assert( count >= 3 ); // cases for 0,1,2 are handled elsewhere 63 | assert( count <= 0x10000000 ); // sanity limit to 2^28, MSB=1 will cause an inf loop 64 | 65 | size_t pow = 2; 66 | while(pow < count) pow <<= 1; 67 | return pow >> 1; 68 | } 69 | 70 | void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash) { 71 | // The blockchain block at height 202612 https://moneroblocks.info/block/202612 72 | // contained 514 transactions, that triggered bad calculation of variable "cnt" in the original version of this function 73 | // as from CryptoNote code. 74 | // 75 | // This bug applies to all CN altcoins. 76 | // 77 | // Mathematical bug here was first published on 14:45:34 (GMT+2) 2014-09-04 by Rafal Freeman 78 | // https://github.com/rfree2monero/bitmonero/commit/b417abfb7a297d09f1bbb6de29030f8de9952ac8 79 | // and soon also applied to CryptoNote (15:10 GMT+2), and BoolBerry used not fully correct work around: 80 | // the work around of sizeof(size_t)*8 or <<3 as used before in 2 coins and in BBL later was blocking 81 | // exploitation on normal platforms, how ever we strongly recommend the following fix because it removes 82 | // mistake in mathematical formula. 83 | 84 | assert(count > 0); 85 | if (count == 1) { 86 | memcpy(root_hash, hashes, HASH_SIZE); 87 | } else if (count == 2) { 88 | cn_fast_hash(hashes, 2 * HASH_SIZE, root_hash); 89 | } else { 90 | size_t i, j; 91 | 92 | size_t cnt = tree_hash_cnt( count ); 93 | 94 | char (*ints)[HASH_SIZE]; 95 | size_t ints_size = cnt * HASH_SIZE; 96 | ints = alloca(ints_size); memset( ints , 0 , ints_size); // allocate, and zero out as extra protection for using uninitialized mem 97 | 98 | memcpy(ints, hashes, (2 * cnt - count) * HASH_SIZE); 99 | 100 | for (i = 2 * cnt - count, j = 2 * cnt - count; j < cnt; i += 2, ++j) { 101 | cn_fast_hash(hashes[i], 64, ints[j]); 102 | } 103 | assert(i == count); 104 | 105 | while (cnt > 2) { 106 | cnt >>= 1; 107 | for (i = 0, j = 0; j < cnt; i += 2, ++j) { 108 | cn_fast_hash(ints[i], 64, ints[j]); 109 | } 110 | } 111 | 112 | cn_fast_hash(ints[0], 64, root_hash); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/crypto/variant2_int_sqrt.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIANT2_INT_SQRT_H 2 | #define VARIANT2_INT_SQRT_H 3 | 4 | #include 5 | #include 6 | 7 | #define VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2() \ 8 | do { \ 9 | const __m128i exp_double_bias = _mm_set_epi64x(0, 1023ULL << 52); \ 10 | __m128d x = _mm_castsi128_pd(_mm_add_epi64(_mm_cvtsi64_si128(sqrt_input >> 12), exp_double_bias)); \ 11 | x = _mm_sqrt_sd(_mm_setzero_pd(), x); \ 12 | sqrt_result = (uint64_t)(_mm_cvtsi128_si64(_mm_sub_epi64(_mm_castpd_si128(x), exp_double_bias))) >> 19; \ 13 | } while(0) 14 | 15 | #define VARIANT2_INTEGER_MATH_SQRT_STEP_FP64() \ 16 | do { \ 17 | sqrt_result = sqrt(sqrt_input + 18446744073709551616.0) * 2.0 - 8589934592.0; \ 18 | } while(0) 19 | 20 | #define VARIANT2_INTEGER_MATH_SQRT_STEP_REF() \ 21 | sqrt_result = integer_square_root_v2(sqrt_input) 22 | 23 | // Reference implementation of the integer square root for Cryptonight variant 2 24 | // Computes integer part of "sqrt(2^64 + n) * 2 - 2^33" 25 | // 26 | // In other words, given 64-bit unsigned integer n: 27 | // 1) Write it as x = 1.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN000... in binary (1 <= x < 2, all 64 bits of n are used) 28 | // 2) Calculate sqrt(x) = 1.0RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR... (1 <= sqrt(x) < sqrt(2), so it will always start with "1.0" in binary) 29 | // 3) Take 32 bits that come after "1.0" and return them as a 32-bit unsigned integer, discard all remaining bits 30 | // 31 | // Some sample inputs and outputs: 32 | // 33 | // Input | Output | Exact value of "sqrt(2^64 + n) * 2 - 2^33" 34 | // -----------------|------------|------------------------------------------- 35 | // 0 | 0 | 0 36 | // 2^32 | 0 | 0.99999999994179233909330885695244... 37 | // 2^32 + 1 | 1 | 1.0000000001746229827200734316305... 38 | // 2^50 | 262140 | 262140.00012206565608606978175873... 39 | // 2^55 + 20963331 | 8384515 | 8384515.9999999997673963974959744... 40 | // 2^55 + 20963332 | 8384516 | 8384516 41 | // 2^62 + 26599786 | 1013904242 | 1013904242.9999999999479374853545... 42 | // 2^62 + 26599787 | 1013904243 | 1013904243.0000000001561875439364... 43 | // 2^64 - 1 | 3558067407 | 3558067407.9041987696409179931096... 44 | 45 | // The reference implementation as it is now uses only unsigned int64 arithmetic, so it can't have undefined behavior 46 | // It was tested once for all edge cases and confirmed correct 47 | static inline uint32_t integer_square_root_v2(uint64_t n) 48 | { 49 | uint64_t r = 1ULL << 63; 50 | 51 | for (uint64_t bit = 1ULL << 60; bit; bit >>= 2) 52 | { 53 | const bool b = (n < r + bit); 54 | const uint64_t n_next = n - (r + bit); 55 | const uint64_t r_next = r + bit * 2; 56 | n = b ? n : n_next; 57 | r = b ? r : r_next; 58 | r >>= 1; 59 | } 60 | 61 | return r * 2 + ((n > r) ? 1 : 0); 62 | } 63 | 64 | /* 65 | VARIANT2_INTEGER_MATH_SQRT_FIXUP checks that "r" is an integer part of "sqrt(2^64 + sqrt_input) * 2 - 2^33" and adds or subtracts 1 if needed 66 | It's hard to understand how it works, so here is a full calculation of formulas used in VARIANT2_INTEGER_MATH_SQRT_FIXUP 67 | 68 | The following inequalities must hold for r if it's an integer part of "sqrt(2^64 + sqrt_input) * 2 - 2^33": 69 | 1) r <= sqrt(2^64 + sqrt_input) * 2 - 2^33 70 | 2) r + 1 > sqrt(2^64 + sqrt_input) * 2 - 2^33 71 | 72 | We need to check them using only unsigned integer arithmetic to avoid rounding errors and undefined behavior 73 | 74 | First inequality: r <= sqrt(2^64 + sqrt_input) * 2 - 2^33 75 | ----------------------------------------------------------------------------------- 76 | r <= sqrt(2^64 + sqrt_input) * 2 - 2^33 77 | r + 2^33 <= sqrt(2^64 + sqrt_input) * 2 78 | r/2 + 2^32 <= sqrt(2^64 + sqrt_input) 79 | (r/2 + 2^32)^2 <= 2^64 + sqrt_input 80 | 81 | Rewrite r as r = s * 2 + b (s = trunc(r/2), b is 0 or 1) 82 | 83 | ((s*2+b)/2 + 2^32)^2 <= 2^64 + sqrt_input 84 | (s*2+b)^2/4 + 2*2^32*(s*2+b)/2 + 2^64 <= 2^64 + sqrt_input 85 | (s*2+b)^2/4 + 2*2^32*(s*2+b)/2 <= sqrt_input 86 | (s*2+b)^2/4 + 2^32*r <= sqrt_input 87 | (s^2*4+2*s*2*b+b^2)/4 + 2^32*r <= sqrt_input 88 | s^2+s*b+b^2/4 + 2^32*r <= sqrt_input 89 | s*(s+b) + b^2/4 + 2^32*r <= sqrt_input 90 | 91 | Let r2 = s*(s+b) + r*2^32 92 | r2 + b^2/4 <= sqrt_input 93 | 94 | If this inequality doesn't hold, then we must decrement r: IF "r2 + b^2/4 > sqrt_input" THEN r = r - 1 95 | 96 | b can be 0 or 1 97 | If b is 0 then we need to compare "r2 > sqrt_input" 98 | If b is 1 then b^2/4 = 0.25, so we need to compare "r2 + 0.25 > sqrt_input" 99 | Since both r2 and sqrt_input are integers, we can safely replace it with "r2 + 1 > sqrt_input" 100 | ----------------------------------------------------------------------------------- 101 | Both cases can be merged to a single expression "r2 + b > sqrt_input" 102 | ----------------------------------------------------------------------------------- 103 | There will be no overflow when calculating "r2 + b", so it's safe to compare with sqrt_input: 104 | r2 + b = s*(s+b) + r*2^32 + b 105 | The largest value s, b and r can have is s = 1779033703, b = 1, r = 3558067407 when sqrt_input = 2^64 - 1 106 | r2 + b <= 1779033703*1779033704 + 3558067407*2^32 + 1 = 18446744068217447385 < 2^64 107 | 108 | Second inequality: r + 1 > sqrt(2^64 + sqrt_input) * 2 - 2^33 109 | ----------------------------------------------------------------------------------- 110 | r + 1 > sqrt(2^64 + sqrt_input) * 2 - 2^33 111 | r + 1 + 2^33 > sqrt(2^64 + sqrt_input) * 2 112 | ((r+1)/2 + 2^32)^2 > 2^64 + sqrt_input 113 | 114 | Rewrite r as r = s * 2 + b (s = trunc(r/2), b is 0 or 1) 115 | 116 | ((s*2+b+1)/2 + 2^32)^2 > 2^64 + sqrt_input 117 | (s*2+b+1)^2/4 + 2*(s*2+b+1)/2*2^32 + 2^64 > 2^64 + sqrt_input 118 | (s*2+b+1)^2/4 + (s*2+b+1)*2^32 > sqrt_input 119 | (s*2+b+1)^2/4 + (r+1)*2^32 > sqrt_input 120 | (s*2+(b+1))^2/4 + r*2^32 + 2^32 > sqrt_input 121 | (s^2*4+2*s*2*(b+1)+(b+1)^2)/4 + r*2^32 + 2^32 > sqrt_input 122 | s^2+s*(b+1)+(b+1)^2/4 + r*2^32 + 2^32 > sqrt_input 123 | s*(s+b) + s + (b+1)^2/4 + r*2^32 + 2^32 > sqrt_input 124 | 125 | Let r2 = s*(s+b) + r*2^32 126 | 127 | r2 + s + (b+1)^2/4 + 2^32 > sqrt_input 128 | r2 + 2^32 + (b+1)^2/4 > sqrt_input - s 129 | 130 | If this inequality doesn't hold, then we must decrement r: IF "r2 + 2^32 + (b+1)^2/4 <= sqrt_input - s" THEN r = r - 1 131 | b can be 0 or 1 132 | If b is 0 then we need to compare "r2 + 2^32 + 1/4 <= sqrt_input - s" which is equal to "r2 + 2^32 < sqrt_input - s" because all numbers here are integers 133 | If b is 1 then (b+1)^2/4 = 1, so we need to compare "r2 + 2^32 + 1 <= sqrt_input - s" which is also equal to "r2 + 2^32 < sqrt_input - s" 134 | ----------------------------------------------------------------------------------- 135 | Both cases can be merged to a single expression "r2 + 2^32 < sqrt_input - s" 136 | ----------------------------------------------------------------------------------- 137 | There will be no overflow when calculating "r2 + 2^32": 138 | r2 + 2^32 = s*(s+b) + r*2^32 + 2^32 = s*(s+b) + (r+1)*2^32 139 | The largest value s, b and r can have is s = 1779033703, b = 1, r = 3558067407 when sqrt_input = 2^64 - 1 140 | r2 + b <= 1779033703*1779033704 + 3558067408*2^32 = 18446744072512414680 < 2^64 141 | 142 | There will be no integer overflow when calculating "sqrt_input - s", i.e. "sqrt_input >= s" at all times: 143 | s = trunc(r/2) = trunc(sqrt(2^64 + sqrt_input) - 2^32) < sqrt(2^64 + sqrt_input) - 2^32 + 1 144 | sqrt_input > sqrt(2^64 + sqrt_input) - 2^32 + 1 145 | sqrt_input + 2^32 - 1 > sqrt(2^64 + sqrt_input) 146 | (sqrt_input + 2^32 - 1)^2 > sqrt_input + 2^64 147 | sqrt_input^2 + 2*sqrt_input*(2^32 - 1) + (2^32-1)^2 > sqrt_input + 2^64 148 | sqrt_input^2 + sqrt_input*(2^33 - 2) + (2^32-1)^2 > sqrt_input + 2^64 149 | sqrt_input^2 + sqrt_input*(2^33 - 3) + (2^32-1)^2 > 2^64 150 | sqrt_input^2 + sqrt_input*(2^33 - 3) + 2^64-2^33+1 > 2^64 151 | sqrt_input^2 + sqrt_input*(2^33 - 3) - 2^33 + 1 > 0 152 | This inequality is true if sqrt_input > 1 and it's easy to check that s = 0 if sqrt_input is 0 or 1, so there will be no integer overflow 153 | */ 154 | 155 | #define VARIANT2_INTEGER_MATH_SQRT_FIXUP(r) \ 156 | do { \ 157 | const uint64_t s = r >> 1; \ 158 | const uint64_t b = r & 1; \ 159 | const uint64_t r2 = (uint64_t)(s) * (s + b) + (r << 32); \ 160 | r += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \ 161 | } while(0) 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /src/crypto/variant4_random_math.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIANT4_RANDOM_MATH_H 2 | #define VARIANT4_RANDOM_MATH_H 3 | 4 | // Register size can be configured to either 32 bit (uint32_t) or 64 bit (uint64_t) 5 | typedef uint32_t v4_reg; 6 | 7 | enum V4_Settings 8 | { 9 | // Generate code with minimal theoretical latency = 45 cycles, which is equivalent to 15 multiplications 10 | TOTAL_LATENCY = 15 * 3, 11 | 12 | // Always generate at least 60 instructions 13 | NUM_INSTRUCTIONS_MIN = 60, 14 | 15 | // Never generate more than 70 instructions (final RET instruction doesn't count here) 16 | NUM_INSTRUCTIONS_MAX = 70, 17 | 18 | // Available ALUs for MUL 19 | // Modern CPUs typically have only 1 ALU which can do multiplications 20 | ALU_COUNT_MUL = 1, 21 | 22 | // Total available ALUs 23 | // Modern CPUs have 4 ALUs, but we use only 3 because random math executes together with other main loop code 24 | ALU_COUNT = 3, 25 | }; 26 | 27 | enum V4_InstructionList 28 | { 29 | MUL, // a*b 30 | ADD, // a+b + C, C is an unsigned 32-bit constant 31 | SUB, // a-b 32 | ROR, // rotate right "a" by "b & 31" bits 33 | ROL, // rotate left "a" by "b & 31" bits 34 | XOR, // a^b 35 | RET, // finish execution 36 | V4_INSTRUCTION_COUNT = RET, 37 | }; 38 | 39 | // V4_InstructionDefinition is used to generate code from random data 40 | // Every random sequence of bytes is a valid code 41 | // 42 | // There are 9 registers in total: 43 | // - 4 variable registers 44 | // - 5 constant registers initialized from loop variables 45 | // This is why dst_index is 2 bits 46 | enum V4_InstructionDefinition 47 | { 48 | V4_OPCODE_BITS = 3, 49 | V4_DST_INDEX_BITS = 2, 50 | V4_SRC_INDEX_BITS = 3, 51 | }; 52 | 53 | struct V4_Instruction 54 | { 55 | uint8_t opcode; 56 | uint8_t dst_index; 57 | uint8_t src_index; 58 | uint32_t C; 59 | }; 60 | 61 | #ifndef FORCEINLINE 62 | #if defined(__GNUC__) 63 | #define FORCEINLINE __attribute__((always_inline)) inline 64 | #elif defined(_MSC_VER) 65 | #define FORCEINLINE __forceinline 66 | #else 67 | #define FORCEINLINE inline 68 | #endif 69 | #endif 70 | 71 | #ifndef UNREACHABLE_CODE 72 | #if defined(__GNUC__) 73 | #define UNREACHABLE_CODE __builtin_unreachable() 74 | #elif defined(_MSC_VER) 75 | #define UNREACHABLE_CODE __assume(false) 76 | #else 77 | #define UNREACHABLE_CODE 78 | #endif 79 | #endif 80 | 81 | // Random math interpreter's loop is fully unrolled and inlined to achieve 100% branch prediction on CPU: 82 | // every switch-case will point to the same destination on every iteration of Cryptonight main loop 83 | // 84 | // This is about as fast as it can get without using low-level machine code generation 85 | static FORCEINLINE void v4_random_math(const struct V4_Instruction* code, v4_reg* r) 86 | { 87 | enum 88 | { 89 | REG_BITS = sizeof(v4_reg) * 8, 90 | }; 91 | 92 | #define V4_EXEC(i) \ 93 | { \ 94 | const struct V4_Instruction* op = code + i; \ 95 | const v4_reg src = r[op->src_index]; \ 96 | v4_reg* dst = r + op->dst_index; \ 97 | switch (op->opcode) \ 98 | { \ 99 | case MUL: \ 100 | *dst *= src; \ 101 | break; \ 102 | case ADD: \ 103 | *dst += src + op->C; \ 104 | break; \ 105 | case SUB: \ 106 | *dst -= src; \ 107 | break; \ 108 | case ROR: \ 109 | { \ 110 | const uint32_t shift = src % REG_BITS; \ 111 | *dst = (*dst >> shift) | (*dst << ((REG_BITS - shift) % REG_BITS)); \ 112 | } \ 113 | break; \ 114 | case ROL: \ 115 | { \ 116 | const uint32_t shift = src % REG_BITS; \ 117 | *dst = (*dst << shift) | (*dst >> ((REG_BITS - shift) % REG_BITS)); \ 118 | } \ 119 | break; \ 120 | case XOR: \ 121 | *dst ^= src; \ 122 | break; \ 123 | case RET: \ 124 | return; \ 125 | default: \ 126 | UNREACHABLE_CODE; \ 127 | break; \ 128 | } \ 129 | } 130 | 131 | #define V4_EXEC_10(j) \ 132 | V4_EXEC(j + 0) \ 133 | V4_EXEC(j + 1) \ 134 | V4_EXEC(j + 2) \ 135 | V4_EXEC(j + 3) \ 136 | V4_EXEC(j + 4) \ 137 | V4_EXEC(j + 5) \ 138 | V4_EXEC(j + 6) \ 139 | V4_EXEC(j + 7) \ 140 | V4_EXEC(j + 8) \ 141 | V4_EXEC(j + 9) 142 | 143 | // Generated program can have 60 + a few more (usually 2-3) instructions to achieve required latency 144 | // I've checked all block heights < 10,000,000 and here is the distribution of program sizes: 145 | // 146 | // 60 27960 147 | // 61 105054 148 | // 62 2452759 149 | // 63 5115997 150 | // 64 1022269 151 | // 65 1109635 152 | // 66 153145 153 | // 67 8550 154 | // 68 4529 155 | // 69 102 156 | 157 | // Unroll 70 instructions here 158 | V4_EXEC_10(0); // instructions 0-9 159 | V4_EXEC_10(10); // instructions 10-19 160 | V4_EXEC_10(20); // instructions 20-29 161 | V4_EXEC_10(30); // instructions 30-39 162 | V4_EXEC_10(40); // instructions 40-49 163 | V4_EXEC_10(50); // instructions 50-59 164 | V4_EXEC_10(60); // instructions 60-69 165 | 166 | #undef V4_EXEC_10 167 | #undef V4_EXEC 168 | } 169 | 170 | // If we don't have enough data available, generate more 171 | static FORCEINLINE void check_data(size_t* data_index, const size_t bytes_needed, int8_t* data, const size_t data_size) 172 | { 173 | if (*data_index + bytes_needed > data_size) 174 | { 175 | hash_extra_blake(data, data_size, (char*) data); 176 | *data_index = 0; 177 | } 178 | } 179 | 180 | // Generates as many random math operations as possible with given latency and ALU restrictions 181 | // "code" array must have space for NUM_INSTRUCTIONS_MAX+1 instructions 182 | static inline int v4_random_math_init(struct V4_Instruction* code, const uint64_t height) 183 | { 184 | // MUL is 3 cycles, 3-way addition and rotations are 2 cycles, SUB/XOR are 1 cycle 185 | // These latencies match real-life instruction latencies for Intel CPUs starting from Sandy Bridge and up to Skylake/Coffee lake 186 | // 187 | // AMD Ryzen has the same latencies except 1-cycle ROR/ROL, so it'll be a bit faster than Intel Sandy Bridge and newer processors 188 | // Surprisingly, Intel Nehalem also has 1-cycle ROR/ROL, so it'll also be faster than Intel Sandy Bridge and newer processors 189 | // AMD Bulldozer has 4 cycles latency for MUL (slower than Intel) and 1 cycle for ROR/ROL (faster than Intel), so average performance will be the same 190 | // Source: https://www.agner.org/optimize/instruction_tables.pdf 191 | const int op_latency[V4_INSTRUCTION_COUNT] = { 3, 2, 1, 2, 2, 1 }; 192 | 193 | // Instruction latencies for theoretical ASIC implementation 194 | const int asic_op_latency[V4_INSTRUCTION_COUNT] = { 3, 1, 1, 1, 1, 1 }; 195 | 196 | // Available ALUs for each instruction 197 | const int op_ALUs[V4_INSTRUCTION_COUNT] = { ALU_COUNT_MUL, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT, ALU_COUNT }; 198 | 199 | int8_t data[32]; 200 | memset(data, 0, sizeof(data)); 201 | uint64_t tmp = SWAP64LE(height); 202 | memcpy(data, &tmp, sizeof(uint64_t)); 203 | data[20] = 0xda; // change seed 204 | 205 | // Set data_index past the last byte in data 206 | // to trigger full data update with blake hash 207 | // before we start using it 208 | size_t data_index = sizeof(data); 209 | 210 | int code_size; 211 | 212 | // There is a small chance (1.8%) that register R8 won't be used in the generated program 213 | // So we keep track of it and try again if it's not used 214 | bool r8_used; 215 | do { 216 | int latency[9]; 217 | int asic_latency[9]; 218 | 219 | // Tracks previous instruction and value of the source operand for registers R0-R3 throughout code execution 220 | // byte 0: current value of the destination register 221 | // byte 1: instruction opcode 222 | // byte 2: current value of the source register 223 | // 224 | // Registers R4-R8 are constant and are treated as having the same value because when we do 225 | // the same operation twice with two constant source registers, it can be optimized into a single operation 226 | uint32_t inst_data[9] = { 0, 1, 2, 3, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF }; 227 | 228 | bool alu_busy[TOTAL_LATENCY + 1][ALU_COUNT]; 229 | bool is_rotation[V4_INSTRUCTION_COUNT]; 230 | bool rotated[4]; 231 | int rotate_count = 0; 232 | 233 | memset(latency, 0, sizeof(latency)); 234 | memset(asic_latency, 0, sizeof(asic_latency)); 235 | memset(alu_busy, 0, sizeof(alu_busy)); 236 | memset(is_rotation, 0, sizeof(is_rotation)); 237 | memset(rotated, 0, sizeof(rotated)); 238 | is_rotation[ROR] = true; 239 | is_rotation[ROL] = true; 240 | 241 | int num_retries = 0; 242 | code_size = 0; 243 | 244 | int total_iterations = 0; 245 | r8_used = false; 246 | 247 | // Generate random code to achieve minimal required latency for our abstract CPU 248 | // Try to get this latency for all 4 registers 249 | while (((latency[0] < TOTAL_LATENCY) || (latency[1] < TOTAL_LATENCY) || (latency[2] < TOTAL_LATENCY) || (latency[3] < TOTAL_LATENCY)) && (num_retries < 64)) 250 | { 251 | // Fail-safe to guarantee loop termination 252 | ++total_iterations; 253 | if (total_iterations > 256) 254 | break; 255 | 256 | check_data(&data_index, 1, data, sizeof(data)); 257 | 258 | const uint8_t c = ((uint8_t*)data)[data_index++]; 259 | 260 | // MUL = opcodes 0-2 261 | // ADD = opcode 3 262 | // SUB = opcode 4 263 | // ROR/ROL = opcode 5, shift direction is selected randomly 264 | // XOR = opcodes 6-7 265 | uint8_t opcode = c & ((1 << V4_OPCODE_BITS) - 1); 266 | if (opcode == 5) 267 | { 268 | check_data(&data_index, 1, data, sizeof(data)); 269 | opcode = (data[data_index++] >= 0) ? ROR : ROL; 270 | } 271 | else if (opcode >= 6) 272 | { 273 | opcode = XOR; 274 | } 275 | else 276 | { 277 | opcode = (opcode <= 2) ? MUL : (opcode - 2); 278 | } 279 | 280 | uint8_t dst_index = (c >> V4_OPCODE_BITS) & ((1 << V4_DST_INDEX_BITS) - 1); 281 | uint8_t src_index = (c >> (V4_OPCODE_BITS + V4_DST_INDEX_BITS)) & ((1 << V4_SRC_INDEX_BITS) - 1); 282 | 283 | const int a = dst_index; 284 | int b = src_index; 285 | 286 | // Don't do ADD/SUB/XOR with the same register 287 | if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b)) 288 | { 289 | // Use register R8 as source instead 290 | b = 8; 291 | src_index = 8; 292 | } 293 | 294 | // Don't do rotation with the same destination twice because it's equal to a single rotation 295 | if (is_rotation[opcode] && rotated[a]) 296 | { 297 | continue; 298 | } 299 | 300 | // Don't do the same instruction (except MUL) with the same source value twice because all other cases can be optimized: 301 | // 2xADD(a, b, C) = ADD(a, b*2, C1+C2), same for SUB and rotations 302 | // 2xXOR(a, b) = NOP 303 | if ((opcode != MUL) && ((inst_data[a] & 0xFFFF00) == (opcode << 8) + ((inst_data[b] & 255) << 16))) 304 | { 305 | continue; 306 | } 307 | 308 | // Find which ALU is available (and when) for this instruction 309 | int next_latency = (latency[a] > latency[b]) ? latency[a] : latency[b]; 310 | int alu_index = -1; 311 | while (next_latency < TOTAL_LATENCY) 312 | { 313 | for (int i = op_ALUs[opcode] - 1; i >= 0; --i) 314 | { 315 | if (!alu_busy[next_latency][i]) 316 | { 317 | // ADD is implemented as two 1-cycle instructions on a real CPU, so do an additional availability check 318 | if ((opcode == ADD) && alu_busy[next_latency + 1][i]) 319 | { 320 | continue; 321 | } 322 | 323 | // Rotation can only start when previous rotation is finished, so do an additional availability check 324 | if (is_rotation[opcode] && (next_latency < rotate_count * op_latency[opcode])) 325 | { 326 | continue; 327 | } 328 | 329 | alu_index = i; 330 | break; 331 | } 332 | } 333 | if (alu_index >= 0) 334 | { 335 | break; 336 | } 337 | ++next_latency; 338 | } 339 | 340 | // Don't generate instructions that leave some register unchanged for more than 7 cycles 341 | if (next_latency > latency[a] + 7) 342 | { 343 | continue; 344 | } 345 | 346 | next_latency += op_latency[opcode]; 347 | 348 | if (next_latency <= TOTAL_LATENCY) 349 | { 350 | if (is_rotation[opcode]) 351 | { 352 | ++rotate_count; 353 | } 354 | 355 | // Mark ALU as busy only for the first cycle when it starts executing the instruction because ALUs are fully pipelined 356 | alu_busy[next_latency - op_latency[opcode]][alu_index] = true; 357 | latency[a] = next_latency; 358 | 359 | // ASIC is supposed to have enough ALUs to run as many independent instructions per cycle as possible, so latency calculation for ASIC is simple 360 | asic_latency[a] = ((asic_latency[a] > asic_latency[b]) ? asic_latency[a] : asic_latency[b]) + asic_op_latency[opcode]; 361 | 362 | rotated[a] = is_rotation[opcode]; 363 | 364 | inst_data[a] = code_size + (opcode << 8) + ((inst_data[b] & 255) << 16); 365 | 366 | code[code_size].opcode = opcode; 367 | code[code_size].dst_index = dst_index; 368 | code[code_size].src_index = src_index; 369 | code[code_size].C = 0; 370 | 371 | if (src_index == 8) 372 | { 373 | r8_used = true; 374 | } 375 | 376 | if (opcode == ADD) 377 | { 378 | // ADD instruction is implemented as two 1-cycle instructions on a real CPU, so mark ALU as busy for the next cycle too 379 | alu_busy[next_latency - op_latency[opcode] + 1][alu_index] = true; 380 | 381 | // ADD instruction requires 4 more random bytes for 32-bit constant "C" in "a = a + b + C" 382 | check_data(&data_index, sizeof(uint32_t), data, sizeof(data)); 383 | uint32_t t; 384 | memcpy(&t, data + data_index, sizeof(uint32_t)); 385 | code[code_size].C = SWAP32LE(t); 386 | data_index += sizeof(uint32_t); 387 | } 388 | 389 | ++code_size; 390 | if (code_size >= NUM_INSTRUCTIONS_MIN) 391 | { 392 | break; 393 | } 394 | } 395 | else 396 | { 397 | ++num_retries; 398 | } 399 | } 400 | 401 | // ASIC has more execution resources and can extract as much parallelism from the code as possible 402 | // We need to add a few more MUL and ROR instructions to achieve minimal required latency for ASIC 403 | // Get this latency for at least 1 of the 4 registers 404 | const int prev_code_size = code_size; 405 | while ((code_size < NUM_INSTRUCTIONS_MAX) && (asic_latency[0] < TOTAL_LATENCY) && (asic_latency[1] < TOTAL_LATENCY) && (asic_latency[2] < TOTAL_LATENCY) && (asic_latency[3] < TOTAL_LATENCY)) 406 | { 407 | int min_idx = 0; 408 | int max_idx = 0; 409 | for (int i = 1; i < 4; ++i) 410 | { 411 | if (asic_latency[i] < asic_latency[min_idx]) min_idx = i; 412 | if (asic_latency[i] > asic_latency[max_idx]) max_idx = i; 413 | } 414 | 415 | const uint8_t pattern[3] = { ROR, MUL, MUL }; 416 | const uint8_t opcode = pattern[(code_size - prev_code_size) % 3]; 417 | latency[min_idx] = latency[max_idx] + op_latency[opcode]; 418 | asic_latency[min_idx] = asic_latency[max_idx] + asic_op_latency[opcode]; 419 | 420 | code[code_size].opcode = opcode; 421 | code[code_size].dst_index = min_idx; 422 | code[code_size].src_index = max_idx; 423 | code[code_size].C = 0; 424 | ++code_size; 425 | } 426 | 427 | // There is ~98.15% chance that loop condition is false, so this loop will execute only 1 iteration most of the time 428 | // It never does more than 4 iterations for all block heights < 10,000,000 429 | } while (!r8_used || (code_size < NUM_INSTRUCTIONS_MIN) || (code_size > NUM_INSTRUCTIONS_MAX)); 430 | 431 | // It's guaranteed that NUM_INSTRUCTIONS_MIN <= code_size <= NUM_INSTRUCTIONS_MAX here 432 | // Add final instruction to stop the interpreter 433 | code[code_size].opcode = RET; 434 | code[code_size].dst_index = 0; 435 | code[code_size].src_index = 0; 436 | code[code_size].C = 0; 437 | 438 | return code_size; 439 | } 440 | 441 | #endif 442 | -------------------------------------------------------------------------------- /src/crypto/warnings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(_MSC_VER) 4 | 5 | #define PUSH_WARNINGS __pragma(warning(push)) 6 | #define POP_WARNINGS __pragma(warning(pop)) 7 | #define DISABLE_VS_WARNINGS(w) __pragma(warning(disable: w)) 8 | #define DISABLE_GCC_WARNING(w) 9 | #define DISABLE_CLANG_WARNING(w) 10 | #define DISABLE_GCC_AND_CLANG_WARNING(w) 11 | 12 | #else 13 | 14 | #include 15 | 16 | #define PUSH_WARNINGS _Pragma("GCC diagnostic push") 17 | #define POP_WARNINGS _Pragma("GCC diagnostic pop") 18 | #define DISABLE_VS_WARNINGS(w) 19 | 20 | #if defined(__clang__) 21 | #define DISABLE_GCC_WARNING(w) 22 | #define DISABLE_CLANG_WARNING DISABLE_GCC_AND_CLANG_WARNING 23 | #else 24 | #define DISABLE_GCC_WARNING DISABLE_GCC_AND_CLANG_WARNING 25 | #define DISABLE_CLANG_WARNING(w) 26 | #endif 27 | 28 | #define DISABLE_GCC_AND_CLANG_WARNING(w) _Pragma(BOOST_PP_STRINGIZE(GCC diagnostic ignored BOOST_PP_STRINGIZE(-W##w))) 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018, Jethro Grassie 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include 30 | #include 31 | #include "hash.h" 32 | #include "main.h" 33 | 34 | struct result_t { 35 | crypto::hash hash; 36 | uint32_t nonce; 37 | } result; 38 | 39 | EMSCRIPTEN_KEEPALIVE 40 | void allocate_state() 41 | { 42 | slow_hash_allocate_state(); 43 | } 44 | 45 | EMSCRIPTEN_KEEPALIVE 46 | void free_state() 47 | { 48 | slow_hash_free_state(); 49 | } 50 | 51 | EMSCRIPTEN_KEEPALIVE 52 | uint8_t* hash(uint8_t* block_data, const size_t length, const uint32_t target_low, const uint32_t target_high, const uint32_t height) 53 | { 54 | memset(&result, 0, sizeof(struct result_t)); 55 | uint64_t target = (uint64_t) target_high << 32 | target_low; 56 | if(target_high == 0) 57 | target = 0xFFFFFFFFFFFFFFFFULL / (0xFFFFFFFFULL / ((uint64_t)target)); 58 | 59 | uint64_t* p_result = (uint64_t*) (result.hash.data + 24); 60 | uint32_t* p_nonce = (uint32_t*) (block_data + 39); 61 | result.nonce = *p_nonce; 62 | const uint8_t cn_variant = block_data[0] >= 7 ? block_data[0] - 6 : 0; 63 | while(true) 64 | { 65 | crypto::cn_slow_hash(block_data, length, result.hash, cn_variant, height); 66 | if(*p_result < target) 67 | { 68 | break; 69 | } 70 | *p_nonce = ++result.nonce; 71 | } 72 | return (uint8_t*) &result; 73 | } 74 | 75 | int main(int argc, char ** argv) 76 | { 77 | printf("WASM loaded\n"); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018, Jethro Grassie 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #pragma once 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | void slow_hash_allocate_state(); 36 | void slow_hash_free_state(); 37 | 38 | void allocate_state(); 39 | void free_state(); 40 | uint8_t* hash(uint8_t* block_data, const size_t length, const uint32_t target_low, const uint32_t target_high, const uint32_t height); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Emscripten-Generated Code 7 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 |

24 |     
25 | 26 | 88 | {{{ SCRIPT }}} 89 | 90 | 91 | --------------------------------------------------------------------------------