Merge pull request #140 from MyHush/danger

Sync danger to duke branches
This commit is contained in:
Duke Leto
2020-09-14 05:54:30 -07:00
committed by GitHub
37 changed files with 3655 additions and 837 deletions

View File

@@ -462,7 +462,7 @@ libbitcoin_server_a_SOURCES += rpc/testtransactions.cpp
endif endif
# cli: zcash-cli # cli
libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_cli_a_SOURCES = \ libbitcoin_cli_a_SOURCES = \

66
src/crypto/bip39/Makefile Normal file
View File

@@ -0,0 +1,66 @@
CC ?= gcc
OPTFLAGS ?= -O3 -g
CFLAGS += $(OPTFLAGS) \
-std=gnu99 \
-W \
-Wall \
-Wextra \
-Wimplicit-function-declaration \
-Wredundant-decls \
-Wstrict-prototypes \
-Wundef \
-Wshadow \
-Wpointer-arith \
-Wformat \
-Wreturn-type \
-Wsign-compare \
-Wmultichar \
-Wformat-nonliteral \
-Winit-self \
-Wuninitialized \
-Wformat-security \
-Werror
VALGRIND ?= 1
CFLAGS += -I.
CFLAGS += -DVALGRIND=$(VALGRIND)
CFLAGS += $(shell pkg-config --cflags openssl)
# disable certain optimizations and features when small footprint is required
ifdef SMALL
CFLAGS += -DUSE_PRECOMPUTED_CP=0
endif
SRCS = bignum.c ecdsa.c curves.c secp256k1.c nist256p1.c rand.c hmac.c bip32.c bip39.c pbkdf2.c base58.c base32.c
#SRCS += address.c
#SRCS += script.c
SRCS += ripemd160.c
SRCS += sha2.c
SRCS += sha3.c
SRCS += hasher.c
#SRCS += aes/aescrypt.c aes/aeskey.c aes/aestab.c aes/aes_modes.c
#SRCS += ed25519-donna/curve25519-donna-32bit.c ed25519-donna/curve25519-donna-helpers.c ed25519-donna/modm-donna-32bit.c
#SRCS += ed25519-donna/ed25519-donna-basepoint-table.c ed25519-donna/ed25519-donna-32bit-tables.c ed25519-donna/ed25519-donna-impl-base.c
#SRCS += ed25519-donna/ed25519.c ed25519-donna/curve25519-donna-scalarmult-base.c ed25519-donna/ed25519-sha3.c ed25519-donna/ed25519-keccak.c
#SRCS += blake256.c
#SRCS += blake2b.c blake2s.c
#SRCS += chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c
SRCS += memzero.c
OBJS = $(SRCS:.c=.o)
TESTLIBS = $(shell pkg-config --libs check) -lpthread -lm
TESTSSLLIBS = $(shell pkg-config --libs openssl)
all: hasher.o bip39.o memzero.o pbkdf2.o base58.o base32.o
@echo "Created object files, donezo"
%.o: %.c %.h options.h
$(CC) $(CFLAGS) -o $@ -c $<
clean:
rm -rf *.o

233
src/crypto/bip39/base32.c Normal file
View File

@@ -0,0 +1,233 @@
/**
* Copyright (c) 2017 Saleem Rashid
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "base32.h"
#include <string.h>
const char *BASE32_ALPHABET_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789";
static inline void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out);
static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet);
static inline void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out);
static inline int base32_encode_character(uint8_t decoded, const char *alphabet);
static inline int base32_decode_character(char encoded, const char *alphabet);
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet) {
size_t length = base32_encoded_length(inlen);
if (outlen <= length) {
return NULL;
}
base32_encode_unsafe(in, inlen, (uint8_t *) out);
for (size_t i = 0; i < length; i++) {
int ret = base32_encode_character(out[i], alphabet);
if (ret == -1) {
return false;
} else {
out[i] = ret;
}
}
out[length] = '\0';
return &out[length];
}
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet) {
size_t length = base32_decoded_length(inlen);
if (outlen < length) {
return NULL;
}
if (!base32_decode_unsafe((uint8_t *) in, inlen, (uint8_t *) out, alphabet)) {
return NULL;
}
return &out[length];
}
void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out) {
uint8_t remainder = inlen % 5;
size_t limit = inlen - remainder;
size_t i, j;
for (i = 0, j = 0; i < limit; i += 5, j += 8) {
base32_5to8(&in[i], 5, &out[j]);
}
if (remainder) base32_5to8(&in[i], remainder, &out[j]);
}
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet) {
uint8_t remainder = inlen % 8;
size_t limit = inlen - remainder;
size_t i, j;
for (i = 0, j = 0; i < limit; i += 8, j += 5) {
if (!base32_8to5(&in[i], 8, &out[j], alphabet)) {
return false;
}
}
if (remainder && !base32_8to5(&in[i], remainder, &out[j], alphabet)) {
return false;
}
return true;
}
size_t base32_encoded_length(size_t inlen) {
uint8_t remainder = inlen % 5;
return (inlen / 5) * 8 + (remainder * 8 + 4) / 5;
}
size_t base32_decoded_length(size_t inlen) {
uint8_t remainder = inlen % 8;
return (inlen / 8) * 5 + (remainder * 5) / 8;
}
void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out) {
if (length >= 1) {
out[0] = (in[0] >> 3);
out[1] = (in[0] & 7) << 2;
}
if (length >= 2) {
out[1] |= (in[1] >> 6);
out[2] = (in[1] >> 1) & 31;
out[3] = (in[1] & 1) << 4;
}
if (length >= 3) {
out[3] |= (in[2] >> 4);
out[4] = (in[2] & 15) << 1;
}
if (length >= 4) {
out[4] |= (in[3] >> 7);
out[5] = (in[3] >> 2) & 31;
out[6] = (in[3] & 3) << 3;
}
if (length >= 5) {
out[6] |= (in[4] >> 5);
out[7] = (in[4] & 31);
}
}
bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet) {
if (length == 1 || length == 3 || length == 6 || length > 8) {
return false;
}
if (alphabet) {
uint8_t decoded[length];
for (size_t i = 0; i < length; i++) {
int ret = base32_decode_character(in[i], alphabet);
if (ret == -1) {
return false;
} else {
decoded[i] = ret;
}
}
base32_8to5_raw(decoded, length, out);
} else {
base32_8to5_raw(in, length, out);
}
return true;
}
void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out) {
if (length >= 2) {
out[0] = (in[0] << 3);
out[0] |= (in[1] >> 2);
}
if (length >= 4) {
out[1] = (in[1] & 3) << 6;
out[1] |= (in[2] << 1);
out[1] |= (in[3] >> 4);
}
if (length >= 5) {
out[2] = (in[3] & 15) << 4;
out[2] |= (in[4] >> 1);
}
if (length >= 7) {
out[3] = (in[4] & 1) << 7;
out[3] |= (in[5] << 2);
out[3] |= (in[6] >> 3);
}
if (length >= 8) {
out[4] = (in[6] & 7) << 5;
out[4] |= (in[7] & 31);
}
}
int base32_encode_character(uint8_t decoded, const char *alphabet) {
if (decoded >> 5) {
return -1;
}
if (alphabet == BASE32_ALPHABET_RFC4648) {
if (decoded < 26) {
return 'A' + decoded;
} else {
return '2' - 26 + decoded;
}
}
return alphabet[decoded];
}
int base32_decode_character(char encoded, const char *alphabet) {
if (alphabet == BASE32_ALPHABET_RFC4648) {
if (encoded >= 'A' && encoded <= 'Z') {
return encoded - 'A';
} else if (encoded >= 'a' && encoded <= 'z') {
return encoded - 'a';
} else if (encoded >= '2' && encoded <= '7') {
return encoded - '2' + 26;
} else {
return -1;
}
}
const char *occurrence = strchr(alphabet, encoded);
if (occurrence) {
return occurrence - alphabet;
} else {
return -1;
}
}

41
src/crypto/bip39/base32.h Normal file
View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2017 Saleem Rashid
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __BASE32_H__
#define __BASE32_H__
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
extern const char *BASE32_ALPHABET_RFC4648;
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet);
void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out);
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet);
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet);
size_t base32_encoded_length(size_t inlen);
size_t base32_decoded_length(size_t inlen);
#endif

285
src/crypto/bip39/base58.c Normal file
View File

@@ -0,0 +1,285 @@
/**
* Copyright (c) 2012-2014 Luke Dashjr
* Copyright (c) 2013-2014 Pavol Rusnak
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include "base58.h"
#include "sha2.h"
#include "ripemd160.h"
#include "memzero.h"
const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15,16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29,30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39,40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54,55,56,57,-1,-1,-1,-1,-1,
};
bool b58tobin(void *bin, size_t *binszp, const char *b58)
{
size_t binsz = *binszp;
if (binsz == 0) {
return false;
}
const unsigned char *b58u = (const unsigned char*)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
uint64_t t;
uint32_t c;
size_t i, j;
uint8_t bytesleft = binsz % 4;
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
unsigned zerocount = 0;
size_t b58sz;
b58sz = strlen(b58);
memzero(outi, sizeof(outi));
// Leading zeros, just count
for (i = 0; i < b58sz && b58u[i] == '1'; ++i)
++zerocount;
for ( ; i < b58sz; ++i)
{
if (b58u[i] & 0x80)
// High-bit set on invalid digit
return false;
if (b58digits_map[b58u[i]] == -1)
// Invalid base58 digit
return false;
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--; )
{
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
}
if (c)
// Output number too big (carry to the next int32)
return false;
if (outi[0] & zeromask)
// Output number too big (last int32 filled too far)
return false;
}
j = 0;
switch (bytesleft) {
case 3:
*(binu++) = (outi[0] & 0xff0000) >> 16;
//-fallthrough
case 2:
*(binu++) = (outi[0] & 0xff00) >> 8;
//-fallthrough
case 1:
*(binu++) = (outi[0] & 0xff);
++j;
//-fallthrough
default:
break;
}
for (; j < outisz; ++j)
{
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
*(binu++) = (outi[j] >> 0) & 0xff;
}
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{
if (binu[i]) {
if (zerocount > i) {
/* result too large */
return false;
}
break;
}
--*binszp;
}
*binszp += zerocount;
return true;
}
int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str)
{
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
hasher_Raw(hasher_type, bin, binsz - 4, buf);
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
return binc[0];
}
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
{
const uint8_t *bin = data;
int carry;
ssize_t i, j, high, zcount = 0;
size_t size;
while (zcount < (ssize_t)binsz && !bin[zcount])
++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memzero(buf, size);
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < (ssize_t)size && !buf[j]; ++j);
if (*b58sz <= zcount + size - j)
{
*b58sz = zcount + size - j + 1;
return false;
}
if (zcount)
memset(b58, '1', zcount);
for (i = zcount; j < (ssize_t)size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
*b58sz = i + 1;
return true;
}
int base58_encode_check(const uint8_t *data, int datalen, HasherType hasher_type, char *str, int strsize)
{
if (datalen > 128) {
return 0;
}
uint8_t buf[datalen + 32];
uint8_t *hash = buf + datalen;
memcpy(buf, data, datalen);
hasher_Raw(hasher_type, data, datalen, hash);
size_t res = strsize;
bool success = b58enc(str, &res, buf, datalen + 4);
memzero(buf, sizeof(buf));
return success ? res : 0;
}
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen)
{
if (datalen > 128) {
return 0;
}
uint8_t d[datalen + 4];
size_t res = datalen + 4;
if (b58tobin(d, &res, str) != true) {
return 0;
}
uint8_t *nd = d + datalen + 4 - res;
if (b58check(nd, res, hasher_type, str) < 0) {
return 0;
}
memcpy(data, nd, res - 4);
return res - 4;
}
#if USE_GRAPHENE
int b58gphcheck(const void *bin, size_t binsz, const char *base58str)
{
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
ripemd160(bin, binsz - 4, buf); // No double SHA256, but a single RIPEMD160
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
return binc[0];
}
int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize)
{
if (datalen > 128) {
return 0;
}
uint8_t buf[datalen + 32];
uint8_t *hash = buf + datalen;
memcpy(buf, data, datalen);
ripemd160(data, datalen, hash); // No double SHA256, but a single RIPEMD160
size_t res = strsize;
bool success = b58enc(str, &res, buf, datalen + 4);
memzero(buf, sizeof(buf));
return success ? res : 0;
}
int base58gph_decode_check(const char *str, uint8_t *data, int datalen)
{
if (datalen > 128) {
return 0;
}
uint8_t d[datalen + 4];
size_t res = datalen + 4;
if (b58tobin(d, &res, str) != true) {
return 0;
}
uint8_t *nd = d + datalen + 4 - res;
if (b58gphcheck(nd, res, str) < 0) {
return 0;
}
memcpy(data, nd, res - 4);
return res - 4;
}
#endif

49
src/crypto/bip39/base58.h Normal file
View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2013-2014 Tomas Dzetkulic
* Copyright (c) 2013-2014 Pavol Rusnak
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __BASE58_H__
#define __BASE58_H__
#include <stdint.h>
#include <stdbool.h>
#include "hasher.h"
#include "options.h"
extern const char b58digits_ordered[];
extern const int8_t b58digits_map[];
int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type, char *str, int strsize);
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen);
// Private
bool b58tobin(void *bin, size_t *binszp, const char *b58);
int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str);
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz);
#if USE_GRAPHENE
int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize);
int base58gph_decode_check(const char *str, uint8_t *data, int datalen);
int b58gphcheck(const void *bin, size_t binsz, const char *base58str);
#endif
#endif

112
src/crypto/bip39/bip32.h Normal file
View File

@@ -0,0 +1,112 @@
/**
* Copyright (c) 2013-2014 Tomas Dzetkulic
* Copyright (c) 2013-2014 Pavol Rusnak
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __BIP32_H__
#define __BIP32_H__
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "ecdsa.h"
#include "ed25519-donna/ed25519.h"
#include "options.h"
typedef struct {
const char *bip32_name; // string for generating BIP32 xprv from seed
const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519
HasherType hasher_base58;
HasherType hasher_sign;
HasherType hasher_pubkey;
HasherType hasher_script;
} curve_info;
typedef struct {
uint32_t depth;
uint32_t child_num;
uint8_t chain_code[32];
uint8_t private_key[32];
uint8_t private_key_extension[32];
uint8_t public_key[33];
const curve_info *curve;
} HDNode;
int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char *curve, HDNode *out);
int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char *curve, HDNode *out);
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, HDNode *out);
#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000))
int hdnode_private_ckd(HDNode *inout, uint32_t i);
#if USE_CARDANO
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i);
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len, const uint8_t *seed, int seed_len, HDNode *out);
#endif
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, const uint8_t *parent_chain_code, uint32_t i, curve_point *child, uint8_t *child_chain_code);
int hdnode_public_ckd(HDNode *inout, uint32_t i);
void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *chain_code, uint32_t i, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize, int addrformat);
#if USE_BIP32_CACHE
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, uint32_t *fingerprint);
#endif
uint32_t hdnode_fingerprint(HDNode *node);
void hdnode_fill_public_key(HDNode *node);
#if USE_ETHEREUM
int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash);
#endif
#if USE_NEM
int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address);
int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key);
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, const uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer);
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer);
#endif
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, HasherType hasher_sign, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size);
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize);
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize);
int hdnode_deserialize(const char *str, uint32_t version_public, uint32_t version_private, const char *curve, HDNode *node, uint32_t *fingerprint);
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw);
void hdnode_get_address(HDNode *node, uint32_t version, char *addr, int addrsize);
const curve_info *get_curve_by_name(const char *curve_name);
#endif

View File

@@ -35,6 +35,8 @@
#if USE_BIP39_CACHE #if USE_BIP39_CACHE
int BIP39_WORDS = 2048;
static int bip39_cache_index = 0; static int bip39_cache_index = 0;
static CONFIDENTIAL struct { static CONFIDENTIAL struct {

View File

@@ -24,13 +24,11 @@
#ifndef __BIP39_H__ #ifndef __BIP39_H__
#define __BIP39_H__ #define __BIP39_H__
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define BIP39_WORDS 2048
#define BIP39_PBKDF2_ROUNDS 2048 #define BIP39_PBKDF2_ROUNDS 2048
const char *mnemonic_generate(int strength); // strength in bits const char *mnemonic_generate(int strength); // strength in bits
const char *mnemonic_from_data(const uint8_t *data, int len); const char *mnemonic_from_data(const uint8_t *data, int len);
void mnemonic_clear(void); void mnemonic_clear(void);
@@ -39,14 +37,8 @@ int mnemonic_check(const char *mnemonic);
int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy); int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy);
// passphrase must be at most 256 characters otherwise it would be truncated // passphrase must be at most 256 characters otherwise it would be truncated
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total));
uint8_t seed[512 / 8],
void (*progress_callback)(uint32_t current,
uint32_t total));
int mnemonic_find_word(const char *word); const char * const *mnemonic_wordlist(void);
const char *mnemonic_complete_word(const char *prefix, int len);
const char *mnemonic_get_word(int index);
uint32_t mnemonic_word_completion_mask(const char *prefix, int len);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "bip39.h"
#include <sodium.h>
// NOTE: We must override this to implement actual RNG!
void random_buffer(uint8_t *buf, size_t len) {
if( len > 0 ) {
randombytes_buf(buf, len);
}
}
int main(int argc, char **argv)
{
char *this = argv[0];
if (argc > 1) {
fprintf(stderr, "Usage: %s\n", this);
return 1;
}
if (sodium_init() == -1) {
fprintf(stderr, "libsodium init failed! :(\n");
return 1;
}
int strength = 256;
const char *mnemonic = mnemonic_generate(strength);
printf("%s\n", mnemonic);
return 0;
}

View File

@@ -0,0 +1,87 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "bip39.h"
#include "bip32.h"
#include "ecdsa.h"
#include "curves.h"
char iter[256];
uint8_t seed[512 / 8];
uint8_t addr[21], pubkeyhash[20];
int count = 0, found = 0;
HDNode node;
clock_t start;
// around 280 tries per second
// testing data:
//
// mnemonic: "all all all all all all all all all all all all"
// address: "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL"
// passphrase: ""
//
// mnemonic: "all all all all all all all all all all all all"
// address: "1N3uJ5AU3FTYQ1ZQgTMtYmgSvMBmQiGVBS"
// passphrase: "testing"
int main(int argc, char **argv)
{
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage: bip39bruteforce address [mnemonic]\n");
return 1;
}
const char *address = argv[1];
const char *mnemonic, *item;
if (argc == 3) {
mnemonic = argv[2];
item = "passphrase";
} else {
mnemonic = NULL;
item = "mnemonic";
}
if (mnemonic && !mnemonic_check(mnemonic)) {
fprintf(stderr, "\"%s\" is not a valid mnemonic\n", mnemonic);
return 2;
}
if (!ecdsa_address_decode(address, 0, HASHER_SHA2, addr)) {
fprintf(stderr, "\"%s\" is not a valid address\n", address);
return 3;
}
printf("Reading %ss from stdin ...\n", item);
start = clock();
for (;;) {
if (fgets(iter, 256, stdin) == NULL) break;
int len = strlen(iter);
if (len <= 0) {
continue;
}
count++;
iter[len - 1] = 0;
if (mnemonic) {
mnemonic_to_seed(mnemonic, iter, seed, NULL);
} else {
mnemonic_to_seed(iter, "", seed, NULL);
}
hdnode_from_seed(seed, 512 / 8, SECP256K1_NAME, &node);
hdnode_private_ckd_prime(&node, 44);
hdnode_private_ckd_prime(&node, 0);
hdnode_private_ckd_prime(&node, 0);
hdnode_private_ckd(&node, 0);
hdnode_private_ckd(&node, 0);
hdnode_fill_public_key(&node);
ecdsa_get_pubkeyhash(node.public_key, HASHER_SHA2, pubkeyhash);
if (memcmp(addr + 1, pubkeyhash, 20) == 0) {
found = 1;
break;
}
}
float dur = (float)(clock() - start) / CLOCKS_PER_SEC;
printf("Tried %d %ss in %f seconds = %f tries/second\n", count, item, dur, (float)count/dur);
if (found) {
printf("Correct %s found! :-)\n\"%s\"\n", item, iter);
return 0;
}
printf("Correct %s not found. :-(\n", item);
return 4;
}

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2014-2017, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#ifndef __BLAKE256_H__
#define __BLAKE256_H__
#include <stdint.h>
#include <stddef.h>
#define BLAKE256_DIGEST_LENGTH 32
#define BLAKE256_BLOCK_LENGTH 64
typedef struct {
uint32_t h[8], s[4], t[2];
size_t buflen;
uint8_t nullt;
uint8_t buf[64];
} BLAKE256_CTX;
void blake256_Init(BLAKE256_CTX *);
void blake256_Update(BLAKE256_CTX *, const uint8_t *, size_t);
void blake256_Final(BLAKE256_CTX *, uint8_t *);
void blake256(const uint8_t *, size_t, uint8_t *);
#endif /* __BLAKE256_H__ */

View File

@@ -0,0 +1,39 @@
static inline uint32_t load32( const void *src )
{
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
}
static inline uint64_t load64( const void *src )
{
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
}
static inline void store16( void *dst, uint16_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline void store32( void *dst, uint32_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline void store64( void *dst, uint64_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
}

View File

@@ -0,0 +1,41 @@
#ifndef __BLAKE2B_H__
#define __BLAKE2B_H__
#include <stdint.h>
#include <stddef.h>
enum blake2b_constant
{
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};
typedef struct __blake2b_state
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2b_state;
#define BLAKE2B_CTX blake2b_state
#define BLAKE2B_BLOCK_LENGTH BLAKE2B_BLOCKBYTES
#define BLAKE2B_DIGEST_LENGTH BLAKE2B_OUTBYTES
#define BLAKE2B_KEY_LENGTH BLAKE2B_KEYBYTES
int blake2b_Init(blake2b_state *S, size_t outlen);
int blake2b_InitKey(blake2b_state *S, size_t outlen, const void *key, size_t keylen);
int blake2b_InitPersonal(blake2b_state *S, size_t outlen, const void *personal, size_t personal_len);
int blake2b_Update(blake2b_state *S, const void *pin, size_t inlen);
int blake2b_Final(blake2b_state *S, void *out, size_t outlen);
int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen);
int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen);
#endif

View File

@@ -0,0 +1,41 @@
#ifndef __BLAKE2S_H__
#define __BLAKE2S_H__
#include <stdint.h>
#include <stddef.h>
enum blake2s_constant
{
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8
};
typedef struct __blake2s_state
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
uint8_t buf[BLAKE2S_BLOCKBYTES];
uint32_t buflen;
uint8_t outlen;
uint8_t last_node;
} blake2s_state;
#define BLAKE2S_CTX blake2s_state
#define BLAKE2S_BLOCK_LENGTH BLAKE2S_BLOCKBYTES
#define BLAKE2S_DIGEST_LENGTH BLAKE2S_OUTBYTES
#define BLAKE2S_KEY_LENGTH BLAKE2S_KEYBYTES
int blake2s_Init(blake2s_state *S, size_t outlen);
int blake2s_InitKey(blake2s_state *S, size_t outlen, const void *key, size_t keylen);
int blake2s_InitPersonal(blake2s_state *S, size_t outlen, const void *personal, size_t personal_len);
int blake2s_Update(blake2s_state *S, const void *pin, size_t inlen);
int blake2s_Final(blake2s_state *S, void *out, size_t outlen);
int blake2s(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen);
int blake2s_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen);
#endif

144
src/crypto/bip39/hasher.c Normal file
View File

@@ -0,0 +1,144 @@
/**
* Copyright (c) 2017 Saleem Rashid
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "hasher.h"
#include "ripemd160.h"
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param, uint32_t param_size) {
hasher->type = type;
hasher->param = param;
hasher->param_size = param_size;
switch (hasher->type) {
case HASHER_SHA2:
case HASHER_SHA2D:
case HASHER_SHA2_RIPEMD:
sha256_Init(&hasher->ctx.sha2);
break;
case HASHER_SHA3:
#if USE_KECCAK
case HASHER_SHA3K:
#endif
sha3_256_Init(&hasher->ctx.sha3);
break;
case HASHER_BLAKE:
case HASHER_BLAKED:
case HASHER_BLAKE_RIPEMD:
blake256_Init(&hasher->ctx.blake);
break;
case HASHER_GROESTLD_TRUNC:
groestl512_Init(&hasher->ctx.groestl);
break;
case HASHER_BLAKE2B:
blake2b_Init(&hasher->ctx.blake2b, 32);
break;
case HASHER_BLAKE2B_PERSONAL:
blake2b_InitPersonal(&hasher->ctx.blake2b, 32, hasher->param, hasher->param_size);
break;
}
}
void hasher_Init(Hasher *hasher, HasherType type) {
hasher_InitParam(hasher, type, NULL, 0);
}
void hasher_Reset(Hasher *hasher) {
hasher_InitParam(hasher, hasher->type, hasher->param, hasher->param_size);
}
void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length) {
switch (hasher->type) {
case HASHER_SHA2:
case HASHER_SHA2D:
case HASHER_SHA2_RIPEMD:
sha256_Update(&hasher->ctx.sha2, data, length);
break;
case HASHER_SHA3:
#if USE_KECCAK
case HASHER_SHA3K:
#endif
sha3_Update(&hasher->ctx.sha3, data, length);
break;
case HASHER_BLAKE:
case HASHER_BLAKED:
case HASHER_BLAKE_RIPEMD:
blake256_Update(&hasher->ctx.blake, data, length);
break;
case HASHER_GROESTLD_TRUNC:
groestl512_Update(&hasher->ctx.groestl, data, length);
break;
case HASHER_BLAKE2B:
case HASHER_BLAKE2B_PERSONAL:
blake2b_Update(&hasher->ctx.blake2b, data, length);
break;
}
}
void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) {
switch (hasher->type) {
case HASHER_SHA2:
sha256_Final(&hasher->ctx.sha2, hash);
break;
case HASHER_SHA2D:
sha256_Final(&hasher->ctx.sha2, hash);
hasher_Raw(HASHER_SHA2, hash, HASHER_DIGEST_LENGTH, hash);
break;
case HASHER_SHA2_RIPEMD:
sha256_Final(&hasher->ctx.sha2, hash);
ripemd160(hash, HASHER_DIGEST_LENGTH, hash);
break;
case HASHER_SHA3:
sha3_Final(&hasher->ctx.sha3, hash);
break;
#if USE_KECCAK
case HASHER_SHA3K:
keccak_Final(&hasher->ctx.sha3, hash);
break;
#endif
case HASHER_BLAKE:
blake256_Final(&hasher->ctx.blake, hash);
break;
case HASHER_BLAKED:
blake256_Final(&hasher->ctx.blake, hash);
hasher_Raw(HASHER_BLAKE, hash, HASHER_DIGEST_LENGTH, hash);
break;
case HASHER_BLAKE_RIPEMD:
blake256_Final(&hasher->ctx.blake, hash);
ripemd160(hash, HASHER_DIGEST_LENGTH, hash);
break;
case HASHER_GROESTLD_TRUNC:
groestl512_DoubleTrunc(&hasher->ctx.groestl, hash);
break;
case HASHER_BLAKE2B:
case HASHER_BLAKE2B_PERSONAL:
blake2b_Final(&hasher->ctx.blake2b, hash, 32);
break;
}
}
void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]) {
Hasher hasher;
hasher_Init(&hasher, type);
hasher_Update(&hasher, data, length);
hasher_Final(&hasher, hash);
}

80
src/crypto/bip39/hasher.h Normal file
View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) 2017 Saleem Rashid
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __HASHER_H__
#define __HASHER_H__
#include <stddef.h>
#include <stdint.h>
#include "sha2.h"
#include "sha3.h"
#include "blake256.h"
#include "groestl.h"
#include "blake2b.h"
#define HASHER_DIGEST_LENGTH 32
typedef enum {
HASHER_SHA2,
HASHER_SHA2D,
HASHER_SHA2_RIPEMD,
HASHER_SHA3,
#if USE_KECCAK
HASHER_SHA3K,
#endif
HASHER_BLAKE,
HASHER_BLAKED,
HASHER_BLAKE_RIPEMD,
HASHER_GROESTLD_TRUNC, /* Double Groestl512 hasher truncated to 256 bits */
HASHER_BLAKE2B,
HASHER_BLAKE2B_PERSONAL,
} HasherType;
typedef struct {
HasherType type;
union {
SHA256_CTX sha2; // for HASHER_SHA2{,D}
SHA3_CTX sha3; // for HASHER_SHA3{,K}
BLAKE256_CTX blake; // for HASHER_BLAKE{,D}
GROESTL512_CTX groestl; // for HASHER_GROESTLD_TRUNC
BLAKE2B_CTX blake2b; // for HASHER_BLAKE2B{,_PERSONAL}
} ctx;
const void *param;
uint32_t param_size;
} Hasher;
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param, uint32_t param_size);
void hasher_Init(Hasher *hasher, HasherType type);
void hasher_Reset(Hasher *hasher);
void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length);
void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]);
void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]);
#endif

View File

@@ -28,33 +28,25 @@
#include "sha2.h" #include "sha2.h"
typedef struct _HMAC_SHA256_CTX { typedef struct _HMAC_SHA256_CTX {
uint8_t o_key_pad[SHA256_BLOCK_LENGTH]; uint8_t o_key_pad[SHA256_BLOCK_LENGTH];
SHA256_CTX ctx; SHA256_CTX ctx;
} HMAC_SHA256_CTX; } HMAC_SHA256_CTX;
typedef struct _HMAC_SHA512_CTX { typedef struct _HMAC_SHA512_CTX {
uint8_t o_key_pad[SHA512_BLOCK_LENGTH]; uint8_t o_key_pad[SHA512_BLOCK_LENGTH];
SHA512_CTX ctx; SHA512_CTX ctx;
} HMAC_SHA512_CTX; } HMAC_SHA512_CTX;
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen);
const uint32_t keylen); void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen);
void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg,
const uint32_t msglen);
void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac); void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac);
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac);
const uint32_t msglen, uint8_t *hmac); void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest);
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen,
uint32_t *opad_digest, uint32_t *ipad_digest);
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen);
const uint32_t keylen); void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen);
void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg,
const uint32_t msglen);
void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac); void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac);
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac);
const uint32_t msglen, uint8_t *hmac); void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest);
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen,
uint64_t *opad_digest, uint64_t *ipad_digest);
#endif #endif

View File

@@ -0,0 +1,66 @@
#ifndef __STDC_WANT_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1 // C11's bounds-checking interface.
#endif
#include <string.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef __unix__
#include <strings.h>
#include <sys/param.h>
#endif
// C11's bounds-checking interface.
#if defined(__STDC_LIB_EXT1__)
#define HAVE_MEMSET_S 1
#endif
// GNU C Library version 2.25 or later.
#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#define HAVE_EXPLICIT_BZERO 1
#endif
// Newlib
#if defined( __NEWLIB__)
#define HAVE_EXPLICIT_BZERO 1
#endif
// FreeBSD version 11.0 or later.
#if defined(__FreeBSD__) && __FreeBSD_version >= 1100037
#define HAVE_EXPLICIT_BZERO 1
#endif
// OpenBSD version 5.5 or later.
#if defined(__OpenBSD__) && OpenBSD >= 201405
#define HAVE_EXPLICIT_BZERO 1
#endif
// NetBSD version 7.2 or later.
#if defined(__NetBSD__) && __NetBSD_Version__ >= 702000000
#define HAVE_EXPLICIT_MEMSET 1
#endif
// Adapted from https://github.com/jedisct1/libsodium/blob/1647f0d53ae0e370378a9195477e3df0a792408f/src/libsodium/sodium/utils.c#L102-L130
void memzero(void *const pnt, const size_t len)
{
#ifdef _WIN32
SecureZeroMemory(pnt, len);
#elif defined(HAVE_MEMSET_S)
memset_s(pnt, (rsize_t) len, 0, (rsize_t) len);
#elif defined(HAVE_EXPLICIT_BZERO)
explicit_bzero(pnt, len);
#elif defined(HAVE_EXPLICIT_MEMSET)
explicit_memset(pnt, 0, len);
#else
volatile unsigned char *volatile pnt_ =
(volatile unsigned char *volatile) pnt;
size_t i = (size_t) 0U;
while (i < len) {
pnt_[i++] = 0U;
}
#endif
}

View File

@@ -3,6 +3,6 @@
#include <stddef.h> #include <stddef.h>
void memzero(void* const pnt, const size_t len); void memzero(void * const pnt, const size_t len);
#endif #endif

View File

@@ -52,7 +52,7 @@
// support constructing BIP32 nodes from ed25519 and curve25519 curves. // support constructing BIP32 nodes from ed25519 and curve25519 curves.
#ifndef USE_BIP32_25519_CURVES #ifndef USE_BIP32_25519_CURVES
#define USE_BIP32_25519_CURVES 1 #define USE_BIP32_25519_CURVES 1
#endif #endif
// implement BIP39 caching // implement BIP39 caching

View File

@@ -28,39 +28,29 @@
#include "sha2.h" #include "sha2.h"
typedef struct _PBKDF2_HMAC_SHA256_CTX { typedef struct _PBKDF2_HMAC_SHA256_CTX {
uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)];
uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)];
uint32_t f[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; uint32_t f[SHA256_DIGEST_LENGTH / sizeof(uint32_t)];
uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)];
char first; char first;
} PBKDF2_HMAC_SHA256_CTX; } PBKDF2_HMAC_SHA256_CTX;
typedef struct _PBKDF2_HMAC_SHA512_CTX { typedef struct _PBKDF2_HMAC_SHA512_CTX {
uint64_t odig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; uint64_t odig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)];
uint64_t idig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; uint64_t idig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)];
uint64_t f[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; uint64_t f[SHA512_DIGEST_LENGTH / sizeof(uint64_t)];
uint64_t g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; uint64_t g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)];
char first; char first;
} PBKDF2_HMAC_SHA512_CTX; } PBKDF2_HMAC_SHA512_CTX;
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr);
int passlen, const uint8_t *salt, int saltlen, void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations);
uint32_t blocknr);
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx,
uint32_t iterations);
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key); void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key);
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen);
int saltlen, uint32_t iterations, uint8_t *key,
int keylen);
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr);
int passlen, const uint8_t *salt, int saltlen, void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations);
uint32_t blocknr);
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx,
uint32_t iterations);
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key); void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key);
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen);
int saltlen, uint32_t iterations, uint8_t *key,
int keylen);
#endif #endif

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) 2013-2014 Tomas Dzetkulic
* Copyright (c) 2013-2014 Pavol Rusnak
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __SECP256K1_H__
#define __SECP256K1_H__
#include <stdint.h>
#include "ecdsa.h"
#include "bip32.h"
extern const ecdsa_curve secp256k1;
extern const curve_info secp256k1_info;
extern const curve_info secp256k1_decred_info;
extern const curve_info secp256k1_groestl_info;
extern const curve_info secp256k1_smart_info;
#endif

View File

@@ -392,6 +392,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
#endif #endif
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
strUsage += HelpMessageOpt("-txsend=<cmd>", _("Execute command to send a transaction instead of broadcasting (%s in cmd is replaced by transaction hex)"));
strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX)); strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX));
strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX)); strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX));
strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX)); strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX));
@@ -1118,6 +1119,16 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#endif #endif
} }
if (mapArgs.count("-txsend")) {
if (GetBoolArg("-walletbroadcast", true)) {
if (SoftSetBoolArg("-walletbroadcast", false)) {
LogPrintf("%s: parameter interaction: -txsend=<cmd> -> setting -walletbroadcast=0\n", __func__);
} else {
return InitError(_("Wallet transaction broadcasting is incompatible with -txsend (for privacy)."));
}
}
}
// ********************************************************* Step 3: parameter-to-internal-flags // ********************************************************* Step 3: parameter-to-internal-flags
fZdebug=GetBoolArg("-zdebug", false); fZdebug=GetBoolArg("-zdebug", false);

View File

@@ -1238,6 +1238,70 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
// 10% of all block rewards go towards Hush core team // 10% of all block rewards go towards Hush core team
// If you do not like this, you are encouraged to fork the chain // If you do not like this, you are encouraged to fork the chain
// or start your own Hush Smart Chain: https://github.com/myhush/hush-smart-chains // or start your own Hush Smart Chain: https://github.com/myhush/hush-smart-chains
// HUSH supply curve cannot be exactly represented via KMD AC CLI args, so we do it ourselves.
// You specify the BR, and the FR % gets added so 10% of 12.5 is 1.25
// but to tell the AC params, I need to say "11% of 11.25" is 1.25
// 11% ie. 1/9th cannot be exactly represented and so the FR has tiny amounts of error unless done manually
// Do not change this code unless you really know what you are doing.
// Here Be Dragons! -- Duke Leto
uint64_t hush_commission(int height)
{
// TODO: Calculate new BR_END based on 75s block time!!! 2X old BR_END is a rough estimate, not exact!
int32_t starting_commission = 125000000, HALVING1 = GetArg("-z2zheight",340000),
INTERVAL = GetArg("-ac_halving1",840000), TRANSITION = 129, BR_END = 2*5422111;
// TODO: how many halvings will we have given new 75s blocktime?
int32_t commisions[] = {starting_commission, 31250000, 15625000, 78125000, 39062500, 19531250, 9765625, // these are exact
4882812, 2441406, 1220703, 610351 // these have deviation from ideal BR
// Just like BTC, BRs in the far future will be slightly less than
// they should be because exact values are not integers, causing
// slightly less coins to be actually mined
};
uint64_t commission = 0;
if( height > HALVING1) {
// Block time going from 150s to 75s (half) means the interval between halvings
// must be twice as often, i.e. 840000*2=1680000
// With 150s blocks, we have 210,000 blocks per year
// With 75s blocks, we have 420,000 blocks per year
INTERVAL = GetArg("-ac_halving2",1680000);
fprintf(stderr,"%s: height=%d increasing interval to %d\n", __func__, height, INTERVAL);
}
// Transition period of 128 blocks has BR=FR=0
if (height < TRANSITION) {
commission = 0;
} else if (height < HALVING1) { // before 1st Halving @ Block 340000 (Nov 2020)
commission = commisions[0];
} else if (height < HALVING1+1*INTERVAL) { // before 2nd Halving @ Block 2020000
commission = commisions[1];
} else if (height < HALVING1+2*INTERVAL) { // before 3rd Halving @ Block 3700000
commission = commisions[2];
} else if (height < HALVING1+3*INTERVAL) { // before 4th Halving @ Block 5380000
commission = commisions[3];
} else if (height < HALVING1+4*INTERVAL) { // before 5th Halving @ Block 7060000
commission = commisions[4];
} else if (height < HALVING1+5*INTERVAL) { // before 6th Halving @ Block 8740000
commission = commisions[5];
} else if (height < HALVING1+6*INTERVAL) { // before 7th Halving @ Block 10420000
commission = commisions[6];
} else if (height < HALVING1+7*INTERVAL) { // before 8th Halving @ Block 12100000
// TODO: Still true??? Block reward will go to zero between 7th+8th halvings, ac_end may need adjusting
commission = commisions[7];
} else if (height < HALVING1+8*INTERVAL) { // before 9th Halving @ Block 13780000
// BR should be zero before this halving happens
commission = commisions[8];
}
// Explicitly set the last block reward
// BR_END is the block with the last non-zero block reward, which overrides
// the -ac_end param on HUSH3
if(height > BR_END) {
fprintf(stderr,"%s: HUSH block reward has gone to zero at height %d!!! It was a good run folks\n", __func__, height);
commission = 0;
}
fprintf(stderr,"%s: commission=%lu,interval=%d at height %d\n", __func__, commission, INTERVAL, height);
return commission;
}
uint64_t komodo_commission(const CBlock *pblock,int32_t height) uint64_t komodo_commission(const CBlock *pblock,int32_t height)
{ {
fprintf(stderr,"%s at height=%d\n",__func__,height); fprintf(stderr,"%s at height=%d\n",__func__,height);
@@ -1256,78 +1320,25 @@ uint64_t komodo_commission(const CBlock *pblock,int32_t height)
fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION)); fprintf(stderr,"ht.%d nSubsidy %.8f prod %llu\n",height,(double)nSubsidy/COIN,(long long)(nSubsidy * ASSETCHAINS_COMMISSION));
commission = ((nSubsidy * ASSETCHAINS_COMMISSION) / COIN); commission = ((nSubsidy * ASSETCHAINS_COMMISSION) / COIN);
// Do not change this code unless you really know what you are doing.
// Here Be Dragons! -- Duke Leto
if (ishush3) { if (ishush3) {
// TODO: Calculate new BR_END based on 75s block time!!! 2X old BR_END is a rough estimate, not exact! commission = hush_commission(height);
int32_t starting_commission = 125000000, HALVING1 = GetArg("-z2zheight",340000),
INTERVAL = GetArg("-ac_halving1",840000), TRANSITION = 129, BR_END = 2*5422111;
// TODO: how many halvings will we have given new 75s blocktime?
int32_t commisions[] = {starting_commission, 31250000, 15625000, 78125000, 39062500, 19531250, 9765625, // these are exact
4882812, 2441406, 1220703, 610351 // these have deviation from ideal BR
// Just like BTC, BRs in the far future will be slightly less than
// they should be because exact values are not integers, causing
// slightly less coins to be actually mined
};
// HUSH supply curve cannot be exactly represented via KMD AC CLI args, so we do it ourselves.
// You specify the BR, and the FR % gets added so 10% of 12.5 is 1.25
// but to tell the AC params, I need to say "11% of 11.25" is 1.25
// 11% ie. 1/9th cannot be exactly represented and so the FR has tiny amounts of error unless done manually
if( height > HALVING1) {
// Block time going from 150s to 75s (half) means the interval between halvings
// must be twice as often, i.e. 840000*2=1680000
// With 150s blocks, we have 210,000 blocks per year
// With 75s blocks, we have 420,000 blocks per year
INTERVAL = GetArg("-ac_halving2",1680000);
}
// Transition period of 128 blocks has BR=FR=0
if (height < TRANSITION) {
commission = 0;
} else if (height < HALVING1) { // before 1st Halving @ Block 340000 (Nov 2020)
commission = commisions[0];
} else if (height < HALVING1+1*INTERVAL) { // before 2nd Halving @ Block 2020000
commission = commisions[1];
} else if (height < HALVING1+2*INTERVAL) { // before 3rd Halving @ Block 3700000
commission = commisions[2];
} else if (height < HALVING1+3*INTERVAL) { // before 4th Halving @ Block 5380000
commission = commisions[3];
} else if (height < HALVING1+4*INTERVAL) { // before 5th Halving @ Block 7060000
commission = commisions[4];
} else if (height < HALVING1+5*INTERVAL) { // before 6th Halving @ Block 8740000
commission = commisions[5];
} else if (height < HALVING1+6*INTERVAL) { // before 7th Halving @ Block 10420000
commission = commisions[6];
} else if (height < HALVING1+7*INTERVAL) { // before 8th Halving @ Block 12100000
// TODO: Still true??? Block reward will go to zero between 7th+8th halvings, ac_end may need adjusting
commission = commisions[7];
} else if (height < HALVING1+8*INTERVAL) { // before 9th Halving @ Block 13780000
// BR should be zero before this halving happens
commission = commisions[8];
}
// Explicitly set the last block reward
// BR_END is the block with the last non-zero block reward, which overrides
// the -ac_end param on HUSH3
if(height > BR_END) {
commission = 0;
}
} }
if ( ASSETCHAINS_FOUNDERS > 1 ) if ( ASSETCHAINS_FOUNDERS > 1 )
{ {
if ( (height % ASSETCHAINS_FOUNDERS) == 0 ) if ( (height % ASSETCHAINS_FOUNDERS) == 0 )
{ {
if ( ASSETCHAINS_FOUNDERS_REWARD == 0 ) if ( ASSETCHAINS_FOUNDERS_REWARD == 0 ) {
commission = commission * ASSETCHAINS_FOUNDERS; commission = commission * ASSETCHAINS_FOUNDERS;
else } else {
commission = ASSETCHAINS_FOUNDERS_REWARD; commission = ASSETCHAINS_FOUNDERS_REWARD;
}
fprintf(stderr,"%s: set commission=%lu at height %d with\n",__func__,commission, height);
} else {
commission = 0;
} }
else commission = 0;
} }
} } else if ( pblock != 0 ) {
else if ( pblock != 0 )
{
txn_count = pblock->vtx.size(); txn_count = pblock->vtx.size();
for (i=0; i<txn_count; i++) for (i=0; i<txn_count; i++)
{ {

View File

@@ -1541,6 +1541,8 @@ uint64_t komodo_max_money()
return komodo_current_supply(10000000); return komodo_current_supply(10000000);
} }
// This implements the Hush Emission Curve
uint64_t hush_block_subsidy(int nHeight) uint64_t hush_block_subsidy(int nHeight)
{ {
uint64_t subsidy=0; uint64_t subsidy=0;
@@ -1557,6 +1559,8 @@ uint64_t hush_block_subsidy(int nHeight)
} }
return subsidy; return subsidy;
} }
// wrapper for more general supply curves of Hush Smart Chains
uint64_t komodo_ac_block_subsidy(int nHeight) uint64_t komodo_ac_block_subsidy(int nHeight)
{ {
fprintf(stderr,"%s: ht.%d\n", __func__, nHeight); fprintf(stderr,"%s: ht.%d\n", __func__, nHeight);

View File

@@ -169,11 +169,11 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "z_listsentbyaddress", 3}, { "z_listsentbyaddress", 3},
{ "z_listsentbyaddress", 4}, { "z_listsentbyaddress", 4},
{ "z_listsentbyaddress", 5}, { "z_listsentbyaddress", 5},
{ "z_listreceivedbyaddress", 1}, { "z_listreceivedaddress", 1},
{ "z_listreceivedbyaddress", 2}, { "z_listreceivedaddress", 2},
{ "z_listreceivedbyaddress", 3}, { "z_listreceivedaddress", 3},
{ "z_listreceivedbyaddress", 4}, { "z_listreceivedaddress", 4},
{ "z_listreceivedbyaddress", 5}, { "z_listreceivedaddress", 5},
// crosschain // crosschain
{ "assetchainproof", 1}, { "assetchainproof", 1},

View File

@@ -45,7 +45,10 @@
#include <stdint.h> #include <stdint.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/assign/list_of.hpp> #include <boost/assign/list_of.hpp>
#include <boost/thread.hpp>
#include <univalue.h> #include <univalue.h>
@@ -82,65 +85,6 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
out.push_back(Pair("addresses", a)); out.push_back(Pair("addresses", a));
} }
UniValue TxJoinSplitToJSON(const CTransaction& tx) {
bool useGroth = tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION;
UniValue vjoinsplit(UniValue::VARR);
for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
const JSDescription& jsdescription = tx.vjoinsplit[i];
UniValue joinsplit(UniValue::VOBJ);
joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
joinsplit.push_back(Pair("vpub_oldZat", jsdescription.vpub_old));
joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
joinsplit.push_back(Pair("vpub_newZat", jsdescription.vpub_new));
joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
{
UniValue nullifiers(UniValue::VARR);
BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
nullifiers.push_back(nf.GetHex());
}
joinsplit.push_back(Pair("nullifiers", nullifiers));
}
{
UniValue commitments(UniValue::VARR);
BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
commitments.push_back(commitment.GetHex());
}
joinsplit.push_back(Pair("commitments", commitments));
}
joinsplit.push_back(Pair("onetimePubKey", jsdescription.ephemeralKey.GetHex()));
joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex()));
{
UniValue macs(UniValue::VARR);
BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
macs.push_back(mac.GetHex());
}
joinsplit.push_back(Pair("macs", macs));
}
CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
auto ps = SproutProofSerializer<CDataStream>(ssProof, useGroth);
boost::apply_visitor(ps, jsdescription.proof);
joinsplit.push_back(Pair("proof", HexStr(ssProof.begin(), ssProof.end())));
{
UniValue ciphertexts(UniValue::VARR);
for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) {
ciphertexts.push_back(HexStr(ct.begin(), ct.end()));
}
joinsplit.push_back(Pair("ciphertexts", ciphertexts));
}
vjoinsplit.push_back(joinsplit);
}
return vjoinsplit;
}
uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
UniValue TxShieldedSpendsToJSON(const CTransaction& tx) { UniValue TxShieldedSpendsToJSON(const CTransaction& tx) {
@@ -306,9 +250,6 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue&
} }
entry.push_back(Pair("vout", vout)); entry.push_back(Pair("vout", vout));
UniValue vjoinsplit = TxJoinSplitToJSON(tx);
entry.push_back(Pair("vjoinsplit", vjoinsplit));
if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) { if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance))); entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance)));
UniValue vspenddesc = TxShieldedSpendsToJSON(tx); UniValue vspenddesc = TxShieldedSpendsToJSON(tx);
@@ -390,9 +331,6 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
} }
entry.push_back(Pair("vout", vout)); entry.push_back(Pair("vout", vout));
UniValue vjoinsplit = TxJoinSplitToJSON(tx);
entry.push_back(Pair("vjoinsplit", vjoinsplit));
if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) { if (tx.fOverwintered && tx.nVersion >= SAPLING_TX_VERSION) {
entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance))); entry.push_back(Pair("valueBalance", ValueFromAmount(tx.valueBalance)));
UniValue vspenddesc = TxShieldedSpendsToJSON(tx); UniValue vspenddesc = TxShieldedSpendsToJSON(tx);
@@ -478,33 +416,6 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp, const CPubKey& my
" }\n" " }\n"
" ,...\n" " ,...\n"
" ],\n" " ],\n"
" \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\n"
" {\n"
" \"vpub_old\" : x.xxx, (numeric) public input value\n"
" \"vpub_new\" : x.xxx, (numeric) public output value\n"
" \"anchor\" : \"hex\", (string) the anchor\n"
" \"nullifiers\" : [ (json array of string)\n"
" \"hex\" (string) input note nullifier\n"
" ,...\n"
" ],\n"
" \"commitments\" : [ (json array of string)\n"
" \"hex\" (string) output note commitment\n"
" ,...\n"
" ],\n"
" \"onetimePubKey\" : \"hex\", (string) the onetime public key used to encrypt the ciphertexts\n"
" \"randomSeed\" : \"hex\", (string) the random seed\n"
" \"macs\" : [ (json array of string)\n"
" \"hex\" (string) input note MAC\n"
" ,...\n"
" ],\n"
" \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
" \"ciphertexts\" : [ (json array of string)\n"
" \"hex\" (string) output note ciphertext\n"
" ,...\n"
" ]\n"
" }\n"
" ,...\n"
" ],\n"
" \"blockhash\" : \"hash\", (string) the block hash\n" " \"blockhash\" : \"hash\", (string) the block hash\n"
" \"confirmations\" : n, (numeric) The number of notarized DPoW confirmations\n" " \"confirmations\" : n, (numeric) The number of notarized DPoW confirmations\n"
" \"rawconfirmations\" : n, (numeric) The number of raw confirmations\n" " \"rawconfirmations\" : n, (numeric) The number of raw confirmations\n"
@@ -933,33 +844,6 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp, const CPubKey&
" }\n" " }\n"
" ,...\n" " ,...\n"
" ],\n" " ],\n"
" \"vjoinsplit\" : [ (array of json objects, only for version >= 2)\n"
" {\n"
" \"vpub_old\" : x.xxx, (numeric) public input value in HUSH\n"
" \"vpub_new\" : x.xxx, (numeric) public output value in HUSH\n"
" \"anchor\" : \"hex\", (string) the anchor\n"
" \"nullifiers\" : [ (json array of string)\n"
" \"hex\" (string) input note nullifier\n"
" ,...\n"
" ],\n"
" \"commitments\" : [ (json array of string)\n"
" \"hex\" (string) output note commitment\n"
" ,...\n"
" ],\n"
" \"onetimePubKey\" : \"hex\", (string) the onetime public key used to encrypt the ciphertexts\n"
" \"randomSeed\" : \"hex\", (string) the random seed\n"
" \"macs\" : [ (json array of string)\n"
" \"hex\" (string) input note MAC\n"
" ,...\n"
" ],\n"
" \"proof\" : \"hex\", (string) the zero-knowledge proof\n"
" \"ciphertexts\" : [ (json array of string)\n"
" \"hex\" (string) output note ciphertext\n"
" ,...\n"
" ]\n"
" }\n"
" ,...\n"
" ],\n"
"}\n" "}\n"
"\nExamples:\n" "\nExamples:\n"
@@ -1373,6 +1257,19 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& m
const CCoins* existingCoins = view.AccessCoins(hashTx); const CCoins* existingCoins = view.AccessCoins(hashTx);
bool fHaveMempool = mempool.exists(hashTx); bool fHaveMempool = mempool.exists(hashTx);
bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000; bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
// If we are configured to send transactions via an
// external service instead of broadcasting, do that
std::string strCmd = GetArg("-txsend", "");
if (!strCmd.empty()) {
if (fHaveChain) {
throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
}
boost::replace_all(strCmd, "%s", EncodeHexTx(tx));
boost::thread t(runCommand, strCmd); // thread runs free
// Return here so we don't add to our mempool or broadcast to peers
return hashTx.GetHex();
}
if (!fHaveMempool && !fHaveChain) { if (!fHaveMempool && !fHaveChain) {
// push to local node and sync with wallets // push to local node and sync with wallets
CValidationState state; CValidationState state;

View File

@@ -652,6 +652,7 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
{ "wallet", "walletpassphrase", &walletpassphrase, true }, { "wallet", "walletpassphrase", &walletpassphrase, true },
{ "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false }, { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false },
{ "wallet", "z_listreceivedaddress", &z_listreceivedaddress, false },
{ "wallet", "z_getbalance", &z_getbalance, false }, { "wallet", "z_getbalance", &z_getbalance, false },
{ "wallet", "z_gettotalbalance", &z_gettotalbalance, false }, { "wallet", "z_gettotalbalance", &z_gettotalbalance, false },
{ "wallet", "z_mergetoaddress", &z_mergetoaddress, false }, { "wallet", "z_mergetoaddress", &z_mergetoaddress, false },

View File

@@ -480,6 +480,7 @@ extern UniValue z_listnullifiers(const UniValue& params, bool fHelp, const CPubK
extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp
extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdump.cpp
extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
extern UniValue z_listreceivedaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
extern UniValue z_getbalance(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_getbalance(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp
extern UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp

View File

@@ -66,9 +66,10 @@ void CScheduler::serviceQueue()
// Some boost versions have a conflicting overload of wait_until that returns void. // Some boost versions have a conflicting overload of wait_until that returns void.
// Explicitly use a template here to avoid hitting that overload. // Explicitly use a template here to avoid hitting that overload.
while (!shouldStop() && !taskQueue.empty() && while (!shouldStop() && !taskQueue.empty()) {
newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) { boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
// Keep waiting until timeout if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout)
break; // Exit loop after timeout, it means we reached the time of the event
} }
// If there are multiple threads, the queue can empty while we're waiting (another // If there are multiple threads, the queue can empty while we're waiting (another

View File

@@ -1,3 +1,4 @@
// Copyright (c) 2019-2020 The Hush developers
// Copyright (c) 2016 The Zcash developers // Copyright (c) 2016 The Zcash developers
// Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44 // Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44
@@ -74,9 +75,9 @@ void ThreadSendAlert()
if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert")) if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert"))
return; return;
//TODO: wait until KOMODO_IN_SYNC
MilliSleep(60*1000); // Wait a minute so we get connected MilliSleep(60*1000); // Wait a minute so we get connected
//
// Alerts are relayed around the network until nRelayUntil, flood // Alerts are relayed around the network until nRelayUntil, flood
// filling to every node. // filling to every node.
// After the relay time is past, new nodes are told about alerts // After the relay time is past, new nodes are told about alerts
@@ -87,7 +88,7 @@ void ThreadSendAlert()
CAlert alert; CAlert alert;
alert.nRelayUntil = GetTime() + 15 * 60; alert.nRelayUntil = GetTime() + 15 * 60;
alert.nExpiration = GetTime() + 10 * 365 * 24 * 60 * 60; alert.nExpiration = GetTime() + 10 * 365 * 24 * 60 * 60;
alert.nID = 1005; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs alert.nID = 1005; // HUSH3 has never had any alert id's
alert.nCancel = 1004; // cancels previous messages up to this ID number alert.nCancel = 1004; // cancels previous messages up to this ID number
// These versions are protocol versions // These versions are protocol versions
@@ -103,12 +104,12 @@ void ThreadSendAlert()
// 4000 or higher will put the RPC into safe mode // 4000 or higher will put the RPC into safe mode
alert.nPriority = 4000; alert.nPriority = 4000;
alert.strComment = ""; alert.strComment = "";
alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Hush (3.2.0 or later)."; alert.strStatusBar = "Your client version has degraded networking behavior. Please update to the most recent version of Hush (3.5.0 or later).";
alert.strRPCError = alert.strStatusBar; alert.strRPCError = alert.strStatusBar;
// Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done:
// alert.setSubVer.insert(std::string("/MagicBean:0.7.2/")); // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/"));
const std::vector<std::string> useragents = {}; //{"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"}; const std::vector<std::string> useragents = {}; //{"MagicBean", "BeanStalk", "AppleSeed" };
BOOST_FOREACH(const std::string& useragent, useragents) { BOOST_FOREACH(const std::string& useragent, useragents) {
} }

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2019-2020 The Hush developers * * Copyright © 2019-2020 The Hush developers *
* * * *
* See the AUTHORS and LICENSE files at * * See the AUTHORS and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -10,6 +10,7 @@
* or distributed except according to the terms contained in the GPLv3 * * or distributed except according to the terms contained in the GPLv3 *
* * * *
* Removal or modification of this copyright notice is prohibited. * * Removal or modification of this copyright notice is prohibited. *
* https://myhush.org *
* * * *
******************************************************************************/ ******************************************************************************/
@@ -24,6 +25,7 @@ string newSietchZaddr() {
SendManyRecipient newSietchRecipient(string zaddr) { SendManyRecipient newSietchRecipient(string zaddr) {
int nAmount = 0; int nAmount = 0;
// TODO: Should we randomize length of data, perhaps into buckets?
// Sietch zouts have random data in their memos so they are indistinguishable from // Sietch zouts have random data in their memos so they are indistinguishable from
// encrypted data being stored in the memo field // encrypted data being stored in the memo field
char hex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; char hex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@@ -36,223 +38,11 @@ SendManyRecipient newSietchRecipient(string zaddr) {
return SendManyRecipient( zaddr, nAmount, string(str) ); return SendManyRecipient( zaddr, nAmount, string(str) );
} }
// The network essentially DoS's these addresses and reduces their privacy slightly
// by making them public, but in return, the rest of the shielded pool benefits
// and so it's a large benefit for a small cost.
string randomSietchZaddr() { string randomSietchZaddr() {
std::vector<string> SietchShieldedPool1 = { auto sk = libzcash::SaplingSpendingKey::random();
"zs1qqj4aw35ku9yn72g3tha588mxk66mhl5smnn99as40887xvdg49d4yqf43hhqnj9rpsq7qaqqhx", auto expsk = sk.expanded_spending_key();
"zs1qywzq2cutvg6rkynjljtssz246easagumg3hlwjluz4g7qttg9kqrld7s43ewutpph56jmn2zu6", auto zdust = sk.default_address();
"zs1qx7swmw28dj992f6zs0aqucds9kag88mnca5u73dddeqek4m97pg7h9qsaxxwwkgqxht6zujaxc", return EncodePaymentAddress(zdust);
"zs1q82pkqu58uemrm2749x6g2ta5shnsra9p5jgk0qqzxd3e08ke6vyeezz7lhldj32jxtsuemskk7",
"zs1qvah5w05qq4yhrsqrt73ckgntkmwdv9mntxep8clnxqfph8xggqad96a5nvwg4evfr9pc5ruvc8",
"zs1qwrkjcmnrwrqqkz3dyfjvdvdppe0ndnm8fhhpsz8stje4qcfc54jtuygz2jfwc3aag69wsjcm8h",
"zs1q5pd7h4x7dtnpa4ace7tytye5sd0j4043t4f3jdntyxvg9ex258nu6pw9tthn6t5gmjq5gv0lhc",
"zs1q6vjrpsuf468an545q7fh9cx0xlkwh75a7qjpemjh3ymuqqzxz5ts2n2dcth3yfnlv6vqpjyglr",
"zs1qmsvwtxkwlh3tkh0lqtwqv2mxy94jt778f7j74a8067nejkt4j3m2rkmypccju7cfuw7xyg0gg8",
"zs1qu3jxrw5qwuvl7zfvnsdvywr4a9cn4h00me65te29platx5agek072f5rvxgt8kdt630qs4tgtr",
"zs1qamxwddwrl5xn56alffruk69p304cqf7uf5nhqpwfc374l9ph00m78xv2kzwymyz0fhxcku7v5k",
"zs1q7gv479e6q7d8fxc35v5s27em66mmm5gz50excudf95rzjgnwdy5pnwdfytvm7gt8kt6wpkfphq",
"zs1pqvxd9a2zcsh2v8gaswh3jp2qkzz5umrucl5k4gx0rkvmq68krpx3jesavxftd8t0z56v8whllj",
"zs1ppn2mdznaa2pd9mavfnxrcjtv0c9un8pg6jaa9ww4wy6wdfs8xxwquqk5umtcjwm6vr4zrqy5x7",
"zs1pz9c9ydyrm7e876cvae9ha45ww77ru5fhys2yz33kjy8ej9230wjy8yupfxkynwqr6nfupgmf94",
"zs1p83g95avpsgr847eu3rm3xcmgurt9hc77wtndnmpypa046n529aqdc9ptz04ugsuhvum2ztzwe3",
"zs1p83jle2p8awu4peevq389y5kyrs5tqxxyrk32zy0t98d4cfepmme0myxp68nrq60xwzc5teulvg",
"zs1pg5ggzwx4yaa7g83yuhay8kzh78nahxfe7cgavn88f7rxlnuckhl2vznv0f33yuqhhs3sh62vl6",
"zs1p2nrefmqfhnwrxqfsz4ruvu8wl7742j5rv2fmwlpmpudwqpdn2yrha9rwsu5gc0fdv2j73tfk6a",
"zs1pw29hkrvszxpe2e4tjpj5h9pszjhql2p4tzcj2c5lf67m7d8jtgc22vehftxdnqze33mgtjc25k",
"zs1p0ggg024alu2l5x8df8ucu4lz8r453su56w2mmshru49uh9a0p6ufy3qfj8a9n7xeu8dxxjrk4p",
"zs1psaydszvszu4mar7ef9gk8atmwpnfjjsh8plajn6ttlgdk44jfud5zv8l3uyq73qk3eskec96ut",
"zs1pjf3kczvrwduuy4x99t03wfrgwstueyw0ypvwa44fz2tukux8kqqqs48uag4y39ed4rux8etvv0",
"zs1pnwzzh4mhehkvf4ys9x70q6meq9mgqj6mgl9ddzwvf8excswrj54lfgu4m9slmc90s37q8e63du",
"zs1pnndevupuakjcqyqzu4sfcgdmdzrhutp8ygxwsl5wvq5hgu20u55auu8p08wphvz9mu3k8ynyr5",
"zs1pmy6tvt9p3xxp5edt70mkwfqk0ljgaranzdnluh5ln36g9g3v2udquleuz5974q2mamywmrxl7j",
"zs1pau6lddk3uapms7v7rsmxvxeekqh52z795kzy9z3dv9qvzq3jwh4pr2adg5cf8fw2e3mzqmgstq",
"zs1zpy6wuvy3jlrfmj0363tx6cuume6j0mqfakk7ydw4f6zvn4s7plewk0gtm7r34pjtppvkp8rzl0",
"zs1zpvkccety206ww6c344ehughuyklc3v02q07j4p72pqewxl0n50zugtje6lclj3m292t6vs56fl",
"zs1zzucdg9kalcjnnknt98gpg42qm9aqpkc6qf5ewgr29udu55r0zt862z3zt23sd4mj9t47k7k6w4",
"zs1z9agq4vq7eswwynhmzdsy58nxq3azhn66y853yw9kvercmve8vv6d5pawpwwpwpuyedmzpcqk8q",
"zs1zvddl2e0pve5kl0hu7fcum30lyhx4pdq64jztq2vp09lqtu5gclfg4fe9fqvnm8k2d5svydg7s4",
"zs1zvsmkn6a4celtcg8ece6exnkvnr2u06ej8kjt6mrpm0983e86dr9al6gd5g73k24j0a0zkpjs3w",
"zs1zv33kglx4n5572dg2pez2k3m7tgtz08a70ndpfj6x204pphlm0pzcppetsnjlat3qflswqfmu83",
"zs1zsz5c9xua7arkvd60vsl559d4dvnjz8ejq4rlmmm9cnz942fdmjmvsgrdl7d5ddxh4y9258jk2l",
"zs1z5n6qvch0wfymumxjflezekxa2j5t978eqzh9ldxsl39h2jjrlzdv9rf00wdrvg0t6afq7mq0us",
"zs1z4ymm3gt22f3pcj9p9l2yg00e2m39kfexgaz99s9y4nsuxhlk6u0sl9lsx9awzywumxyuxv9vuw",
"zs1zkjnhz96xepc97rfyven23epymd5s558yqhp488gcxcj794z6p37h5ej5m5waqxfupmc538mej3",
"zs1zcqdekyq656yj2y86lh08u8zpetfanj5u4rhfpcphne9xw7esce8asux2rdr4yjxzds56fuda5r",
"zs1zceru3jt9m3jqzacnffetvrg8zch6le0zactl7ssfky2vwy7pcffkg3pmauqqpkv5v7nv3uzc5a",
"zs1zellp4tdmxdsd6hmg2c4qlx96m39c0cjlqupw085z87lvzcnx2r0gs7plc0wp4m4upk3zcs35e8",
"zs1zm2pcg2d3hnyxufn8cyshjn742gmffwaqdc0nt5uf9gsytdjywsqaasfdxf4sysfu0sgxjwjp0g",
"zs1za9nk7fpgnfetjulq6t8jgfyks06xg4q8rfwpgsfrkn49k34nc7xhm27dnjuzztgnwkww28ztyw",
"zs1zaaz6j6z7z748mck4v55s3fd4htl4f478kulnwr84m8vn4m0r227juddyq0ncu3cyvc765z9gm4",
"zs1zlz59lgwc8pqq33508v5ygk9e58f7fs4rpj3achhwnkcyn2dku44yfjghdf5l2v50nu2gjzgl2l",
"zs1zlgenma0yuqxmqgns2avpnauclxgfvgd6rf0jt09fmfyaflwlhsscem9ypmrvewl9l356dn3jtr",
"zs1rzu2yg2328l2wlfstu27dl024ucqsjx6g635yxmyhs0wr3lduutkc3peuhqe83uueh5n5q624rd",
"zs1rr9jpeemn9ek30x4h65rx0ddul7xet6cc8atwrjftmq9sdrvj9f5zdc9xg7amtc6dv5fxjyhu54",
"zs1rrgccr0yvfn5fdek39x09y2ylyf42xkydcwzq67wdrzyjj2mv874easa4h4tymz5gj852aqpffk",
"zs1rynh7vl05weafzwkp0p5eafuzzqph04prgg74emqq0sx6xudtrs2380v3ycxgp5lzudw6tmc2zd",
"zs1rxqz0a59zx3yduncc3azyzexwu8xl6cc0zu83hfd28mksrgahhvx8604uhf0u5mna9m4znnj4gr",
"zs1rxr2xff2vcv0y9s6ux6c6t9y7r3zvcvrqmwkvsnxj39t0qv7qwyhncnykhzcqg0ggpu423ykzxe",
"zs1r8chvye5uzlskv8jvt6j8nxnyz4lshy3u46yjhc8w9ekhjhneg402knft3t943t5nrhs6d0d5um",
"zs1rgu6mz58xrqxpyl5xw7ss2szz29cg98s8xl25hu7fy4lcxw58zr93a8rgyha52vwxx7hxj2emkw",
"zs1rveutz8ftruljrlctum42kakjqk4cm8dm2807nqm974dz0rptlxcs999ttsvwp65vc9e59vv9fe",
"zs1rwfqhlezm5ln7kq8wp8hkl08ddn74ryr8cs4cu8qc23spdx79xgfqj4lju4u2yqdrkxkwfvk3ed",
"zs1rwklllsk9jwhhf0fedvlzsqfqdkwer05zh8c8hwypl4tls2hdal54lexhca7kghhum5hycurvfe",
"zs1r0ulehrcg9xz0lfdcukjm3qlvqy74t0u8raqf4zn88vdsta8mzp8t8p9ul8jragssvs9qaqpw2e",
"zs1r3t0cve050wufwl8r2tly05vn7w79v53fe6dagjtt2ese0qm6vgjp3rrsfu4n0am840sq5thn72",
"zs1rnd8zwan2xlrnfwylm9khkeutnzg2v9vjdnyellyuzkwmed94uvd2dq8ceumxwspz037zp2ctqa",
"zs1r4tphfnf3zy34dqyjuld2kgtyg88hrxpv756pkkkmrfdeun0cqzpepac4ma9qrjrvdqxg2z5fuv",
"zs1rcpywy0v4sfej85wdaslfwsp4pe9sa87xgzv24ywhps2l4c9jlrqttv0wl9zkc5e7rsekf42wvp",
"zs1r66et0z9xw3qqhzyc2aht294y7yqyz8wx2l2t63unca4k4zh4v9t44kpmg52z9va5968y45fdkx",
"zs1rat3szdulwxwmx7y4rdphvlpjj5phadvz0fsvj7mtg9ggzwd22sn30hzsh27h7t6cvca6a8wu2n",
"zs1rau4jcth66jsg098ucclp9tfa5qe6jmtmfkcluaqnyj3uatkt9dsrgx44xtmxr3e9xuxv6sy208",
"zs1ypf2v2yu4p4mnlmw0wd3mpztpjlhl39jnn6hkvf77ell0h5u6yg2pgeusvku5y5sykyy6kk6yyh",
"zs1yzkt8catgk6slwj7azu79tvwv6tkd6agcykvvht4rxlevtsh99u036jf5503pju3h05w7x02cm8",
"zs1yrty5fmnyaartpcyjnpal0w44g4mt2ey5tyzcmgq4g6qtsfjmxae7fvy2zsw7t0zvseuwcfwt2e",
"zs1y9p5gazcx04kke96xudep0edzkqr06gdjnr5vm99a6qxzatqz5katput4q9nx95e8965sg7d3pl",
"zs1y9vpfgkxwh3xm3j9d38zkeqql2lh8w3ucgerkww2asdv89p87emdavkzurnqpkrmu7e3xv5myue",
"zs1yfa9gwmn0xe4myrg0rf8kmu36243u8773ukeev0set2yv0z9vpxm6ratee52e9zmpvvx7w2xy28",
"zs1ytpjrujfsgs69smqerxeaf8m38jwxc4ejgxxe4pzc5qu4auqrgy8tf7zxc402pxf9uku646kc0q",
"zs1ytvtdwmcn8tnka6w6wa8n3ghnkf7gp2qaudd4233y6m509ntm59rr0n8eudhre0md7m0zedpcsq",
"zs1yjmeu09mzrt8rgehv2gcfhxx6ddqz7ww87ssfapndvc94hxfrfsdkkgm8f8nr36xm8p7q462qy2",
"zs1ynqghdu0r0c20csp3ygrxdw9hk2l89j3g59q8zhht9jyxycpcc9ccvhyyn2f9j0ehp4pk5wkhqs",
"zs1y5ny4jpjm05vp5awjd6muaqqypdv0y9tr6pz0m5t82cwtrearxwf7km4aznydpcjeuzxqvk0z9m",
"zs1yh2vd5usfsyv4pscjrxg9wdy3gnnyuh8vky27ln3u9jspadmpqsjmyvxmvfyyq3nv4deudvygxa",
"zs1yclvhy57hngs7d233e4x8ywfreswslz2gvn0f8epcs0wrzuqqau3hkrvf7ru6jhh0zmsyn5jkj6",
"zs1yunkgwzf0m5suz380j7xqge6rd9e6acjc5wp22z0jhalqdpspdjey7jfjvgrckgsk9ydc9yrnq3",
"zs19p94fnry6p88ms3yh60nl4kxlxmu7uxv9aafmf5pc4nyd64vslaqgmj30nxe3l5j7cxu5kqeqpm",
"zs19x2df6qmd4c9whrgj6m4mssz22x9qj9x8lmcnexnhw32pey24xy9sws5ts2q7guunm7mx9wmllj",
"zs198a984na6qt2z3uyhdkmj7sfevt794dl3mum3782kddjy4uawr2teznpuxvnzc4dvs3c6zyqxey",
"zs192ld62azpypesveqsat6m63sqaw95ejlqfcjsal5t0fea9zjzqnurmpnl6074zdms0amw83rw0x",
"zs19vsx09xmzlj9vr3s3vu8z4237gpcgrl7qs0vapzzawgnu7gxngeaxlgwqf0ppu0f7us9cfe3cqz",
"zs19wfwd8zufu27zugan77wf2g790egdw7vkulf6f375ylq0arnv2nv94l84nl8lp3tpccv763wetn",
"zs19wcqtqqjj0mnrn90ntcmyq5x8qr2wsaslqwt0fysz4xh2mmjy0z9jjh4sj86sjrgen0axx04zt4",
"zs19jypvpjpvhv5et5wq2ny09skt72hxz9adfgk2ev7nza5jyxr6gss5qelygnxn0szmjqyke2h8a7",
"zs195kll03d43her83a65y7z0zsetynlnft4pjxdspegvun0m7cwtx0vsxfm89mv50vxr90qhvcqpz",
"zs195e2g52jpyly7t9vjpfcegt87g7lpa4rm74nxn0zvmtzjhvg7f5gjnskc5ax5skvwprcshenyqs",
"zs194e84mfxc4vn4ssce7hkvgrcm3c8j7vehcetkdf78rele2lwkx9tzcfnrwhykdqa2nmwx5qcr0j",
"zs19cxqspj63ksk6uwtynj0la72zuvh8rxfh0e0pr2y5vuuvw35sm78juzh5gxcuqa8jggv703rplf",
"zs19e04k24qrca0sx5z47dxmtx0swcx2ywxqjt5594gu95rjaeyxrpa2vyylvzxpau5spt2v529me6",
"zs19707gmdvc4hfwg4lgvxg55695gltx3jwye8l2gjekrx4zqz7yr6grq8s8hpfqwggrywx509ln5y",
"zs1xrw8nwla7yrz8l3d7y3rxlhamel2ly4kdmxlc6w4cztxhd6l8wufqv2pcsvtl3d7s6awvjatyx9",
"zs1xymrgyhle6dcvjk5f62k4xygr0vrr2wckqy7sp6wc6cttn29hra77dzhwxst7z9rxqxkz08jd7g",
"zs1x9c8tetxgauxh474hlhnlscuhgzww8vnvxfwm0p8589x73t5yl2fph8q8r8qpl8sh0wfwx0vg62",
"zs1xxcpzsfpyekhvvum3erxjpt34pw3h70ma8vxwecg85tze380f4srlg8zlgxty8yqhutt234nk9q",
"zs1xx6pd3vtj78tg0zpwtc0jjkdxlfy48vegzd6cng4m9w0gtcya8ck7pqgf4l5sxf9ml5zvzru5xg",
"zs1x8qre6x5d8e3tt2m4l9q2tujw8ajun70qelp8tfynyw390rm6vhjtmpf58dmx4hccef9xe50az0",
"zs1x88vjduckqarz2j8tp2me08ya4dgd6pw7j4j98j5jynrze3xy2jjptzye7eftjxd6dn4sj03v7m",
};
std::vector<string> SietchShieldedPool2 = {
"zs1ehrs7hetemzsmfz9xwt8xetxag33j3xzj8mhdgywdnvkk4dmtvw6eqys6gm3vr679y865jz7rth",
"zs1ehyr6w0c4mwp0wlp6w5letgm3rjk32rxa9kkkur86e5x8lutr9mwzey0hsesnz0yaarmxra7w2z",
"zs1ec793pjf3anee0qq9ex5u2qygjzk9llmwfygev563l89quc3u8wxvtz9kctlmv2dtjgqwn7krcg",
"zs1eclpgnqy7qll0l5z0gy7m4ew86yjvp397yxyau9y2y43x5mqfdw2sll95l83ux6h8mppzsx3xnp",
"zs1eexedkctuzhjysl00m0j3ekknd32635yd8rejx9ykjp6zz77fyzf5388env642ja2qlg6mrwgsc",
"zs1e77uz8yaj998arp56d0fm4p827wchlf2w09hve6rgkmavhzeyhke8qsk3l7s5k6yh2jwjheqpup",
"zs1elj4qvy42jpts2cu22tcwt0kmwzafpmrjgztwf2xcqaycrlr4rpfxfpswx63e6agvhz96gps9yf",
"zs16q0fzcvf25fh70ysn38v7qkpfspakmelnljgnyrpu7rvllyew57n5cpqjqe0wmy5j57au47j6x8",
"zs16pnkw3mucdef34jjk6q28zd7ghhatdcqn598vs3g70qev234uc5uw6xxxjnzef3pt2t567qev8v",
"zs16rmnl4hd6c226u3v6eekk68y59u0x7v37n8pmytt9xw6drugjml7ryhd243nf3l2pvafw42rnxc",
"zs16ruwvwmetmnnns0rxwtx2kss23da2pccares0tehzw3v3nxd483qn49c9apdfua0hpm8xdecdt4",
"zs16ymafsjd7fp9zdl9vtyvfedecvn7q2vcs7emeglwy7hpuphve97d3j87v2evqs0xm3jrx44nwfe",
"zs1697ggm9zqp4rh0fv4r9hnh9uy6gg4hk7r2lm33tp2we4ry5azpxq6nwuzscha0g2nx03x4sstq8",
"zs168t8u6at9k6kt748dv749dxahnk8rv8yn32z8gcgvc9rkhkewscgu8r8vuzv0zecnq26w9p7x0c",
"zs16gnyx6f8vql24cepamfquhr3jjt7wgmzjcvwtct4lwy9p2studln6ut9kjzf6empwqjtxqmddqy",
"zs1622ra8snywvxufsunk97pccr7k0j32p960evl9yqjadhju22m4sk48md84q5u238gej8xnm4xm5",
"zs162stv8m0udzy4c6ff5kqva2g7pqth2rrdn7rjjgw29dcx7lj3vs4dnj8fz0gczsat3u3q5axgva",
"zs16t78376h9ledgt50k2dmwssuhyy4hn94wfgd8vzegvqy9k9kauuvpe8xz0f3va65l8ufqhgv4gv",
"zs16vxrghgv7mth6k9unzdude9cyt9vl76ms5hm9ce4py92rk69j4p9u570974nh8kqh8e2stqknj5",
"zs1654eafn589g2ujzcasa8caz8exag742tra2dd6mjkp22axh27hda6sy9exh3wkp4c6f5vztafr0",
"zs164u3ntsnn7s3zrp6c5gsqfrwr0ywhspynvunq3fhvr9crwz5eme706j5awwvuatqwh7m2qqkqm9",
"zs16cpqwm4yml5x8j5r3q5j0xljam68pf56xt40hylzn69w45venwdvd4h8drys5t380mspkvt7h8r",
"zs16c6m9aqs0q9kadm4nk6hugmqw6p0lf2h6v5d9ccwszssyecq35sm6284c3uqx2u40da4s2mr2ap",
"zs16u7rc066566j9ux73dcq0m7cq4qdmtd3gefrnhhrpjww3z00j4za7m5mcutmj6qcezkzys87mpp",
"zs1673rm5d5z9sh2k9uc2cvgwk2e44z0sekx6ezt9n4fvgnky5yxa2tc306dw7n2dg5vwfn7ppwr5s",
"zs167nvq5ahvu4s26447rem9j37qglgtle4fghsgpksumkz34g2q9x783pak5jgdhhzylmgs9wemg8",
"zs16lluayez28xevxg0rawxxcd7yx5t7qaraet256sxe8ac69lj7n7ppncsx3m2tddxlzptzyxv0qr",
"zs1mydlmczamey4ydc79n8gj5wtgs79zge4nwhcg8g640r6fvwu6wpt70970p7ptkcrzg6r6frqh0u",
"zs1my6tgqmy3kgdlqncyd5dv9s727x9hcrmj8h06e5whn4hkn5t2x46j84276yd8pw0p6ysx53u38u",
"zs1mte528eue8smvjwpe9cs8qz3wud9735rnk7vrtefu9lhyvh5pyeyenpaq5fa08jpwrl4x7sz069",
"zs1mvmu20syf3u5yzd6hpdd29xfej8237x2k0pcmf7pvra46qem5g0jralrmdcvncgf5j0y5varzr2",
"zs1mw86y6g2c8972a2ndw57648p9qcx2jppxr9g5k24df8hl3rgfzfsfe2xyesemdfmasutk88duht",
"zs1mwca7dqjq0r2mzmn4qarw8acmt4rjk26lyyar35sssqe2fky2nmv3kmf0lfxs2a9htugsadg027",
"zs1m0rpcrkfagzpex9mlw2htyrwpxe48v47pj8zg96l9wm5k8xkj3kev3xca6wumv5avkgsjtygush",
"zs1mjgyju3jnyxjhekv72y448edq3j2cvtk5s4wrej790zzpv3uc20dvewt7nhjdqryuecmykfm0je",
"zs1mjlfwyma3fv45yg50j73wcswnap2s4lsh5c9km6lcem73wky9lej7vy8wrlkr75sy6z2g0agtmw",
"zs1mkh9s9gdfxx4dkug47dqnc98g76dhm09zty779pm6gqc5aye4gvxvduqm5j56nq4lncx5ygqu90",
"zs1mm7tesf30r56l8xmnxjyxvgmnsny2zntsxahllrd930q8ycahz8npdxt7lqwu3k8ljs9sw7uzs8",
"zs1mu34v9wtyhtlr22phfxkp670wt0gj4z8czumx0m4u05elg7kjzu0dzveq5jn28xg5a2wqr6cywd",
"zs1ma3xy4fj0vm0w37a4kur3ghe72f8nstmqmmvh0u48kurtlwg50rqqlw39j6ng8lrxgam2dh0zyr",
"zs1m7yauj7694wjz92m5sxds8udp43z6kclarqwzc22wn2q6svkkk4lpzx53kwctwfn6jqcu4yww5u",
"zs1m77qqksfvuqmjmwdm22xr2u99z3uz4glenk02md4tq5z066gc7jkdayhf2txspqggv29quacpy4",
"zs1uq88d69zrnksytnquejpksdvdlp9e5y3xec3eyf0rrya8zap623zpwjs5mfzadrp7twawkpennl",
"zs1uq0zzag2cmekwn9a35vkf2q45sary5v8nt2adukhej9ydq3qpegskg5naysl3wvvxtzuyv5lu8w",
"zs1uqs3n3j8kfgurz8tj0ea5g2ny200c69rwwpq50kkup8sxntdne6h9uhx3wc2y5jjkcggvpvcl4g",
"zs1uqmnl793xh4cskxjherwlpt7xfnt6fy2sp2l3n58hpmd4msj2g3fjsks02069tqgzzvn77mpfg7",
"zs1uz73f8arfahrvgtxcjwya33ql5w8mwkmyrvxvjrjx5rla07hv3ax49hkeqg3aqynxx39z4y4vtt",
"zs1urzuwedq4qgnqjsjwjeauzyyjwxvs27mau6zmpretn37my92h3jqc0waad4r8s7zeeczq6jfas6",
"zs1urfls60sjxpnla4hhe736qu54w7047akw2p9cksx054y8e8gdyknkhwv6spwzgstf7z2wrsdapw",
"zs1u9jum0rl3959ay3qqxskkak5emv0fpceuhuhcj9rnkzfy6gpe2uv6ny29c399nrc68fx6fffg6c",
"zs1u8fdxg8lu08p6s5z9qe6jf6fkvd74a99yg3n5exlm6wm8paypygy82ue2smf0qqlhdhjzy2jxq4",
"zs1u8u44rlv4ay27248807fqwyf6lw2w76v8evn26nvwv887caqlenjgsw0nqlajzw9equn7phhs95",
"zs1u4jhx25fghqzn2az7he7lrv7xj23xd8spcl660g9kzqa3wyykm5gucuu5wwxvum6l6spq4u4e5s",
"zs1uh85d43vr4wwqnq6e7akxtlwkzx2y8cmdm3wrxzj6m42pzj3xs2heqey79hgxrhwhapwu8tt73g",
"zs1uhwgwkg2y3xex7e34dvnx97d0jdnhmchevcvg54tg4dg00ay9sjucr82py4jqx0kkf7cz5dytad",
"zs1uhkhsv3c3m5r8z7unmceg4zln6edwfr25wjauv5u8fxdqhdflj7vuc2xnkm9028y802w2pyf07g",
"zs1uhuwuzu89j05p9y48nseklu7gfhw4mrwv68f9s66csafrkpsmpsh23zzgxm24nspmsgrvtpttzg",
"zs1ucetuz8ysvz42uvuwndjfnphrtsfgekgef228meuhfrqtm97gql87rsvhxmxplw2xmj27p9jemj",
"zs1ucm95fgyy72rf6x5rwl5m5pldt38lulzqf9ueepel4gvd4cqjhk8xrf4kvl2lnn5ge9fwyfrfva",
"zs1um3pu2u0eu0zpx4czj9dufvxnud2zd0x5lygepp6maz96j572r6mh8gpmlm3w6jhmxxz2sepdfh",
"zs1ulkw8j488xuhhlewedj9dr7atm5jatmlwsxz83lquhz42ln78utqmtqsmhagcquq6uqszk23g9d",
"zs1az03j8f46n2600z47xnf5y28j34rpxljh3j6w5p3xgsmqt2fuklmhyd383aljxf4mx4pcfv0xm8",
"zs1ayal4wq4crwj70u6hae82h6r4jpk7ptycfhs9v5y83lxc7u4gadegu2r5ggsgt95n0rjk284fzj",
"zs1a984wux9sr2594lr24yal43zq6pstczyevj7yr8pn403643zuge88ekrc0cj8n2fk6z6xrxjpsz",
"zs1a95ptq9d6nauwtvgdj2lnct9y6g4cmm258jzyuqhsk4m3gqmaz62t4klqe42eu83n27jcpgz0ed",
"zs1a8xdhdzpjqx0alrjg43enszjnf6nn6nhf6c3xd77ecrvp4kfarvux4u4lcttv3rgyhmgzxukw2q",
"zs1afqnaljmvzunvjhr3m8yf2g4r0pe66kkxkm6ldjhylyjfsclk3nf88u29pskdqx76szdz48tt3m",
"zs1avx0j6mrcqrhp9903xrysptm6gefcyv6uqltta92hsgjpp2f8h8rz8suwxgjkp2f8366y6n6dj8",
"zs1a036amk3q8azryytah2zpdhyazeruq2q7zq2c06l0845kl0v2rmg0h8cdjvta4alxj0my4kcfad",
"zs1ahy2sja2ala03wrc79xx2ks3ujxxnsm44uh6yucmy5p5l0xcfa3g90cdgs4l9rhy975zvd4uzts",
"zs1aeyqta7xs8edzq2c0z6e9v3vjep55e4lg9fp9ls6d55x2mel6snxud6kqcaz8nl7zgrxxj96d6a",
"zs1aap3thj9xna07vlg3yz389c34v9mgd06g234d3htyq667286phjsf98nndm8frts7frmcyjfa90",
"zs17qdqrdgwcafkpgchc4rvk22e4u86alhnmzne5xzantpecwrxf3c6jxqk7xgzanzjj4kmxd2tuwg",
"zs17z3fmn6e84ypzpzn0p0j9nddptrj2nwhk9lhaw952j0lzxslrp24cj0ltuem9g5dustakcq4dsp",
"zs17zut2398dst3hnmnslnk0jv9w4q9yn8akelymvs8ewurdytxushp92nyqv30quqhy0yju7rn7lw",
"zs17r4fuv9ldl3kzwk5stv59exusc7jlsmtcz4t2uzjnrgrr6aj6tvnp04wc9jq2n3eh6fsyqe2ru5",
"zs17rajftxlkcywcenl0cn3fqw4lh2un5lpfegjdz06j3vl9gjmay2d5pk7uequ02vw6tmtzz6jrst",
"zs179rvu8endcr48sft7zg4w6uvxwu4ps94r06uwk7e606yffkgtx7epaamlfdqnc6xa4l9scqcv4v",
"zs178dr2z7zgqrsg5ul3sxx05qky2kemfequf08dxr332n9f5fq9cj98jttssz97lzmf2k22xpn54m",
"zs172zz77ds82urqmsa9pgyz65k04euw7uuk58k4ardcxectjc4t4yjekxm8xxmgd7gqs8k6jupypk",
"zs172eamykp6sl4vx4tsgmg2t0p482hnn3gg4my9y4frd4tl5zgsyrsvjvlxc9zjtqpve6e6djdc4x",
"zs17v4xqdu83fkvrjxrpnjksuanj0pung2kqn9ys533nnm8kq8ad8xv9kd48e4utrz947pejg55p46",
"zs17dgakqvwzgh4dgfe70cjulju698cs50zvchsze2e3zvdp68wytqdcvj4suh4vq2acdg7wuvs7ar",
"zs17snaqr6vukwp4apsdf44h6w3flgphzrnpmdjly662tgqtvkgs72lpz7m7tnkksdmt5uzjgmpg2e",
"zs173ad7l6u8dr90e2t5jkrnw0gc9u2mppv9vjeh8l6q2jdvgnq6tq4anxxltwuxm3wssfzgg6hfcy",
"zs17nez6jn8tnse243f5uf72d8y000ynmjnm6vsrpzpd2fj75wq4u4lu7xc8fmtn2e5v0r7uknphs3",
"zs174c6x8u2yagjnsq2kswnd6fh8u2f3g5dkrk7r7ja5n30zwjm4ke3x84syt9qklqyk0m7vekcx9f",
"zs174mlfm6snsmgj4usez3e6xtd5nkwwl24vgg96srpnv7ulz4de6n4lx6cmxaqszqnk7p9y6wcl8q",
"zs17h5lnrnpprdtkjwq09ax94qetryf65qm5jqv0gpyeesw4wujytks9qljvlry863flf242arvx8f",
"zs1lp07e40usxenrznuuf2nzn5v7tx9pzp9r6eaw6upnm4t9cer8l5fckzm7jr58j5l77tzjrprv8v",
"zs1ly5u5sqeeax9g3uafva7fl35r3wv0nm2aka9m940graqjh0zlw7rrcgay0a7f29j3ar4wrj4uzu",
"zs1lgqckcp2uqx5c6gdm5zklzrxz8ygva9kxtxc4u4dlzpg68m9prga5q3ur3uqutkcy4ztuhclrxw",
"zs1lgz7ychnnhe58hk2e379zhqdxynp30e6fdh6xjxx8u9ga9rmwzdrdvqcq5kps2uetyf6gzeqdn2",
"zs1l2ghymesqwrfw89pqnw08u346es6wn86r77a55n7d7xky2rc58jfhn7man9kjjesnegec3frxeh",
"zs1ls3lyaqhm39zgz3528ereaa48vzsw4cw99k536524a6ruxmdqyvqnv4pl477q7rwptrzx8dhhzu",
"zs1lsnr42d2ez0w55pxws4qn70f68vxllv92wppu24n75y7a0wrmkw6qgup0md5jhjmkwhzu742zx4",
"zs1ljzwlum9nme83hhvkjkxl323u0ezm4sgnk84nzkyu5acum0kxf0s6g06gy78w0hl66f5263g7ha",
"zs1l5kfev0dpl8swjlyvyms5t9yhhnvg0590jfgpxw7zxx6eh29vd7453q9d0ne75x7gsm42j65l3v",
"zs1lhpxmvxmfpdfa5myd35wf24pmacrgdhrcpxydrcwz3qvmfvpt9x78nf2ne3kkqh40m0nvhhd3uj",
"zs1lhkhftvpkvcuyhwgcz4gq9y9l3ly5esglk2g0sgdctrz2cd63lgss2gtn8eedsvtuh8f6shpwww",
};
//TODO: Assumes pools of 100
int randIndex = GetRandInt(100); // random int between 0 and 99
if(randIndex % 2) {
return SietchShieldedPool1[randIndex];
} else {
return SietchShieldedPool2[randIndex];
}
} }
#endif #endif

View File

@@ -134,6 +134,9 @@ void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpen
void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress) { void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress) {
if(fZdebug)
fprintf(stderr,"%s: txid=%s\n", __func__, wtx.GetHash().ToString().c_str() );
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
//Check address //Check address
@@ -401,6 +404,10 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd
//Begin Compiling the Decrypted Transaction //Begin Compiling the Decrypted Transaction
tx.push_back(Pair("txid", wtx.GetHash().ToString())); tx.push_back(Pair("txid", wtx.GetHash().ToString()));
if(fZdebug)
fprintf(stderr,"%s: txid=%s\n", __func__, wtx.GetHash().ToString().c_str() );
if (wtx.IsCoinBase()) if (wtx.IsCoinBase())
{ {
tx.push_back(Pair("coinbase", true)); tx.push_back(Pair("coinbase", true));

View File

@@ -72,8 +72,7 @@ using namespace libzcash;
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; extern std::string ASSETCHAINS_OVERRIDE_PUBKEY;
const std::string ADDR_TYPE_SAPLING = "sapling"; const std::string ADDR_TYPE_SAPLING = "sapling";
const std::string ADDR_TYPE_DONOTREMEMBER = "donotremember"; const std::string ADDR_TYPE_AMNESIA = "amnesia";
extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
extern int32_t KOMODO_INSYNC; extern int32_t KOMODO_INSYNC;
uint32_t komodo_segid32(char *coinaddr); uint32_t komodo_segid32(char *coinaddr);
int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs);
@@ -170,7 +169,6 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue)
entry.push_back(Pair(item.first, item.second)); entry.push_back(Pair(item.first, item.second));
entry.push_back(Pair("vjoinsplit", TxJoinSplitToJSON(wtx)));
} }
string AccountFromValue(const UniValue& value) string AccountFromValue(const UniValue& value)
@@ -3352,8 +3350,8 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
if (fHelp || params.size() > 5 || params.size() == 3) if (fHelp || params.size() > 5 || params.size() == 3)
throw runtime_error( throw runtime_error(
"z_listreceivedbyaddress\n" "z_listreceivedaddress\n"
"\nReturns received outputs for a single address.\n" "\nReturns received outputs.\n"
"\n" "\n"
"This function only returns information on addresses with full spending keys." "This function only returns information on addresses with full spending keys."
"\n" "\n"
@@ -3411,8 +3409,8 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
" }],\n" " }],\n"
" },\n" " },\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("z_listreceivedbyaddress", "R...") + HelpExampleCli("z_listreceivedaddress", "\"*\"")
+ HelpExampleRpc("z_listreceivedbyaddress", "R...") + HelpExampleRpc("z_listreceivedaddress", "RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn")
); );
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -3895,16 +3893,16 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
throw runtime_error( throw runtime_error(
"z_getnewaddress ( type )\n" "z_getnewaddress ( type )\n"
"\nReturns a new shielded address for receiving payments.\n" "\nReturns a new shielded address for receiving payments.\n"
"\nWith no arguments, returns a Sapling address.\n" "\nWith no arguments, returns a Sapling address (zaddr).\n"
"\nBe very careful with 'donotremember' address type, the extended spending key (xsk) of that address is not stored in wallet.dat!\n" "\nBe very careful with 'amnesia' address type, the address is not stored in wallet.dat and if you send funds to it THEY WILL BE LOST FOREVER\n"
"\nArguments:\n" "\nArguments:\n"
"1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. Either "+ ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_DONOTREMEMBER + " .\n" "1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. Either "+ ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_AMNESIA + " .\n"
"\nResult:\n" "\nResult:\n"
"\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new shielded address.\n" "\"" + strprintf("%s",komodo_chainname()) + "_address\" (string) The new shielded address.\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("z_getnewaddress", "") + HelpExampleCli("z_getnewaddress", "")
+ HelpExampleCli("z_getnewaddress", ADDR_TYPE_SAPLING) + HelpExampleCli("z_getnewaddress", ADDR_TYPE_SAPLING)
+ HelpExampleCli("z_getnewaddress", ADDR_TYPE_DONOTREMEMBER) + HelpExampleCli("z_getnewaddress", ADDR_TYPE_AMNESIA)
); );
LOCK2(cs_main, pwalletMain->cs_wallet); LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -3917,15 +3915,14 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk
} }
if (addrType == ADDR_TYPE_SAPLING) { if (addrType == ADDR_TYPE_SAPLING) {
return EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey()); return EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey());
} else if (addrType == ADDR_TYPE_DONOTREMEMBER) { } else if (addrType == ADDR_TYPE_AMNESIA) {
bool addToWallet = false; auto zaddr = randomSietchZaddr();
auto zaddr = EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey(addToWallet));
if(fZdebug) { if(fZdebug) {
fprintf(stderr,"%s: Sietch zaddr=%s created, xsk not stored in wallet.dat!\n", __FUNCTION__, zaddr.c_str() ); fprintf(stderr,"%s: Sietch zaddr=%s created, not stored in wallet.dat!\n", __FUNCTION__, zaddr.c_str() );
} }
return zaddr; return zaddr;
} else { } else {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type! Try " + ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_DONOTREMEMBER); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type! Try " + ADDR_TYPE_SAPLING + " or " + ADDR_TYPE_AMNESIA);
} }
} }
@@ -4086,7 +4083,8 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK
" \"txid\": xxxxx, (string) the transaction id\n" " \"txid\": xxxxx, (string) the transaction id\n"
" \"amount\": xxxxx, (numeric) the amount of value in the note\n" " \"amount\": xxxxx, (numeric) the amount of value in the note\n"
" \"memo\": xxxxx, (string) hexadecimal string representation of memo field\n" " \"memo\": xxxxx, (string) hexadecimal string representation of memo field\n"
" \"confirmations\" : n, (numeric) the number of confirmations\n" " \"confirmations\" : n, (numeric) the number of notarized confirmations (dpowconfs)\n"
" \"rawconfirmations\" : n, (numeric) the number of raw confirmations\n"
" \"outindex\" (sapling) : n, (numeric) the output index\n" " \"outindex\" (sapling) : n, (numeric) the output index\n"
" \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n" " \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n"
"}\n" "}\n"
@@ -4131,7 +4129,6 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK
if (boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr) { if (boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr) {
for (SaplingNoteEntry & entry : saplingEntries) { for (SaplingNoteEntry & entry : saplingEntries) {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
int nHeight = tx_height(entry.op.hash); int nHeight = tx_height(entry.op.hash);
int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations); int dpowconfs = komodo_dpowconfs(nHeight, entry.confirmations);
// Only return notarized results when minconf>1 // Only return notarized results when minconf>1
@@ -4152,6 +4149,10 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK
} }
obj.push_back(Pair("outindex", (int)entry.op.n)); obj.push_back(Pair("outindex", (int)entry.op.n));
obj.push_back(Pair("rawconfirmations", entry.confirmations)); obj.push_back(Pair("rawconfirmations", entry.confirmations));
auto wtx = pwalletMain->mapWallet.at(entry.op.hash); //.ToString());
//fprintf(stderr,"%s: txid=%s not found in wallet!\n", __func__, entry.op.hash.ToString().c_str());
obj.push_back(Pair("time", wtx.GetTxTime()));
obj.push_back(Pair("confirmations", dpowconfs)); obj.push_back(Pair("confirmations", dpowconfs));
if (hasSpendingKey) { if (hasSpendingKey) {
obj.push_back(Pair("change", pwalletMain->IsNoteSaplingChange(nullifierSet, entry.address, entry.op))); obj.push_back(Pair("change", pwalletMain->IsNoteSaplingChange(nullifierSet, entry.address, entry.op)));
@@ -4740,24 +4741,22 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
// End goal is to have this be as large as possible without slowing xtns down too much // End goal is to have this be as large as possible without slowing xtns down too much
// A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations // A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations
unsigned int DEFAULT_MIN_ZOUTS=7; unsigned int DEFAULT_MIN_ZOUTS=7;
unsigned int MAX_ZOUTS=25; unsigned int MAX_ZOUTS=50;
unsigned int MIN_ZOUTS=GetArg("--sietch-min-zouts", DEFAULT_MIN_ZOUTS); unsigned int MIN_ZOUTS=GetArg("--sietch-min-zouts", DEFAULT_MIN_ZOUTS);
if((MIN_ZOUTS<3) || (MIN_ZOUTS>MAX_ZOUTS)) { if((MIN_ZOUTS<3) || (MIN_ZOUTS>MAX_ZOUTS)) {
fprintf(stderr,"%s: Sietch min zouts must be >=3 and <= 25, setting to default value of %d\n", __FUNCTION__, DEFAULT_MIN_ZOUTS ); fprintf(stderr,"%s: Sietch min zouts must be >= 3 and <= %d, setting to default value of %d\n", __FUNCTION__, MAX_ZOUTS, DEFAULT_MIN_ZOUTS );
MIN_ZOUTS=DEFAULT_MIN_ZOUTS; MIN_ZOUTS=DEFAULT_MIN_ZOUTS;
} }
int nAmount = 0; int nAmount = 0;
// Dynamic Sietch zaddrs default to OFF
bool fSietchDynamic = GetArg("--sietch-dynamic",0);
while (zaddrRecipients.size() < MIN_ZOUTS) { while (zaddrRecipients.size() < MIN_ZOUTS) {
// OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically // OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically
int decider = 1 + GetRandInt(100); // random int between 1 and 100 int decider = 1 + GetRandInt(100); // random int between 1 and 100
string zdust1, zdust2; string zdust1, zdust2;
// Which zaddr we send to is non-deterministically chosen from two zpools... // Which zaddr we send to is randomly generated
zdust1 = fSietchDynamic ? newSietchZaddr() : randomSietchZaddr(); zdust1 = randomSietchZaddr();
// And their ordering when given to internals is also non-deterministic, which // And their ordering when given to internals is also non-deterministic, which
// helps breaks assumptions blockchain analysts may use from z_sendmany internals // helps breaks assumptions blockchain analysts may use from z_sendmany internals
@@ -4771,7 +4770,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
//50% chance of adding another zout //50% chance of adding another zout
if (decider % 2) { if (decider % 2) {
zdust2 = fSietchDynamic ? newSietchZaddr() : randomSietchZaddr(); zdust2 = randomSietchZaddr();
// 50% chance of adding it to the front or back since all odd numbers are 1 or 3 mod 4 // 50% chance of adding it to the front or back since all odd numbers are 1 or 3 mod 4
if(decider % 4 == 3) { if(decider % 4 == 3) {
zaddrRecipients.push_back( newSietchRecipient(zdust2) ); zaddrRecipients.push_back( newSietchRecipient(zdust2) );

View File

@@ -3950,6 +3950,8 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
// Track how many getdata requests our transaction gets // Track how many getdata requests our transaction gets
mapRequestCount[wtxNew.GetHash()] = 0; mapRequestCount[wtxNew.GetHash()] = 0;
std::string strCmd = GetArg("-txsend", "");
if (fBroadcastTransactions) if (fBroadcastTransactions)
{ {
// Broadcast // Broadcast
@@ -3962,6 +3964,12 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
} }
wtxNew.RelayWalletTransaction(); wtxNew.RelayWalletTransaction();
} }
// If we are configured to send transactions via an
// external service instead of broadcasting, do that
else if (!strCmd.empty()) {
boost::replace_all(strCmd, "%s", EncodeHexTx(wtxNew));
boost::thread t(runCommand, strCmd); // thread runs free
}
} }
return true; return true;
} }