From 57986fd46f742b6bc3c15281b803b9bc8ddc40e9 Mon Sep 17 00:00:00 2001 From: xtruan Date: Tue, 7 Mar 2023 11:28:27 -0800 Subject: [PATCH] running flipper fmt --- crypto/Makefile | 8 +- crypto/README.md | 2 +- crypto/address.c | 102 +- crypto/address.h | 7 +- crypto/aes/aes.h | 174 +- crypto/aes/aes_modes.c | 779 +++--- crypto/aes/aescrypt.c | 270 +- crypto/aes/aeskey.c | 720 ++--- crypto/aes/aesopt.h | 609 ++--- crypto/aes/aestab.c | 435 ++- crypto/aes/aestab.h | 106 +- crypto/aes/aestst.c | 107 +- crypto/aes/aestst.h | 92 +- crypto/base32.c | 330 +-- crypto/base32.h | 14 +- crypto/base58.c | 320 ++- crypto/base58.h | 18 +- crypto/bignum.c | 1486 ++++++----- crypto/bignum.h | 214 +- crypto/bip32.c | 1259 ++++----- crypto/bip32.h | 227 +- crypto/bip39.c | 389 +-- crypto/bip39.h | 29 +- crypto/bip39_english.c | 598 ++--- crypto/blake256.c | 388 ++- crypto/blake256.h | 18 +- crypto/blake2_common.h | 40 +- crypto/blake2b.c | 495 ++-- crypto/blake2b.h | 50 +- crypto/blake2s.c | 478 ++-- crypto/blake2s.h | 48 +- crypto/byte_order.h | 28 +- crypto/cardano.c | 419 +-- crypto/cardano.h | 26 +- crypto/cash_addr.c | 259 +- crypto/cash_addr.h | 11 +- crypto/chacha20poly1305/chacha20poly1305.c | 19 +- crypto/chacha20poly1305/chacha20poly1305.h | 19 +- crypto/chacha20poly1305/chacha_merged.c | 449 ++-- crypto/chacha20poly1305/ecrypt-portable.h | 275 -- .../{ecrypt-config.h => ecrypt_config.h} | 84 +- .../{ecrypt-machine.h => ecrypt_machine.h} | 12 +- crypto/chacha20poly1305/ecrypt_portable.h | 246 ++ .../{ecrypt-sync.h => ecrypt_sync.h} | 124 +- .../{ecrypt-types.h => ecrypt_types.h} | 8 +- crypto/chacha20poly1305/poly1305-donna-32.h | 219 -- crypto/chacha20poly1305/poly1305-donna.c | 179 -- crypto/chacha20poly1305/poly1305-donna.h | 20 - crypto/chacha20poly1305/poly1305_donna.c | 208 ++ crypto/chacha20poly1305/poly1305_donna.h | 23 + crypto/chacha20poly1305/poly1305_donna_32.h | 252 ++ crypto/chacha20poly1305/rfc7539.c | 14 +- crypto/chacha20poly1305/rfc7539.h | 6 +- crypto/chacha_drbg.c | 147 +- crypto/chacha_drbg.h | 29 +- crypto/check_mem.h | 42 +- crypto/ecdsa.c | 1969 +++++++------- crypto/ecdsa.h | 177 +- crypto/ed25519-donna/curve25519-donna-32bit.c | 681 ----- .../ed25519-donna/curve25519-donna-helpers.c | 66 - .../curve25519-donna-scalarmult-base.c | 67 - .../ed25519-donna-32bit-tables.c | 63 - .../ed25519-donna-basepoint-table.c | 261 -- .../ed25519-donna/ed25519-donna-impl-base.c | 730 ----- .../ed25519-donna/ed25519-donna-impl-base.h | 104 - crypto/ed25519-donna/ed25519-donna-portable.h | 24 - crypto/ed25519-donna/ed25519-keccak.h | 27 - crypto/ed25519-donna/ed25519-sha3.h | 21 - crypto/ed25519-donna/ed25519.c | 318 --- crypto/ed25519-donna/ed25519.h | 45 - crypto/ed25519-donna/modm-donna-32bit.c | 517 ---- .../README.md | 16 +- crypto/ed25519_donna/curve25519_donna_32bit.c | 953 +++++++ .../curve25519_donna_32bit.h} | 0 .../ed25519_donna/curve25519_donna_helpers.c | 66 + .../curve25519_donna_helpers.h} | 0 .../curve25519_donna_scalarmult_base.c | 70 + .../curve25519_donna_scalarmult_base.h} | 5 +- crypto/ed25519_donna/ed25519.c | 336 +++ crypto/ed25519_donna/ed25519.h | 78 + .../ed25519_donna.h} | 22 +- .../ed25519_donna_32bit_tables.c | 1049 ++++++++ .../ed25519_donna_32bit_tables.h} | 0 .../ed25519_donna_basepoint_table.c | 1796 +++++++++++++ .../ed25519_donna_basepoint_table.h} | 0 .../ed25519_donna/ed25519_donna_impl_base.c | 829 ++++++ .../ed25519_donna/ed25519_donna_impl_base.h | 127 + crypto/ed25519_donna/ed25519_donna_portable.h | 22 + .../ed25519_hash_custom.h} | 0 .../ed25519_hash_custom_keccak.h} | 0 .../ed25519_hash_custom_sha3.h} | 0 .../ed25519_keccak.c} | 4 +- crypto/ed25519_donna/ed25519_keccak.h | 38 + .../ed25519_sha3.c} | 4 +- crypto/ed25519_donna/ed25519_sha3.h | 32 + crypto/ed25519_donna/modm_donna_32bit.c | 800 ++++++ .../modm_donna_32bit.h} | 17 +- crypto/groestl.c | 1418 +++++----- crypto/groestl.h | 22 +- crypto/groestl_internal.h | 382 ++- crypto/hasher.c | 155 +- crypto/hasher.h | 62 +- crypto/hmac.c | 254 +- crypto/hmac.h | 54 +- crypto/hmac_drbg.c | 171 +- crypto/hmac_drbg.h | 24 +- crypto/memzero.c | 31 +- crypto/monero/base58.c | 392 +-- crypto/monero/base58.h | 22 +- crypto/monero/{int-util.h => int_util.h} | 63 +- crypto/monero/monero.h | 4 +- crypto/monero/serialize.c | 74 +- crypto/monero/serialize.h | 8 +- crypto/monero/xmr.c | 240 +- crypto/monero/xmr.h | 77 +- crypto/nem.c | 850 +++--- crypto/nem.h | 204 +- crypto/nist256p1.c | 75 +- crypto/pbkdf2.c | 242 +- crypto/pbkdf2.h | 72 +- crypto/rand.c | 32 +- crypto/rand.h | 4 +- crypto/rc4.c | 46 +- crypto/rc4.h | 8 +- crypto/rfc6979.c | 49 +- crypto/rfc6979.h | 11 +- crypto/ripemd160.c | 391 ++- crypto/ripemd160.h | 16 +- crypto/script.c | 66 +- crypto/script.h | 3 +- crypto/secp256k1.c | 63 +- crypto/segwit_addr.c | 148 +- crypto/segwit_addr.h | 33 +- crypto/sha2.c | 1909 +++++++------ crypto/sha2.h | 42 +- crypto/sha3.c | 543 ++-- crypto/sha3.h | 57 +- crypto/shamir.c | 449 ++-- crypto/shamir.h | 11 +- crypto/slip39.c | 157 +- crypto/slip39_wordlist.h | 2351 ++++++++--------- flipbip.c | 42 +- flipbip.h | 2 +- helpers/flipbip_file.c | 47 +- helpers/flipbip_file.h | 2 +- helpers/flipbip_haptic.c | 9 +- helpers/flipbip_haptic.h | 1 - helpers/flipbip_led.c | 12 +- helpers/flipbip_led.h | 1 - helpers/flipbip_speaker.c | 2 +- helpers/flipbip_string.c | 117 +- helpers/flipbip_string.h | 15 +- scenes/flipbip_scene_menu.c | 35 +- scenes/flipbip_scene_scene_1.c | 38 +- scenes/flipbip_scene_settings.c | 21 +- scenes/flipbip_scene_startscreen.c | 49 +- views/flipbip_scene_1.c | 345 ++- views/flipbip_startscreen.c | 87 +- 158 files changed, 20053 insertions(+), 16321 deletions(-) delete mode 100644 crypto/chacha20poly1305/ecrypt-portable.h rename crypto/chacha20poly1305/{ecrypt-config.h => ecrypt_config.h} (70%) rename crypto/chacha20poly1305/{ecrypt-machine.h => ecrypt_machine.h} (72%) create mode 100644 crypto/chacha20poly1305/ecrypt_portable.h rename crypto/chacha20poly1305/{ecrypt-sync.h => ecrypt_sync.h} (72%) rename crypto/chacha20poly1305/{ecrypt-types.h => ecrypt_types.h} (88%) delete mode 100644 crypto/chacha20poly1305/poly1305-donna-32.h delete mode 100644 crypto/chacha20poly1305/poly1305-donna.c delete mode 100644 crypto/chacha20poly1305/poly1305-donna.h create mode 100644 crypto/chacha20poly1305/poly1305_donna.c create mode 100644 crypto/chacha20poly1305/poly1305_donna.h create mode 100644 crypto/chacha20poly1305/poly1305_donna_32.h delete mode 100644 crypto/ed25519-donna/curve25519-donna-32bit.c delete mode 100644 crypto/ed25519-donna/curve25519-donna-helpers.c delete mode 100644 crypto/ed25519-donna/curve25519-donna-scalarmult-base.c delete mode 100644 crypto/ed25519-donna/ed25519-donna-32bit-tables.c delete mode 100644 crypto/ed25519-donna/ed25519-donna-basepoint-table.c delete mode 100644 crypto/ed25519-donna/ed25519-donna-impl-base.c delete mode 100644 crypto/ed25519-donna/ed25519-donna-impl-base.h delete mode 100644 crypto/ed25519-donna/ed25519-donna-portable.h delete mode 100644 crypto/ed25519-donna/ed25519-keccak.h delete mode 100644 crypto/ed25519-donna/ed25519-sha3.h delete mode 100644 crypto/ed25519-donna/ed25519.c delete mode 100644 crypto/ed25519-donna/ed25519.h delete mode 100644 crypto/ed25519-donna/modm-donna-32bit.c rename crypto/{ed25519-donna => ed25519_donna}/README.md (93%) create mode 100644 crypto/ed25519_donna/curve25519_donna_32bit.c rename crypto/{ed25519-donna/curve25519-donna-32bit.h => ed25519_donna/curve25519_donna_32bit.h} (100%) create mode 100644 crypto/ed25519_donna/curve25519_donna_helpers.c rename crypto/{ed25519-donna/curve25519-donna-helpers.h => ed25519_donna/curve25519_donna_helpers.h} (100%) create mode 100644 crypto/ed25519_donna/curve25519_donna_scalarmult_base.c rename crypto/{ed25519-donna/curve25519-donna-scalarmult-base.h => ed25519_donna/curve25519_donna_scalarmult_base.h} (66%) create mode 100644 crypto/ed25519_donna/ed25519.c create mode 100644 crypto/ed25519_donna/ed25519.h rename crypto/{ed25519-donna/ed25519-donna.h => ed25519_donna/ed25519_donna.h} (68%) create mode 100644 crypto/ed25519_donna/ed25519_donna_32bit_tables.c rename crypto/{ed25519-donna/ed25519-donna-32bit-tables.h => ed25519_donna/ed25519_donna_32bit_tables.h} (100%) create mode 100644 crypto/ed25519_donna/ed25519_donna_basepoint_table.c rename crypto/{ed25519-donna/ed25519-donna-basepoint-table.h => ed25519_donna/ed25519_donna_basepoint_table.h} (100%) create mode 100644 crypto/ed25519_donna/ed25519_donna_impl_base.c create mode 100644 crypto/ed25519_donna/ed25519_donna_impl_base.h create mode 100644 crypto/ed25519_donna/ed25519_donna_portable.h rename crypto/{ed25519-donna/ed25519-hash-custom.h => ed25519_donna/ed25519_hash_custom.h} (100%) rename crypto/{ed25519-donna/ed25519-hash-custom-keccak.h => ed25519_donna/ed25519_hash_custom_keccak.h} (100%) rename crypto/{ed25519-donna/ed25519-hash-custom-sha3.h => ed25519_donna/ed25519_hash_custom_sha3.h} (100%) rename crypto/{ed25519-donna/ed25519-keccak.c => ed25519_donna/ed25519_keccak.c} (66%) create mode 100644 crypto/ed25519_donna/ed25519_keccak.h rename crypto/{ed25519-donna/ed25519-sha3.c => ed25519_donna/ed25519_sha3.c} (53%) create mode 100644 crypto/ed25519_donna/ed25519_sha3.h create mode 100644 crypto/ed25519_donna/modm_donna_32bit.c rename crypto/{ed25519-donna/modm-donna-32bit.h => ed25519_donna/modm_donna_32bit.h} (86%) rename crypto/monero/{int-util.h => int_util.h} (56%) diff --git a/crypto/Makefile b/crypto/Makefile index b6dbeeedb09..aa1bf6e0038 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -97,9 +97,9 @@ 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 += 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 += monero/base58.c SRCS += monero/serialize.c SRCS += monero/xmr.c @@ -177,7 +177,7 @@ secp256k1-zkp.o: $(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -fPIC -I$(ZKP_PATH) -I$(ZKP_PATH)/src -c $(ZKP_PATH)/src/secp256k1.c -o secp256k1-zkp.o clean: - rm -f *.o aes/*.o chacha20poly1305/*.o ed25519-donna/*.o monero/*.o + rm -f *.o aes/*.o chacha20poly1305/*.o ed25519_donna/*.o monero/*.o rm -f tests/*.o tests/test_check tests/test_speed tests/test_openssl tests/libtrezor-crypto.so tests/aestst rm -f tools/*.o tools/xpubaddrgen tools/mktable tools/bip39bruteforce rm -f fuzzer/*.o fuzzer/fuzzer diff --git a/crypto/README.md b/crypto/README.md index 34b7b940217..d13cbc64d69 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -40,6 +40,6 @@ Distibuted under MIT License. - SHA1/SHA2: http://www.aarongifford.com/computers/sha.html - SHA3: https://github.com/rhash/RHash - Curve25519: https://github.com/agl/curve25519-donna -- Ed25519: https://github.com/floodyberry/ed25519-donna +- Ed25519: https://github.com/floodyberry/ed25519_donna - Chacha20: https://github.com/wg/c20p1305 - Poly1305: https://github.com/floodyberry/poly1305-donna diff --git a/crypto/address.c b/crypto/address.c index 598a49f7134..2e791d05f3e 100644 --- a/crypto/address.c +++ b/crypto/address.c @@ -25,70 +25,66 @@ #include "bignum.h" size_t address_prefix_bytes_len(uint32_t address_type) { - if (address_type <= 0xFF) return 1; - if (address_type <= 0xFFFF) return 2; - if (address_type <= 0xFFFFFF) return 3; - return 4; + if(address_type <= 0xFF) return 1; + if(address_type <= 0xFFFF) return 2; + if(address_type <= 0xFFFFFF) return 3; + return 4; } -void address_write_prefix_bytes(uint32_t address_type, uint8_t *out) { - if (address_type > 0xFFFFFF) *(out++) = address_type >> 24; - if (address_type > 0xFFFF) *(out++) = (address_type >> 16) & 0xFF; - if (address_type > 0xFF) *(out++) = (address_type >> 8) & 0xFF; - *(out++) = address_type & 0xFF; +void address_write_prefix_bytes(uint32_t address_type, uint8_t* out) { + if(address_type > 0xFFFFFF) *(out++) = address_type >> 24; + if(address_type > 0xFFFF) *(out++) = (address_type >> 16) & 0xFF; + if(address_type > 0xFF) *(out++) = (address_type >> 8) & 0xFF; + *(out++) = address_type & 0xFF; } -bool address_check_prefix(const uint8_t *addr, uint32_t address_type) { - if (address_type <= 0xFF) { - return address_type == (uint32_t)(addr[0]); - } - if (address_type <= 0xFFFF) { - return address_type == (((uint32_t)addr[0] << 8) | ((uint32_t)addr[1])); - } - if (address_type <= 0xFFFFFF) { - return address_type == (((uint32_t)addr[0] << 16) | - ((uint32_t)addr[1] << 8) | ((uint32_t)addr[2])); - } - return address_type == - (((uint32_t)addr[0] << 24) | ((uint32_t)addr[1] << 16) | - ((uint32_t)addr[2] << 8) | ((uint32_t)addr[3])); +bool address_check_prefix(const uint8_t* addr, uint32_t address_type) { + if(address_type <= 0xFF) { + return address_type == (uint32_t)(addr[0]); + } + if(address_type <= 0xFFFF) { + return address_type == (((uint32_t)addr[0] << 8) | ((uint32_t)addr[1])); + } + if(address_type <= 0xFFFFFF) { + return address_type == + (((uint32_t)addr[0] << 16) | ((uint32_t)addr[1] << 8) | ((uint32_t)addr[2])); + } + return address_type == (((uint32_t)addr[0] << 24) | ((uint32_t)addr[1] << 16) | + ((uint32_t)addr[2] << 8) | ((uint32_t)addr[3])); } #if USE_ETHEREUM #include "sha3.h" -void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, - uint64_t chain_id) { - const char *hex = "0123456789abcdef"; - address[0] = '0'; - address[1] = 'x'; - for (int i = 0; i < 20; i++) { - address[2 + i * 2] = hex[(addr[i] >> 4) & 0xF]; - address[2 + i * 2 + 1] = hex[addr[i] & 0xF]; - } - address[42] = 0; - - SHA3_CTX ctx = {0}; - uint8_t hash[32] = {0}; - keccak_256_Init(&ctx); - if (rskip60) { - char prefix[16] = {0}; - int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false, 0, - prefix, sizeof(prefix)); - keccak_Update(&ctx, (const uint8_t *)prefix, prefix_size); - } - keccak_Update(&ctx, (const uint8_t *)(address + 2), 40); - keccak_Final(&ctx, hash); +void ethereum_address_checksum(const uint8_t* addr, char* address, bool rskip60, uint64_t chain_id) { + const char* hex = "0123456789abcdef"; + address[0] = '0'; + address[1] = 'x'; + for(int i = 0; i < 20; i++) { + address[2 + i * 2] = hex[(addr[i] >> 4) & 0xF]; + address[2 + i * 2 + 1] = hex[addr[i] & 0xF]; + } + address[42] = 0; - for (int i = 0; i < 20; i++) { - if ((hash[i] & 0x80) && address[2 + i * 2] >= 'a' && - address[2 + i * 2] <= 'f') { - address[2 + i * 2] -= 0x20; + SHA3_CTX ctx = {0}; + uint8_t hash[32] = {0}; + keccak_256_Init(&ctx); + if(rskip60) { + char prefix[16] = {0}; + int prefix_size = + bn_format_uint64(chain_id, NULL, "0x", 0, 0, false, 0, prefix, sizeof(prefix)); + keccak_Update(&ctx, (const uint8_t*)prefix, prefix_size); } - if ((hash[i] & 0x08) && address[2 + i * 2 + 1] >= 'a' && - address[2 + i * 2 + 1] <= 'f') { - address[2 + i * 2 + 1] -= 0x20; + keccak_Update(&ctx, (const uint8_t*)(address + 2), 40); + keccak_Final(&ctx, hash); + + for(int i = 0; i < 20; i++) { + if((hash[i] & 0x80) && address[2 + i * 2] >= 'a' && address[2 + i * 2] <= 'f') { + address[2 + i * 2] -= 0x20; + } + if((hash[i] & 0x08) && address[2 + i * 2 + 1] >= 'a' && address[2 + i * 2 + 1] <= 'f') { + address[2 + i * 2 + 1] -= 0x20; + } } - } } #endif diff --git a/crypto/address.h b/crypto/address.h index e799484ee9a..e2767d6b0be 100644 --- a/crypto/address.h +++ b/crypto/address.h @@ -30,11 +30,10 @@ #include "options.h" size_t address_prefix_bytes_len(uint32_t address_type); -void address_write_prefix_bytes(uint32_t address_type, uint8_t *out); -bool address_check_prefix(const uint8_t *addr, uint32_t address_type); +void address_write_prefix_bytes(uint32_t address_type, uint8_t* out); +bool address_check_prefix(const uint8_t* addr, uint32_t address_type); #if USE_ETHEREUM -void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, - uint64_t chain_id); +void ethereum_address_checksum(const uint8_t* addr, char* address, bool rskip60, uint64_t chain_id); #endif #endif diff --git a/crypto/aes/aes.h b/crypto/aes/aes.h index 878943b575a..b277c390d24 100644 --- a/crypto/aes/aes.h +++ b/crypto/aes/aes.h @@ -27,27 +27,26 @@ Issue Date: 02/08/2018 #include #include -#define VOID_RETURN void -#define INT_RETURN int -#define ALIGN_OFFSET(x,n) (((intptr_t)(x)) & ((n) - 1)) -#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((intptr_t)(x)) & ((n) - 1))) -#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((intptr_t)(x)) & ((n) - 1))) +#define VOID_RETURN void +#define INT_RETURN int +#define ALIGN_OFFSET(x, n) (((intptr_t)(x)) & ((n)-1)) +#define ALIGN_FLOOR(x, n) ((uint8_t*)(x) - (((intptr_t)(x)) & ((n)-1))) +#define ALIGN_CEIL(x, n) ((uint8_t*)(x) + (-((intptr_t)(x)) & ((n)-1))) #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif // #define AES_128 /* if a fast 128 bit key scheduler is needed */ // #define AES_192 /* if a fast 192 bit key scheduler is needed */ -#define AES_256 /* if a fast 256 bit key scheduler is needed */ +#define AES_256 /* if a fast 256 bit key scheduler is needed */ // #define AES_VAR /* if variable key size scheduler is needed */ #if 1 -# define AES_MODES /* if support is needed for modes in the C code */ -#endif /* (these will use AES_NI if it is present) */ -#if 0 /* add this to make direct calls to the AES_NI */ -# /* implemented CBC and CTR modes available */ -# define ADD_AESNI_MODE_CALLS +#define AES_MODES /* if support is needed for modes in the C code */ +#endif /* (these will use AES_NI if it is present) */ +#if 0 /* add this to make direct calls to the AES_NI */ +#/* implemented CBC and CTR modes available */ +#define ADD_AESNI_MODE_CALLS #endif /* The following must also be set in assembler files if being used */ @@ -55,20 +54,20 @@ extern "C" #define AES_ENCRYPT /* if support for encryption is needed */ #define AES_DECRYPT /* if support for decryption is needed */ -#define AES_BLOCK_SIZE_P2 4 /* AES block size as a power of 2 */ -#define AES_BLOCK_SIZE (1 << AES_BLOCK_SIZE_P2) /* AES block size */ -#define N_COLS 4 /* the number of columns in the state */ +#define AES_BLOCK_SIZE_P2 4 /* AES block size as a power of 2 */ +#define AES_BLOCK_SIZE (1 << AES_BLOCK_SIZE_P2) /* AES block size */ +#define N_COLS 4 /* the number of columns in the state */ /* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ /* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ /* or 44, 52 or 60 32-bit words. */ -#if defined( AES_VAR ) || defined( AES_256 ) -#define KS_LENGTH 60 -#elif defined( AES_192 ) -#define KS_LENGTH 52 +#if defined(AES_VAR) || defined(AES_256) +#define KS_LENGTH 60 +#elif defined(AES_192) +#define KS_LENGTH 52 #else -#define KS_LENGTH 44 +#define KS_LENGTH 44 #endif #define AES_RETURN INT_RETURN @@ -78,35 +77,35 @@ extern "C" /* to hold the number of rounds multiplied by 16. The other three */ /* elements can be used by code that implements additional modes */ -typedef union -{ uint32_t l; +typedef union { + uint32_t l; uint8_t b[4]; } aes_inf; #ifdef _MSC_VER -# pragma warning( disable : 4324 ) +#pragma warning(disable : 4324) #endif #if defined(_MSC_VER) && defined(_WIN64) #define ALIGNED_(x) __declspec(align(x)) #elif defined(__GNUC__) && defined(__x86_64__) -#define ALIGNED_(x) __attribute__ ((aligned(x))) +#define ALIGNED_(x) __attribute__((aligned(x))) #else #define ALIGNED_(x) #endif -typedef struct ALIGNED_(16) -{ uint32_t ks[KS_LENGTH]; +typedef struct ALIGNED_(16) { + uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_encrypt_ctx; -typedef struct ALIGNED_(16) -{ uint32_t ks[KS_LENGTH]; +typedef struct ALIGNED_(16) { + uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_decrypt_ctx; #ifdef _MSC_VER -# pragma warning( default : 4324 ) +#pragma warning(default : 4324) #endif /* This routine must be called before first use if non-static */ @@ -117,51 +116,51 @@ AES_RETURN aes_init(void); /* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ /* those in the range 128 <= key_len <= 256 are given in bits */ -#if defined( AES_ENCRYPT ) +#if defined(AES_ENCRYPT) -#if defined( AES_128 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); +#if defined(AES_128) || defined(AES_VAR) +AES_RETURN aes_encrypt_key128(const unsigned char* key, aes_encrypt_ctx cx[1]); #endif -#if defined( AES_192 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); +#if defined(AES_192) || defined(AES_VAR) +AES_RETURN aes_encrypt_key192(const unsigned char* key, aes_encrypt_ctx cx[1]); #endif -#if defined( AES_256 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); +#if defined(AES_256) || defined(AES_VAR) +AES_RETURN aes_encrypt_key256(const unsigned char* key, aes_encrypt_ctx cx[1]); #endif -#if defined( AES_VAR ) -AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); +#if defined(AES_VAR) +AES_RETURN aes_encrypt_key(const unsigned char* key, int key_len, aes_encrypt_ctx cx[1]); #endif -AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); +AES_RETURN aes_encrypt(const unsigned char* in, unsigned char* out, const aes_encrypt_ctx cx[1]); #endif -#if defined( AES_DECRYPT ) +#if defined(AES_DECRYPT) -#if defined( AES_128 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); +#if defined(AES_128) || defined(AES_VAR) +AES_RETURN aes_decrypt_key128(const unsigned char* key, aes_decrypt_ctx cx[1]); #endif -#if defined( AES_192 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); +#if defined(AES_192) || defined(AES_VAR) +AES_RETURN aes_decrypt_key192(const unsigned char* key, aes_decrypt_ctx cx[1]); #endif -#if defined( AES_256 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); +#if defined(AES_256) || defined(AES_VAR) +AES_RETURN aes_decrypt_key256(const unsigned char* key, aes_decrypt_ctx cx[1]); #endif -#if defined( AES_VAR ) -AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); +#if defined(AES_VAR) +AES_RETURN aes_decrypt_key(const unsigned char* key, int key_len, aes_decrypt_ctx cx[1]); #endif -AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); +AES_RETURN aes_decrypt(const unsigned char* in, unsigned char* out, const aes_decrypt_ctx cx[1]); #endif -#if defined( AES_MODES ) +#if defined(AES_MODES) /* Multiple calls to the following subroutines for multiple block */ /* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ @@ -181,41 +180,72 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de AES_RETURN aes_test_alignment_detection(unsigned int n); -AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_encrypt_ctx cx[1]); - -AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_decrypt_ctx cx[1]); - -AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); - -AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); +AES_RETURN aes_ecb_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_ecb_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + const aes_decrypt_ctx cx[1]); + +AES_RETURN aes_cbc_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cbc_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + const aes_decrypt_ctx cx[1]); AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); -AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); +AES_RETURN aes_cfb_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx cx[1]); -AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); +AES_RETURN aes_cfb_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx cx[1]); #define aes_ofb_encrypt aes_ofb_crypt #define aes_ofb_decrypt aes_ofb_crypt -AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); +AES_RETURN aes_ofb_crypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx cx[1]); -typedef void cbuf_inc(unsigned char *cbuf); +typedef void cbuf_inc(unsigned char* cbuf); #define aes_ctr_encrypt aes_ctr_crypt #define aes_ctr_decrypt aes_ctr_crypt -AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); +AES_RETURN aes_ctr_crypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* cbuf, + cbuf_inc ctr_inc, + aes_encrypt_ctx cx[1]); -void aes_ctr_cbuf_inc(unsigned char *cbuf); +void aes_ctr_cbuf_inc(unsigned char* cbuf); #endif diff --git a/crypto/aes/aes_modes.c b/crypto/aes/aes_modes.c index 3ee98d1c36f..7e6b7eb34ad 100644 --- a/crypto/aes/aes_modes.c +++ b/crypto/aes/aes_modes.c @@ -31,17 +31,16 @@ Issue Date: 20/12/2007 #include "aesopt.h" -#if defined( AES_MODES ) +#if defined(AES_MODES) #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif -#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#if defined(_MSC_VER) && (_MSC_VER > 800) #pragma intrinsic(memcpy) #endif -#define BFR_BLOCKS 8 +#define BFR_BLOCKS 8 /* These values are used to detect long word alignment in order to */ /* speed up some buffer operations. This facility may not work on */ @@ -49,19 +48,19 @@ extern "C" #define FAST_BUFFER_OPERATIONS -#define lp32(x) ((uint32_t*)(x)) +#define lp32(x) ((uint32_t*)(x)) -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) #include "aes_via_ace.h" #pragma pack(16) -aligned_array(unsigned long, enc_gen_table, 12, 16) = NEH_ENC_GEN_DATA; -aligned_array(unsigned long, enc_load_table, 12, 16) = NEH_ENC_LOAD_DATA; +aligned_array(unsigned long, enc_gen_table, 12, 16) = NEH_ENC_GEN_DATA; +aligned_array(unsigned long, enc_load_table, 12, 16) = NEH_ENC_LOAD_DATA; aligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA; -aligned_array(unsigned long, dec_gen_table, 12, 16) = NEH_DEC_GEN_DATA; -aligned_array(unsigned long, dec_load_table, 12, 16) = NEH_DEC_LOAD_DATA; +aligned_array(unsigned long, dec_gen_table, 12, 16) = NEH_DEC_GEN_DATA; +aligned_array(unsigned long, dec_load_table, 12, 16) = NEH_DEC_LOAD_DATA; aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; /* NOTE: These control word macros must only be used after */ @@ -70,15 +69,15 @@ aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; /* and aes_via_ace.h for non-default NEH_KEY_TYPE values */ #ifndef NEH_KEY_TYPE -# define NEH_KEY_TYPE NEH_HYBRID +#define NEH_KEY_TYPE NEH_HYBRID #endif #if NEH_KEY_TYPE == NEH_LOAD -#define kd_adr(c) ((uint8_t*)(c)->ks) +#define kd_adr(c) ((uint8_t*)(c)->ks) #elif NEH_KEY_TYPE == NEH_GENERATE -#define kd_adr(c) ((uint8_t*)(c)->ks + (c)->inf.b[0]) +#define kd_adr(c) ((uint8_t*)(c)->ks + (c)->inf.b[0]) #elif NEH_KEY_TYPE == NEH_HYBRID -#define kd_adr(c) ((uint8_t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0)) +#define kd_adr(c) ((uint8_t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0)) #else #error no key type defined for VIA ACE #endif @@ -86,37 +85,34 @@ aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; #else #define aligned_array(type, name, no, stride) type name[no] -#define aligned_auto(type, name, no, stride) type name[no] +#define aligned_auto(type, name, no, stride) type name[no] #endif -#if defined( _MSC_VER ) && _MSC_VER > 1200 +#if defined(_MSC_VER) && _MSC_VER > 1200 -#define via_cwd(cwd, ty, dir, len) \ - unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4)) +#define via_cwd(cwd, ty, dir, len) unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4)) #else -#define via_cwd(cwd, ty, dir, len) \ - aligned_auto(unsigned long, cwd, 4, 16); \ - cwd[1] = cwd[2] = cwd[3] = 0; \ +#define via_cwd(cwd, ty, dir, len) \ + aligned_auto(unsigned long, cwd, 4, 16); \ + cwd[1] = cwd[2] = cwd[3] = 0; \ cwd[0] = neh_##dir##_##ty##_key(len) #endif /* test the code for detecting and setting pointer alignment */ -AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */ -{ uint8_t p[16]; +AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */ +{ + uint8_t p[16]; uint32_t i = 0, count_eq = 0, count_neq = 0; - if(n < 4 || n > 16) - return EXIT_FAILURE; + if(n < 4 || n > 16) return EXIT_FAILURE; - for(i = 0; i < n; ++i) - { - uint8_t *qf = ALIGN_FLOOR(p + i, n), - *qh = ALIGN_CEIL(p + i, n); + for(i = 0; i < n; ++i) { + uint8_t *qf = ALIGN_FLOOR(p + i, n), *qh = ALIGN_CEIL(p + i, n); if(qh == qf) ++count_eq; @@ -128,50 +124,45 @@ AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */ return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS); } -AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1]) -{ +AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1]) { ctx->inf.b[2] = 0; return EXIT_SUCCESS; } -AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_encrypt_ctx ctx[1]) -{ int nb = len >> AES_BLOCK_SIZE_P2; +AES_RETURN aes_ecb_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + const aes_encrypt_ctx ctx[1]) { + int nb = len >> AES_BLOCK_SIZE_P2; - if(len & (AES_BLOCK_SIZE - 1)) - return EXIT_FAILURE; + if(len & (AES_BLOCK_SIZE - 1)) return EXIT_FAILURE; -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { uint8_t *ksp = (uint8_t*)(ctx->ks); + if(ctx->inf.b[1] == 0xff) { + uint8_t* ksp = (uint8_t*)(ctx->ks); via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16)) { via_ecb_op5(ksp, cwd, ibuf, obuf, nb); - } - else - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + } else { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_ecb_op5(ksp, cwd, ip, op, m); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; @@ -184,11 +175,9 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, #endif -#if !defined( ASSUME_VIA_ACE_PRESENT ) - while(nb--) - { - if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; +#if !defined(ASSUME_VIA_ACE_PRESENT) + while(nb--) { + if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } @@ -196,44 +185,40 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_decrypt_ctx ctx[1]) -{ int nb = len >> AES_BLOCK_SIZE_P2; +AES_RETURN aes_ecb_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + const aes_decrypt_ctx ctx[1]) { + int nb = len >> AES_BLOCK_SIZE_P2; - if(len & (AES_BLOCK_SIZE - 1)) - return EXIT_FAILURE; + if(len & (AES_BLOCK_SIZE - 1)) return EXIT_FAILURE; -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { uint8_t *ksp = kd_adr(ctx); + if(ctx->inf.b[1] == 0xff) { + uint8_t* ksp = kd_adr(ctx); via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16)) { via_ecb_op5(ksp, cwd, ibuf, obuf, nb); - } - else - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + } else { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_ecb_op5(ksp, cwd, ip, op, m); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; @@ -246,11 +231,9 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, #endif -#if !defined( ASSUME_VIA_ACE_PRESENT ) - while(nb--) - { - if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; +#if !defined(ASSUME_VIA_ACE_PRESENT) + while(nb--) { + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } @@ -258,51 +241,48 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_encrypt_ctx ctx[1]) -{ int nb = len >> AES_BLOCK_SIZE_P2; +AES_RETURN aes_cbc_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + const aes_encrypt_ctx ctx[1]) { + int nb = len >> AES_BLOCK_SIZE_P2; - if(len & (AES_BLOCK_SIZE - 1)) - return EXIT_FAILURE; + if(len & (AES_BLOCK_SIZE - 1)) return EXIT_FAILURE; -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; + if(ctx->inf.b[1] == 0xff) { + uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + if(ALIGN_OFFSET(iv, 16)) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16) && !ALIGN_OFFSET(iv, 16)) { via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); - } - else - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + } else { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_cbc_op7(ksp, cwd, ip, op, m, ivp, ivp); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; @@ -310,43 +290,46 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, } } - if(iv != ivp) - memcpy(iv, ivp, AES_BLOCK_SIZE); + if(iv != ivp) memcpy(iv, ivp, AES_BLOCK_SIZE); return EXIT_SUCCESS; } #endif -#if !defined( ASSUME_VIA_ACE_PRESENT ) -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) - while(nb--) - { +#if !defined(ASSUME_VIA_ACE_PRESENT) +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(ibuf, 4) && !ALIGN_OFFSET(iv, 4)) + while(nb--) { lp32(iv)[0] ^= lp32(ibuf)[0]; lp32(iv)[1] ^= lp32(ibuf)[1]; lp32(iv)[2] ^= lp32(ibuf)[2]; lp32(iv)[3] ^= lp32(ibuf)[3]; - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; memcpy(obuf, iv, AES_BLOCK_SIZE); ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } else -# endif - while(nb--) - { - iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1]; - iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3]; - iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5]; - iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7]; - iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9]; - iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11]; - iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13]; - iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15]; - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; +#endif + while(nb--) { + iv[0] ^= ibuf[0]; + iv[1] ^= ibuf[1]; + iv[2] ^= ibuf[2]; + iv[3] ^= ibuf[3]; + iv[4] ^= ibuf[4]; + iv[5] ^= ibuf[5]; + iv[6] ^= ibuf[6]; + iv[7] ^= ibuf[7]; + iv[8] ^= ibuf[8]; + iv[9] ^= ibuf[9]; + iv[10] ^= ibuf[10]; + iv[11] ^= ibuf[11]; + iv[12] ^= ibuf[12]; + iv[13] ^= ibuf[13]; + iv[14] ^= ibuf[14]; + iv[15] ^= ibuf[15]; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; memcpy(obuf, iv, AES_BLOCK_SIZE); ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; @@ -355,52 +338,49 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_decrypt_ctx ctx[1]) -{ unsigned char tmp[AES_BLOCK_SIZE]; +AES_RETURN aes_cbc_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + const aes_decrypt_ctx ctx[1]) { + unsigned char tmp[AES_BLOCK_SIZE]; int nb = len >> AES_BLOCK_SIZE_P2; - if(len & (AES_BLOCK_SIZE - 1)) - return EXIT_FAILURE; + if(len & (AES_BLOCK_SIZE - 1)) return EXIT_FAILURE; -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { uint8_t *ksp = kd_adr(ctx), *ivp = iv; + if(ctx->inf.b[1] == 0xff) { + uint8_t *ksp = kd_adr(ctx), *ivp = iv; aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + if(ALIGN_OFFSET(iv, 16)) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16) && !ALIGN_OFFSET(iv, 16)) { via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp); - } - else - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + } else { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_cbc_op6(ksp, cwd, ip, op, m, ivp); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; @@ -408,21 +388,18 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, } } - if(iv != ivp) - memcpy(iv, ivp, AES_BLOCK_SIZE); + if(iv != ivp) memcpy(iv, ivp, AES_BLOCK_SIZE); return EXIT_SUCCESS; } #endif -#if !defined( ASSUME_VIA_ACE_PRESENT ) -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) - while(nb--) - { +#if !defined(ASSUME_VIA_ACE_PRESENT) +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(obuf, 4) && !ALIGN_OFFSET(iv, 4)) + while(nb--) { memcpy(tmp, ibuf, AES_BLOCK_SIZE); - if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; lp32(obuf)[0] ^= lp32(iv)[0]; lp32(obuf)[1] ^= lp32(iv)[1]; lp32(obuf)[2] ^= lp32(iv)[2]; @@ -432,20 +409,26 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, obuf += AES_BLOCK_SIZE; } else -# endif - while(nb--) - { +#endif + while(nb--) { memcpy(tmp, ibuf, AES_BLOCK_SIZE); - if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; - obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1]; - obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3]; - obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5]; - obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7]; - obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9]; - obuf[10] ^= iv[10]; obuf[11] ^= iv[11]; - obuf[12] ^= iv[12]; obuf[13] ^= iv[13]; - obuf[14] ^= iv[14]; obuf[15] ^= iv[15]; + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; + obuf[0] ^= iv[0]; + obuf[1] ^= iv[1]; + obuf[2] ^= iv[2]; + obuf[3] ^= iv[3]; + obuf[4] ^= iv[4]; + obuf[5] ^= iv[5]; + obuf[6] ^= iv[6]; + obuf[7] ^= iv[7]; + obuf[8] ^= iv[8]; + obuf[9] ^= iv[9]; + obuf[10] ^= iv[10]; + obuf[11] ^= iv[11]; + obuf[12] ^= iv[12]; + obuf[13] ^= iv[13]; + obuf[14] ^= iv[14]; + obuf[15] ^= iv[15]; memcpy(iv, tmp, AES_BLOCK_SIZE); ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; @@ -454,14 +437,17 @@ AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) -{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; +AES_RETURN aes_cfb_encrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx ctx[1]) { + int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; - if(b_pos) /* complete any partial block */ + if(b_pos) /* complete any partial block */ { - while(b_pos < AES_BLOCK_SIZE && cnt < len) - { + while(b_pos < AES_BLOCK_SIZE && cnt < len) { *obuf++ = (iv[b_pos++] ^= *ibuf++); cnt++; } @@ -469,105 +455,100 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); } - if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ + if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ { -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { int m; + if(ctx->inf.b[1] == 0xff) { + int m; uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + if(ALIGN_OFFSET(iv, 16)) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16)) { via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); ibuf += nb * AES_BLOCK_SIZE; obuf += nb * AES_BLOCK_SIZE; - cnt += nb * AES_BLOCK_SIZE; - } - else /* input, output or both are unaligned */ - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + cnt += nb * AES_BLOCK_SIZE; + } else /* input, output or both are unaligned */ + { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; - cnt += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; } } - if(ivp != iv) - memcpy(iv, ivp, AES_BLOCK_SIZE); + if(ivp != iv) memcpy(iv, ivp, AES_BLOCK_SIZE); } #else -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) - while(cnt + AES_BLOCK_SIZE <= len) - { +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(ibuf, 4) && !ALIGN_OFFSET(obuf, 4) && !ALIGN_OFFSET(iv, 4)) + while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0]; lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1]; lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2]; lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3]; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } else -# endif - while(cnt + AES_BLOCK_SIZE <= len) - { +#endif + while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; - obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1]; - obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3]; - obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5]; - obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7]; - obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9]; - obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11]; - obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13]; - obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15]; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; + obuf[0] = iv[0] ^= ibuf[0]; + obuf[1] = iv[1] ^= ibuf[1]; + obuf[2] = iv[2] ^= ibuf[2]; + obuf[3] = iv[3] ^= ibuf[3]; + obuf[4] = iv[4] ^= ibuf[4]; + obuf[5] = iv[5] ^= ibuf[5]; + obuf[6] = iv[6] ^= ibuf[6]; + obuf[7] = iv[7] ^= ibuf[7]; + obuf[8] = iv[8] ^= ibuf[8]; + obuf[9] = iv[9] ^= ibuf[9]; + obuf[10] = iv[10] ^= ibuf[10]; + obuf[11] = iv[11] ^= ibuf[11]; + obuf[12] = iv[12] ^= ibuf[12]; + obuf[13] = iv[13] ^= ibuf[13]; + obuf[14] = iv[14] ^= ibuf[14]; + obuf[15] = iv[15] ^= ibuf[15]; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } #endif } - while(cnt < len) - { - if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + while(cnt < len) { + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; - while(cnt < len && b_pos < AES_BLOCK_SIZE) - { + while(cnt < len && b_pos < AES_BLOCK_SIZE) { *obuf++ = (iv[b_pos++] ^= *ibuf++); cnt++; } @@ -579,15 +560,19 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) -{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; +AES_RETURN aes_cfb_decrypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx ctx[1]) { + int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; - if(b_pos) /* complete any partial block */ - { uint8_t t; + if(b_pos) /* complete any partial block */ + { + uint8_t t; - while(b_pos < AES_BLOCK_SIZE && cnt < len) - { + while(b_pos < AES_BLOCK_SIZE && cnt < len) { t = *ibuf++; *obuf++ = t ^ iv[b_pos]; iv[b_pos++] = t; @@ -597,95 +582,89 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); } - if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ + if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ { -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { int m; + if(ctx->inf.b[1] == 0xff) { + int m; uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + if(ALIGN_OFFSET(iv, 16)) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16)) { via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp); ibuf += nb * AES_BLOCK_SIZE; obuf += nb * AES_BLOCK_SIZE; - cnt += nb * AES_BLOCK_SIZE; - } - else /* input, output or both are unaligned */ - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + cnt += nb * AES_BLOCK_SIZE; + } else /* input, output or both are unaligned */ + { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) /* input buffer is not aligned */ + if(ip != ibuf) /* input buffer is not aligned */ memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_cfb_op6(ksp, cwd, ip, op, m, ivp); - if(op != obuf) /* output buffer is not aligned */ + if(op != obuf) /* output buffer is not aligned */ memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; - cnt += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; } } - if(ivp != iv) - memcpy(iv, ivp, AES_BLOCK_SIZE); + if(ivp != iv) memcpy(iv, ivp, AES_BLOCK_SIZE); } #else -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 )) - while(cnt + AES_BLOCK_SIZE <= len) - { uint32_t t; +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(ibuf, 4) && !ALIGN_OFFSET(obuf, 4) && !ALIGN_OFFSET(iv, 4)) + while(cnt + AES_BLOCK_SIZE <= len) { + uint32_t t; assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t; t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t; t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t; t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } else -# endif - while(cnt + AES_BLOCK_SIZE <= len) - { uint8_t t; +#endif + while(cnt + AES_BLOCK_SIZE <= len) { + uint8_t t; assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; - t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t; - t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t; - t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t; - t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t; - t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t; - t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t; - t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t; - t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t; - t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t; - t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; + t = ibuf[0], obuf[0] = t ^ iv[0], iv[0] = t; + t = ibuf[1], obuf[1] = t ^ iv[1], iv[1] = t; + t = ibuf[2], obuf[2] = t ^ iv[2], iv[2] = t; + t = ibuf[3], obuf[3] = t ^ iv[3], iv[3] = t; + t = ibuf[4], obuf[4] = t ^ iv[4], iv[4] = t; + t = ibuf[5], obuf[5] = t ^ iv[5], iv[5] = t; + t = ibuf[6], obuf[6] = t ^ iv[6], iv[6] = t; + t = ibuf[7], obuf[7] = t ^ iv[7], iv[7] = t; + t = ibuf[8], obuf[8] = t ^ iv[8], iv[8] = t; + t = ibuf[9], obuf[9] = t ^ iv[9], iv[9] = t; t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t; t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t; t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t; @@ -694,19 +673,17 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } #endif } - while(cnt < len) - { uint8_t t; + while(cnt < len) { + uint8_t t; - if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; - while(cnt < len && b_pos < AES_BLOCK_SIZE) - { + while(cnt < len && b_pos < AES_BLOCK_SIZE) { t = *ibuf++; *obuf++ = t ^ iv[b_pos]; iv[b_pos++] = t; @@ -720,14 +697,17 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) -{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; +AES_RETURN aes_ofb_crypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* iv, + aes_encrypt_ctx ctx[1]) { + int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; - if(b_pos) /* complete any partial block */ + if(b_pos) /* complete any partial block */ { - while(b_pos < AES_BLOCK_SIZE && cnt < len) - { + while(b_pos < AES_BLOCK_SIZE && cnt < len) { *obuf++ = iv[b_pos++] ^ *ibuf++; cnt++; } @@ -735,105 +715,100 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); } - if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ + if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */ { -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) - if(ctx->inf.b[1] == 0xff) - { int m; + if(ctx->inf.b[1] == 0xff) { + int m; uint8_t *ksp = (uint8_t*)(ctx->ks), *ivp = iv; aligned_auto(uint8_t, liv, AES_BLOCK_SIZE, 16); via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; - if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ + if(ALIGN_OFFSET(iv, 16)) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) - { + if(!ALIGN_OFFSET(ibuf, 16) && !ALIGN_OFFSET(obuf, 16)) { via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp); ibuf += nb * AES_BLOCK_SIZE; obuf += nb * AES_BLOCK_SIZE; - cnt += nb * AES_BLOCK_SIZE; - } - else /* input, output or both are unaligned */ - { aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); - uint8_t *ip = NULL, *op = NULL; + cnt += nb * AES_BLOCK_SIZE; + } else /* input, output or both are unaligned */ + { + aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); + uint8_t *ip = NULL, *op = NULL; - while(nb) - { + while(nb) { m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; - ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); - op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); + ip = (ALIGN_OFFSET(ibuf, 16) ? buf : ibuf); + op = (ALIGN_OFFSET(obuf, 16) ? buf : obuf); - if(ip != ibuf) - memcpy(buf, ibuf, m * AES_BLOCK_SIZE); + if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_ofb_op6(ksp, cwd, ip, op, m, ivp); - if(op != obuf) - memcpy(obuf, buf, m * AES_BLOCK_SIZE); + if(op != obuf) memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; obuf += m * AES_BLOCK_SIZE; - cnt += m * AES_BLOCK_SIZE; + cnt += m * AES_BLOCK_SIZE; } } - if(ivp != iv) - memcpy(iv, ivp, AES_BLOCK_SIZE); + if(ivp != iv) memcpy(iv, ivp, AES_BLOCK_SIZE); } #else -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) - while(cnt + AES_BLOCK_SIZE <= len) - { +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(ibuf, 4) && !ALIGN_OFFSET(obuf, 4) && !ALIGN_OFFSET(iv, 4)) + while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0]; lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1]; lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2]; lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3]; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } else -# endif - while(cnt + AES_BLOCK_SIZE <= len) - { +#endif + while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; - obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1]; - obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3]; - obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5]; - obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7]; - obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9]; - obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11]; - obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13]; - obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15]; + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; + obuf[0] = iv[0] ^ ibuf[0]; + obuf[1] = iv[1] ^ ibuf[1]; + obuf[2] = iv[2] ^ ibuf[2]; + obuf[3] = iv[3] ^ ibuf[3]; + obuf[4] = iv[4] ^ ibuf[4]; + obuf[5] = iv[5] ^ ibuf[5]; + obuf[6] = iv[6] ^ ibuf[6]; + obuf[7] = iv[7] ^ ibuf[7]; + obuf[8] = iv[8] ^ ibuf[8]; + obuf[9] = iv[9] ^ ibuf[9]; + obuf[10] = iv[10] ^ ibuf[10]; + obuf[11] = iv[11] ^ ibuf[11]; + obuf[12] = iv[12] ^ ibuf[12]; + obuf[13] = iv[13] ^ ibuf[13]; + obuf[14] = iv[14] ^ ibuf[14]; + obuf[15] = iv[15] ^ ibuf[15]; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; - cnt += AES_BLOCK_SIZE; + cnt += AES_BLOCK_SIZE; } #endif } - while(cnt < len) - { - if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + while(cnt < len) { + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; - while(cnt < len && b_pos < AES_BLOCK_SIZE) - { + while(cnt < len && b_pos < AES_BLOCK_SIZE) { *obuf++ = iv[b_pos++] ^ *ibuf++; cnt++; } @@ -845,67 +820,62 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -#define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE) +#define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE) -AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1]) -{ unsigned char *ip; - int i = 0, blen = 0, b_pos = (int)(ctx->inf.b[2]); +AES_RETURN aes_ctr_crypt( + const unsigned char* ibuf, + unsigned char* obuf, + int len, + unsigned char* cbuf, + cbuf_inc ctr_inc, + aes_encrypt_ctx ctx[1]) { + unsigned char* ip; + int i = 0, blen = 0, b_pos = (int)(ctx->inf.b[2]); -#if defined( USE_VIA_ACE_IF_PRESENT ) +#if defined(USE_VIA_ACE_IF_PRESENT) aligned_auto(uint8_t, buf, BFR_LENGTH, 16); - if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 )) - return EXIT_FAILURE; + if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET(ctx, 16)) return EXIT_FAILURE; #else uint8_t buf[BFR_LENGTH] = {0}; #endif - if(b_pos) - { + if(b_pos) { memcpy(buf, cbuf, AES_BLOCK_SIZE); - if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) - return EXIT_FAILURE; + if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; - while(b_pos < AES_BLOCK_SIZE && len) - { + while(b_pos < AES_BLOCK_SIZE && len) { *obuf++ = *ibuf++ ^ buf[b_pos++]; --len; } - if(len) - ctr_inc(cbuf), b_pos = 0; + if(len) ctr_inc(cbuf), b_pos = 0; } - while(len) - { + while(len) { blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen; - for(i = 0, ip = buf; i < (blen >> AES_BLOCK_SIZE_P2); ++i) - { + for(i = 0, ip = buf; i < (blen >> AES_BLOCK_SIZE_P2); ++i) { memcpy(ip, cbuf, AES_BLOCK_SIZE); ctr_inc(cbuf); ip += AES_BLOCK_SIZE; } - if(blen & (AES_BLOCK_SIZE - 1)) - memcpy(ip, cbuf, AES_BLOCK_SIZE), i++; + if(blen & (AES_BLOCK_SIZE - 1)) memcpy(ip, cbuf, AES_BLOCK_SIZE), i++; -#if defined( USE_VIA_ACE_IF_PRESENT ) - if(ctx->inf.b[1] == 0xff) - { +#if defined(USE_VIA_ACE_IF_PRESENT) + if(ctx->inf.b[1] == 0xff) { via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); via_ecb_op5((ctx->ks), cwd, buf, buf, i); - } - else + } else #endif - if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) + if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) return EXIT_FAILURE; - i = 0; ip = buf; -# ifdef FAST_BUFFER_OPERATIONS - if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 )) - while(i + AES_BLOCK_SIZE <= blen) - { + i = 0; + ip = buf; +#ifdef FAST_BUFFER_OPERATIONS + if(!ALIGN_OFFSET(ibuf, 4) && !ALIGN_OFFSET(obuf, 4) && !ALIGN_OFFSET(ip, 4)) + while(i + AES_BLOCK_SIZE <= blen) { lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0]; lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1]; lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2]; @@ -917,36 +887,41 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, } else #endif - while(i + AES_BLOCK_SIZE <= blen) - { - obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1]; - obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3]; - obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5]; - obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7]; - obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9]; - obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11]; - obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13]; - obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15]; + while(i + AES_BLOCK_SIZE <= blen) { + obuf[0] = ibuf[0] ^ ip[0]; + obuf[1] = ibuf[1] ^ ip[1]; + obuf[2] = ibuf[2] ^ ip[2]; + obuf[3] = ibuf[3] ^ ip[3]; + obuf[4] = ibuf[4] ^ ip[4]; + obuf[5] = ibuf[5] ^ ip[5]; + obuf[6] = ibuf[6] ^ ip[6]; + obuf[7] = ibuf[7] ^ ip[7]; + obuf[8] = ibuf[8] ^ ip[8]; + obuf[9] = ibuf[9] ^ ip[9]; + obuf[10] = ibuf[10] ^ ip[10]; + obuf[11] = ibuf[11] ^ ip[11]; + obuf[12] = ibuf[12] ^ ip[12]; + obuf[13] = ibuf[13] ^ ip[13]; + obuf[14] = ibuf[14] ^ ip[14]; + obuf[15] = ibuf[15] ^ ip[15]; i += AES_BLOCK_SIZE; ip += AES_BLOCK_SIZE; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } - while(i++ < blen) - *obuf++ = *ibuf++ ^ ip[b_pos++]; + while(i++ < blen) *obuf++ = *ibuf++ ^ ip[b_pos++]; } ctx->inf.b[2] = (uint8_t)b_pos; return EXIT_SUCCESS; } -void aes_ctr_cbuf_inc(unsigned char *cbuf) -{ +void aes_ctr_cbuf_inc(unsigned char* cbuf) { int i = AES_BLOCK_SIZE - 1; - while (i >= 0) { + while(i >= 0) { cbuf[i]++; - if (cbuf[i]) return; // if there was no overflow + if(cbuf[i]) return; // if there was no overflow i--; } } diff --git a/crypto/aes/aescrypt.c b/crypto/aes/aescrypt.c index 48b2f88d38f..a160b6f9511 100644 --- a/crypto/aes/aescrypt.c +++ b/crypto/aes/aescrypt.c @@ -21,42 +21,56 @@ Issue Date: 20/12/2007 #include "aesopt.h" #include "aestab.h" -#if defined( USE_INTEL_AES_IF_PRESENT ) -# include "aes_ni.h" +#if defined(USE_INTEL_AES_IF_PRESENT) +#include "aes_ni.h" #else /* map names here to provide the external API ('name' -> 'aes_name') */ -# define aes_xi(x) aes_ ## x +#define aes_xi(x) aes_##x #endif #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif -#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) -#define so(y,x,c) word_out(y, c, s(x,c)) +#define si(y, x, k, c) (s(y, c) = word_in(x, c) ^ (k)[c]) +#define so(y, x, c) word_out(y, c, s(x, c)) #if defined(ARRAYS) -#define locals(y,x) x[4],y[4] +#define locals(y, x) x[4], y[4] #else -#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 +#define locals(y, x) x##0, x##1, x##2, x##3, y##0, y##1, y##2, y##3 #endif -#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ - s(y,2) = s(x,2); s(y,3) = s(x,3); -#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) -#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) -#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) - -#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) +#define l_copy(y, x) \ + s(y, 0) = s(x, 0); \ + s(y, 1) = s(x, 1); \ + s(y, 2) = s(x, 2); \ + s(y, 3) = s(x, 3); +#define state_in(y, x, k) \ + si(y, x, k, 0); \ + si(y, x, k, 1); \ + si(y, x, k, 2); \ + si(y, x, k, 3) +#define state_out(y, x) \ + so(y, x, 0); \ + so(y, x, 1); \ + so(y, x, 2); \ + so(y, x, 3) +#define round(rm, y, x, k) \ + rm(y, x, k, 0); \ + rm(y, x, k, 1); \ + rm(y, x, k, 2); \ + rm(y, x, k, 3) + +#if(FUNCS_IN_C & ENCRYPTION_IN_C) /* Visual C++ .Net v7.1 provides the fastest encryption code when using Pentium optimiation with small code but this is poor for decryption so we need to control this with the following VC++ pragmas */ -#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ ) -#pragma optimize( "s", on ) +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(__clang__) +#pragma optimize("s", on) #endif /* Given the column (c) of the output state variable, the following @@ -70,88 +84,102 @@ extern "C" Yellin for this construction) */ -#define fwd_var(x,r,c)\ - ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ - : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ - : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ - : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) +#define fwd_var(x, r, c) \ + (r == 0 ? (c == 0 ? s(x, 0) : \ + c == 1 ? s(x, 1) : \ + c == 2 ? s(x, 2) : \ + s(x, 3)) : \ + r == 1 ? (c == 0 ? s(x, 1) : \ + c == 1 ? s(x, 2) : \ + c == 2 ? s(x, 3) : \ + s(x, 0)) : \ + r == 2 ? (c == 0 ? s(x, 2) : \ + c == 1 ? s(x, 3) : \ + c == 2 ? s(x, 0) : \ + s(x, 1)) : \ + (c == 0 ? s(x, 3) : \ + c == 1 ? s(x, 0) : \ + c == 2 ? s(x, 1) : \ + s(x, 2))) #if defined(FT4_SET) -#undef dec_fmvars -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) +#undef dec_fmvars +#define fwd_rnd(y, x, k, c) (s(y, c) = (k)[c] ^ four_tables(x, t_use(f, n), fwd_var, rf1, c)) #elif defined(FT1_SET) -#undef dec_fmvars -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) +#undef dec_fmvars +#define fwd_rnd(y, x, k, c) (s(y, c) = (k)[c] ^ one_table(x, upr, t_use(f, n), fwd_var, rf1, c)) #else -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) +#define fwd_rnd(y, x, k, c) \ + (s(y, c) = (k)[c] ^ fwd_mcol(no_table(x, t_use(s, box), fwd_var, rf1, c))) #endif #if defined(FL4_SET) -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) +#define fwd_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ four_tables(x, t_use(f, l), fwd_var, rf1, c)) #elif defined(FL1_SET) -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) +#define fwd_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ one_table(x, ups, t_use(f, l), fwd_var, rf1, c)) #else -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) +#define fwd_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ no_table(x, t_use(s, box), fwd_var, rf1, c)) #endif -AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) -{ uint32_t locals(b0, b1); - const uint32_t *kp = NULL; -#if defined( dec_fmvars ) +AES_RETURN +aes_xi(encrypt)(const unsigned char* in, unsigned char* out, const aes_encrypt_ctx cx[1]) { + uint32_t locals(b0, b1); + const uint32_t* kp = NULL; +#if defined(dec_fmvars) dec_fmvars; /* declare variables for fwd_mcol() if needed */ #endif - if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) - return EXIT_FAILURE; + if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && + cx->inf.b[0] != 14 * AES_BLOCK_SIZE) + return EXIT_FAILURE; - kp = cx->ks; + kp = cx->ks; state_in(b0, in, kp); -#if (ENC_UNROLL == FULL) +#if(ENC_UNROLL == FULL) - switch(cx->inf.b[0]) - { + switch(cx->inf.b[0]) { case 14 * AES_BLOCK_SIZE: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); kp += 2 * N_COLS; //-fallthrough case 12 * AES_BLOCK_SIZE: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); kp += 2 * N_COLS; //-fallthrough case 10 * AES_BLOCK_SIZE: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); - round(fwd_rnd, b1, b0, kp + 3 * N_COLS); - round(fwd_rnd, b0, b1, kp + 4 * N_COLS); - round(fwd_rnd, b1, b0, kp + 5 * N_COLS); - round(fwd_rnd, b0, b1, kp + 6 * N_COLS); - round(fwd_rnd, b1, b0, kp + 7 * N_COLS); - round(fwd_rnd, b0, b1, kp + 8 * N_COLS); - round(fwd_rnd, b1, b0, kp + 9 * N_COLS); - round(fwd_lrnd, b0, b1, kp +10 * N_COLS); + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + round(fwd_rnd, b1, b0, kp + 3 * N_COLS); + round(fwd_rnd, b0, b1, kp + 4 * N_COLS); + round(fwd_rnd, b1, b0, kp + 5 * N_COLS); + round(fwd_rnd, b0, b1, kp + 6 * N_COLS); + round(fwd_rnd, b1, b0, kp + 7 * N_COLS); + round(fwd_rnd, b0, b1, kp + 8 * N_COLS); + round(fwd_rnd, b1, b0, kp + 9 * N_COLS); + round(fwd_lrnd, b0, b1, kp + 10 * N_COLS); //-fallthrough } #else -#if (ENC_UNROLL == PARTIAL) - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) - { +#if(ENC_UNROLL == PARTIAL) + { + uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) { kp += N_COLS; round(fwd_rnd, b1, b0, kp); kp += N_COLS; round(fwd_rnd, b0, b1, kp); } kp += N_COLS; - round(fwd_rnd, b1, b0, kp); + round(fwd_rnd, b1, b0, kp); #else - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) - { + { + uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) { kp += N_COLS; round(fwd_rnd, b1, b0, kp); l_copy(b0, b1); @@ -168,15 +196,15 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae #endif -#if ( FUNCS_IN_C & DECRYPTION_IN_C) +#if(FUNCS_IN_C & DECRYPTION_IN_C) /* Visual C++ .Net v7.1 provides the fastest encryption code when using Pentium optimiation with small code but this is poor for decryption so we need to control this with the following VC++ pragmas */ -#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ ) -#pragma optimize( "t", on ) +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(__clang__) +#pragma optimize("t", on) #endif /* Given the column (c) of the output state variable, the following @@ -190,28 +218,41 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae Yellin for this construction) */ -#define inv_var(x,r,c)\ - ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ - : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\ - : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ - : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) +#define inv_var(x, r, c) \ + (r == 0 ? (c == 0 ? s(x, 0) : \ + c == 1 ? s(x, 1) : \ + c == 2 ? s(x, 2) : \ + s(x, 3)) : \ + r == 1 ? (c == 0 ? s(x, 3) : \ + c == 1 ? s(x, 0) : \ + c == 2 ? s(x, 1) : \ + s(x, 2)) : \ + r == 2 ? (c == 0 ? s(x, 2) : \ + c == 1 ? s(x, 3) : \ + c == 2 ? s(x, 0) : \ + s(x, 1)) : \ + (c == 0 ? s(x, 1) : \ + c == 1 ? s(x, 2) : \ + c == 2 ? s(x, 3) : \ + s(x, 0))) #if defined(IT4_SET) -#undef dec_imvars -#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) +#undef dec_imvars +#define inv_rnd(y, x, k, c) (s(y, c) = (k)[c] ^ four_tables(x, t_use(i, n), inv_var, rf1, c)) #elif defined(IT1_SET) -#undef dec_imvars -#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) +#undef dec_imvars +#define inv_rnd(y, x, k, c) (s(y, c) = (k)[c] ^ one_table(x, upr, t_use(i, n), inv_var, rf1, c)) #else -#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) +#define inv_rnd(y, x, k, c) \ + (s(y, c) = inv_mcol((k)[c] ^ no_table(x, t_use(i, box), inv_var, rf1, c))) #endif #if defined(IL4_SET) -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) +#define inv_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ four_tables(x, t_use(i, l), inv_var, rf1, c)) #elif defined(IL1_SET) -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) +#define inv_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ one_table(x, ups, t_use(i, l), inv_var, rf1, c)) #else -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) +#define inv_lrnd(y, x, k, c) (s(y, c) = (k)[c] ^ no_table(x, t_use(i, box), inv_var, rf1, c)) #endif /* This code can work with the decryption key schedule in the */ @@ -222,59 +263,60 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae /* AES_REV_DKS is defined) */ #ifdef AES_REV_DKS -#define key_ofs 0 -#define rnd_key(n) (kp + n * N_COLS) +#define key_ofs 0 +#define rnd_key(n) (kp + n * N_COLS) #else -#define key_ofs 1 -#define rnd_key(n) (kp - n * N_COLS) +#define key_ofs 1 +#define rnd_key(n) (kp - n * N_COLS) #endif -AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) -{ uint32_t locals(b0, b1); -#if defined( dec_imvars ) +AES_RETURN +aes_xi(decrypt)(const unsigned char* in, unsigned char* out, const aes_decrypt_ctx cx[1]) { + uint32_t locals(b0, b1); +#if defined(dec_imvars) dec_imvars; /* declare variables for inv_mcol() if needed */ #endif - const uint32_t *kp = NULL; + const uint32_t* kp = NULL; - if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) - return EXIT_FAILURE; + if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && + cx->inf.b[0] != 14 * AES_BLOCK_SIZE) + return EXIT_FAILURE; kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); state_in(b0, in, kp); -#if (DEC_UNROLL == FULL) +#if(DEC_UNROLL == FULL) kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); - switch(cx->inf.b[0]) - { + switch(cx->inf.b[0]) { case 14 * AES_BLOCK_SIZE: - round(inv_rnd, b1, b0, rnd_key(-13)); - round(inv_rnd, b0, b1, rnd_key(-12)); + round(inv_rnd, b1, b0, rnd_key(-13)); + round(inv_rnd, b0, b1, rnd_key(-12)); //-fallthrough case 12 * AES_BLOCK_SIZE: - round(inv_rnd, b1, b0, rnd_key(-11)); - round(inv_rnd, b0, b1, rnd_key(-10)); + round(inv_rnd, b1, b0, rnd_key(-11)); + round(inv_rnd, b0, b1, rnd_key(-10)); //-fallthrough case 10 * AES_BLOCK_SIZE: - round(inv_rnd, b1, b0, rnd_key(-9)); - round(inv_rnd, b0, b1, rnd_key(-8)); - round(inv_rnd, b1, b0, rnd_key(-7)); - round(inv_rnd, b0, b1, rnd_key(-6)); - round(inv_rnd, b1, b0, rnd_key(-5)); - round(inv_rnd, b0, b1, rnd_key(-4)); - round(inv_rnd, b1, b0, rnd_key(-3)); - round(inv_rnd, b0, b1, rnd_key(-2)); - round(inv_rnd, b1, b0, rnd_key(-1)); - round(inv_lrnd, b0, b1, rnd_key( 0)); + round(inv_rnd, b1, b0, rnd_key(-9)); + round(inv_rnd, b0, b1, rnd_key(-8)); + round(inv_rnd, b1, b0, rnd_key(-7)); + round(inv_rnd, b0, b1, rnd_key(-6)); + round(inv_rnd, b1, b0, rnd_key(-5)); + round(inv_rnd, b0, b1, rnd_key(-4)); + round(inv_rnd, b1, b0, rnd_key(-3)); + round(inv_rnd, b0, b1, rnd_key(-2)); + round(inv_rnd, b1, b0, rnd_key(-1)); + round(inv_lrnd, b0, b1, rnd_key(0)); //-fallthrough } #else -#if (DEC_UNROLL == PARTIAL) - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) - { +#if(DEC_UNROLL == PARTIAL) + { + uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) { kp = rnd_key(1); round(inv_rnd, b1, b0, kp); kp = rnd_key(1); @@ -283,9 +325,9 @@ AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const ae kp = rnd_key(1); round(inv_rnd, b1, b0, kp); #else - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) - { + { + uint32_t rnd; + for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) { kp = rnd_key(1); round(inv_rnd, b1, b0, kp); l_copy(b0, b1); @@ -293,7 +335,7 @@ AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const ae #endif kp = rnd_key(1); round(inv_lrnd, b0, b1, kp); - } + } #endif state_out(out, b0); diff --git a/crypto/aes/aeskey.c b/crypto/aes/aeskey.c index 0ec5f89544b..0092be4396c 100644 --- a/crypto/aes/aeskey.c +++ b/crypto/aes/aeskey.c @@ -21,20 +21,19 @@ Issue Date: 20/12/2007 #include "aesopt.h" #include "aestab.h" -#if defined( USE_INTEL_AES_IF_PRESENT ) -# include "aes_ni.h" +#if defined(USE_INTEL_AES_IF_PRESENT) +#include "aes_ni.h" #else /* map names here to provide the external API ('name' -> 'aes_name') */ -# define aes_xi(x) aes_ ## x +#define aes_xi(x) aes_##x #endif #ifdef USE_VIA_ACE_IF_PRESENT -# include "aes_via_ace.h" +#include "aes_via_ace.h" #endif #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif /* Initialise the key schedule from the user supplied key. The key @@ -55,32 +54,33 @@ extern "C" cx->n_col = 8 29 23 19 17 14 */ -#if defined( REDUCE_CODE_SIZE ) -# define ls_box ls_sub - uint32_t ls_sub(const uint32_t t, const uint32_t n); -# define inv_mcol im_sub - uint32_t im_sub(const uint32_t x); -# ifdef ENC_KS_UNROLL -# undef ENC_KS_UNROLL -# endif -# ifdef DEC_KS_UNROLL -# undef DEC_KS_UNROLL -# endif +#if defined(REDUCE_CODE_SIZE) +#define ls_box ls_sub +uint32_t ls_sub(const uint32_t t, const uint32_t n); +#define inv_mcol im_sub +uint32_t im_sub(const uint32_t x); +#ifdef ENC_KS_UNROLL +#undef ENC_KS_UNROLL +#endif +#ifdef DEC_KS_UNROLL +#undef DEC_KS_UNROLL +#endif #endif -#if (FUNCS_IN_C & ENC_KEYING_IN_C) +#if(FUNCS_IN_C & ENC_KEYING_IN_C) -#if defined(AES_128) || defined( AES_VAR ) +#if defined(AES_128) || defined(AES_VAR) -#define ke4(k,i) \ -{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - k[4*(i)+5] = ss[1] ^= ss[0]; \ - k[4*(i)+6] = ss[2] ^= ss[1]; \ - k[4*(i)+7] = ss[3] ^= ss[2]; \ -} +#define ke4(k, i) \ + { \ + k[4 * (i) + 4] = ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \ + k[4 * (i) + 5] = ss[1] ^= ss[0]; \ + k[4 * (i) + 6] = ss[2] ^= ss[1]; \ + k[4 * (i) + 7] = ss[3] ^= ss[2]; \ + } -AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[4]; +AES_RETURN aes_xi(encrypt_key128)(const unsigned char* key, aes_encrypt_ctx cx[1]) { + uint32_t ss[4]; cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); @@ -88,15 +88,19 @@ AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->ks[3] = ss[3] = word_in(key, 3); #ifdef ENC_KS_UNROLL - ke4(cx->ks, 0); ke4(cx->ks, 1); - ke4(cx->ks, 2); ke4(cx->ks, 3); - ke4(cx->ks, 4); ke4(cx->ks, 5); - ke4(cx->ks, 6); ke4(cx->ks, 7); + ke4(cx->ks, 0); + ke4(cx->ks, 1); + ke4(cx->ks, 2); + ke4(cx->ks, 3); + ke4(cx->ks, 4); + ke4(cx->ks, 5); + ke4(cx->ks, 6); + ke4(cx->ks, 7); ke4(cx->ks, 8); #else - { uint32_t i; - for(i = 0; i < 9; ++i) - ke4(cx->ks, i); + { + uint32_t i; + for(i = 0; i < 9; ++i) ke4(cx->ks, i); } #endif ke4(cx->ks, 9); @@ -104,33 +108,34 @@ AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->inf.b[0] = 10 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } #endif -#if defined(AES_192) || defined( AES_VAR ) +#if defined(AES_192) || defined(AES_VAR) -#define kef6(k,i) \ -{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - k[6*(i)+ 7] = ss[1] ^= ss[0]; \ - k[6*(i)+ 8] = ss[2] ^= ss[1]; \ - k[6*(i)+ 9] = ss[3] ^= ss[2]; \ -} +#define kef6(k, i) \ + { \ + k[6 * (i) + 6] = ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \ + k[6 * (i) + 7] = ss[1] ^= ss[0]; \ + k[6 * (i) + 8] = ss[2] ^= ss[1]; \ + k[6 * (i) + 9] = ss[3] ^= ss[2]; \ + } -#define ke6(k,i) \ -{ kef6(k,i); \ - k[6*(i)+10] = ss[4] ^= ss[3]; \ - k[6*(i)+11] = ss[5] ^= ss[4]; \ -} +#define ke6(k, i) \ + { \ + kef6(k, i); \ + k[6 * (i) + 10] = ss[4] ^= ss[3]; \ + k[6 * (i) + 11] = ss[5] ^= ss[4]; \ + } -AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[6]; +AES_RETURN aes_xi(encrypt_key192)(const unsigned char* key, aes_encrypt_ctx cx[1]) { + uint32_t ss[6]; - cx->ks[0] = ss[0] = word_in(key, 0); + cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); cx->ks[2] = ss[2] = word_in(key, 2); cx->ks[3] = ss[3] = word_in(key, 3); @@ -138,14 +143,17 @@ AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->ks[5] = ss[5] = word_in(key, 5); #ifdef ENC_KS_UNROLL - ke6(cx->ks, 0); ke6(cx->ks, 1); - ke6(cx->ks, 2); ke6(cx->ks, 3); - ke6(cx->ks, 4); ke6(cx->ks, 5); + ke6(cx->ks, 0); + ke6(cx->ks, 1); + ke6(cx->ks, 2); + ke6(cx->ks, 3); + ke6(cx->ks, 4); + ke6(cx->ks, 5); ke6(cx->ks, 6); #else - { uint32_t i; - for(i = 0; i < 7; ++i) - ke6(cx->ks, i); + { + uint32_t i; + for(i = 0; i < 7; ++i) ke6(cx->ks, i); } #endif kef6(cx->ks, 7); @@ -153,33 +161,34 @@ AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->inf.b[0] = 12 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } #endif -#if defined(AES_256) || defined( AES_VAR ) +#if defined(AES_256) || defined(AES_VAR) -#define kef8(k,i) \ -{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - k[8*(i)+ 9] = ss[1] ^= ss[0]; \ - k[8*(i)+10] = ss[2] ^= ss[1]; \ - k[8*(i)+11] = ss[3] ^= ss[2]; \ -} +#define kef8(k, i) \ + { \ + k[8 * (i) + 8] = ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \ + k[8 * (i) + 9] = ss[1] ^= ss[0]; \ + k[8 * (i) + 10] = ss[2] ^= ss[1]; \ + k[8 * (i) + 11] = ss[3] ^= ss[2]; \ + } -#define ke8(k,i) \ -{ kef8(k,i); \ - k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ - k[8*(i)+13] = ss[5] ^= ss[4]; \ - k[8*(i)+14] = ss[6] ^= ss[5]; \ - k[8*(i)+15] = ss[7] ^= ss[6]; \ -} +#define ke8(k, i) \ + { \ + kef8(k, i); \ + k[8 * (i) + 12] = ss[4] ^= ls_box(ss[3], 0); \ + k[8 * (i) + 13] = ss[5] ^= ss[4]; \ + k[8 * (i) + 14] = ss[6] ^= ss[5]; \ + k[8 * (i) + 15] = ss[7] ^= ss[6]; \ + } -AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[8]; +AES_RETURN aes_xi(encrypt_key256)(const unsigned char* key, aes_encrypt_ctx cx[1]) { + uint32_t ss[8]; cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); @@ -191,13 +200,16 @@ AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->ks[7] = ss[7] = word_in(key, 7); #ifdef ENC_KS_UNROLL - ke8(cx->ks, 0); ke8(cx->ks, 1); - ke8(cx->ks, 2); ke8(cx->ks, 3); - ke8(cx->ks, 4); ke8(cx->ks, 5); + ke8(cx->ks, 0); + ke8(cx->ks, 1); + ke8(cx->ks, 2); + ke8(cx->ks, 3); + ke8(cx->ks, 4); + ke8(cx->ks, 5); #else - { uint32_t i; - for(i = 0; i < 6; ++i) - ke8(cx->ks, i); + { + uint32_t i; + for(i = 0; i < 6; ++i) ke8(cx->ks, i); } #endif kef8(cx->ks, 6); @@ -205,8 +217,7 @@ AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1 cx->inf.b[0] = 14 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } @@ -215,116 +226,146 @@ AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1 #endif -#if (FUNCS_IN_C & DEC_KEYING_IN_C) +#if(FUNCS_IN_C & DEC_KEYING_IN_C) /* this is used to store the decryption round keys */ /* in forward or reverse order */ #ifdef AES_REV_DKS -#define v(n,i) ((n) - (i) + 2 * ((i) & 3)) +#define v(n, i) ((n) - (i) + 2 * ((i)&3)) #else -#define v(n,i) (i) +#define v(n, i) (i) #endif #if DEC_ROUND == NO_TABLES -#define ff(x) (x) +#define ff(x) (x) #else -#define ff(x) inv_mcol(x) -#if defined( dec_imvars ) -#define d_vars dec_imvars +#define ff(x) inv_mcol(x) +#if defined(dec_imvars) +#define d_vars dec_imvars #endif #endif -#if defined(AES_128) || defined( AES_VAR ) +#if defined(AES_128) || defined(AES_VAR) -#define k4e(k,i) \ -{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \ - k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \ - k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \ -} +#define k4e(k, i) \ + { \ + k[v(40, (4 * (i)) + 4)] = ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \ + k[v(40, (4 * (i)) + 5)] = ss[1] ^= ss[0]; \ + k[v(40, (4 * (i)) + 6)] = ss[2] ^= ss[1]; \ + k[v(40, (4 * (i)) + 7)] = ss[3] ^= ss[2]; \ + } #if 1 -#define kdf4(k,i) \ -{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ - ss[1] = ss[1] ^ ss[3]; \ - ss[2] = ss[2] ^ ss[3]; \ - ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ - ss[i % 4] ^= ss[4]; \ - ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \ -} +#define kdf4(k, i) \ + { \ + ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ + ss[1] = ss[1] ^ ss[3]; \ + ss[2] = ss[2] ^ ss[3]; \ + ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \ + ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[v(40, (4 * (i)))]; \ + k[v(40, (4 * (i)) + 4)] = ff(ss[4]); \ + ss[4] ^= k[v(40, (4 * (i)) + 1)]; \ + k[v(40, (4 * (i)) + 5)] = ff(ss[4]); \ + ss[4] ^= k[v(40, (4 * (i)) + 2)]; \ + k[v(40, (4 * (i)) + 6)] = ff(ss[4]); \ + ss[4] ^= k[v(40, (4 * (i)) + 3)]; \ + k[v(40, (4 * (i)) + 7)] = ff(ss[4]); \ + } -#define kd4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ - ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ - k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \ - k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \ - k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \ - k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \ -} +#define kd4(k, i) \ + { \ + ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \ + ss[i % 4] ^= ss[4]; \ + ss[4] = ff(ss[4]); \ + k[v(40, (4 * (i)) + 4)] = ss[4] ^= k[v(40, (4 * (i)))]; \ + k[v(40, (4 * (i)) + 5)] = ss[4] ^= k[v(40, (4 * (i)) + 1)]; \ + k[v(40, (4 * (i)) + 6)] = ss[4] ^= k[v(40, (4 * (i)) + 2)]; \ + k[v(40, (4 * (i)) + 7)] = ss[4] ^= k[v(40, (4 * (i)) + 3)]; \ + } -#define kdl4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ - k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ - k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \ - k[v(40,(4*(i))+6)] = ss[0]; \ - k[v(40,(4*(i))+7)] = ss[1]; \ -} +#define kdl4(k, i) \ + { \ + ss[4] = ls_box(ss[(i + 3) % 4], 3) ^ t_use(r, c)[i]; \ + ss[i % 4] ^= ss[4]; \ + k[v(40, (4 * (i)) + 4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ + k[v(40, (4 * (i)) + 5)] = ss[1] ^ ss[3]; \ + k[v(40, (4 * (i)) + 6)] = ss[0]; \ + k[v(40, (4 * (i)) + 7)] = ss[1]; \ + } #else -#define kdf4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \ -} +#define kdf4(k, i) \ + { \ + ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \ + k[v(40, (4 * (i)) + 4)] = ff(ss[0]); \ + ss[1] ^= ss[0]; \ + k[v(40, (4 * (i)) + 5)] = ff(ss[1]); \ + ss[2] ^= ss[1]; \ + k[v(40, (4 * (i)) + 6)] = ff(ss[2]); \ + ss[3] ^= ss[2]; \ + k[v(40, (4 * (i)) + 7)] = ff(ss[3]); \ + } -#define kd4(k,i) \ -{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \ -} +#define kd4(k, i) \ + { \ + ss[4] = ls_box(ss[3], 3) ^ t_use(r, c)[i]; \ + ss[0] ^= ss[4]; \ + ss[4] = ff(ss[4]); \ + k[v(40, (4 * (i)) + 4)] = ss[4] ^= k[v(40, (4 * (i)))]; \ + ss[1] ^= ss[0]; \ + k[v(40, (4 * (i)) + 5)] = ss[4] ^= k[v(40, (4 * (i)) + 1)]; \ + ss[2] ^= ss[1]; \ + k[v(40, (4 * (i)) + 6)] = ss[4] ^= k[v(40, (4 * (i)) + 2)]; \ + ss[3] ^= ss[2]; \ + k[v(40, (4 * (i)) + 7)] = ss[4] ^= k[v(40, (4 * (i)) + 3)]; \ + } -#define kdl4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \ -} +#define kdl4(k, i) \ + { \ + ss[0] ^= ls_box(ss[3], 3) ^ t_use(r, c)[i]; \ + k[v(40, (4 * (i)) + 4)] = ss[0]; \ + ss[1] ^= ss[0]; \ + k[v(40, (4 * (i)) + 5)] = ss[1]; \ + ss[2] ^= ss[1]; \ + k[v(40, (4 * (i)) + 6)] = ss[2]; \ + ss[3] ^= ss[2]; \ + k[v(40, (4 * (i)) + 7)] = ss[3]; \ + } #endif -AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[5]; -#if defined( d_vars ) - d_vars; +AES_RETURN aes_xi(decrypt_key128)(const unsigned char* key, aes_decrypt_ctx cx[1]) { + uint32_t ss[5]; +#if defined(d_vars) + d_vars; #endif - cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); + cx->ks[v(40, (0))] = ss[0] = word_in(key, 0); + cx->ks[v(40, (1))] = ss[1] = word_in(key, 1); + cx->ks[v(40, (2))] = ss[2] = word_in(key, 2); + cx->ks[v(40, (3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL - kdf4(cx->ks, 0); kd4(cx->ks, 1); - kd4(cx->ks, 2); kd4(cx->ks, 3); - kd4(cx->ks, 4); kd4(cx->ks, 5); - kd4(cx->ks, 6); kd4(cx->ks, 7); - kd4(cx->ks, 8); kdl4(cx->ks, 9); + kdf4(cx->ks, 0); + kd4(cx->ks, 1); + kd4(cx->ks, 2); + kd4(cx->ks, 3); + kd4(cx->ks, 4); + kd4(cx->ks, 5); + kd4(cx->ks, 6); + kd4(cx->ks, 7); + kd4(cx->ks, 8); + kdl4(cx->ks, 9); #else - { uint32_t i; - for(i = 0; i < 10; ++i) - k4e(cx->ks, i); + { + uint32_t i; + for(i = 0; i < 10; ++i) k4e(cx->ks, i); #if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 10 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); + for(i = N_COLS; i < 10 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif @@ -332,86 +373,110 @@ AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1 cx->inf.b[0] = 10 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } #endif -#if defined(AES_192) || defined( AES_VAR ) +#if defined(AES_192) || defined(AES_VAR) -#define k6ef(k,i) \ -{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \ - k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \ - k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \ -} +#define k6ef(k, i) \ + { \ + k[v(48, (6 * (i)) + 6)] = ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \ + k[v(48, (6 * (i)) + 7)] = ss[1] ^= ss[0]; \ + k[v(48, (6 * (i)) + 8)] = ss[2] ^= ss[1]; \ + k[v(48, (6 * (i)) + 9)] = ss[3] ^= ss[2]; \ + } -#define k6e(k,i) \ -{ k6ef(k,i); \ - k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \ - k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \ -} +#define k6e(k, i) \ + { \ + k6ef(k, i); \ + k[v(48, (6 * (i)) + 10)] = ss[4] ^= ss[3]; \ + k[v(48, (6 * (i)) + 11)] = ss[5] ^= ss[4]; \ + } -#define kdf6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \ - ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \ - ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \ -} +#define kdf6(k, i) \ + { \ + ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \ + k[v(48, (6 * (i)) + 6)] = ff(ss[0]); \ + ss[1] ^= ss[0]; \ + k[v(48, (6 * (i)) + 7)] = ff(ss[1]); \ + ss[2] ^= ss[1]; \ + k[v(48, (6 * (i)) + 8)] = ff(ss[2]); \ + ss[3] ^= ss[2]; \ + k[v(48, (6 * (i)) + 9)] = ff(ss[3]); \ + ss[4] ^= ss[3]; \ + k[v(48, (6 * (i)) + 10)] = ff(ss[4]); \ + ss[5] ^= ss[4]; \ + k[v(48, (6 * (i)) + 11)] = ff(ss[5]); \ + } -#define kd6(k,i) \ -{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \ - ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \ - ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \ -} +#define kd6(k, i) \ + { \ + ss[6] = ls_box(ss[5], 3) ^ t_use(r, c)[i]; \ + ss[0] ^= ss[6]; \ + ss[6] = ff(ss[6]); \ + k[v(48, (6 * (i)) + 6)] = ss[6] ^= k[v(48, (6 * (i)))]; \ + ss[1] ^= ss[0]; \ + k[v(48, (6 * (i)) + 7)] = ss[6] ^= k[v(48, (6 * (i)) + 1)]; \ + ss[2] ^= ss[1]; \ + k[v(48, (6 * (i)) + 8)] = ss[6] ^= k[v(48, (6 * (i)) + 2)]; \ + ss[3] ^= ss[2]; \ + k[v(48, (6 * (i)) + 9)] = ss[6] ^= k[v(48, (6 * (i)) + 3)]; \ + ss[4] ^= ss[3]; \ + k[v(48, (6 * (i)) + 10)] = ss[6] ^= k[v(48, (6 * (i)) + 4)]; \ + ss[5] ^= ss[4]; \ + k[v(48, (6 * (i)) + 11)] = ss[6] ^= k[v(48, (6 * (i)) + 5)]; \ + } -#define kdl6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \ -} +#define kdl6(k, i) \ + { \ + ss[0] ^= ls_box(ss[5], 3) ^ t_use(r, c)[i]; \ + k[v(48, (6 * (i)) + 6)] = ss[0]; \ + ss[1] ^= ss[0]; \ + k[v(48, (6 * (i)) + 7)] = ss[1]; \ + ss[2] ^= ss[1]; \ + k[v(48, (6 * (i)) + 8)] = ss[2]; \ + ss[3] ^= ss[2]; \ + k[v(48, (6 * (i)) + 9)] = ss[3]; \ + } -AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[7]; -#if defined( d_vars ) - d_vars; +AES_RETURN aes_xi(decrypt_key192)(const unsigned char* key, aes_decrypt_ctx cx[1]) { + uint32_t ss[7]; +#if defined(d_vars) + d_vars; #endif - cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); + cx->ks[v(48, (0))] = ss[0] = word_in(key, 0); + cx->ks[v(48, (1))] = ss[1] = word_in(key, 1); + cx->ks[v(48, (2))] = ss[2] = word_in(key, 2); + cx->ks[v(48, (3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL ss[4] = word_in(key, 4); ss[5] = word_in(key, 5); - cx->ks[v(48,(4))] = ff(ss[4]); - cx->ks[v(48,(5))] = ff(ss[5]); - kdf6(cx->ks, 0); kd6(cx->ks, 1); - kd6(cx->ks, 2); kd6(cx->ks, 3); - kd6(cx->ks, 4); kd6(cx->ks, 5); - kd6(cx->ks, 6); kdl6(cx->ks, 7); + cx->ks[v(48, (4))] = ff(ss[4]); + cx->ks[v(48, (5))] = ff(ss[5]); + kdf6(cx->ks, 0); + kd6(cx->ks, 1); + kd6(cx->ks, 2); + kd6(cx->ks, 3); + kd6(cx->ks, 4); + kd6(cx->ks, 5); + kd6(cx->ks, 6); + kdl6(cx->ks, 7); #else - cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); - cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); - { uint32_t i; + cx->ks[v(48, (4))] = ss[4] = word_in(key, 4); + cx->ks[v(48, (5))] = ss[5] = word_in(key, 5); + { + uint32_t i; - for(i = 0; i < 7; ++i) - k6e(cx->ks, i); + for(i = 0; i < 7; ++i) k6e(cx->ks, i); k6ef(cx->ks, 7); #if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 12 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); + for(i = N_COLS; i < 12 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif @@ -419,99 +484,127 @@ AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1 cx->inf.b[0] = 12 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } #endif -#if defined(AES_256) || defined( AES_VAR ) +#if defined(AES_256) || defined(AES_VAR) -#define k8ef(k,i) \ -{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \ - k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \ - k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \ -} +#define k8ef(k, i) \ + { \ + k[v(56, (8 * (i)) + 8)] = ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \ + k[v(56, (8 * (i)) + 9)] = ss[1] ^= ss[0]; \ + k[v(56, (8 * (i)) + 10)] = ss[2] ^= ss[1]; \ + k[v(56, (8 * (i)) + 11)] = ss[3] ^= ss[2]; \ + } -#define k8e(k,i) \ -{ k8ef(k,i); \ - k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \ - k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \ - k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \ - k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \ -} +#define k8e(k, i) \ + { \ + k8ef(k, i); \ + k[v(56, (8 * (i)) + 12)] = ss[4] ^= ls_box(ss[3], 0); \ + k[v(56, (8 * (i)) + 13)] = ss[5] ^= ss[4]; \ + k[v(56, (8 * (i)) + 14)] = ss[6] ^= ss[5]; \ + k[v(56, (8 * (i)) + 15)] = ss[7] ^= ss[6]; \ + } -#define kdf8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \ - ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \ - ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \ - ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \ - ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \ -} +#define kdf8(k, i) \ + { \ + ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \ + k[v(56, (8 * (i)) + 8)] = ff(ss[0]); \ + ss[1] ^= ss[0]; \ + k[v(56, (8 * (i)) + 9)] = ff(ss[1]); \ + ss[2] ^= ss[1]; \ + k[v(56, (8 * (i)) + 10)] = ff(ss[2]); \ + ss[3] ^= ss[2]; \ + k[v(56, (8 * (i)) + 11)] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3], 0); \ + k[v(56, (8 * (i)) + 12)] = ff(ss[4]); \ + ss[5] ^= ss[4]; \ + k[v(56, (8 * (i)) + 13)] = ff(ss[5]); \ + ss[6] ^= ss[5]; \ + k[v(56, (8 * (i)) + 14)] = ff(ss[6]); \ + ss[7] ^= ss[6]; \ + k[v(56, (8 * (i)) + 15)] = ff(ss[7]); \ + } -#define kd8(k,i) \ -{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \ - ss[8] = ls_box(ss[3],0); \ - ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \ - ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \ - ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \ - ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \ -} +#define kd8(k, i) \ + { \ + ss[8] = ls_box(ss[7], 3) ^ t_use(r, c)[i]; \ + ss[0] ^= ss[8]; \ + ss[8] = ff(ss[8]); \ + k[v(56, (8 * (i)) + 8)] = ss[8] ^= k[v(56, (8 * (i)))]; \ + ss[1] ^= ss[0]; \ + k[v(56, (8 * (i)) + 9)] = ss[8] ^= k[v(56, (8 * (i)) + 1)]; \ + ss[2] ^= ss[1]; \ + k[v(56, (8 * (i)) + 10)] = ss[8] ^= k[v(56, (8 * (i)) + 2)]; \ + ss[3] ^= ss[2]; \ + k[v(56, (8 * (i)) + 11)] = ss[8] ^= k[v(56, (8 * (i)) + 3)]; \ + ss[8] = ls_box(ss[3], 0); \ + ss[4] ^= ss[8]; \ + ss[8] = ff(ss[8]); \ + k[v(56, (8 * (i)) + 12)] = ss[8] ^= k[v(56, (8 * (i)) + 4)]; \ + ss[5] ^= ss[4]; \ + k[v(56, (8 * (i)) + 13)] = ss[8] ^= k[v(56, (8 * (i)) + 5)]; \ + ss[6] ^= ss[5]; \ + k[v(56, (8 * (i)) + 14)] = ss[8] ^= k[v(56, (8 * (i)) + 6)]; \ + ss[7] ^= ss[6]; \ + k[v(56, (8 * (i)) + 15)] = ss[8] ^= k[v(56, (8 * (i)) + 7)]; \ + } -#define kdl8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \ -} +#define kdl8(k, i) \ + { \ + ss[0] ^= ls_box(ss[7], 3) ^ t_use(r, c)[i]; \ + k[v(56, (8 * (i)) + 8)] = ss[0]; \ + ss[1] ^= ss[0]; \ + k[v(56, (8 * (i)) + 9)] = ss[1]; \ + ss[2] ^= ss[1]; \ + k[v(56, (8 * (i)) + 10)] = ss[2]; \ + ss[3] ^= ss[2]; \ + k[v(56, (8 * (i)) + 11)] = ss[3]; \ + } -AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[9]; -#if defined( d_vars ) - d_vars; +AES_RETURN aes_xi(decrypt_key256)(const unsigned char* key, aes_decrypt_ctx cx[1]) { + uint32_t ss[9]; +#if defined(d_vars) + d_vars; #endif - cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); + cx->ks[v(56, (0))] = ss[0] = word_in(key, 0); + cx->ks[v(56, (1))] = ss[1] = word_in(key, 1); + cx->ks[v(56, (2))] = ss[2] = word_in(key, 2); + cx->ks[v(56, (3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL ss[4] = word_in(key, 4); ss[5] = word_in(key, 5); ss[6] = word_in(key, 6); ss[7] = word_in(key, 7); - cx->ks[v(56,(4))] = ff(ss[4]); - cx->ks[v(56,(5))] = ff(ss[5]); - cx->ks[v(56,(6))] = ff(ss[6]); - cx->ks[v(56,(7))] = ff(ss[7]); - kdf8(cx->ks, 0); kd8(cx->ks, 1); - kd8(cx->ks, 2); kd8(cx->ks, 3); - kd8(cx->ks, 4); kd8(cx->ks, 5); + cx->ks[v(56, (4))] = ff(ss[4]); + cx->ks[v(56, (5))] = ff(ss[5]); + cx->ks[v(56, (6))] = ff(ss[6]); + cx->ks[v(56, (7))] = ff(ss[7]); + kdf8(cx->ks, 0); + kd8(cx->ks, 1); + kd8(cx->ks, 2); + kd8(cx->ks, 3); + kd8(cx->ks, 4); + kd8(cx->ks, 5); kdl8(cx->ks, 6); #else - cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); - cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); - cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); - cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); - { uint32_t i; - - for(i = 0; i < 6; ++i) - k8e(cx->ks, i); - k8ef(cx->ks, 6); + cx->ks[v(56, (4))] = ss[4] = word_in(key, 4); + cx->ks[v(56, (5))] = ss[5] = word_in(key, 5); + cx->ks[v(56, (6))] = ss[6] = word_in(key, 6); + cx->ks[v(56, (7))] = ss[7] = word_in(key, 7); + { + uint32_t i; + + for(i = 0; i < 6; ++i) k8e(cx->ks, i); + k8ef(cx->ks, 6); #if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 14 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); + for(i = N_COLS; i < 14 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif @@ -519,8 +612,7 @@ AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1 cx->inf.b[0] = 14 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; + if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif return EXIT_SUCCESS; } @@ -529,28 +621,38 @@ AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1 #endif -#if defined( AES_VAR ) +#if defined(AES_VAR) -AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) -{ - switch(key_len) - { - case 16: case 128: return aes_encrypt_key128(key, cx); - case 24: case 192: return aes_encrypt_key192(key, cx); - case 32: case 256: return aes_encrypt_key256(key, cx); - default: return EXIT_FAILURE; - } +AES_RETURN aes_encrypt_key(const unsigned char* key, int key_len, aes_encrypt_ctx cx[1]) { + switch(key_len) { + case 16: + case 128: + return aes_encrypt_key128(key, cx); + case 24: + case 192: + return aes_encrypt_key192(key, cx); + case 32: + case 256: + return aes_encrypt_key256(key, cx); + default: + return EXIT_FAILURE; + } } -AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) -{ - switch(key_len) - { - case 16: case 128: return aes_decrypt_key128(key, cx); - case 24: case 192: return aes_decrypt_key192(key, cx); - case 32: case 256: return aes_decrypt_key256(key, cx); - default: return EXIT_FAILURE; - } +AES_RETURN aes_decrypt_key(const unsigned char* key, int key_len, aes_decrypt_ctx cx[1]) { + switch(key_len) { + case 16: + case 128: + return aes_decrypt_key128(key, cx); + case 24: + case 192: + return aes_decrypt_key192(key, cx); + case 32: + case 256: + return aes_decrypt_key256(key, cx); + default: + return EXIT_FAILURE; + } } #endif diff --git a/crypto/aes/aesopt.h b/crypto/aes/aesopt.h index 550e6f469fe..6d4de004fd2 100644 --- a/crypto/aes/aesopt.h +++ b/crypto/aes/aesopt.h @@ -84,10 +84,10 @@ Issue Date: 20/12/2007 AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const */ -#if !defined( _AESOPT_H ) +#if !defined(_AESOPT_H) #define _AESOPT_H -#if defined( __cplusplus ) +#if defined(__cplusplus) #include "aescpp.h" #else #include "aes.h" @@ -108,17 +108,17 @@ Issue Date: 20/12/2007 #if clauses. The following local defines should not be changed. */ -#define ENCRYPTION_IN_C 1 -#define DECRYPTION_IN_C 2 -#define ENC_KEYING_IN_C 4 -#define DEC_KEYING_IN_C 8 +#define ENCRYPTION_IN_C 1 +#define DECRYPTION_IN_C 2 +#define ENC_KEYING_IN_C 4 +#define DEC_KEYING_IN_C 8 -#define NO_TABLES 0 -#define ONE_TABLE 1 -#define FOUR_TABLES 4 -#define NONE 0 -#define PARTIAL 1 -#define FULL 2 +#define NO_TABLES 0 +#define ONE_TABLE 1 +#define FOUR_TABLES 4 +#define NONE 0 +#define PARTIAL 1 +#define FULL 2 /* --- START OF USER CONFIGURED OPTIONS --- */ @@ -154,32 +154,31 @@ Issue Date: 20/12/2007 */ #if 1 -# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER #elif 0 -# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN +#define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN #elif 0 -# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN +#define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN #else -# error The algorithm byte order is not defined +#error The algorithm byte order is not defined #endif /* 2. Intel AES AND VIA ACE SUPPORT */ -#if defined( __GNUC__ ) && defined( __i386__ ) && !defined(__BEOS__) \ - || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ - || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -# define VIA_ACE_POSSIBLE +#if defined(__GNUC__) && defined(__i386__) && !defined(__BEOS__) || \ + defined(_WIN32) && defined(_M_IX86) && \ + !(defined(_WIN64) || defined(_WIN32_WCE) || defined(_MSC_VER) && (_MSC_VER <= 800)) +#define VIA_ACE_POSSIBLE #endif /* AESNI is supported by all Windows x64 compilers, but for Linux/GCC we have to test for SSE 2, SSE 3, and AES to before enabling it; */ -#if !defined( INTEL_AES_POSSIBLE ) -# if defined( _WIN64 ) && defined( _MSC_VER ) \ - || defined( __GNUC__ ) && defined( __x86_64__ ) && \ - defined( __SSE2__ ) && defined( __SSE3__ ) && \ - defined( __AES__ ) -# define INTEL_AES_POSSIBLE -# endif +#if !defined(INTEL_AES_POSSIBLE) +#if defined(_WIN64) && defined(_MSC_VER) || defined(__GNUC__) && defined(__x86_64__) && \ + defined(__SSE2__) && defined(__SSE3__) && \ + defined(__AES__) +#define INTEL_AES_POSSIBLE +#endif #endif /* Define this option if support for the Intel AESNI is required @@ -196,8 +195,8 @@ Issue Date: 20/12/2007 code files must match that here if they are used). */ -#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) -# define USE_INTEL_AES_IF_PRESENT +#if 0 && defined(INTEL_AES_POSSIBLE) && !defined(USE_INTEL_AES_IF_PRESENT) +#define USE_INTEL_AES_IF_PRESENT #endif /* Define this option if support for the VIA ACE is required. This uses @@ -217,13 +216,13 @@ Issue Date: 20/12/2007 AES_REV_DKS must be set for assembler code used with a VIA ACE build */ -#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT ) -# define USE_VIA_ACE_IF_PRESENT +#if 0 && defined(VIA_ACE_POSSIBLE) && !defined(USE_VIA_ACE_IF_PRESENT) +#define USE_VIA_ACE_IF_PRESENT #endif -#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT ) -# define ASSUME_VIA_ACE_PRESENT -# endif +#if 0 && defined(VIA_ACE_POSSIBLE) && !defined(ASSUME_VIA_ACE_PRESENT) +#define ASSUME_VIA_ACE_PRESENT +#endif /* 3. ASSEMBLER SUPPORT @@ -244,25 +243,25 @@ Issue Date: 20/12/2007 as a compilation option. */ -#if 0 && !defined( ASM_X86_V1C ) -# define ASM_X86_V1C -#elif 0 && !defined( ASM_X86_V2 ) -# define ASM_X86_V2 -#elif 0 && !defined( ASM_X86_V2C ) -# define ASM_X86_V2C -#elif 0 && !defined( ASM_AMD64_C ) -# define ASM_AMD64_C +#if 0 && !defined(ASM_X86_V1C) +#define ASM_X86_V1C +#elif 0 && !defined(ASM_X86_V2) +#define ASM_X86_V2 +#elif 0 && !defined(ASM_X86_V2C) +#define ASM_X86_V2C +#elif 0 && !defined(ASM_AMD64_C) +#define ASM_AMD64_C #endif -#if defined( __i386 ) || defined( _M_IX86 ) -# define A32_ -#elif defined( __x86_64__ ) || defined( _M_X64 ) -# define A64_ +#if defined(__i386) || defined(_M_IX86) +#define A32_ +#elif defined(__x86_64__) || defined(_M_X64) +#define A64_ #endif -#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ - && !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ ) -# error Assembler code is only available for x86 and AMD64 systems +#if(defined(ASM_X86_V1C) || defined(ASM_X86_V2) || defined(ASM_X86_V2C)) && !defined(A32_) || \ + defined(ASM_AMD64_C) && !defined(A64_) +#error Assembler code is only available for x86 and AMD64 systems #endif /* 4. FAST INPUT/OUTPUT OPERATIONS. @@ -281,8 +280,8 @@ Issue Date: 20/12/2007 assumed that access to byte arrays as if they are arrays of 32-bit words will not cause problems when such accesses are misaligned. */ -#if 1 && !defined( _MSC_VER ) -# define SAFE_IO +#if 1 && !defined(_MSC_VER) +#define SAFE_IO #endif /* 5. LOOP UNROLLING @@ -297,27 +296,27 @@ Issue Date: 20/12/2007 to be set independently for encryption and decryption */ #if 1 -# define ENC_UNROLL FULL +#define ENC_UNROLL FULL #elif 0 -# define ENC_UNROLL PARTIAL +#define ENC_UNROLL PARTIAL #else -# define ENC_UNROLL NONE +#define ENC_UNROLL NONE #endif #if 1 -# define DEC_UNROLL FULL +#define DEC_UNROLL FULL #elif 0 -# define DEC_UNROLL PARTIAL +#define DEC_UNROLL PARTIAL #else -# define DEC_UNROLL NONE +#define DEC_UNROLL NONE #endif #if 1 -# define ENC_KS_UNROLL +#define ENC_KS_UNROLL #endif #if 1 -# define DEC_KS_UNROLL +#define DEC_KS_UNROLL #endif /* 6. FAST FINITE FIELD OPERATIONS @@ -326,7 +325,7 @@ Issue Date: 20/12/2007 field arithmetic (this has no effect if STATIC_TABLES is defined). */ #if 1 -# define FF_TABLES +#define FF_TABLES #endif /* 7. INTERNAL STATE VARIABLE FORMAT @@ -337,7 +336,7 @@ Issue Date: 20/12/2007 varaibles in arrays. Otherwise individual local variables will be used. */ #if 1 -# define ARRAYS +#define ARRAYS #endif /* 8. FIXED OR DYNAMIC TABLES @@ -346,8 +345,8 @@ Issue Date: 20/12/2007 statically into the binary file. Otherwise the subroutine aes_init() must be called to compute them before the code is first used. */ -#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -# define STATIC_TABLES +#if 1 && !(defined(_MSC_VER) && (_MSC_VER <= 800)) +#define STATIC_TABLES #endif /* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES @@ -356,9 +355,9 @@ Issue Date: 20/12/2007 rather than using a cast. This option allows this choice. */ #if 0 -# define to_byte(x) ((uint8_t)(x)) +#define to_byte(x) ((uint8_t)(x)) #else -# define to_byte(x) ((x) & 0xff) +#define to_byte(x) ((x)&0xff) #endif /* 10. TABLE ALIGNMENT @@ -370,8 +369,8 @@ Issue Date: 20/12/2007 it seems to sometimes cause trouble for the VC++ version 6 compiler. */ -#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) -# define TABLE_ALIGN 32 +#if 1 && defined(_MSC_VER) && (_MSC_VER >= 1300) +#define TABLE_ALIGN 32 #endif /* 11. REDUCE CODE AND TABLE SIZE @@ -380,8 +379,8 @@ Issue Date: 20/12/2007 AES_ASM_V2C are defined */ -#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) -# define REDUCE_CODE_SIZE +#if 1 && (defined(ASM_X86_V2) || defined(ASM_X86_V2C)) +#define REDUCE_CODE_SIZE #endif /* 12. TABLE OPTIONS @@ -404,36 +403,36 @@ Issue Date: 20/12/2007 of tables used by this implementation. */ -#if 1 /* set tables for the normal encryption round */ -# define ENC_ROUND FOUR_TABLES +#if 1 /* set tables for the normal encryption round */ +#define ENC_ROUND FOUR_TABLES #elif 0 -# define ENC_ROUND ONE_TABLE +#define ENC_ROUND ONE_TABLE #else -# define ENC_ROUND NO_TABLES +#define ENC_ROUND NO_TABLES #endif -#if 1 /* set tables for the last encryption round */ -# define LAST_ENC_ROUND FOUR_TABLES +#if 1 /* set tables for the last encryption round */ +#define LAST_ENC_ROUND FOUR_TABLES #elif 0 -# define LAST_ENC_ROUND ONE_TABLE +#define LAST_ENC_ROUND ONE_TABLE #else -# define LAST_ENC_ROUND NO_TABLES +#define LAST_ENC_ROUND NO_TABLES #endif -#if 1 /* set tables for the normal decryption round */ -# define DEC_ROUND FOUR_TABLES +#if 1 /* set tables for the normal decryption round */ +#define DEC_ROUND FOUR_TABLES #elif 0 -# define DEC_ROUND ONE_TABLE +#define DEC_ROUND ONE_TABLE #else -# define DEC_ROUND NO_TABLES +#define DEC_ROUND NO_TABLES #endif -#if 1 /* set tables for the last decryption round */ -# define LAST_DEC_ROUND FOUR_TABLES +#if 1 /* set tables for the last decryption round */ +#define LAST_DEC_ROUND FOUR_TABLES #elif 0 -# define LAST_DEC_ROUND ONE_TABLE +#define LAST_DEC_ROUND ONE_TABLE #else -# define LAST_DEC_ROUND NO_TABLES +#define LAST_DEC_ROUND NO_TABLES #endif /* The decryption key schedule can be speeded up with tables in the same @@ -441,46 +440,46 @@ Issue Date: 20/12/2007 defines to set this requirement. */ #if 1 -# define KEY_SCHED FOUR_TABLES +#define KEY_SCHED FOUR_TABLES #elif 0 -# define KEY_SCHED ONE_TABLE +#define KEY_SCHED ONE_TABLE #else -# define KEY_SCHED NO_TABLES +#define KEY_SCHED NO_TABLES #endif /* ---- END OF USER CONFIGURED OPTIONS ---- */ /* VIA ACE support is only available for VC++ and GCC */ -#if !defined( _MSC_VER ) && !defined( __GNUC__ ) -# if defined( ASSUME_VIA_ACE_PRESENT ) -# undef ASSUME_VIA_ACE_PRESENT -# endif -# if defined( USE_VIA_ACE_IF_PRESENT ) -# undef USE_VIA_ACE_IF_PRESENT -# endif +#if !defined(_MSC_VER) && !defined(__GNUC__) +#if defined(ASSUME_VIA_ACE_PRESENT) +#undef ASSUME_VIA_ACE_PRESENT +#endif +#if defined(USE_VIA_ACE_IF_PRESENT) +#undef USE_VIA_ACE_IF_PRESENT +#endif #endif -#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) -# define USE_VIA_ACE_IF_PRESENT +#if defined(ASSUME_VIA_ACE_PRESENT) && !defined(USE_VIA_ACE_IF_PRESENT) +#define USE_VIA_ACE_IF_PRESENT #endif /* define to reverse decryption key schedule */ -#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS ) -# define AES_REV_DKS +#if 1 || defined(USE_VIA_ACE_IF_PRESENT) && !defined(AES_REV_DKS) +#define AES_REV_DKS #endif /* Intel AESNI uses a decryption key schedule in the encryption order */ -#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS ) -# undef AES_REV_DKS +#if defined(USE_INTEL_AES_IF_PRESENT) && defined(AES_REV_DKS) +#undef AES_REV_DKS #endif /* Assembler support requires the use of platform byte order */ -#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \ - && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) -# undef ALGORITHM_BYTE_ORDER -# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#if(defined(ASM_X86_V1C) || defined(ASM_X86_V2C) || defined(ASM_AMD64_C)) && \ + (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) +#undef ALGORITHM_BYTE_ORDER +#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER #endif /* In this implementation the columns of the state array are each held in @@ -494,10 +493,10 @@ Issue Date: 20/12/2007 register names. */ -#if defined( ARRAYS ) -# define s(x,c) x[c] +#if defined(ARRAYS) +#define s(x, c) x[c] #else -# define s(x,c) x##c +#define s(x, c) x##c #endif /* This implementation provides subroutines for encryption, decryption @@ -506,69 +505,69 @@ Issue Date: 20/12/2007 up here to determine which will be implemented in C */ -#if !defined( AES_ENCRYPT ) -# define EFUNCS_IN_C 0 -#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ - || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) -# define EFUNCS_IN_C ENC_KEYING_IN_C -#elif !defined( ASM_X86_V2 ) -# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C ) +#if !defined(AES_ENCRYPT) +#define EFUNCS_IN_C 0 +#elif defined(ASSUME_VIA_ACE_PRESENT) || defined(ASM_X86_V1C) || defined(ASM_X86_V2C) || \ + defined(ASM_AMD64_C) +#define EFUNCS_IN_C ENC_KEYING_IN_C +#elif !defined(ASM_X86_V2) +#define EFUNCS_IN_C (ENCRYPTION_IN_C | ENC_KEYING_IN_C) #else -# define EFUNCS_IN_C 0 +#define EFUNCS_IN_C 0 #endif -#if !defined( AES_DECRYPT ) -# define DFUNCS_IN_C 0 -#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ - || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) -# define DFUNCS_IN_C DEC_KEYING_IN_C -#elif !defined( ASM_X86_V2 ) -# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C ) +#if !defined(AES_DECRYPT) +#define DFUNCS_IN_C 0 +#elif defined(ASSUME_VIA_ACE_PRESENT) || defined(ASM_X86_V1C) || defined(ASM_X86_V2C) || \ + defined(ASM_AMD64_C) +#define DFUNCS_IN_C DEC_KEYING_IN_C +#elif !defined(ASM_X86_V2) +#define DFUNCS_IN_C (DECRYPTION_IN_C | DEC_KEYING_IN_C) #else -# define DFUNCS_IN_C 0 +#define DFUNCS_IN_C 0 #endif -#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C ) +#define FUNCS_IN_C (EFUNCS_IN_C | DFUNCS_IN_C) /* END OF CONFIGURATION OPTIONS */ -#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) +#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) /* Disable or report errors on some combinations of options */ #if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES -# undef LAST_ENC_ROUND -# define LAST_ENC_ROUND NO_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND NO_TABLES #elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES -# undef LAST_ENC_ROUND -# define LAST_ENC_ROUND ONE_TABLE +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND ONE_TABLE #endif #if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE -# undef ENC_UNROLL -# define ENC_UNROLL NONE +#undef ENC_UNROLL +#define ENC_UNROLL NONE #endif #if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES -# undef LAST_DEC_ROUND -# define LAST_DEC_ROUND NO_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND NO_TABLES #elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES -# undef LAST_DEC_ROUND -# define LAST_DEC_ROUND ONE_TABLE +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND ONE_TABLE #endif #if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE -# undef DEC_UNROLL -# define DEC_UNROLL NONE +#undef DEC_UNROLL +#define DEC_UNROLL NONE #endif -#if defined( bswap32 ) -# define aes_sw32 bswap32 -#elif defined( bswap_32 ) -# define aes_sw32 bswap_32 +#if defined(bswap32) +#define aes_sw32 bswap32 +#elif defined(bswap_32) +#define aes_sw32 bswap_32 #else -# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n))) -# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00)) +#define brot(x, n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n))) +#define aes_sw32(x) ((brot((x), 8) & 0x00ff00ff) | (brot((x), 24) & 0xff00ff00)) #endif /* upr(x,n): rotates bytes within words by n positions, moving bytes to @@ -582,45 +581,54 @@ Issue Date: 20/12/2007 time constants */ -#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN ) -# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n)))) -# define ups(x,n) ((uint32_t) (x) << (8 * (n))) -# define bval(x,n) to_byte((x) >> (8 * (n))) -# define bytes2word(b0, b1, b2, b3) \ - (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) -#endif - -#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN ) -# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n)))) -# define ups(x,n) ((uint32_t) (x) >> (8 * (n))) -# define bval(x,n) to_byte((x) >> (24 - 8 * (n))) -# define bytes2word(b0, b1, b2, b3) \ - (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3)) -#endif - -#if defined( SAFE_IO ) -# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \ - ((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3]) -# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \ - ((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); } -#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER ) -# define word_in(x,c) (*((uint32_t*)(x)+(c))) -# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v)) +#if(ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define upr(x, n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n)))) +#define ups(x, n) ((uint32_t)(x) << (8 * (n))) +#define bval(x, n) to_byte((x) >> (8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) +#endif + +#if(ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN) +#define upr(x, n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n)))) +#define ups(x, n) ((uint32_t)(x) >> (8 * (n))) +#define bval(x, n) to_byte((x) >> (24 - 8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3)) +#endif + +#if defined(SAFE_IO) +#define word_in(x, c) \ + bytes2word( \ + ((const uint8_t*)(x) + 4 * c)[0], \ + ((const uint8_t*)(x) + 4 * c)[1], \ + ((const uint8_t*)(x) + 4 * c)[2], \ + ((const uint8_t*)(x) + 4 * c)[3]) +#define word_out(x, c, v) \ + { \ + ((uint8_t*)(x) + 4 * c)[0] = bval(v, 0); \ + ((uint8_t*)(x) + 4 * c)[1] = bval(v, 1); \ + ((uint8_t*)(x) + 4 * c)[2] = bval(v, 2); \ + ((uint8_t*)(x) + 4 * c)[3] = bval(v, 3); \ + } +#elif(ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER) +#define word_in(x, c) (*((uint32_t*)(x) + (c))) +#define word_out(x, c, v) (*((uint32_t*)(x) + (c)) = (v)) #else -# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c))) -# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v)) +#define word_in(x, c) aes_sw32(*((uint32_t*)(x) + (c))) +#define word_out(x, c, v) (*((uint32_t*)(x) + (c)) = aes_sw32(v)) #endif /* the finite field modular polynomial and elements */ -#define WPOLY 0x011b -#define BPOLY 0x1b +#define WPOLY 0x011b +#define BPOLY 0x1b /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ -#define gf_c1 0x80808080 -#define gf_c2 0x7f7f7f7f -#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY)) +#define gf_c1 0x80808080 +#define gf_c2 0x7f7f7f7f +#define gf_mulx(x) ((((x)&gf_c2) << 1) ^ ((((x)&gf_c1) >> 7) * BPOLY)) /* The following defines provide alternative definitions of gf_mulx that might give improved performance if a fast 32-bit multiply is not available. Note @@ -633,152 +641,153 @@ Issue Date: 20/12/2007 /* Work out which tables are needed for the different options */ -#if defined( ASM_X86_V1C ) -# if defined( ENC_ROUND ) -# undef ENC_ROUND -# endif -# define ENC_ROUND FOUR_TABLES -# if defined( LAST_ENC_ROUND ) -# undef LAST_ENC_ROUND -# endif -# define LAST_ENC_ROUND FOUR_TABLES -# if defined( DEC_ROUND ) -# undef DEC_ROUND -# endif -# define DEC_ROUND FOUR_TABLES -# if defined( LAST_DEC_ROUND ) -# undef LAST_DEC_ROUND -# endif -# define LAST_DEC_ROUND FOUR_TABLES -# if defined( KEY_SCHED ) -# undef KEY_SCHED -# define KEY_SCHED FOUR_TABLES -# endif -#endif - -#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C ) -# if ENC_ROUND == ONE_TABLE -# define FT1_SET -# elif ENC_ROUND == FOUR_TABLES -# define FT4_SET -# else -# define SBX_SET -# endif -# if LAST_ENC_ROUND == ONE_TABLE -# define FL1_SET -# elif LAST_ENC_ROUND == FOUR_TABLES -# define FL4_SET -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -#endif - -#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C ) -# if DEC_ROUND == ONE_TABLE -# define IT1_SET -# elif DEC_ROUND == FOUR_TABLES -# define IT4_SET -# else -# define ISB_SET -# endif -# if LAST_DEC_ROUND == ONE_TABLE -# define IL1_SET -# elif LAST_DEC_ROUND == FOUR_TABLES -# define IL4_SET -# elif !defined(ISB_SET) -# define ISB_SET -# endif -#endif - -#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) -# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) -# if KEY_SCHED == ONE_TABLE -# if !defined( FL1_SET ) && !defined( FL4_SET ) -# define LS1_SET -# endif -# elif KEY_SCHED == FOUR_TABLES -# if !defined( FL4_SET ) -# define LS4_SET -# endif -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -# endif -# if (FUNCS_IN_C & DEC_KEYING_IN_C) -# if KEY_SCHED == ONE_TABLE -# define IM1_SET -# elif KEY_SCHED == FOUR_TABLES -# define IM4_SET -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -# endif +#if defined(ASM_X86_V1C) +#if defined(ENC_ROUND) +#undef ENC_ROUND +#endif +#define ENC_ROUND FOUR_TABLES +#if defined(LAST_ENC_ROUND) +#undef LAST_ENC_ROUND +#endif +#define LAST_ENC_ROUND FOUR_TABLES +#if defined(DEC_ROUND) +#undef DEC_ROUND +#endif +#define DEC_ROUND FOUR_TABLES +#if defined(LAST_DEC_ROUND) +#undef LAST_DEC_ROUND +#endif +#define LAST_DEC_ROUND FOUR_TABLES +#if defined(KEY_SCHED) +#undef KEY_SCHED +#define KEY_SCHED FOUR_TABLES +#endif +#endif + +#if(FUNCS_IN_C & ENCRYPTION_IN_C) || defined(ASM_X86_V1C) +#if ENC_ROUND == ONE_TABLE +#define FT1_SET +#elif ENC_ROUND == FOUR_TABLES +#define FT4_SET +#else +#define SBX_SET +#endif +#if LAST_ENC_ROUND == ONE_TABLE +#define FL1_SET +#elif LAST_ENC_ROUND == FOUR_TABLES +#define FL4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#if(FUNCS_IN_C & DECRYPTION_IN_C) || defined(ASM_X86_V1C) +#if DEC_ROUND == ONE_TABLE +#define IT1_SET +#elif DEC_ROUND == FOUR_TABLES +#define IT4_SET +#else +#define ISB_SET +#endif +#if LAST_DEC_ROUND == ONE_TABLE +#define IL1_SET +#elif LAST_DEC_ROUND == FOUR_TABLES +#define IL4_SET +#elif !defined(ISB_SET) +#define ISB_SET +#endif +#endif + +#if !(defined(REDUCE_CODE_SIZE) && (defined(ASM_X86_V2) || defined(ASM_X86_V2C))) +#if((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) +#if KEY_SCHED == ONE_TABLE +#if !defined(FL1_SET) && !defined(FL4_SET) +#define LS1_SET +#endif +#elif KEY_SCHED == FOUR_TABLES +#if !defined(FL4_SET) +#define LS4_SET +#endif +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif +#if(FUNCS_IN_C & DEC_KEYING_IN_C) +#if KEY_SCHED == ONE_TABLE +#define IM1_SET +#elif KEY_SCHED == FOUR_TABLES +#define IM4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif #endif /* generic definitions of Rijndael macros that use tables */ -#define no_table(x,box,vf,rf,c) bytes2word( \ - box[bval(vf(x,0,c),rf(0,c))], \ - box[bval(vf(x,1,c),rf(1,c))], \ - box[bval(vf(x,2,c),rf(2,c))], \ - box[bval(vf(x,3,c),rf(3,c))]) +#define no_table(x, box, vf, rf, c) \ + bytes2word( \ + box[bval(vf(x, 0, c), rf(0, c))], \ + box[bval(vf(x, 1, c), rf(1, c))], \ + box[bval(vf(x, 2, c), rf(2, c))], \ + box[bval(vf(x, 3, c), rf(3, c))]) -#define one_table(x,op,tab,vf,rf,c) \ - ( tab[bval(vf(x,0,c),rf(0,c))] \ - ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ - ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ - ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) +#define one_table(x, op, tab, vf, rf, c) \ + (tab[bval(vf(x, 0, c), rf(0, c))] ^ op(tab[bval(vf(x, 1, c), rf(1, c))], 1) ^ \ + op(tab[bval(vf(x, 2, c), rf(2, c))], 2) ^ op(tab[bval(vf(x, 3, c), rf(3, c))], 3)) -#define four_tables(x,tab,vf,rf,c) \ - ( tab[0][bval(vf(x,0,c),rf(0,c))] \ - ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ - ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ - ^ tab[3][bval(vf(x,3,c),rf(3,c))]) +#define four_tables(x, tab, vf, rf, c) \ + (tab[0][bval(vf(x, 0, c), rf(0, c))] ^ tab[1][bval(vf(x, 1, c), rf(1, c))] ^ \ + tab[2][bval(vf(x, 2, c), rf(2, c))] ^ tab[3][bval(vf(x, 3, c), rf(3, c))]) -#define vf1(x,r,c) (x) -#define rf1(r,c) (r) -#define rf2(r,c) ((8+r-c)&3) +#define vf1(x, r, c) (x) +#define rf1(r, c) (r) +#define rf2(r, c) ((8 + r - c) & 3) /* perform forward and inverse column mix operation on four bytes in long word x in */ /* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ -#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) +#if !(defined(REDUCE_CODE_SIZE) && (defined(ASM_X86_V2) || defined(ASM_X86_V2C))) -#if defined( FM4_SET ) /* not currently used */ -# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) -#elif defined( FM1_SET ) /* not currently used */ -# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) +#if defined(FM4_SET) /* not currently used */ +#define fwd_mcol(x) four_tables(x, t_use(f, m), vf1, rf1, 0) +#elif defined(FM1_SET) /* not currently used */ +#define fwd_mcol(x) one_table(x, upr, t_use(f, m), vf1, rf1, 0) #else -# define dec_fmvars uint32_t g2 -# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) +#define dec_fmvars uint32_t g2 +#define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) #endif -#if defined( IM4_SET ) -# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) -#elif defined( IM1_SET ) -# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) +#if defined(IM4_SET) +#define inv_mcol(x) four_tables(x, t_use(i, m), vf1, rf1, 0) +#elif defined(IM1_SET) +#define inv_mcol(x) one_table(x, upr, t_use(i, m), vf1, rf1, 0) #else -# define dec_imvars uint32_t g2, g4, g9 -# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ - (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) -#endif - -#if defined( FL4_SET ) -# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) -#elif defined( LS4_SET ) -# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) -#elif defined( FL1_SET ) -# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) -#elif defined( LS1_SET ) -# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) +#define dec_imvars uint32_t g2, g4, g9 +#define inv_mcol(x) \ + (g2 = gf_mulx(x), \ + g4 = gf_mulx(g2), \ + g9 = (x) ^ gf_mulx(g4), \ + g4 ^= g9, \ + (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) +#endif + +#if defined(FL4_SET) +#define ls_box(x, c) four_tables(x, t_use(f, l), vf1, rf2, c) +#elif defined(LS4_SET) +#define ls_box(x, c) four_tables(x, t_use(l, s), vf1, rf2, c) +#elif defined(FL1_SET) +#define ls_box(x, c) one_table(x, upr, t_use(f, l), vf1, rf2, c) +#elif defined(LS1_SET) +#define ls_box(x, c) one_table(x, upr, t_use(l, s), vf1, rf2, c) #else -# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) +#define ls_box(x, c) no_table(x, t_use(s, box), vf1, rf2, c) #endif #endif -#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) -# define ISB_SET +#if defined(ASM_X86_V1C) && defined(AES_DECRYPT) && !defined(ISB_SET) +#define ISB_SET #endif #endif diff --git a/crypto/aes/aestab.c b/crypto/aes/aestab.c index cc8a24f9fa7..0bfb7808fed 100644 --- a/crypto/aes/aestab.c +++ b/crypto/aes/aestab.c @@ -25,142 +25,138 @@ Issue Date: 20/12/2007 #if defined(STATIC_TABLES) -#define sb_data(w) {\ - w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ - w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ - w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ - w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ - w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ - w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ - w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ - w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ - w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ - w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ - w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ - w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ - w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ - w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ - w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ - w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ - w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ - w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ - w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ - w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ - w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ - w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ - w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ - w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ - w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ - w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ - w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ - w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ - w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ - w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ - w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ - w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } - -#define isb_data(w) {\ - w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ - w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ - w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ - w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ - w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ - w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ - w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ - w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ - w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ - w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ - w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ - w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ - w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ - w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ - w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ - w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ - w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ - w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ - w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ - w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ - w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ - w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ - w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ - w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ - w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ - w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ - w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ - w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ - w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ - w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ - w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ - w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } - -#define mm_data(w) {\ - w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ - w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ - w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ - w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ - w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ - w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ - w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ - w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ - w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ - w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ - w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ - w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ - w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ - w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ - w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ - w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ - w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ - w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ - w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ - w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ - w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ - w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ - w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ - w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ - w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ - w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ - w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ - w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ - w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ - w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ - w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ - w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } - -#define rc_data(w) {\ - w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\ - w(0x1b), w(0x36) } - -#define h0(x) (x) - -#define w0(p) bytes2word(p, 0, 0, 0) -#define w1(p) bytes2word(0, p, 0, 0) -#define w2(p) bytes2word(0, 0, p, 0) -#define w3(p) bytes2word(0, 0, 0, p) - -#define u0(p) bytes2word(f2(p), p, p, f3(p)) -#define u1(p) bytes2word(f3(p), f2(p), p, p) -#define u2(p) bytes2word(p, f3(p), f2(p), p) -#define u3(p) bytes2word(p, p, f3(p), f2(p)) - -#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) -#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) -#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) -#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) +#define sb_data(w) \ + { \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5), w(0x30), w(0x01), \ + w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76), w(0xca), w(0x82), w(0xc9), \ + w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0), w(0xad), w(0xd4), w(0xa2), w(0xaf), \ + w(0x9c), w(0xa4), w(0x72), w(0xc0), w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), \ + w(0x3f), w(0xf7), w(0xcc), w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), \ + w(0x31), w(0x15), w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), \ + w(0x9a), w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75), \ + w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0), w(0x52), \ + w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84), w(0x53), w(0xd1), \ + w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b), w(0x6a), w(0xcb), w(0xbe), \ + w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf), w(0xd0), w(0xef), w(0xaa), w(0xfb), \ + w(0x43), w(0x4d), w(0x33), w(0x85), w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), \ + w(0x3c), w(0x9f), w(0xa8), w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), \ + w(0x38), w(0xf5), w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), \ + w(0xd2), w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17), \ + w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73), w(0x60), \ + w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88), w(0x46), w(0xee), \ + w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb), w(0xe0), w(0x32), w(0x3a), \ + w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c), w(0xc2), w(0xd3), w(0xac), w(0x62), \ + w(0x91), w(0x95), w(0xe4), w(0x79), w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), \ + w(0xd5), w(0x4e), w(0xa9), w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), \ + w(0xae), w(0x08), w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), \ + w(0xc6), w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a), \ + w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e), w(0x61), \ + w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e), w(0xe1), w(0xf8), \ + w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94), w(0x9b), w(0x1e), w(0x87), \ + w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf), w(0x8c), w(0xa1), w(0x89), w(0x0d), \ + w(0xbf), w(0xe6), w(0x42), w(0x68), w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), \ + w(0x54), w(0xbb), w(0x16) \ + } + +#define isb_data(w) \ + { \ + w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38), w(0xbf), w(0x40), \ + w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb), w(0x7c), w(0xe3), w(0x39), \ + w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87), w(0x34), w(0x8e), w(0x43), w(0x44), \ + w(0xc4), w(0xde), w(0xe9), w(0xcb), w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), \ + w(0xc2), w(0x23), w(0x3d), w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), \ + w(0xc3), w(0x4e), w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), \ + w(0xb2), w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25), \ + w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16), w(0xd4), \ + w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92), w(0x6c), w(0x70), \ + w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda), w(0x5e), w(0x15), w(0x46), \ + w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84), w(0x90), w(0xd8), w(0xab), w(0x00), \ + w(0x8c), w(0xbc), w(0xd3), w(0x0a), w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), \ + w(0xb3), w(0x45), w(0x06), w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), \ + w(0x0f), w(0x02), w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), \ + w(0x6b), w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea), \ + w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73), w(0x96), \ + w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85), w(0xe2), w(0xf9), \ + w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e), w(0x47), w(0xf1), w(0x1a), \ + w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89), w(0x6f), w(0xb7), w(0x62), w(0x0e), \ + w(0xaa), w(0x18), w(0xbe), w(0x1b), w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), \ + w(0xd2), w(0x79), w(0x20), w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), \ + w(0x5a), w(0xf4), w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), \ + w(0x31), w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f), \ + w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d), w(0x2d), \ + w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef), w(0xa0), w(0xe0), \ + w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0), w(0xc8), w(0xeb), w(0xbb), \ + w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61), w(0x17), w(0x2b), w(0x04), w(0x7e), \ + w(0xba), w(0x77), w(0xd6), w(0x26), w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), \ + w(0x21), w(0x0c), w(0x7d) \ + } + +#define mm_data(w) \ + { \ + w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07), w(0x08), w(0x09), \ + w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f), w(0x10), w(0x11), w(0x12), \ + w(0x13), w(0x14), w(0x15), w(0x16), w(0x17), w(0x18), w(0x19), w(0x1a), w(0x1b), \ + w(0x1c), w(0x1d), w(0x1e), w(0x1f), w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), \ + w(0x25), w(0x26), w(0x27), w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), \ + w(0x2e), w(0x2f), w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), \ + w(0x37), w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f), \ + w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47), w(0x48), \ + w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f), w(0x50), w(0x51), \ + w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57), w(0x58), w(0x59), w(0x5a), \ + w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f), w(0x60), w(0x61), w(0x62), w(0x63), \ + w(0x64), w(0x65), w(0x66), w(0x67), w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), \ + w(0x6d), w(0x6e), w(0x6f), w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), \ + w(0x76), w(0x77), w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), \ + w(0x7f), w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87), \ + w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f), w(0x90), \ + w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97), w(0x98), w(0x99), \ + w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f), w(0xa0), w(0xa1), w(0xa2), \ + w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7), w(0xa8), w(0xa9), w(0xaa), w(0xab), \ + w(0xac), w(0xad), w(0xae), w(0xaf), w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), \ + w(0xb5), w(0xb6), w(0xb7), w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), \ + w(0xbe), w(0xbf), w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), \ + w(0xc7), w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf), \ + w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7), w(0xd8), \ + w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf), w(0xe0), w(0xe1), \ + w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7), w(0xe8), w(0xe9), w(0xea), \ + w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef), w(0xf0), w(0xf1), w(0xf2), w(0xf3), \ + w(0xf4), w(0xf5), w(0xf6), w(0xf7), w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), \ + w(0xfd), w(0xfe), w(0xff) \ + } + +#define rc_data(w) \ + { w(0x01), w(0x02), w(0x04), w(0x08), w(0x10), w(0x20), w(0x40), w(0x80), w(0x1b), w(0x36) } + +#define h0(x) (x) + +#define w0(p) bytes2word(p, 0, 0, 0) +#define w1(p) bytes2word(0, p, 0, 0) +#define w2(p) bytes2word(0, 0, p, 0) +#define w3(p) bytes2word(0, 0, 0, p) + +#define u0(p) bytes2word(f2(p), p, p, f3(p)) +#define u1(p) bytes2word(f3(p), f2(p), p, p) +#define u2(p) bytes2word(p, f3(p), f2(p), p) +#define u3(p) bytes2word(p, p, f3(p), f2(p)) + +#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) +#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) +#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) +#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) #endif #if defined(STATIC_TABLES) || !defined(FF_TABLES) -#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) -#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) -#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ - ^ (((x>>5) & 4) * WPOLY)) -#define f3(x) (f2(x) ^ x) -#define f9(x) (f8(x) ^ x) -#define fb(x) (f8(x) ^ f2(x) ^ x) -#define fd(x) (f8(x) ^ f4(x) ^ x) -#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) +#define f2(x) ((x << 1) ^ (((x >> 7) & 1) * WPOLY)) +#define f4(x) ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY)) +#define f8(x) \ + ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) ^ (((x >> 5) & 4) * WPOLY)) +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) #else @@ -176,24 +172,22 @@ Issue Date: 20/12/2007 #include "aestab.h" #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif #if defined(STATIC_TABLES) /* implemented in case of wrong call for fixed tables */ -AES_RETURN aes_init(void) -{ +AES_RETURN aes_init(void) { return EXIT_SUCCESS; } -#else /* Generate the tables for the dynamic table option */ +#else /* Generate the tables for the dynamic table option */ #if defined(FF_TABLES) -#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0) +#define gf_inv(x) ((x) ? pow[255 - log[x]] : 0) #else @@ -208,8 +202,8 @@ AES_RETURN aes_init(void) used so that locals within fi can be bytes rather than words */ -static uint8_t hibit(const uint32_t x) -{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); +static uint8_t hibit(const uint32_t x) { + uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); r |= (r >> 2); r |= (r >> 4); @@ -218,28 +212,25 @@ static uint8_t hibit(const uint32_t x) /* return the inverse of the finite field element x */ -static uint8_t gf_inv(const uint8_t x) -{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; +static uint8_t gf_inv(const uint8_t x) { + uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; - if(x < 2) - return x; + if(x < 2) return x; - for( ; ; ) - { + for(;;) { if(n1) - while(n2 >= n1) /* divide polynomial p2 by p1 */ + while(n2 >= n1) /* divide polynomial p2 by p1 */ { - n2 /= n1; /* shift smaller polynomial left */ + n2 /= n1; /* shift smaller polynomial left */ p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ - v2 ^= v1 * n2; /* shift accumulated value and */ - n2 = hibit(p2); /* add into result */ + v2 ^= v1 * n2; /* shift accumulated value and */ + n2 = hibit(p2); /* add into result */ } else return v1; - if(n2) /* repeat with values swapped */ - while(n1 >= n2) - { + if(n2) /* repeat with values swapped */ + while(n1 >= n2) { n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; @@ -253,130 +244,126 @@ static uint8_t gf_inv(const uint8_t x) #endif /* The forward and inverse affine transformations used in the S-box */ -uint8_t fwd_affine(const uint8_t x) -{ uint32_t w = x; +uint8_t fwd_affine(const uint8_t x) { + uint32_t w = x; w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); return 0x63 ^ ((w ^ (w >> 8)) & 0xff); } -uint8_t inv_affine(const uint8_t x) -{ uint32_t w = x; +uint8_t inv_affine(const uint8_t x) { + uint32_t w = x; w = (w << 1) ^ (w << 3) ^ (w << 6); return 0x05 ^ ((w ^ (w >> 8)) & 0xff); } static int init = 0; -AES_RETURN aes_init(void) -{ uint32_t i, w; +AES_RETURN aes_init(void) { + uint32_t i, w; #if defined(FF_TABLES) - uint8_t pow[512] = {0}, log[256] = {0}; + uint8_t pow[512] = {0}, log[256] = {0}; - if(init) - return EXIT_SUCCESS; + if(init) return EXIT_SUCCESS; /* log and power tables for GF(2^8) finite field with WPOLY as modular polynomial - the simplest primitive root is 0x03, used here to generate the tables */ - i = 0; w = 1; - do - { + i = 0; + w = 1; + do { pow[i] = (uint8_t)w; pow[i + 255] = (uint8_t)w; log[w] = (uint8_t)i++; - w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); - } - while (w != 1); + w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); + } while(w != 1); #else - if(init) - return EXIT_SUCCESS; + if(init) return EXIT_SUCCESS; #endif - for(i = 0, w = 1; i < RC_LENGTH; ++i) - { - t_set(r,c)[i] = bytes2word(w, 0, 0, 0); + for(i = 0, w = 1; i < RC_LENGTH; ++i) { + t_set(r, c)[i] = bytes2word(w, 0, 0, 0); w = f2(w); } - for(i = 0; i < 256; ++i) - { uint8_t b; + for(i = 0; i < 256; ++i) { + uint8_t b; b = fwd_affine(gf_inv((uint8_t)i)); w = bytes2word(f2(b), b, b, f3(b)); -#if defined( SBX_SET ) - t_set(s,box)[i] = b; +#if defined(SBX_SET) + t_set(s, box)[i] = b; #endif -#if defined( FT1_SET ) /* tables for a normal encryption round */ - t_set(f,n)[i] = w; +#if defined(FT1_SET) /* tables for a normal encryption round */ + t_set(f, n)[i] = w; #endif -#if defined( FT4_SET ) - t_set(f,n)[0][i] = w; - t_set(f,n)[1][i] = upr(w,1); - t_set(f,n)[2][i] = upr(w,2); - t_set(f,n)[3][i] = upr(w,3); +#if defined(FT4_SET) + t_set(f, n)[0][i] = w; + t_set(f, n)[1][i] = upr(w, 1); + t_set(f, n)[2][i] = upr(w, 2); + t_set(f, n)[3][i] = upr(w, 3); #endif w = bytes2word(b, 0, 0, 0); -#if defined( FL1_SET ) /* tables for last encryption round (may also */ - t_set(f,l)[i] = w; /* be used in the key schedule) */ +#if defined(FL1_SET) /* tables for last encryption round (may also */ + t_set(f, l)[i] = w; /* be used in the key schedule) */ #endif -#if defined( FL4_SET ) - t_set(f,l)[0][i] = w; - t_set(f,l)[1][i] = upr(w,1); - t_set(f,l)[2][i] = upr(w,2); - t_set(f,l)[3][i] = upr(w,3); +#if defined(FL4_SET) + t_set(f, l)[0][i] = w; + t_set(f, l)[1][i] = upr(w, 1); + t_set(f, l)[2][i] = upr(w, 2); + t_set(f, l)[3][i] = upr(w, 3); #endif -#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/ - t_set(l,s)[i] = w; /* not of the required form */ +#if defined(LS1_SET) /* table for key schedule if t_set(f,l) above is*/ + t_set(l, s)[i] = w; /* not of the required form */ #endif -#if defined( LS4_SET ) - t_set(l,s)[0][i] = w; - t_set(l,s)[1][i] = upr(w,1); - t_set(l,s)[2][i] = upr(w,2); - t_set(l,s)[3][i] = upr(w,3); +#if defined(LS4_SET) + t_set(l, s)[0][i] = w; + t_set(l, s)[1][i] = upr(w, 1); + t_set(l, s)[2][i] = upr(w, 2); + t_set(l, s)[3][i] = upr(w, 3); #endif b = gf_inv(inv_affine((uint8_t)i)); w = bytes2word(fe(b), f9(b), fd(b), fb(b)); -#if defined( IM1_SET ) /* tables for the inverse mix column operation */ - t_set(i,m)[b] = w; +#if defined(IM1_SET) /* tables for the inverse mix column operation */ + t_set(i, m)[b] = w; #endif -#if defined( IM4_SET ) - t_set(i,m)[0][b] = w; - t_set(i,m)[1][b] = upr(w,1); - t_set(i,m)[2][b] = upr(w,2); - t_set(i,m)[3][b] = upr(w,3); +#if defined(IM4_SET) + t_set(i, m)[0][b] = w; + t_set(i, m)[1][b] = upr(w, 1); + t_set(i, m)[2][b] = upr(w, 2); + t_set(i, m)[3][b] = upr(w, 3); #endif -#if defined( ISB_SET ) - t_set(i,box)[i] = b; +#if defined(ISB_SET) + t_set(i, box)[i] = b; #endif -#if defined( IT1_SET ) /* tables for a normal decryption round */ - t_set(i,n)[i] = w; +#if defined(IT1_SET) /* tables for a normal decryption round */ + t_set(i, n)[i] = w; #endif -#if defined( IT4_SET ) - t_set(i,n)[0][i] = w; - t_set(i,n)[1][i] = upr(w,1); - t_set(i,n)[2][i] = upr(w,2); - t_set(i,n)[3][i] = upr(w,3); +#if defined(IT4_SET) + t_set(i, n)[0][i] = w; + t_set(i, n)[1][i] = upr(w, 1); + t_set(i, n)[2][i] = upr(w, 2); + t_set(i, n)[3][i] = upr(w, 3); #endif w = bytes2word(b, 0, 0, 0); -#if defined( IL1_SET ) /* tables for last decryption round */ - t_set(i,l)[i] = w; +#if defined(IL1_SET) /* tables for last decryption round */ + t_set(i, l)[i] = w; #endif -#if defined( IL4_SET ) - t_set(i,l)[0][i] = w; - t_set(i,l)[1][i] = upr(w,1); - t_set(i,l)[2][i] = upr(w,2); - t_set(i,l)[3][i] = upr(w,3); +#if defined(IL4_SET) + t_set(i, l)[0][i] = w; + t_set(i, l)[1][i] = upr(w, 1); + t_set(i, l)[2][i] = upr(w, 2); + t_set(i, l)[3][i] = upr(w, 3); #endif } init = 1; @@ -393,20 +380,19 @@ AES_RETURN aes_init(void) #pragma section(".CRT$XCU", read) -__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init; +__declspec(allocate(".CRT$XCU")) void(__cdecl* aes_startup)(void) = aes_init; #elif defined(__GNUC__) static void aes_startup(void) __attribute__((constructor)); -static void aes_startup(void) -{ +static void aes_startup(void) { aes_init(); } #else -#pragma message( "dynamic tables must be initialised manually on your system" ) +#pragma message("dynamic tables must be initialised manually on your system") #endif @@ -415,4 +401,3 @@ static void aes_startup(void) #if defined(__cplusplus) } #endif - diff --git a/crypto/aes/aestab.h b/crypto/aes/aestab.h index 8fe32d1800d..9dfcded1ae2 100644 --- a/crypto/aes/aestab.h +++ b/crypto/aes/aestab.h @@ -58,32 +58,32 @@ Issue Date: 20/12/2007 t_xxx(r,c) => the rcon table */ -#if !defined( _AESTAB_H ) +#if !defined(_AESTAB_H) #define _AESTAB_H #if defined(__cplusplus) extern "C" { #endif -#define t_dec(m,n) t_##m##n -#define t_set(m,n) t_##m##n -#define t_use(m,n) t_##m##n +#define t_dec(m, n) t_##m##n +#define t_set(m, n) t_##m##n +#define t_use(m, n) t_##m##n #if defined(STATIC_TABLES) -# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) +#if !defined(__GNUC__) && (defined(__MSDOS__) || defined(__WIN16__)) /* make tables far data to avoid using too much DGROUP space (PG) */ -# define CONST const far -# else -# define CONST const -# endif +#define CONST const far #else -# define CONST +#define CONST const +#endif +#else +#define CONST #endif #if defined(DO_TABLES) -# define EXTERN +#define EXTERN #else -# define EXTERN extern +#define EXTERN extern #endif #if defined(_MSC_VER) && defined(TABLE_ALIGN) @@ -92,78 +92,78 @@ extern "C" { #define ALIGN #endif -#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) -# define XP_DIR __cdecl +#if defined(__WATCOMC__) && (__WATCOMC__ >= 1100) +#define XP_DIR __cdecl #else -# define XP_DIR +#define XP_DIR #endif #if defined(DO_TABLES) && defined(STATIC_TABLES) -#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) -#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } -EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0); +#define d_1(t, n, b, e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) +#define d_4(t, n, b, e, f, g, h) EXTERN ALIGN CONST XP_DIR t n[4][256] = {b(e), b(f), b(g), b(h)} +EXTERN ALIGN CONST uint32_t t_dec(r, c)[RC_LENGTH] = rc_data(w0); #else -#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] -#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] -EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH]; +#define d_1(t, n, b, e) EXTERN ALIGN CONST XP_DIR t n[256] +#define d_4(t, n, b, e, f, g, h) EXTERN ALIGN CONST XP_DIR t n[4][256] +EXTERN ALIGN CONST uint32_t t_dec(r, c)[RC_LENGTH]; #endif -#if defined( SBX_SET ) - d_1(uint8_t, t_dec(s,box), sb_data, h0); +#if defined(SBX_SET) +d_1(uint8_t, t_dec(s, box), sb_data, h0); #endif -#if defined( ISB_SET ) - d_1(uint8_t, t_dec(i,box), isb_data, h0); +#if defined(ISB_SET) +d_1(uint8_t, t_dec(i, box), isb_data, h0); #endif -#if defined( FT1_SET ) - d_1(uint32_t, t_dec(f,n), sb_data, u0); +#if defined(FT1_SET) +d_1(uint32_t, t_dec(f, n), sb_data, u0); #endif -#if defined( FT4_SET ) - d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3); +#if defined(FT4_SET) +d_4(uint32_t, t_dec(f, n), sb_data, u0, u1, u2, u3); #endif -#if defined( FL1_SET ) - d_1(uint32_t, t_dec(f,l), sb_data, w0); +#if defined(FL1_SET) +d_1(uint32_t, t_dec(f, l), sb_data, w0); #endif -#if defined( FL4_SET ) - d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3); +#if defined(FL4_SET) +d_4(uint32_t, t_dec(f, l), sb_data, w0, w1, w2, w3); #endif -#if defined( IT1_SET ) - d_1(uint32_t, t_dec(i,n), isb_data, v0); +#if defined(IT1_SET) +d_1(uint32_t, t_dec(i, n), isb_data, v0); #endif -#if defined( IT4_SET ) - d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3); +#if defined(IT4_SET) +d_4(uint32_t, t_dec(i, n), isb_data, v0, v1, v2, v3); #endif -#if defined( IL1_SET ) - d_1(uint32_t, t_dec(i,l), isb_data, w0); +#if defined(IL1_SET) +d_1(uint32_t, t_dec(i, l), isb_data, w0); #endif -#if defined( IL4_SET ) - d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3); +#if defined(IL4_SET) +d_4(uint32_t, t_dec(i, l), isb_data, w0, w1, w2, w3); #endif -#if defined( LS1_SET ) -#if defined( FL1_SET ) -#undef LS1_SET +#if defined(LS1_SET) +#if defined(FL1_SET) +#undef LS1_SET #else - d_1(uint32_t, t_dec(l,s), sb_data, w0); +d_1(uint32_t, t_dec(l, s), sb_data, w0); #endif #endif -#if defined( LS4_SET ) -#if defined( FL4_SET ) -#undef LS4_SET +#if defined(LS4_SET) +#if defined(FL4_SET) +#undef LS4_SET #else - d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3); +d_4(uint32_t, t_dec(l, s), sb_data, w0, w1, w2, w3); #endif #endif -#if defined( IM1_SET ) - d_1(uint32_t, t_dec(i,m), mm_data, v0); +#if defined(IM1_SET) +d_1(uint32_t, t_dec(i, m), mm_data, v0); #endif -#if defined( IM4_SET ) - d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3); +#if defined(IM4_SET) +d_4(uint32_t, t_dec(i, m), mm_data, v0, v1, v2, v3); #endif #if defined(__cplusplus) diff --git a/crypto/aes/aestst.c b/crypto/aes/aestst.c index 95259bc9b67..f9d6465dd39 100644 --- a/crypto/aes/aestst.c +++ b/crypto/aes/aestst.c @@ -51,50 +51,36 @@ #include "aes.h" #include "aestst.h" -void out_state(long s0, long s1, long s2, long s3) -{ +void out_state(long s0, long s1, long s2, long s3) { printf("\n%08lx%08lx%08lx%08lx", s0, s1, s2, s3); } -void oblk(char m[], unsigned char v[], unsigned long n) -{ unsigned long i; +void oblk(char m[], unsigned char v[], unsigned long n) { + unsigned long i; printf("\n%s", m); - for(i = 0; i < n; ++i) - printf("%02x", v[i]); + for(i = 0; i < n; ++i) printf("%02x", v[i]); } -void message(const char *s) { printf("%s", s); } +void message(const char* s) { + printf("%s", s); +} unsigned char pih[32] = // hex digits of pi -{ - 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, - 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, - 0x4a, 0x40, 0x93, 0x82, 0x22, 0x99, 0xf3, 0x1d, - 0x00, 0x82, 0xef, 0xa9, 0x8e, 0xc4, 0xe6, 0xc8 -}; - -unsigned char exh[32] = // hex digits of e -{ - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - 0x76, 0x2e, 0x71, 0x60, 0xf3, 0x8b, 0x4d, 0xa5, - 0x6a, 0x78, 0x4d, 0x90, 0x45, 0x19, 0x0c, 0xfe -}; - -unsigned char res[3][32] = -{ - { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, - 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 - }, - { 0xf9, 0xfb, 0x29, 0xae, 0xfc, 0x38, 0x4a, 0x25, - 0x03, 0x40, 0xd8, 0x33, 0xb8, 0x7e, 0xbc, 0x00 - }, - { 0x1a, 0x6e, 0x6c, 0x2c, 0x66, 0x2e, 0x7d, 0xa6, - 0x50, 0x1f, 0xfb, 0x62, 0xbc, 0x9e, 0x93, 0xf3 - } -}; + {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, + 0xa2, 0xe0, 0x37, 0x07, 0x34, 0x4a, 0x40, 0x93, 0x82, 0x22, 0x99, + 0xf3, 0x1d, 0x00, 0x82, 0xef, 0xa9, 0x8e, 0xc4, 0xe6, 0xc8}; + +unsigned char exh[32] = // hex digits of e + {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, + 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0x76, 0x2e, 0x71, 0x60, 0xf3, 0x8b, + 0x4d, 0xa5, 0x6a, 0x78, 0x4d, 0x90, 0x45, 0x19, 0x0c, 0xfe}; + +unsigned char res[3][32] = { + {0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32}, + {0xf9, 0xfb, 0x29, 0xae, 0xfc, 0x38, 0x4a, 0x25, 0x03, 0x40, 0xd8, 0x33, 0xb8, 0x7e, 0xbc, 0x00}, + {0x1a, 0x6e, 0x6c, 0x2c, 0x66, 0x2e, 0x7d, 0xa6, 0x50, 0x1f, 0xfb, 0x62, 0xbc, 0x9e, 0x93, 0xf3}}; // void cycles(volatile uint64_t *rtn) // { @@ -116,10 +102,10 @@ unsigned char res[3][32] = // #endif // } -int main(void) -{ unsigned char out[32], ret[32], err = 0; - f_ectx alge[1]; - f_dctx algd[1]; +int main(void) { + unsigned char out[32], ret[32], err = 0; + f_ectx alge[1]; + f_dctx algd[1]; aes_init(); @@ -128,49 +114,70 @@ int main(void) memset(&alge, 0, sizeof(aes_encrypt_ctx)); memset(&algd, 0, sizeof(aes_decrypt_ctx)); -#if defined( AES_128 ) - memset(out, 0xcc, 16); memset(ret, 0xcc, 16); +#if defined(AES_128) + memset(out, 0xcc, 16); + memset(ret, 0xcc, 16); printf("\n\n// lengths: block = 16, bytes, key = 16 bytes"); f_enc_key128(alge, exh); oblk("// key = ", exh, 16); oblk("// input = ", pih, 16); do_enc(alge, pih, out, 1); oblk("// encrypt = ", out, 16); - if(memcmp(out, res[0], 16)) { message (" error"); err += 1; } + if(memcmp(out, res[0], 16)) { + message(" error"); + err += 1; + } f_dec_key128(algd, exh); do_dec(algd, out, ret, 1); oblk("// decrypt = ", ret, 16); - if(memcmp(ret, pih, 16)) { message (" error"); err += 2; } + if(memcmp(ret, pih, 16)) { + message(" error"); + err += 2; + } #endif -#if defined( AES_192 ) - memset(out, 0xcc, 16); memset(ret, 0xcc, 16); +#if defined(AES_192) + memset(out, 0xcc, 16); + memset(ret, 0xcc, 16); printf("\n\n// lengths: block = 16, bytes, key = 24 bytes"); f_enc_key192(alge, exh); oblk("// key = ", exh, 24); oblk("// input = ", pih, 16); do_enc(alge, pih, out, 1); oblk("// encrypt = ", out, 16); - if(memcmp(out, res[1], 16)) { message (" error"); err += 4; } + if(memcmp(out, res[1], 16)) { + message(" error"); + err += 4; + } f_dec_key192(algd, exh); do_dec(algd, out, ret, 1); oblk("// decrypt = ", ret, 16); - if(memcmp(ret, pih, 16)) { message (" error"); err += 8; } + if(memcmp(ret, pih, 16)) { + message(" error"); + err += 8; + } #endif -#if defined( AES_256 ) - memset(out, 0xcc, 16); memset(ret, 0xcc, 16); +#if defined(AES_256) + memset(out, 0xcc, 16); + memset(ret, 0xcc, 16); printf("\n\n// lengths: block = 16, bytes, key = 32 bytes"); f_enc_key256(alge, exh); oblk("// key = ", exh, 32); oblk("// input = ", pih, 16); do_enc(alge, pih, out, 1); oblk("// encrypt = ", out, 16); - if(memcmp(out, res[2], 16)) { message (" error"); err += 16; } + if(memcmp(out, res[2], 16)) { + message(" error"); + err += 16; + } f_dec_key256(algd, exh); do_dec(algd, out, ret, 1); oblk("// decrypt = ", ret, 16); - if(memcmp(ret, pih, 16)) { message (" error"); err += 32; } + if(memcmp(ret, pih, 16)) { + message(" error"); + err += 32; + } #endif if(!err) diff --git a/crypto/aes/aestst.h b/crypto/aes/aestst.h index 3c5461c3c84..bb38b04349d 100644 --- a/crypto/aes/aestst.h +++ b/crypto/aes/aestst.h @@ -26,60 +26,60 @@ Issue Date: 20/12/2007 #ifndef AESTST_H #define AESTST_H -#define f_info(x) (x)->inf.b[2] -#define f_ectx aes_encrypt_ctx -#define f_enc_key128(a,b) aes_encrypt_key128((b),(a)) -#define f_enc_key192(a,b) aes_encrypt_key192((b),(a)) -#define f_enc_key256(a,b) aes_encrypt_key256((b),(a)) -#define f_enc_key(a,b,c) aes_encrypt_key((b),(c),(a)) -#define f_enc_blk(a,b,c) aes_encrypt((b),(c),(a)) +#define f_info(x) (x)->inf.b[2] +#define f_ectx aes_encrypt_ctx +#define f_enc_key128(a, b) aes_encrypt_key128((b), (a)) +#define f_enc_key192(a, b) aes_encrypt_key192((b), (a)) +#define f_enc_key256(a, b) aes_encrypt_key256((b), (a)) +#define f_enc_key(a, b, c) aes_encrypt_key((b), (c), (a)) +#define f_enc_blk(a, b, c) aes_encrypt((b), (c), (a)) -#define f_dctx aes_decrypt_ctx -#define f_dec_key128(a,b) aes_decrypt_key128((b),(a)) -#define f_dec_key192(a,b) aes_decrypt_key192((b),(a)) -#define f_dec_key256(a,b) aes_decrypt_key256((b),(a)) -#define f_dec_key(a,b,c) aes_decrypt_key((b),(c),(a)) -#define f_dec_blk(a,b,c) aes_decrypt((b),(c),(a)) +#define f_dctx aes_decrypt_ctx +#define f_dec_key128(a, b) aes_decrypt_key128((b), (a)) +#define f_dec_key192(a, b) aes_decrypt_key192((b), (a)) +#define f_dec_key256(a, b) aes_decrypt_key256((b), (a)) +#define f_dec_key(a, b, c) aes_decrypt_key((b), (c), (a)) +#define f_dec_blk(a, b, c) aes_decrypt((b), (c), (a)) -#define f_talign(a,b) aes_test_alignment_detection(b) -#define f_mode_reset(a) aes_mode_reset(a) -#define f_ecb_enc(a,b,c,d) aes_ecb_encrypt((b),(c),(d),(a)) -#define f_ecb_dec(a,b,c,d) aes_ecb_decrypt((b),(c),(d),(a)) -#define f_cbc_enc(a,b,c,d,e) aes_cbc_encrypt((b),(c),(d),(e),(a)) -#define f_cbc_dec(a,b,c,d,e) aes_cbc_decrypt((b),(c),(d),(e),(a)) -#define f_cfb_enc(a,b,c,d,e) aes_cfb_encrypt((b),(c),(d),(e),(a)) -#define f_cfb_dec(a,b,c,d,e) aes_cfb_decrypt((b),(c),(d),(e),(a)) -#define f_ofb_cry(a,b,c,d,e) aes_ofb_crypt((b),(c),(d),(e),(a)) -#define f_ctr_cry(a,b,c,d,e,f) aes_ctr_crypt((b),(c),(d),(e),(f),(a)) +#define f_talign(a, b) aes_test_alignment_detection(b) +#define f_mode_reset(a) aes_mode_reset(a) +#define f_ecb_enc(a, b, c, d) aes_ecb_encrypt((b), (c), (d), (a)) +#define f_ecb_dec(a, b, c, d) aes_ecb_decrypt((b), (c), (d), (a)) +#define f_cbc_enc(a, b, c, d, e) aes_cbc_encrypt((b), (c), (d), (e), (a)) +#define f_cbc_dec(a, b, c, d, e) aes_cbc_decrypt((b), (c), (d), (e), (a)) +#define f_cfb_enc(a, b, c, d, e) aes_cfb_encrypt((b), (c), (d), (e), (a)) +#define f_cfb_dec(a, b, c, d, e) aes_cfb_decrypt((b), (c), (d), (e), (a)) +#define f_ofb_cry(a, b, c, d, e) aes_ofb_crypt((b), (c), (d), (e), (a)) +#define f_ctr_cry(a, b, c, d, e, f) aes_ctr_crypt((b), (c), (d), (e), (f), (a)) -#define ek_name128 "aes_encrypt_key128" -#define ek_name192 "aes_encrypt_key192" -#define ek_name256 "aes_encrypt_key256" -#define ek_name "aes_encrypt_key" -#define eb_name "aes_encrypt" +#define ek_name128 "aes_encrypt_key128" +#define ek_name192 "aes_encrypt_key192" +#define ek_name256 "aes_encrypt_key256" +#define ek_name "aes_encrypt_key" +#define eb_name "aes_encrypt" -#define dk_name128 "aes_decrypt_key128" -#define dk_name192 "aes_decrypt_key192" -#define dk_name256 "aes_decrypt_key256" -#define dk_name "aes_decrypt_key" -#define db_name "aes_decrypt" +#define dk_name128 "aes_decrypt_key128" +#define dk_name192 "aes_decrypt_key192" +#define dk_name256 "aes_decrypt_key256" +#define dk_name "aes_decrypt_key" +#define db_name "aes_decrypt" -#define eres_name "aes_mode_reset" -#define ecbe_name "aes_ecb_encrypt" -#define ecbd_name "aes_ecb_decrypt" -#define cbce_name "aes_cbc_encrypt" -#define cbcd_name "aes_cbc_decrypt" -#define cfbe_name "aes_cfb_encrypt" -#define cfbd_name "aes_cfb_decrypt" -#define ofb_name "aes_ofb_crypt" -#define ctr_name "aes_ctr_crypt" +#define eres_name "aes_mode_reset" +#define ecbe_name "aes_ecb_encrypt" +#define ecbd_name "aes_ecb_decrypt" +#define cbce_name "aes_cbc_encrypt" +#define cbcd_name "aes_cbc_decrypt" +#define cfbe_name "aes_cfb_encrypt" +#define cfbd_name "aes_cfb_decrypt" +#define ofb_name "aes_ofb_crypt" +#define ctr_name "aes_ctr_crypt" #ifndef AES_N_BLOCK -#define do_enc(a,b,c,d) f_enc_blk(a, b, c) -#define do_dec(a,b,c,d) f_dec_blk(a, b, c) +#define do_enc(a, b, c, d) f_enc_blk(a, b, c) +#define do_dec(a, b, c, d) f_dec_blk(a, b, c) #else -#define do_enc(a,b,c,d) f_ecb_enc(a, b, c, 1) -#define do_dec(a,b,c,d) f_ecb_dec(a, b, c, 1) +#define do_enc(a, b, c, d) f_ecb_enc(a, b, c, 1) +#define do_dec(a, b, c, d) f_ecb_dec(a, b, c, 1) #endif #endif diff --git a/crypto/base32.c b/crypto/base32.c index ef9b76bec20..e211bb308f0 100644 --- a/crypto/base32.c +++ b/crypto/base32.c @@ -24,218 +24,218 @@ #include -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; - } +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); + base32_encode_unsafe(in, inlen, (uint8_t*)out); - for (size_t i = 0; i < length; i++) { - int ret = base32_encode_character(out[i], alphabet); + 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; + if(ret == -1) { + return false; + } else { + out[i] = ret; + } } - } - out[length] = '\0'; - return &out[length]; + 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; - } +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; - } + if(!base32_decode_unsafe((uint8_t*)in, inlen, (uint8_t*)out, alphabet)) { + return NULL; + } - return &out[length]; + 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; +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 = 0, j = 0; - for (i = 0, j = 0; i < limit; i += 5, j += 8) { - base32_5to8(&in[i], 5, &out[j]); - } + size_t i = 0, j = 0; + 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]); + 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; +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 = 0, j = 0; - for (i = 0, j = 0; i < limit; i += 8, j += 5) { - if (!base32_8to5(&in[i], 8, &out[j], alphabet)) { - return false; + size_t i = 0, j = 0; + 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; - } + if(remainder && !base32_8to5(&in[i], remainder, &out[j], alphabet)) { + return false; + } - return true; + return true; } size_t base32_encoded_length(size_t inlen) { - uint8_t remainder = inlen % 5; + uint8_t remainder = inlen % 5; - return (inlen / 5) * 8 + (remainder * 8 + 4) / 5; + return (inlen / 5) * 8 + (remainder * 8 + 4) / 5; } size_t base32_decoded_length(size_t inlen) { - uint8_t remainder = inlen % 8; + uint8_t remainder = inlen % 8; - return (inlen / 8) * 5 + (remainder * 5) / 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); - } -} +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; + } -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(length >= 2) { + out[1] |= (in[1] >> 6); + out[2] = (in[1] >> 1) & 31; + out[3] = (in[1] & 1) << 4; + } - if (alphabet) { - uint8_t decoded[length]; - memset(decoded, 0, sizeof(decoded)); + if(length >= 3) { + out[3] |= (in[2] >> 4); + out[4] = (in[2] & 15) << 1; + } - for (size_t i = 0; i < length; i++) { - int ret = base32_decode_character(in[i], alphabet); + if(length >= 4) { + out[4] |= (in[3] >> 7); + out[5] = (in[3] >> 2) & 31; + out[6] = (in[3] & 3) << 3; + } - if (ret == -1) { + 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; - } else { - decoded[i] = ret; - } } - base32_8to5_raw(decoded, length, out); - } else { - base32_8to5_raw(in, length, out); - } + if(alphabet) { + uint8_t decoded[length]; + memset(decoded, 0, sizeof(decoded)); + + for(size_t i = 0; i < length; i++) { + int ret = base32_decode_character(in[i], alphabet); - return true; + 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); - } +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; - } +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; + if(alphabet == BASE32_ALPHABET_RFC4648) { + if(decoded < 26) { + return 'A' + decoded; + } else { + return '2' - 26 + decoded; + } } - } - return alphabet[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; +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); + const char* occurrence = strchr(alphabet, encoded); - if (occurrence) { - return occurrence - alphabet; - } else { - return -1; - } + if(occurrence) { + return occurrence - alphabet; + } else { + return -1; + } } diff --git a/crypto/base32.h b/crypto/base32.h index 8b5cc8513fc..5e214aabb9a 100644 --- a/crypto/base32.h +++ b/crypto/base32.h @@ -27,16 +27,14 @@ #include #include -extern const char *BASE32_ALPHABET_RFC4648; +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); +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); +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); diff --git a/crypto/base58.c b/crypto/base58.c index ef687f027b9..dbcd3832f6d 100644 --- a/crypto/base58.c +++ b/crypto/base58.c @@ -28,16 +28,14 @@ #include "ripemd160.h" #include "sha2.h" -const char b58digits_ordered[] = - "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +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, + -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, }; typedef uint64_t b58_maxint_t; @@ -49,173 +47,173 @@ static const b58_almostmaxint_t b58_almostmaxint_mask = // Decodes a null-terminated Base58 string `b58` to binary and writes the result // at the end of the buffer `bin` of size `*binszp`. On success `*binszp` is set // to the number of valid bytes at the end of the buffer. -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 + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t); - b58_almostmaxint_t outi[outisz]; - b58_maxint_t t = 0; - b58_almostmaxint_t c = 0; - size_t i = 0, j = 0; - uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t); - b58_almostmaxint_t zeromask = - bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0; - unsigned zerocount = 0; - - size_t 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 = ((b58_maxint_t)outi[j]) * 58 + c; - c = t >> b58_almostmaxint_bits; - outi[j] = t & b58_almostmaxint_mask; +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 + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t); + b58_almostmaxint_t outi[outisz]; + b58_maxint_t t = 0; + b58_almostmaxint_t c = 0; + size_t i = 0, j = 0; + uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t); + b58_almostmaxint_t zeromask = bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0; + unsigned zerocount = 0; + + size_t 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 = ((b58_maxint_t)outi[j]) * 58 + c; + c = t >> b58_almostmaxint_bits; + outi[j] = t & b58_almostmaxint_mask; + } + 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; + if(bytesleft) { + for(i = bytesleft; i > 0; --i) { + *(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff; + } + ++j; + } + + for(; j < outisz; ++j) { + for(i = sizeof(*outi); i > 0; --i) { + *(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff; + } } - 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; - if (bytesleft) { - for (i = bytesleft; i > 0; --i) { - *(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff; + + // locate the most significant byte + binu = bin; + for(i = 0; i < binsz; ++i) { + if(binu[i]) break; } - ++j; - } - for (; j < outisz; ++j) { - for (i = sizeof(*outi); i > 0; --i) { - *(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff; + // prepend the correct number of null-bytes + if(zerocount > i) { + /* result too large */ + return false; } - } - - // locate the most significant byte - binu = bin; - for (i = 0; i < binsz; ++i) { - if (binu[i]) break; - } - - // prepend the correct number of null-bytes - if (zerocount > i) { - /* result too large */ - return false; - } - *binszp = binsz - i + zerocount; - - return true; + *binszp = binsz - i + zerocount; + + return true; } -int b58check(const void *bin, size_t binsz, HasherType hasher_type, - const char *base58str) { - unsigned char buf[32] = {0}; - const uint8_t *binc = bin; - unsigned i = 0; - 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]; +int b58check(const void* bin, size_t binsz, HasherType hasher_type, const char* base58str) { + unsigned char buf[32] = {0}; + const uint8_t* binc = bin; + unsigned i = 0; + 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 = 0; - size_t i = 0, j = 0, high = 0, zcount = 0; - size_t size = 0; - - while (zcount < binsz && !bin[zcount]) ++zcount; - - size = (binsz - zcount) * 138 / 100 + 1; - uint8_t buf[size]; - memzero(buf, size); - - for (i = zcount, high = size - 1; i < 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; - if (!j) { - // Otherwise j wraps to maxint which is > high - break; - } +bool b58enc(char* b58, size_t* b58sz, const void* data, size_t binsz) { + const uint8_t* bin = data; + int carry = 0; + size_t i = 0, j = 0, high = 0, zcount = 0; + size_t size = 0; + + while(zcount < binsz && !bin[zcount]) ++zcount; + + size = (binsz - zcount) * 138 / 100 + 1; + uint8_t buf[size]; + memzero(buf, size); + + for(i = zcount, high = size - 1; i < 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; + if(!j) { + // Otherwise j wraps to maxint which is > high + break; + } + } } - } - for (j = 0; j < size && !buf[j]; ++j) - ; + for(j = 0; j < size && !buf[j]; ++j) + ; - if (*b58sz <= zcount + size - j) { - *b58sz = zcount + size - j + 1; - return false; - } + if(*b58sz <= zcount + size - j) { + *b58sz = zcount + size - j + 1; + return false; + } - if (zcount) memset(b58, '1', zcount); - for (i = zcount; j < size; ++i, ++j) b58[i] = b58digits_ordered[buf[j]]; - b58[i] = '\0'; - *b58sz = i + 1; + if(zcount) memset(b58, '1', zcount); + for(i = zcount; j < size; ++i, ++j) b58[i] = b58digits_ordered[buf[j]]; + b58[i] = '\0'; + *b58sz = i + 1; - return true; + 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]; - memset(buf, 0, sizeof(buf)); - 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_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]; + memset(buf, 0, sizeof(buf)); + 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]; - memset(d, 0, sizeof(d)); - 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; +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]; + memset(d, 0, sizeof(d)); + 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; } diff --git a/crypto/base58.h b/crypto/base58.h index 9b7762f8efb..0f7fa66d3ad 100644 --- a/crypto/base58.h +++ b/crypto/base58.h @@ -32,15 +32,17 @@ 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); +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); +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); #endif diff --git a/crypto/bignum.c b/crypto/bignum.c index b23adf7a831..f0c7d6e43b2 100644 --- a/crypto/bignum.c +++ b/crypto/bignum.c @@ -77,209 +77,209 @@ control flow and constant memory access flow. */ -#define BN_MAX_DECIMAL_DIGITS \ - 79 // floor(log(2**(LIMBS * BITS_PER_LIMB), 10)) + 1 +#define BN_MAX_DECIMAL_DIGITS 79 // floor(log(2**(LIMBS * BITS_PER_LIMB), 10)) + 1 // out_number = (bignum256) in_number // Assumes in_number is a raw bigendian 256-bit number // Guarantees out_number is normalized -void bn_read_be(const uint8_t *in_number, bignum256 *out_number) { - uint32_t temp = 0; +void bn_read_be(const uint8_t* in_number, bignum256* out_number) { + uint32_t temp = 0; - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t limb = read_be(in_number + (BN_LIMBS - 2 - i) * 4); + for(int i = 0; i < BN_LIMBS - 1; i++) { + uint32_t limb = read_be(in_number + (BN_LIMBS - 2 - i) * 4); - temp |= limb << (BN_EXTRA_BITS * i); - out_number->val[i] = temp & BN_LIMB_MASK; + temp |= limb << (BN_EXTRA_BITS * i); + out_number->val[i] = temp & BN_LIMB_MASK; - temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); - } + temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); + } - out_number->val[BN_LIMBS - 1] = temp; + out_number->val[BN_LIMBS - 1] = temp; } // out_number = (256BE) in_number // Assumes in_number < 2**256 // Guarantess out_number is a raw bigendian 256-bit number -void bn_write_be(const bignum256 *in_number, uint8_t *out_number) { - uint32_t temp = in_number->val[BN_LIMBS - 1]; - for (int i = BN_LIMBS - 2; i >= 0; i--) { - uint32_t limb = in_number->val[i]; +void bn_write_be(const bignum256* in_number, uint8_t* out_number) { + uint32_t temp = in_number->val[BN_LIMBS - 1]; + for(int i = BN_LIMBS - 2; i >= 0; i--) { + uint32_t limb = in_number->val[i]; - temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | - (limb >> (BN_EXTRA_BITS * i)); - write_be(out_number + (BN_LIMBS - 2 - i) * 4, temp); + temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | (limb >> (BN_EXTRA_BITS * i)); + write_be(out_number + (BN_LIMBS - 2 - i) * 4, temp); - temp = limb; - } + temp = limb; + } } // out_number = (bignum256) in_number // Assumes in_number is a raw little endian 256-bit number // Guarantees out_number is normalized -void bn_read_le(const uint8_t *in_number, bignum256 *out_number) { - uint32_t temp = 0; - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t limb = read_le(in_number + i * 4); - - temp |= limb << (BN_EXTRA_BITS * i); - out_number->val[i] = temp & BN_LIMB_MASK; - temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); - } +void bn_read_le(const uint8_t* in_number, bignum256* out_number) { + uint32_t temp = 0; + for(int i = 0; i < BN_LIMBS - 1; i++) { + uint32_t limb = read_le(in_number + i * 4); + + temp |= limb << (BN_EXTRA_BITS * i); + out_number->val[i] = temp & BN_LIMB_MASK; + temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); + } - out_number->val[BN_LIMBS - 1] = temp; + out_number->val[BN_LIMBS - 1] = temp; } // out_number = (256LE) in_number // Assumes in_number < 2**256 // Guarantess out_number is a raw little endian 256-bit number -void bn_write_le(const bignum256 *in_number, uint8_t *out_number) { - uint32_t temp = in_number->val[BN_LIMBS - 1]; - - for (int i = BN_LIMBS - 2; i >= 0; i--) { - uint32_t limb = in_number->val[i]; - temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | - (limb >> (BN_EXTRA_BITS * i)); - write_le(out_number + i * 4, temp); - temp = limb; - } +void bn_write_le(const bignum256* in_number, uint8_t* out_number) { + uint32_t temp = in_number->val[BN_LIMBS - 1]; + + for(int i = BN_LIMBS - 2; i >= 0; i--) { + uint32_t limb = in_number->val[i]; + temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | (limb >> (BN_EXTRA_BITS * i)); + write_le(out_number + i * 4, temp); + temp = limb; + } } // out_number = (bignum256) in_number // Guarantees out_number is normalized -void bn_read_uint32(uint32_t in_number, bignum256 *out_number) { - out_number->val[0] = in_number & BN_LIMB_MASK; - out_number->val[1] = in_number >> BN_BITS_PER_LIMB; - for (uint32_t i = 2; i < BN_LIMBS; i++) out_number->val[i] = 0; +void bn_read_uint32(uint32_t in_number, bignum256* out_number) { + out_number->val[0] = in_number & BN_LIMB_MASK; + out_number->val[1] = in_number >> BN_BITS_PER_LIMB; + for(uint32_t i = 2; i < BN_LIMBS; i++) out_number->val[i] = 0; } // out_number = (bignum256) in_number // Guarantees out_number is normalized -void bn_read_uint64(uint64_t in_number, bignum256 *out_number) { - out_number->val[0] = in_number & BN_LIMB_MASK; - out_number->val[1] = (in_number >>= BN_BITS_PER_LIMB) & BN_LIMB_MASK; - out_number->val[2] = in_number >> BN_BITS_PER_LIMB; - for (uint32_t i = 3; i < BN_LIMBS; i++) out_number->val[i] = 0; +void bn_read_uint64(uint64_t in_number, bignum256* out_number) { + out_number->val[0] = in_number & BN_LIMB_MASK; + out_number->val[1] = (in_number >>= BN_BITS_PER_LIMB) & BN_LIMB_MASK; + out_number->val[2] = in_number >> BN_BITS_PER_LIMB; + for(uint32_t i = 3; i < BN_LIMBS; i++) out_number->val[i] = 0; } // Returns the bitsize of x // Assumes x is normalized // The function doesn't have neither constant control flow nor constant memory // access flow -int bn_bitcount(const bignum256 *x) { - for (int i = BN_LIMBS - 1; i >= 0; i--) { - uint32_t limb = x->val[i]; - if (limb != 0) { - // __builtin_clz returns the number of leading zero bits starting at the - // most significant bit position - return i * BN_BITS_PER_LIMB + (32 - __builtin_clz(limb)); +int bn_bitcount(const bignum256* x) { + for(int i = BN_LIMBS - 1; i >= 0; i--) { + uint32_t limb = x->val[i]; + if(limb != 0) { + // __builtin_clz returns the number of leading zero bits starting at the + // most significant bit position + return i * BN_BITS_PER_LIMB + (32 - __builtin_clz(limb)); + } } - } - return 0; + return 0; } // Returns the number of decimal digits of x; if x is 0, returns 1 // Assumes x is normalized // The function doesn't have neither constant control flow nor constant memory // access flow -unsigned int bn_digitcount(const bignum256 *x) { - bignum256 val = {0}; - bn_copy(x, &val); - - unsigned int digits = 1; - for (unsigned int i = 0; i < BN_MAX_DECIMAL_DIGITS; i += 3) { - uint32_t limb = 0; - - bn_divmod1000(&val, &limb); - - if (limb >= 100) { - digits = i + 3; - } else if (limb >= 10) { - digits = i + 2; - } else if (limb >= 1) { - digits = i + 1; +unsigned int bn_digitcount(const bignum256* x) { + bignum256 val = {0}; + bn_copy(x, &val); + + unsigned int digits = 1; + for(unsigned int i = 0; i < BN_MAX_DECIMAL_DIGITS; i += 3) { + uint32_t limb = 0; + + bn_divmod1000(&val, &limb); + + if(limb >= 100) { + digits = i + 3; + } else if(limb >= 10) { + digits = i + 2; + } else if(limb >= 1) { + digits = i + 1; + } } - } - memzero(&val, sizeof(val)); + memzero(&val, sizeof(val)); - return digits; + return digits; } // x = 0 // Guarantees x is normalized -void bn_zero(bignum256 *x) { - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = 0; - } +void bn_zero(bignum256* x) { + for(int i = 0; i < BN_LIMBS; i++) { + x->val[i] = 0; + } } // x = 1 // Guarantees x is normalized -void bn_one(bignum256 *x) { - x->val[0] = 1; - for (int i = 1; i < BN_LIMBS; i++) { - x->val[i] = 0; - } +void bn_one(bignum256* x) { + x->val[0] = 1; + for(int i = 1; i < BN_LIMBS; i++) { + x->val[i] = 0; + } } // Returns x == 0 // Assumes x is normalized -int bn_is_zero(const bignum256 *x) { - uint32_t result = 0; - for (int i = 0; i < BN_LIMBS; i++) { - result |= x->val[i]; - } - return !result; +int bn_is_zero(const bignum256* x) { + uint32_t result = 0; + for(int i = 0; i < BN_LIMBS; i++) { + result |= x->val[i]; + } + return !result; } // Returns x == 1 // Assumes x is normalized -int bn_is_one(const bignum256 *x) { - uint32_t result = x->val[0] ^ 1; - for (int i = 1; i < BN_LIMBS; i++) { - result |= x->val[i]; - } - return !result; +int bn_is_one(const bignum256* x) { + uint32_t result = x->val[0] ^ 1; + for(int i = 1; i < BN_LIMBS; i++) { + result |= x->val[i]; + } + return !result; } // Returns x < y // Assumes x, y are normalized -int bn_is_less(const bignum256 *x, const bignum256 *y) { - uint32_t res1 = 0; - uint32_t res2 = 0; - for (int i = BN_LIMBS - 1; i >= 0; i--) { - res1 = (res1 << 1) | (x->val[i] < y->val[i]); - res2 = (res2 << 1) | (x->val[i] > y->val[i]); - } - return res1 > res2; +int bn_is_less(const bignum256* x, const bignum256* y) { + uint32_t res1 = 0; + uint32_t res2 = 0; + for(int i = BN_LIMBS - 1; i >= 0; i--) { + res1 = (res1 << 1) | (x->val[i] < y->val[i]); + res2 = (res2 << 1) | (x->val[i] > y->val[i]); + } + return res1 > res2; } // Returns x == y // Assumes x, y are normalized -int bn_is_equal(const bignum256 *x, const bignum256 *y) { - uint32_t result = 0; - for (int i = 0; i < BN_LIMBS; i++) { - result |= x->val[i] ^ y->val[i]; - } - return !result; +int bn_is_equal(const bignum256* x, const bignum256* y) { + uint32_t result = 0; + for(int i = 0; i < BN_LIMBS; i++) { + result |= x->val[i] ^ y->val[i]; + } + return !result; } // res = cond if truecase else falsecase // Assumes cond is either 0 or 1 // Works properly even if &res == &truecase or &res == &falsecase or // &truecase == &falsecase or &res == &truecase == &falsecase -void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, - const bignum256 *falsecase) { - // Intentional use of bitwise OR operator to ensure constant-time - assert((int)(cond == 1) | (int)(cond == 0)); - - uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 - uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF - - for (int i = 0; i < BN_LIMBS; i++) { - res->val[i] = (truecase->val[i] & tmask) | (falsecase->val[i] & fmask); - } +void bn_cmov( + bignum256* res, + volatile uint32_t cond, + const bignum256* truecase, + const bignum256* falsecase) { + // Intentional use of bitwise OR operator to ensure constant-time + assert((int)(cond == 1) | (int)(cond == 0)); + + uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 + uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF + + for(int i = 0; i < BN_LIMBS; i++) { + res->val[i] = (truecase->val[i] & tmask) | (falsecase->val[i] & fmask); + } } // x = -x % prime if cond else x, @@ -290,57 +290,57 @@ void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, // Guarantees x is normalized // Assumes prime is normalized and // 0 < prime < 2**260 == 2**(BITS_PER_LIMB * LIMBS - 1) -void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime) { - // Intentional use of bitwise OR operator to ensure constant time - assert((int)(cond == 1) | (int)(cond == 0)); +void bn_cnegate(volatile uint32_t cond, bignum256* x, const bignum256* prime) { + // Intentional use of bitwise OR operator to ensure constant time + assert((int)(cond == 1) | (int)(cond == 0)); - uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 - uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF + uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 + uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF - bn_mod(x, prime); - // x < prime + bn_mod(x, prime); + // x < prime - uint32_t acc1 = 1; - uint32_t acc2 = 0; + uint32_t acc1 = 1; + uint32_t acc2 = 0; - for (int i = 0; i < BN_LIMBS; i++) { - acc1 += (BN_BASE - 1) + 2 * prime->val[i] - x->val[i]; - // acc1 neither overflows 32 bits nor underflows 0 - // Proof: - // acc1 + (BASE - 1) + 2 * prime[i] - x[i] - // >= (BASE - 1) - x >= (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) - // == 0 - // acc1 + (BASE - 1) + 2 * prime[i] - x[i] - // <= acc1 + (BASE - 1) + 2 * prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) - // == 7 + 3 * 2**29 < 2**32 - - acc2 += prime->val[i] + x->val[i]; - // acc2 doesn't overflow 32 bits - // Proof: - // acc2 + prime[i] + x[i] - // <= 2**(32 - BITS_PER_LIMB) - 1 + 2 * (2**BITS_PER_LIMB - 1) - // == 2**(32 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB + 1) - 2 - // == 2**30 + 5 < 2**32 - - // x = acc1 & LIMB_MASK if cond else acc2 & LIMB_MASK - x->val[i] = ((acc1 & tmask) | (acc2 & fmask)) & BN_LIMB_MASK; - - acc1 >>= BN_BITS_PER_LIMB; - // acc1 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc1 == 2**(BITS_PER_LIMB * (i + 1)) + 2 * prime[:i + 1] - x[:i + 1] - // >> BITS_PER_LIMB * (i + 1) - - acc2 >>= BN_BITS_PER_LIMB; - // acc2 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc2 == prime[:i + 1] + x[:i + 1] >> BITS_PER_LIMB * (i + 1) - } + for(int i = 0; i < BN_LIMBS; i++) { + acc1 += (BN_BASE - 1) + 2 * prime->val[i] - x->val[i]; + // acc1 neither overflows 32 bits nor underflows 0 + // Proof: + // acc1 + (BASE - 1) + 2 * prime[i] - x[i] + // >= (BASE - 1) - x >= (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) + // == 0 + // acc1 + (BASE - 1) + 2 * prime[i] - x[i] + // <= acc1 + (BASE - 1) + 2 * prime[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) + + // (2**BITS_PER_LIMB - 1) + // == 7 + 3 * 2**29 < 2**32 + + acc2 += prime->val[i] + x->val[i]; + // acc2 doesn't overflow 32 bits + // Proof: + // acc2 + prime[i] + x[i] + // <= 2**(32 - BITS_PER_LIMB) - 1 + 2 * (2**BITS_PER_LIMB - 1) + // == 2**(32 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB + 1) - 2 + // == 2**30 + 5 < 2**32 + + // x = acc1 & LIMB_MASK if cond else acc2 & LIMB_MASK + x->val[i] = ((acc1 & tmask) | (acc2 & fmask)) & BN_LIMB_MASK; + + acc1 >>= BN_BITS_PER_LIMB; + // acc1 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + // acc1 == 2**(BITS_PER_LIMB * (i + 1)) + 2 * prime[:i + 1] - x[:i + 1] + // >> BITS_PER_LIMB * (i + 1) + + acc2 >>= BN_BITS_PER_LIMB; + // acc2 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + // acc2 == prime[:i + 1] + x[:i + 1] >> BITS_PER_LIMB * (i + 1) + } - // assert(acc1 == 1); // assert prime <= 2**260 - // assert(acc2 == 0); + // assert(acc1 == 1); // assert prime <= 2**260 + // assert(acc2 == 0); - // clang-format off + // clang-format off // acc1 == 1 // Proof: // acc1 == 2**(BITS_PER_LIMB * LIMBS) + 2 * prime[:LIMBS] - x[:LIMBS] >> BITS_PER_LIMB * LIMBS @@ -363,18 +363,17 @@ void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime) { // <= 2 * (2**(BITS_PER_LIMB * LIMBS - 1) - 1) - 1 >> 261 // == 2**(BITS_PER_LIMB * LIMBS) - 3 >> BITS_PER_LIMB * LIMBS // == 0 - // clang-format on + // clang-format on } // x <<= 1 // Assumes x is normalized, x < 2**260 == 2**(LIMBS*BITS_PER_LIMB - 1) // Guarantees x is normalized -void bn_lshift(bignum256 *x) { - for (int i = BN_LIMBS - 1; i > 0; i--) { - x->val[i] = ((x->val[i] << 1) & BN_LIMB_MASK) | - (x->val[i - 1] >> (BN_BITS_PER_LIMB - 1)); - } - x->val[0] = (x->val[0] << 1) & BN_LIMB_MASK; +void bn_lshift(bignum256* x) { + for(int i = BN_LIMBS - 1; i > 0; i--) { + x->val[i] = ((x->val[i] << 1) & BN_LIMB_MASK) | (x->val[i - 1] >> (BN_BITS_PER_LIMB - 1)); + } + x->val[0] = (x->val[0] << 1) & BN_LIMB_MASK; } // x >>= 1, i.e. x = floor(x/2) @@ -382,12 +381,11 @@ void bn_lshift(bignum256 *x) { // Guarantees x is normalized // If x is partly reduced (fully reduced) modulo prime, // guarantess x will be partly reduced (fully reduced) modulo prime -void bn_rshift(bignum256 *x) { - for (int i = 0; i < BN_LIMBS - 1; i++) { - x->val[i] = - (x->val[i] >> 1) | ((x->val[i + 1] & 1) << (BN_BITS_PER_LIMB - 1)); - } - x->val[BN_LIMBS - 1] >>= 1; +void bn_rshift(bignum256* x) { + for(int i = 0; i < BN_LIMBS - 1; i++) { + x->val[i] = (x->val[i] >> 1) | ((x->val[i + 1] & 1) << (BN_BITS_PER_LIMB - 1)); + } + x->val[BN_LIMBS - 1] >>= 1; } // Sets i-th least significant bit (counting from zero) @@ -395,9 +393,9 @@ void bn_rshift(bignum256 *x) { // Guarantees x is normalized // The function has constant control flow but not constant memory access flow // with regard to i -void bn_setbit(bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - x->val[i / BN_BITS_PER_LIMB] |= (1u << (i % BN_BITS_PER_LIMB)); +void bn_setbit(bignum256* x, uint16_t i) { + assert(i < BN_LIMBS * BN_BITS_PER_LIMB); + x->val[i / BN_BITS_PER_LIMB] |= (1u << (i % BN_BITS_PER_LIMB)); } // clears i-th least significant bit (counting from zero) @@ -405,28 +403,28 @@ void bn_setbit(bignum256 *x, uint16_t i) { // Guarantees x is normalized // The function has constant control flow but not constant memory access flow // with regard to i -void bn_clearbit(bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - x->val[i / BN_BITS_PER_LIMB] &= ~(1u << (i % BN_BITS_PER_LIMB)); +void bn_clearbit(bignum256* x, uint16_t i) { + assert(i < BN_LIMBS * BN_BITS_PER_LIMB); + x->val[i / BN_BITS_PER_LIMB] &= ~(1u << (i % BN_BITS_PER_LIMB)); } // returns i-th least significant bit (counting from zero) // Assumes x is normalized and 0 <= i < 261 == LIMBS*BITS_PER_LIMB // The function has constant control flow but not constant memory access flow // with regard to i -uint32_t bn_testbit(const bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - return (x->val[i / BN_BITS_PER_LIMB] >> (i % BN_BITS_PER_LIMB)) & 1; +uint32_t bn_testbit(const bignum256* x, uint16_t i) { + assert(i < BN_LIMBS * BN_BITS_PER_LIMB); + return (x->val[i / BN_BITS_PER_LIMB] >> (i % BN_BITS_PER_LIMB)) & 1; } // res = x ^ y // Assumes x, y are normalized // Guarantees res is normalized // Works properly even if &res == &x or &res == &y or &res == &x == &y -void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y) { - for (int i = 0; i < BN_LIMBS; i++) { - res->val[i] = x->val[i] ^ y->val[i]; - } +void bn_xor(bignum256* res, const bignum256* x, const bignum256* y) { + for(int i = 0; i < BN_LIMBS; i++) { + res->val[i] = x->val[i] ^ y->val[i]; + } } // x = x / 2 % prime @@ -436,74 +434,73 @@ void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y) { // If x is partly reduced (fully reduced) modulo prime, // guarantess x will be partly reduced (fully reduced) modulo prime // Assumes prime is an odd number and normalized -void bn_mult_half(bignum256 *x, const bignum256 *prime) { - // x = x / 2 if is_even(x) else (x + prime) / 2 - - uint32_t x_is_odd_mask = - -(x->val[0] & 1); // x_is_odd_mask = 0xFFFFFFFF if is_odd(x) else 0 +void bn_mult_half(bignum256* x, const bignum256* prime) { + // x = x / 2 if is_even(x) else (x + prime) / 2 - uint32_t acc = (x->val[0] + (prime->val[0] & x_is_odd_mask)) >> 1; - // acc < 2**BITS_PER_LIMB - // Proof: - // acc == x[0] + prime[0] & x_is_odd_mask >> 1 - // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) >> 1 - // == 2**(BITS_PER_LIMB + 1) - 2 >> 1 - // < 2**(BITS_PER_LIMB) - - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t temp = (x->val[i + 1] + (prime->val[i + 1] & x_is_odd_mask)); - // temp < 2**(BITS_PER_LIMB + 1) - // Proof: - // temp == x[i + 1] + val[i + 1] & x_is_odd_mask - // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) - // < 2**(BITS_PER_LIMB + 1) + uint32_t x_is_odd_mask = -(x->val[0] & 1); // x_is_odd_mask = 0xFFFFFFFF if is_odd(x) else 0 - acc += (temp & 1) << (BN_BITS_PER_LIMB - 1); - // acc doesn't overflow 32 bits + uint32_t acc = (x->val[0] + (prime->val[0] & x_is_odd_mask)) >> 1; + // acc < 2**BITS_PER_LIMB // Proof: - // acc + (temp & 1 << BITS_PER_LIMB - 1) - // <= 2**(BITS_PER_LIMB + 1) + 2**(BITS_PER_LIMB - 1) - // <= 2**30 + 2**28 < 2**32 + // acc == x[0] + prime[0] & x_is_odd_mask >> 1 + // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) >> 1 + // == 2**(BITS_PER_LIMB + 1) - 2 >> 1 + // < 2**(BITS_PER_LIMB) + + for(int i = 0; i < BN_LIMBS - 1; i++) { + uint32_t temp = (x->val[i + 1] + (prime->val[i + 1] & x_is_odd_mask)); + // temp < 2**(BITS_PER_LIMB + 1) + // Proof: + // temp == x[i + 1] + val[i + 1] & x_is_odd_mask + // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) + // < 2**(BITS_PER_LIMB + 1) - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - acc += temp >> 1; - // acc < 2**(BITS_PER_LIMB + 1) - // Proof: - // acc + (temp >> 1) - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB + 1) - 1 >> 1) - // == 7 + 2**(BITS_PER_LIMB) - 1 < 2**(BITS_PER_LIMB + 1) + acc += (temp & 1) << (BN_BITS_PER_LIMB - 1); + // acc doesn't overflow 32 bits + // Proof: + // acc + (temp & 1 << BITS_PER_LIMB - 1) + // <= 2**(BITS_PER_LIMB + 1) + 2**(BITS_PER_LIMB - 1) + // <= 2**30 + 2**28 < 2**32 + + x->val[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + acc += temp >> 1; + // acc < 2**(BITS_PER_LIMB + 1) + // Proof: + // acc + (temp >> 1) + // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB + 1) - 1 >> 1) + // == 7 + 2**(BITS_PER_LIMB) - 1 < 2**(BITS_PER_LIMB + 1) - // acc == x[:i+2]+(prime[:i+2] & x_is_odd_mask) >> BITS_PER_LIMB * (i+1) - } - x->val[BN_LIMBS - 1] = acc; + // acc == x[:i+2]+(prime[:i+2] & x_is_odd_mask) >> BITS_PER_LIMB * (i+1) + } + x->val[BN_LIMBS - 1] = acc; - // assert(acc >> BITS_PER_LIMB == 0); - // acc >> BITS_PER_LIMB == 0 - // Proof: - // acc - // == x[:LIMBS] + (prime[:LIMBS] & x_is_odd_mask) >> BITS_PER_LIMB*LIMBS - // == x + (prime & x_is_odd_mask) >> BITS_PER_LIMB * LIMBS - // <= x + prime >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // == 0 + // assert(acc >> BITS_PER_LIMB == 0); + // acc >> BITS_PER_LIMB == 0 + // Proof: + // acc + // == x[:LIMBS] + (prime[:LIMBS] & x_is_odd_mask) >> BITS_PER_LIMB*LIMBS + // == x + (prime & x_is_odd_mask) >> BITS_PER_LIMB * LIMBS + // <= x + prime >> BITS_PER_LIMB * LIMBS + // <= 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS + // == 0 } // x = x * k % prime // Assumes x is normalized, 0 <= k <= 8 = 2**(32 - BITS_PER_LIMB) // Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 // Guarantees x is normalized and partly reduced modulo prime -void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime) { - assert(k <= 8); - - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = k * x->val[i]; - // x[i] doesn't overflow 32 bits - // k * x[i] <= 2**(32 - BITS_PER_LIMB) * (2**BITS_PER_LIMB - 1) - // < 2**(32 - BITS_PER_LIMB) * 2**BITS_PER_LIMB == 2**32 - } +void bn_mult_k(bignum256* x, uint8_t k, const bignum256* prime) { + assert(k <= 8); + + for(int i = 0; i < BN_LIMBS; i++) { + x->val[i] = k * x->val[i]; + // x[i] doesn't overflow 32 bits + // k * x[i] <= 2**(32 - BITS_PER_LIMB) * (2**BITS_PER_LIMB - 1) + // < 2**(32 - BITS_PER_LIMB) * 2**BITS_PER_LIMB == 2**32 + } - bn_fast_mod(x, prime); + bn_fast_mod(x, prime); } // Reduces partly reduced x modulo prime @@ -511,64 +508,63 @@ void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime) { // Assumes x is partly reduced modulo prime // Guarantees x is fully reduced modulo prime // Assumes prime is nonzero and normalized -void bn_mod(bignum256 *x, const bignum256 *prime) { - uint32_t x_less_prime = bn_is_less(x, prime); +void bn_mod(bignum256* x, const bignum256* prime) { + uint32_t x_less_prime = bn_is_less(x, prime); - bignum256 temp = {0}; - bn_subtract(x, prime, &temp); - bn_cmov(x, x_less_prime, x, &temp); + bignum256 temp = {0}; + bn_subtract(x, prime, &temp); + bn_cmov(x, x_less_prime, x, &temp); - memzero(&temp, sizeof(temp)); + memzero(&temp, sizeof(temp)); } // Auxiliary function for bn_multiply // res = k * x // Assumes k and x are normalized // Guarantees res is normalized 18 digit little endian number in base 2**29 -void bn_multiply_long(const bignum256 *k, const bignum256 *x, - uint32_t res[2 * BN_LIMBS]) { - // Uses long multiplication in base 2**29, see - // https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication - - uint64_t acc = 0; - - // compute lower half - for (int i = 0; i < BN_LIMBS; i++) { - for (int j = 0; j <= i; j++) { - acc += k->val[j] * (uint64_t)x->val[i - j]; - // acc doesn't overflow 64 bits - // Proof: - // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) - // <= (2**(64 - BITS_PER_LIMB) - 1) + - // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) - // <= 2**35 + 9 * 2**58 < 2**64 +void bn_multiply_long(const bignum256* k, const bignum256* x, uint32_t res[2 * BN_LIMBS]) { + // Uses long multiplication in base 2**29, see + // https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication + + uint64_t acc = 0; + + // compute lower half + for(int i = 0; i < BN_LIMBS; i++) { + for(int j = 0; j <= i; j++) { + acc += k->val[j] * (uint64_t)x->val[i - j]; + // acc doesn't overflow 64 bits + // Proof: + // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) + // <= (2**(64 - BITS_PER_LIMB) - 1) + + // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) + // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) + // <= 2**35 + 9 * 2**58 < 2**64 + } + + res[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 2**35 - 1 == 2**(64 - BITS_PER_LIMB) - 1 } - res[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**35 - 1 == 2**(64 - BITS_PER_LIMB) - 1 - } + // compute upper half + for(int i = BN_LIMBS; i < 2 * BN_LIMBS - 1; i++) { + for(int j = i - BN_LIMBS + 1; j < BN_LIMBS; j++) { + acc += k->val[j] * (uint64_t)x->val[i - j]; + // acc doesn't overflow 64 bits + // Proof: + // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) + // <= (2**(64 - BITS_PER_LIMB) - 1) + // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) + // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) + // <= 2**35 + 9 * 2**58 < 2**64 + } - // compute upper half - for (int i = BN_LIMBS; i < 2 * BN_LIMBS - 1; i++) { - for (int j = i - BN_LIMBS + 1; j < BN_LIMBS; j++) { - acc += k->val[j] * (uint64_t)x->val[i - j]; - // acc doesn't overflow 64 bits - // Proof: - // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) - // <= (2**(64 - BITS_PER_LIMB) - 1) - // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) - // <= 2**35 + 9 * 2**58 < 2**64 + res[i] = acc & (BN_BASE - 1); + acc >>= BN_BITS_PER_LIMB; + // acc < 2**35 == 2**(64 - BITS_PER_LIMB) } - res[i] = acc & (BN_BASE - 1); - acc >>= BN_BITS_PER_LIMB; - // acc < 2**35 == 2**(64 - BITS_PER_LIMB) - } - - res[2 * BN_LIMBS - 1] = acc; + res[2 * BN_LIMBS - 1] = acc; } // Auxiliary function for bn_multiply @@ -576,9 +572,8 @@ void bn_multiply_long(const bignum256 *k, const bignum256 *x, // Assumes res is normalized and res < 2**(256 + 29*d + 31) // Guarantess res in normalized and res < 2 * prime * 2**(29*d) // Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256 *prime, - uint32_t d) { - // clang-format off +void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256* prime, uint32_t d) { + // clang-format off // Computes res = res - (res // 2**(256 + BITS_PER_LIMB * d)) * prime * 2**(BITS_PER_LIMB * d) // res - (res // 2**(256 + BITS_PER_LIMB * d)) * prime * 2**(BITS_PER_LIMB * d) < 2 * prime * 2**(BITS_PER_LIMB * d) @@ -595,57 +590,55 @@ void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256 *prime, // <= 2**(29*d) * (2**256 + 2**255) // <= 2**(29*d) * 2 * (2**256 - 2**224) // <= 2 * prime * 2**(29*d) - // clang-format on + // clang-format on - uint32_t coef = - (res[d + BN_LIMBS - 1] >> (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB)) + - (res[d + BN_LIMBS] << ((BN_LIMBS * BN_BITS_PER_LIMB) - 256)); + uint32_t coef = (res[d + BN_LIMBS - 1] >> (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB)) + + (res[d + BN_LIMBS] << ((BN_LIMBS * BN_BITS_PER_LIMB) - 256)); - // coef == res // 2**(256 + BITS_PER_LIMB * d) + // coef == res // 2**(256 + BITS_PER_LIMB * d) - // coef < 2**31 - // Proof: - // coef == res // 2**(256 + BITS_PER_LIMB * d) - // < 2**(256 + 29 * d + 31) // 2**(256 + 29 * d) - // == 2**31 - - const int shift = 31; - uint64_t acc = 1ull << shift; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += (((uint64_t)(BN_BASE - 1)) << shift) + res[d + i] - - prime->val[i] * (uint64_t)coef; - // acc neither overflow 64 bits nor underflow zero + // coef < 2**31 // Proof: - // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef - // >= ((BASE - 1) << shift) - prime[i] * coef - // == 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * - // (2**31 - 1) - // == (2**shift - 2**31 + 1) * (2**BITS_PER_LIMB - 1) - // == (2**31 - 2**31 + 1) * (2**29 - 1) - // == 2**29 - 1 > 0 - // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef - // <= acc + ((BASE - 1) << shift) + res[d+i] - // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) - // + (2*BITS_PER_LIMB - 1) - // == (2**(64 - BITS_PER_LIMB) - 1) + (2**shift + 1) * - // (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + (2**31 + 1) * (2**29 - 1) - // <= 2**35 + 2**60 + 2**29 < 2**64 - - res[d + i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 + // coef == res // 2**(256 + BITS_PER_LIMB * d) + // < 2**(256 + 29 * d + 31) // 2**(256 + 29 * d) + // == 2**31 - // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + res[d : d + i + 1] - // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } + const int shift = 31; + uint64_t acc = 1ull << shift; - // acc += (((uint64_t)(BASE - 1)) << shift) + res[d + LIMBS]; - // acc >>= BITS_PER_LIMB; - // assert(acc <= 1ul << shift); + for(int i = 0; i < BN_LIMBS; i++) { + acc += (((uint64_t)(BN_BASE - 1)) << shift) + res[d + i] - prime->val[i] * (uint64_t)coef; + // acc neither overflow 64 bits nor underflow zero + // Proof: + // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef + // >= ((BASE - 1) << shift) - prime[i] * coef + // == 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * + // (2**31 - 1) + // == (2**shift - 2**31 + 1) * (2**BITS_PER_LIMB - 1) + // == (2**31 - 2**31 + 1) * (2**29 - 1) + // == 2**29 - 1 > 0 + // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef + // <= acc + ((BASE - 1) << shift) + res[d+i] + // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) + // + (2*BITS_PER_LIMB - 1) + // == (2**(64 - BITS_PER_LIMB) - 1) + (2**shift + 1) * + // (2**BITS_PER_LIMB - 1) + // == (2**35 - 1) + (2**31 + 1) * (2**29 - 1) + // <= 2**35 + 2**60 + 2**29 < 2**64 + + res[d + i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 + + // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + res[d : d + i + 1] + // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) + } - // clang-format off + // acc += (((uint64_t)(BASE - 1)) << shift) + res[d + LIMBS]; + // acc >>= BITS_PER_LIMB; + // assert(acc <= 1ul << shift); + + // clang-format off // acc == 1 << shift // Proof: // acc @@ -662,9 +655,9 @@ void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256 *prime, // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + res[d : d + LIMBS + 1] - coef * prime[:LIMBS + 1] >> BITS_PER_LIMB * (LIMBS + 1) // >= (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + 0 >> BITS_PER_LIMB * (LIMBS + 1) // == 1 << shift - // clang-format on + // clang-format on - res[d + BN_LIMBS] = 0; + res[d + BN_LIMBS] = 0; } // Auxiliary function for bn_multiply @@ -672,74 +665,72 @@ void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256 *prime, // Assumes res in normalized and res < 2**519 // Guarantees x is normalized and partly reduced modulo prime // Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply_reduce(bignum256 *x, uint32_t res[2 * BN_LIMBS], - const bignum256 *prime) { - for (int i = BN_LIMBS - 1; i >= 0; i--) { - // res < 2**(256 + 29*i + 31) - // Proof: - // if i == LIMBS - 1: - // res < 2**519 - // == 2**(256 + 29 * 8 + 31) - // == 2**(256 + 29 * (LIMBS - 1) + 31) - // else: - // res < 2 * prime * 2**(29 * (i + 1)) - // <= 2**256 * 2**(29*i + 29) < 2**(256 + 29*i + 31) - bn_multiply_reduce_step(res, prime, i); - } +void bn_multiply_reduce(bignum256* x, uint32_t res[2 * BN_LIMBS], const bignum256* prime) { + for(int i = BN_LIMBS - 1; i >= 0; i--) { + // res < 2**(256 + 29*i + 31) + // Proof: + // if i == LIMBS - 1: + // res < 2**519 + // == 2**(256 + 29 * 8 + 31) + // == 2**(256 + 29 * (LIMBS - 1) + 31) + // else: + // res < 2 * prime * 2**(29 * (i + 1)) + // <= 2**256 * 2**(29*i + 29) < 2**(256 + 29*i + 31) + bn_multiply_reduce_step(res, prime, i); + } - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = res[i]; - } + for(int i = 0; i < BN_LIMBS; i++) { + x->val[i] = res[i]; + } } // x = k * x % prime // Assumes k, x are normalized, k * x < 2**519 // Guarantees x is normalized and partly reduced modulo prime // Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime) { - uint32_t res[2 * BN_LIMBS] = {0}; +void bn_multiply(const bignum256* k, bignum256* x, const bignum256* prime) { + uint32_t res[2 * BN_LIMBS] = {0}; - bn_multiply_long(k, x, res); - bn_multiply_reduce(x, res, prime); + bn_multiply_long(k, x, res); + bn_multiply_reduce(x, res, prime); - memzero(res, sizeof(res)); + memzero(res, sizeof(res)); } // Partly reduces x modulo prime // Assumes limbs of x except the last (the most significant) one are normalized // Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 // Guarantees x is normalized and partly reduced modulo prime -void bn_fast_mod(bignum256 *x, const bignum256 *prime) { - // Computes x = x - (x // 2**256) * prime +void bn_fast_mod(bignum256* x, const bignum256* prime) { + // Computes x = x - (x // 2**256) * prime - // x < 2**((LIMBS - 1) * BITS_PER_LIMB + 32) == 2**264 + // x < 2**((LIMBS - 1) * BITS_PER_LIMB + 32) == 2**264 - // x - (x // 2**256) * prime < 2 * prime - // Proof: - // x - (x // 2**256) * prime - // == x - (x // 2**256) * (2**256 - (2**256 - prime)) - // == x - ((x // 2**256) * 2**256) + (x // 2**256) * (2**256 - prime) - // == (x % prime) + (x // 2**256) * (2**256 - prime) - // <= prime - 1 + (2**264 // 2**256) * (2**256 - prime) - // <= 2**256 + 2**8 * 2**224 == 2**256 + 2**232 - // < 2 * (2**256 - 2**224) - // <= 2 * prime - - // x - (x // 2**256 - 1) * prime < 2 * prime - // Proof: - // x - (x // 2**256) * prime + prime - // == x - (x // 2**256) * (2**256 - (2**256 - prime)) + prime - // == x - ((x//2**256) * 2**256) + (x//2**256) * (2**256 - prime) + prime - // == (x % prime) + (x // 2**256) * (2**256 - prime) + prime - // <= 2 * prime - 1 + (2**264 // 2**256) * (2**256 - prime) - // <= 2 * prime + 2**8 * 2**224 == 2**256 + 2**232 + 2**256 - 2**224 - // < 2 * (2**256 - 2**224) - // <= 2 * prime - - uint32_t coef = - x->val[BN_LIMBS - 1] >> (256 - ((BN_LIMBS - 1) * BN_BITS_PER_LIMB)); - - // clang-format off + // x - (x // 2**256) * prime < 2 * prime + // Proof: + // x - (x // 2**256) * prime + // == x - (x // 2**256) * (2**256 - (2**256 - prime)) + // == x - ((x // 2**256) * 2**256) + (x // 2**256) * (2**256 - prime) + // == (x % prime) + (x // 2**256) * (2**256 - prime) + // <= prime - 1 + (2**264 // 2**256) * (2**256 - prime) + // <= 2**256 + 2**8 * 2**224 == 2**256 + 2**232 + // < 2 * (2**256 - 2**224) + // <= 2 * prime + + // x - (x // 2**256 - 1) * prime < 2 * prime + // Proof: + // x - (x // 2**256) * prime + prime + // == x - (x // 2**256) * (2**256 - (2**256 - prime)) + prime + // == x - ((x//2**256) * 2**256) + (x//2**256) * (2**256 - prime) + prime + // == (x % prime) + (x // 2**256) * (2**256 - prime) + prime + // <= 2 * prime - 1 + (2**264 // 2**256) * (2**256 - prime) + // <= 2 * prime + 2**8 * 2**224 == 2**256 + 2**232 + 2**256 - 2**224 + // < 2 * (2**256 - 2**224) + // <= 2 * prime + + uint32_t coef = x->val[BN_LIMBS - 1] >> (256 - ((BN_LIMBS - 1) * BN_BITS_PER_LIMB)); + + // clang-format off // coef == x // 2**256 // 0 <= coef < 2**((LIMBS - 1) * BITS_PER_LIMB + 32 - 256) == 256 // Proof: @@ -749,39 +740,38 @@ void bn_fast_mod(bignum256 *x, const bignum256 *prime) { // == x[[256 - ((LIMBS - 1) * BITS_PER_LIMB) + (LIMBS - 1) * BITS_PER_LIMB : (LIMBS - 1) * BITS_PER_LIMB + 32]] // == x[[256 : (LIMBS - 1) * BITS_PER_LIMB + 32]] // == x[[256 : 264]] == x // 2**256 - // clang-format on + // clang-format on - const int shift = 8; - uint64_t acc = 1ull << shift; + const int shift = 8; + uint64_t acc = 1ull << shift; - for (int i = 0; i < BN_LIMBS; i++) { - acc += (((uint64_t)(BN_BASE - 1)) << shift) + x->val[i] - - prime->val[i] * (uint64_t)coef; - // acc neither overflows 64 bits nor underflows 0 - // Proof: - // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef - // >= (BASE - 1 << shift) - prime[i] * coef - // >= 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * 255 - // == (2**shift - 255) * (2**BITS_PER_LIMB - 1) - // == (2**8 - 255) * (2**29 - 1) == 2**29 - 1 >= 0 - // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef - // <= acc + ((BASE - 1) << shift) + x[i] - // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) - // + (2**32 - 1) - // == (2**35 - 1) + 2**8 * (2**29 - 1) + 2**32 - // < 2**35 + 2**37 + 2**32 < 2**64 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 - - // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + x[:i + 1] - // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } + for(int i = 0; i < BN_LIMBS; i++) { + acc += (((uint64_t)(BN_BASE - 1)) << shift) + x->val[i] - prime->val[i] * (uint64_t)coef; + // acc neither overflows 64 bits nor underflows 0 + // Proof: + // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef + // >= (BASE - 1 << shift) - prime[i] * coef + // >= 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * 255 + // == (2**shift - 255) * (2**BITS_PER_LIMB - 1) + // == (2**8 - 255) * (2**29 - 1) == 2**29 - 1 >= 0 + // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef + // <= acc + ((BASE - 1) << shift) + x[i] + // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) + // + (2**32 - 1) + // == (2**35 - 1) + 2**8 * (2**29 - 1) + 2**32 + // < 2**35 + 2**37 + 2**32 < 2**64 + + x->val[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 + + // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + x[:i + 1] + // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) + } - // assert(acc == 1 << shift); + // assert(acc == 1 << shift); - // clang-format off + // clang-format off // acc == 1 << shift // Proof: // acc @@ -797,7 +787,7 @@ void bn_fast_mod(bignum256 *x, const bignum256 *prime) { // >= (1 << BITS_PER_LIMB * LIMBS + shift) + 0 >> BITS_PER_LIMB * LIMBS // == (1 << BITS_PER_LIMB * LIMBS + shift) + 0 >> BITS_PER_LIMB * LIMBS // <= 1 << 8 == 1 << shift - // clang-format on + // clang-format on } // res = x**e % prime @@ -807,41 +797,40 @@ void bn_fast_mod(bignum256 *x, const bignum256 *prime) { // Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 // The function doesn't have neither constant control flow nor constant memory // access flow with regard to e -void bn_power_mod(const bignum256 *x, const bignum256 *e, - const bignum256 *prime, bignum256 *res) { - // Uses iterative right-to-left exponentiation by squaring, see - // https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method - - bignum256 acc = {0}; - bn_copy(x, &acc); - - bn_one(res); - for (int i = 0; i < BN_LIMBS; i++) { - uint32_t limb = e->val[i]; - - for (int j = 0; j < BN_BITS_PER_LIMB; j++) { - // Break if the following bits of the last limb are zero - if (i == BN_LIMBS - 1 && limb == 0) break; - - if (limb & 1) - // acc * res < 2**519 - // Proof: - // acc * res <= max(2**259 - 1, 2 * prime) * (2 * prime) - // == max(2**259 - 1, 2**257) * 2**257 < 2**259 * 2**257 - // == 2**516 < 2**519 - bn_multiply(&acc, res, prime); - - limb >>= 1; - // acc * acc < 2**519 - // Proof: - // acc * acc <= max(2**259 - 1, 2 * prime)**2 - // <= (2**259)**2 == 2**518 < 2**519 - bn_multiply(&acc, &acc, prime); +void bn_power_mod(const bignum256* x, const bignum256* e, const bignum256* prime, bignum256* res) { + // Uses iterative right-to-left exponentiation by squaring, see + // https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method + + bignum256 acc = {0}; + bn_copy(x, &acc); + + bn_one(res); + for(int i = 0; i < BN_LIMBS; i++) { + uint32_t limb = e->val[i]; + + for(int j = 0; j < BN_BITS_PER_LIMB; j++) { + // Break if the following bits of the last limb are zero + if(i == BN_LIMBS - 1 && limb == 0) break; + + if(limb & 1) + // acc * res < 2**519 + // Proof: + // acc * res <= max(2**259 - 1, 2 * prime) * (2 * prime) + // == max(2**259 - 1, 2**257) * 2**257 < 2**259 * 2**257 + // == 2**516 < 2**519 + bn_multiply(&acc, res, prime); + + limb >>= 1; + // acc * acc < 2**519 + // Proof: + // acc * acc <= max(2**259 - 1, 2 * prime)**2 + // <= (2**259)**2 == 2**518 < 2**519 + bn_multiply(&acc, &acc, prime); + } + // acc == x**(e[:i + 1]) % prime } - // acc == x**(e[:i + 1]) % prime - } - memzero(&acc, sizeof(acc)); + memzero(&acc, sizeof(acc)); } // x = sqrt(x) % prime @@ -853,24 +842,24 @@ void bn_power_mod(const bignum256 *x, const bignum256 *e, // Guarantees x is normalized and fully reduced modulo prime // The function doesn't have neither constant control flow nor constant memory // access flow with regard to prime -void bn_sqrt(bignum256 *x, const bignum256 *prime) { - // Uses the Lagrange formula for the primes of the special form, see - // http://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus - // If prime % 4 == 3, then sqrt(x) % prime == x**((prime+1)//4) % prime +void bn_sqrt(bignum256* x, const bignum256* prime) { + // Uses the Lagrange formula for the primes of the special form, see + // http://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus + // If prime % 4 == 3, then sqrt(x) % prime == x**((prime+1)//4) % prime - assert(prime->val[BN_LIMBS - 1] % 4 == 3); + assert(prime->val[BN_LIMBS - 1] % 4 == 3); - // e = (prime + 1) // 4 - bignum256 e = {0}; - bn_copy(prime, &e); - bn_addi(&e, 1); - bn_rshift(&e); - bn_rshift(&e); + // e = (prime + 1) // 4 + bignum256 e = {0}; + bn_copy(prime, &e); + bn_addi(&e, 1); + bn_rshift(&e); + bn_rshift(&e); - bn_power_mod(x, &e, prime, x); - bn_mod(x, prime); + bn_power_mod(x, &e, prime, x); + bn_mod(x, prime); - memzero(&e, sizeof(e)); + memzero(&e, sizeof(e)); } // a = 1/a % 2**n @@ -878,26 +867,26 @@ void bn_sqrt(bignum256 *x, const bignum256 *prime) { // The function doesn't have neither constant control flow nor constant memory // access flow with regard to n uint32_t inverse_mod_power_two(uint32_t a, uint32_t n) { - // Uses "Explicit Quadratic Modular inverse modulo 2" from section 3.3 of "On - // Newton-Raphson iteration for multiplicative inverses modulo prime powers" - // by Jean-Guillaume Dumas, see - // https://arxiv.org/pdf/1209.6626.pdf + // Uses "Explicit Quadratic Modular inverse modulo 2" from section 3.3 of "On + // Newton-Raphson iteration for multiplicative inverses modulo prime powers" + // by Jean-Guillaume Dumas, see + // https://arxiv.org/pdf/1209.6626.pdf - // 1/a % 2**n - // = (2-a) * product([1 + (a-1)**(2**i) for i in range(1, floor(log2(n)))]) + // 1/a % 2**n + // = (2-a) * product([1 + (a-1)**(2**i) for i in range(1, floor(log2(n)))]) - uint32_t acc = 2 - a; - uint32_t f = a - 1; + uint32_t acc = 2 - a; + uint32_t f = a - 1; - // mask = (1 << n) - 1 - uint32_t mask = n == 32 ? 0xFFFFFFFF : (1u << n) - 1; + // mask = (1 << n) - 1 + uint32_t mask = n == 32 ? 0xFFFFFFFF : (1u << n) - 1; - for (uint32_t i = 1; i < n; i <<= 1) { - f = (f * f) & mask; - acc = (acc * (1 + f)) & mask; - } + for(uint32_t i = 1; i < n; i <<= 1) { + f = (f * f) & mask; + acc = (acc * (1 + f)) & mask; + } - return acc; + return acc; } // x = (x / 2**BITS_PER_LIMB) % prime @@ -906,56 +895,55 @@ uint32_t inverse_mod_power_two(uint32_t a, uint32_t n) { // Guarantees x is normalized // If x is partly reduced (fully reduced) modulo prime, // guarantess x will be partly reduced (fully reduced) modulo prime -void bn_divide_base(bignum256 *x, const bignum256 *prime) { - // Uses an explicit formula for the modular inverse of power of two - // (x / 2**n) % prime == (x + ((-x / prime) % 2**n) * prime) // 2**n - // Proof: - // (x + ((-x / prime) % 2**n) * prime) % 2**n - // == (x - x / prime * prime) % 2**n - // == 0 - // (x + ((-1 / prime) % 2**n) * prime) % prime - // == x - // if x < prime: - // (x + ((-x / prime) % 2**n) * prime) // 2**n - // <= ((prime - 1) + (2**n - 1) * prime) / 2**n - // == (2**n * prime - 1) / 2**n == prime - 1 / 2**n < prime - // if x < 2 * prime: - // (x + ((-x / prime) % 2**n) * prime) // 2**n - // <= ((2 * prime - 1) + (2**n - 1) * prime) / 2**n - // == (2**n * prime + prime - 1) / 2**n - // == prime + (prime - 1) / 2**n < 2 * prime - - // m = (-x / prime) % 2**BITS_PER_LIMB - uint32_t m = (x->val[0] * (BN_BASE - inverse_mod_power_two( - prime->val[0], BN_BITS_PER_LIMB))) & - BN_LIMB_MASK; - // m < 2**BITS_PER_LIMB - - uint64_t acc = x->val[0] + (uint64_t)m * prime->val[0]; - acc >>= BN_BITS_PER_LIMB; - - for (int i = 1; i < BN_LIMBS; i++) { - acc = acc + x->val[i] + (uint64_t)m * prime->val[i]; - // acc does not overflow 64 bits - // acc == acc + x + m * prime - // <= 2**(64 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB) - // 2**(BITS_PER_LIMB) * 2**(BITS_PER_LIMB) - // <= 2**(2 * BITS_PER_LIMB) + 2**(64 - BITS_PER_LIMB) + - // 2**(BITS_PER_LIMB) - // <= 2**58 + 2**35 + 2**29 < 2**64 - - x->val[i - 1] = acc & BN_LIMB_MASK; +void bn_divide_base(bignum256* x, const bignum256* prime) { + // Uses an explicit formula for the modular inverse of power of two + // (x / 2**n) % prime == (x + ((-x / prime) % 2**n) * prime) // 2**n + // Proof: + // (x + ((-x / prime) % 2**n) * prime) % 2**n + // == (x - x / prime * prime) % 2**n + // == 0 + // (x + ((-1 / prime) % 2**n) * prime) % prime + // == x + // if x < prime: + // (x + ((-x / prime) % 2**n) * prime) // 2**n + // <= ((prime - 1) + (2**n - 1) * prime) / 2**n + // == (2**n * prime - 1) / 2**n == prime - 1 / 2**n < prime + // if x < 2 * prime: + // (x + ((-x / prime) % 2**n) * prime) // 2**n + // <= ((2 * prime - 1) + (2**n - 1) * prime) / 2**n + // == (2**n * prime + prime - 1) / 2**n + // == prime + (prime - 1) / 2**n < 2 * prime + + // m = (-x / prime) % 2**BITS_PER_LIMB + uint32_t m = (x->val[0] * (BN_BASE - inverse_mod_power_two(prime->val[0], BN_BITS_PER_LIMB))) & + BN_LIMB_MASK; + // m < 2**BITS_PER_LIMB + + uint64_t acc = x->val[0] + (uint64_t)m * prime->val[0]; acc >>= BN_BITS_PER_LIMB; - // acc < 2**35 == 2**(64 - BITS_PER_LIMB) - // acc == x[:i + 1] + m * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } + for(int i = 1; i < BN_LIMBS; i++) { + acc = acc + x->val[i] + (uint64_t)m * prime->val[i]; + // acc does not overflow 64 bits + // acc == acc + x + m * prime + // <= 2**(64 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB) + // 2**(BITS_PER_LIMB) * 2**(BITS_PER_LIMB) + // <= 2**(2 * BITS_PER_LIMB) + 2**(64 - BITS_PER_LIMB) + + // 2**(BITS_PER_LIMB) + // <= 2**58 + 2**35 + 2**29 < 2**64 + + x->val[i - 1] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc < 2**35 == 2**(64 - BITS_PER_LIMB) + + // acc == x[:i + 1] + m * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) + } - x->val[BN_LIMBS - 1] = acc; + x->val[BN_LIMBS - 1] = acc; - assert(acc >> BN_BITS_PER_LIMB == 0); + assert(acc >> BN_BITS_PER_LIMB == 0); - // clang-format off + // clang-format off // acc >> BITS_PER_LIMB == 0 // Proof: // acc >> BITS_PER_LIMB @@ -965,7 +953,7 @@ void bn_divide_base(bignum256 *x, const bignum256 *prime) { // == 2**(BITS_PER_LIMB * LIMBS) - 1 + 2**(BITS_PER_LIMB * (LIMBS + 1)) - 2**(BITS_PER_LIMB * LIMBS) - 2**BITS_PER_LIMB + 1 >> BITS_PER_LIMB * (LIMBS + 1) // == 2**(BITS_PER_LIMB * (LIMBS + 1)) - 2**BITS_PER_LIMB >> BITS_PER_LIMB * (LIMBS + 1) // == 0 - // clang-format on + // clang-format on } #if !USE_INVERSE_FAST @@ -976,21 +964,21 @@ void bn_divide_base(bignum256 *x, const bignum256 *prime) { // Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 // The function doesn't have neither constant control flow nor constant memory // access flow with regard to prime -static void bn_inverse_slow(bignum256 *x, const bignum256 *prime) { - // Uses formula 1/x % prime == x**(prime - 2) % prime - // See https://en.wikipedia.org/wiki/Fermat%27s_little_theorem +static void bn_inverse_slow(bignum256* x, const bignum256* prime) { + // Uses formula 1/x % prime == x**(prime - 2) % prime + // See https://en.wikipedia.org/wiki/Fermat%27s_little_theorem - bn_fast_mod(x, prime); + bn_fast_mod(x, prime); - // e = prime - 2 - bignum256 e = {0}; - bn_read_uint32(2, &e); - bn_subtract(prime, &e, &e); + // e = prime - 2 + bignum256 e = {0}; + bn_read_uint32(2, &e); + bn_subtract(prime, &e, &e); - bn_power_mod(x, &e, prime, x); - bn_mod(x, prime); + bn_power_mod(x, &e, prime, x); + bn_mod(x, prime); - memzero(&e, sizeof(e)); + memzero(&e, sizeof(e)); } #endif @@ -1096,12 +1084,12 @@ static void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { // Assumes prime is odd, normalized, 2**256 - 2**224 <= prime <= 2**256 // The function has constant control flow but not constant memory access flow // with regard to prime and x -static void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { - // Custom constant time version of "The Almost Montgomery Inverse" from the - // section 3 of "Constant Time Modular Inversion" by Joppe W. Bos - // See http://www.joppebos.com/files/CTInversion.pdf +static void bn_inverse_fast(bignum256* x, const bignum256* prime) { + // Custom constant time version of "The Almost Montgomery Inverse" from the + // section 3 of "Constant Time Modular Inversion" by Joppe W. Bos + // See http://www.joppebos.com/files/CTInversion.pdf - /* + /* u = prime v = x % prime s = 1 @@ -1129,77 +1117,76 @@ static void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { return s */ - bn_fast_mod(x, prime); - bn_mod(x, prime); + bn_fast_mod(x, prime); + bn_mod(x, prime); - bignum256 u = {0}, v = {0}, r = {0}, s = {0}; - bn_copy(prime, &u); - bn_copy(x, &v); - bn_one(&s); - bn_zero(&r); + bignum256 u = {0}, v = {0}, r = {0}, s = {0}; + bn_copy(prime, &u); + bn_copy(x, &v); + bn_one(&s); + bn_zero(&r); - bignum256 zero = {0}; - bn_zero(&zero); + bignum256 zero = {0}; + bn_zero(&zero); - int k = 0; + int k = 0; - int finished = 0, u_even = 0, v_even = 0, v_less_u = 0, b1 = 0, b2 = 0, - b3 = 0, b4 = 0; - finished = 0; + int finished = 0, u_even = 0, v_even = 0, v_less_u = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0; + finished = 0; - for (int i = 0; i < 2 * BN_LIMBS * BN_BITS_PER_LIMB; i++) { - finished = finished | -bn_is_one(&v); - u_even = -bn_is_even(&u); - v_even = -bn_is_even(&v); - v_less_u = -bn_is_less(&v, &u); + for(int i = 0; i < 2 * BN_LIMBS * BN_BITS_PER_LIMB; i++) { + finished = finished | -bn_is_one(&v); + u_even = -bn_is_even(&u); + v_even = -bn_is_even(&v); + v_less_u = -bn_is_less(&v, &u); - b1 = ~finished & u_even; - b2 = ~finished & ~b1 & v_even; - b3 = ~finished & ~b1 & ~b2 & v_less_u; - b4 = ~finished & ~b1 & ~b2 & ~b3; + b1 = ~finished & u_even; + b2 = ~finished & ~b1 & v_even; + b3 = ~finished & ~b1 & ~b2 & v_less_u; + b4 = ~finished & ~b1 & ~b2 & ~b3; // The ternary operator for pointers with constant control flow // BN_INVERSE_FAST_TERNARY(c, t, f) = t if c else f // Very nasty hack, sorry for that #define BN_INVERSE_FAST_TERNARY(c, t, f) \ - ((void *)(((c) & (uintptr_t)(t)) | (~(c) & (uintptr_t)(f)))) + ((void*)(((c) & (uintptr_t)(t)) | (~(c) & (uintptr_t)(f)))) - bn_subtract(BN_INVERSE_FAST_TERNARY(b3, &u, &v), - BN_INVERSE_FAST_TERNARY( - b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &v, &u), &zero), - BN_INVERSE_FAST_TERNARY(b3, &u, &v)); + bn_subtract( + BN_INVERSE_FAST_TERNARY(b3, &u, &v), + BN_INVERSE_FAST_TERNARY(b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &v, &u), &zero), + BN_INVERSE_FAST_TERNARY(b3, &u, &v)); - bn_add(BN_INVERSE_FAST_TERNARY(b3, &r, &s), - BN_INVERSE_FAST_TERNARY(b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &s, &r), - &zero)); - bn_rshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &u, &v)); - bn_lshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &s, &r)); + bn_add( + BN_INVERSE_FAST_TERNARY(b3, &r, &s), + BN_INVERSE_FAST_TERNARY(b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &s, &r), &zero)); + bn_rshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &u, &v)); + bn_lshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &s, &r)); - k = k - ~finished; - } + k = k - ~finished; + } - // s = s / 2**(k // BITS_PER_LIMB * BITS_PER_LIMB) - for (int i = 0; i < 2 * BN_LIMBS; i++) { - // s = s / 2**BITS_PER_LIMB % prime if i < k // BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_divide_base(&r, prime); - bn_cmov(&s, i < k / BN_BITS_PER_LIMB, &r, &s); - } + // s = s / 2**(k // BITS_PER_LIMB * BITS_PER_LIMB) + for(int i = 0; i < 2 * BN_LIMBS; i++) { + // s = s / 2**BITS_PER_LIMB % prime if i < k // BITS_PER_LIMB else s + bn_copy(&s, &r); + bn_divide_base(&r, prime); + bn_cmov(&s, i < k / BN_BITS_PER_LIMB, &r, &s); + } - // s = s / 2**(k % BITS_PER_LIMB) - for (int i = 0; i < BN_BITS_PER_LIMB; i++) { - // s = s / 2 % prime if i < k % BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_mult_half(&r, prime); - bn_cmov(&s, i < k % BN_BITS_PER_LIMB, &r, &s); - } + // s = s / 2**(k % BITS_PER_LIMB) + for(int i = 0; i < BN_BITS_PER_LIMB; i++) { + // s = s / 2 % prime if i < k % BITS_PER_LIMB else s + bn_copy(&s, &r); + bn_mult_half(&r, prime); + bn_cmov(&s, i < k % BN_BITS_PER_LIMB, &r, &s); + } - bn_cmov(x, bn_is_zero(x), x, &s); + bn_cmov(x, bn_is_zero(x), x, &s); - memzero(&u, sizeof(u)); - memzero(&v, sizeof(v)); - memzero(&r, sizeof(s)); - memzero(&s, sizeof(s)); + memzero(&u, sizeof(u)); + memzero(&v, sizeof(v)); + memzero(&r, sizeof(s)); + memzero(&s, sizeof(s)); } #endif @@ -1350,68 +1337,68 @@ static void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { // Normalizes x // Assumes x < 2**261 == 2**(LIMBS * BITS_PER_LIMB) // Guarantees x is normalized -void bn_normalize(bignum256 *x) { - uint32_t acc = 0; +void bn_normalize(bignum256* x) { + uint32_t acc = 0; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // acc + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) - // == 7 + 2**29 - 1 < 2**32 + for(int i = 0; i < BN_LIMBS; i++) { + acc += x->val[i]; + // acc doesn't overflow 32 bits + // Proof: + // acc + x[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + // == 7 + 2**29 - 1 < 2**32 - x->val[i] = acc & BN_LIMB_MASK; - acc >>= (BN_BITS_PER_LIMB); - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - } + x->val[i] = acc & BN_LIMB_MASK; + acc >>= (BN_BITS_PER_LIMB); + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + } } // x = x + y // Assumes x, y are normalized, x + y < 2**(LIMBS*BITS_PER_LIMB) == 2**261 // Guarantees x is normalized // Works properly even if &x == &y -void bn_add(bignum256 *x, const bignum256 *y) { - uint32_t acc = 0; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i] + y->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // acc + x[i] + y[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) - // == (2**(32 - BITS_PER_LIMB) - 1) + 2**(BITS_PER_LIMB + 1) - 2 - // == 7 + 2**30 - 2 < 2**32 +void bn_add(bignum256* x, const bignum256* y) { + uint32_t acc = 0; + for(int i = 0; i < BN_LIMBS; i++) { + acc += x->val[i] + y->val[i]; + // acc doesn't overflow 32 bits + // Proof: + // acc + x[i] + y[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) + // == (2**(32 - BITS_PER_LIMB) - 1) + 2**(BITS_PER_LIMB + 1) - 2 + // == 7 + 2**30 - 2 < 2**32 - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + x->val[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc == x[:i + 1] + y[:i + 1] >> BITS_PER_LIMB * (i + 1) - } + // acc == x[:i + 1] + y[:i + 1] >> BITS_PER_LIMB * (i + 1) + } - // assert(acc == 0); // assert x + y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + y[:LIMBS] >> LIMBS * BITS_PER_LIMB - // == x + y >> LIMBS * BITS_PER_LIMB - // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> LIMBS * BITS_PER_LIMB == 0 + // assert(acc == 0); // assert x + y < 2**261 + // acc == 0 + // Proof: + // acc == x[:LIMBS] + y[:LIMBS] >> LIMBS * BITS_PER_LIMB + // == x + y >> LIMBS * BITS_PER_LIMB + // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> LIMBS * BITS_PER_LIMB == 0 } // x = x + y % prime // Assumes x, y are normalized // Guarantees x is normalized and partly reduced modulo prime // Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 -void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime) { - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] += y->val[i]; - // x[i] doesn't overflow 32 bits - // Proof: - // x[i] + y[i] - // <= 2 * (2**BITS_PER_LIMB - 1) - // == 2**30 - 2 < 2**32 - } +void bn_addmod(bignum256* x, const bignum256* y, const bignum256* prime) { + for(int i = 0; i < BN_LIMBS; i++) { + x->val[i] += y->val[i]; + // x[i] doesn't overflow 32 bits + // Proof: + // x[i] + y[i] + // <= 2 * (2**BITS_PER_LIMB - 1) + // == 2**30 - 2 < 2**32 + } - bn_fast_mod(x, prime); + bn_fast_mod(x, prime); } // x = x + y @@ -1419,37 +1406,37 @@ void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime) { // Assumes y <= 2**32 - 2**29 == 2**32 - 2**BITS_PER_LIMB and // x + y < 2**261 == 2**(LIMBS * BITS_PER_LIMB) // Guarantees x is normalized -void bn_addi(bignum256 *x, uint32_t y) { - // assert(y <= 3758096384); // assert y <= 2**32 - 2**29 - uint32_t acc = y; +void bn_addi(bignum256* x, uint32_t y) { + // assert(y <= 3758096384); // assert y <= 2**32 - 2**29 + uint32_t acc = y; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // if i == 0: - // acc + x[i] == y + x[0] - // <= (2**32 - 2**BITS_PER_LIMB) + (2**BITS_PER_LIMB - 1) - // == 2**32 - 1 < 2**32 - // else: - // acc + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) - // == 7 + 2**29 - 1 < 2**32 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= (BN_BITS_PER_LIMB); - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == x[:i + 1] + y >> BITS_PER_LIMB * (i + 1) - } + for(int i = 0; i < BN_LIMBS; i++) { + acc += x->val[i]; + // acc doesn't overflow 32 bits + // Proof: + // if i == 0: + // acc + x[i] == y + x[0] + // <= (2**32 - 2**BITS_PER_LIMB) + (2**BITS_PER_LIMB - 1) + // == 2**32 - 1 < 2**32 + // else: + // acc + x[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + // == 7 + 2**29 - 1 < 2**32 + + x->val[i] = acc & BN_LIMB_MASK; + acc >>= (BN_BITS_PER_LIMB); + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + + // acc == x[:i + 1] + y >> BITS_PER_LIMB * (i + 1) + } - // assert(acc == 0); // assert x + y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + y << LIMBS * BITS_PER_LIMB - // == x + y << LIMBS * BITS_PER_LIMB - // <= 2**(LIMBS + BITS_PER_LIMB) - 1 << LIMBS * BITS_PER_LIMB - // == 0 + // assert(acc == 0); // assert x + y < 2**261 + // acc == 0 + // Proof: + // acc == x[:LIMBS] + y << LIMBS * BITS_PER_LIMB + // == x + y << LIMBS * BITS_PER_LIMB + // <= 2**(LIMBS + BITS_PER_LIMB) - 1 << LIMBS * BITS_PER_LIMB + // == 0 } // x = x - y % prime @@ -1460,35 +1447,35 @@ void bn_addi(bignum256 *x, uint32_t y) { // If x is fully reduced modulo prime, // guarantess x will be partly reduced modulo prime // Assumes prime is nonzero and normalized -void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime) { - assert(y < prime->val[0]); +void bn_subi(bignum256* x, uint32_t y, const bignum256* prime) { + assert(y < prime->val[0]); - // x = x + prime - y + // x = x + prime - y - uint32_t acc = -y; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i] + prime->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + x[i] + prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) - // <= 7 + 2**30 - 2 < 2**32 - // acc + x[i] + prime[i] - // >= -y + prime[0] >= 0 + uint32_t acc = -y; + for(int i = 0; i < BN_LIMBS; i++) { + acc += x->val[i] + prime->val[i]; + // acc neither overflows 32 bits nor underflows 0 + // Proof: + // acc + x[i] + prime[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) + // <= 7 + 2**30 - 2 < 2**32 + // acc + x[i] + prime[i] + // >= -y + prime[0] >= 0 - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + x->val[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc == x[:i + 1] + prime[:i + 1] - y >> BITS_PER_LIMB * (i + 1) - } + // acc == x[:i + 1] + prime[:i + 1] - y >> BITS_PER_LIMB * (i + 1) + } - // assert(acc == 0); // assert x + prime - y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + prime[:LIMBS] - y >> BITS_PER_LIMB * LIMBS - // == x + prime - y >> BITS_PER_LIMB * LIMBS - // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> BITS_PER_LIMB * LIMBS == 0 + // assert(acc == 0); // assert x + prime - y < 2**261 + // acc == 0 + // Proof: + // acc == x[:LIMBS] + prime[:LIMBS] - y >> BITS_PER_LIMB * LIMBS + // == x + prime - y >> BITS_PER_LIMB * LIMBS + // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> BITS_PER_LIMB * LIMBS == 0 } // res = x - y % prime @@ -1497,37 +1484,36 @@ void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime) { // Assumes x + 2 * prime - y < 2**261 == 2**(BITS_PER_LIMB * LIMBS) // Guarantees res is normalized // Assumes prime is nonzero and normalized -void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, - const bignum256 *prime) { - // res = x + (2 * prime - y) - - uint32_t acc = 1; +void bn_subtractmod(const bignum256* x, const bignum256* y, bignum256* res, const bignum256* prime) { + // res = x + (2 * prime - y) - for (int i = 0; i < BN_LIMBS; i++) { - acc += (BN_BASE - 1) + x->val[i] + 2 * prime->val[i] - y->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] - // >= (BASE - 1) - y[i] - // == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) == 0 - // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] - // <= acc + (BASE - 1) + x[i] + 2 * prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) + 2 * (2**BITS_PER_LIMB - 1) - // <= (2**(32 - BITS_PER_LIMB) - 1) + 4 * (2**BITS_PER_LIMB - 1) - // == 7 + 4 * 2**29 - 4 == 2**31 + 3 < 2**32 - - res->val[i] = acc & (BN_BASE - 1); - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + uint32_t acc = 1; - // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i+1] - y[:i+1] + 2*prime[:i+1] - // >> BITS_PER_LIMB * (i+1) - } + for(int i = 0; i < BN_LIMBS; i++) { + acc += (BN_BASE - 1) + x->val[i] + 2 * prime->val[i] - y->val[i]; + // acc neither overflows 32 bits nor underflows 0 + // Proof: + // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] + // >= (BASE - 1) - y[i] + // == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) == 0 + // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] + // <= acc + (BASE - 1) + x[i] + 2 * prime[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + + // (2**BITS_PER_LIMB - 1) + 2 * (2**BITS_PER_LIMB - 1) + // <= (2**(32 - BITS_PER_LIMB) - 1) + 4 * (2**BITS_PER_LIMB - 1) + // == 7 + 4 * 2**29 - 4 == 2**31 + 3 < 2**32 + + res->val[i] = acc & (BN_BASE - 1); + acc >>= BN_BITS_PER_LIMB; + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + + // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i+1] - y[:i+1] + 2*prime[:i+1] + // >> BITS_PER_LIMB * (i+1) + } - // assert(acc == 1); // assert x + 2 * prime - y < 2**261 + // assert(acc == 1); // assert x + 2 * prime - y < 2**261 - // clang-format off + // clang-format off // acc == 1 // Proof: // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] + 2 * prime[:LIMBS] >> BITS_PER_LIMB * LIMBS @@ -1542,7 +1528,7 @@ void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, // == 2**(BITS_PER_LIMB * LIMBS) + x + (2 * prime - y) >> BITS_PER_LIMB * LIMBS // >= 2**(BITS_PER_LIMB * LIMBS) + 0 + 1 >> BITS_PER_LIMB * LIMBS // == 1 - // clang-format on + // clang-format on } // res = x - y @@ -1550,32 +1536,32 @@ void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, // Guarantees res is normalized // Works properly even if &x == &y or &x == &res or &y == &res or // &x == &y == &res -void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res) { - uint32_t acc = 1; - for (int i = 0; i < BN_LIMBS; i++) { - acc += (BN_BASE - 1) + x->val[i] - y->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + (BASE - 1) + x[i] - y[i] - // >= (BASE - 1) - y == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) - // == 0 - // acc + (BASE - 1) + x[i] - y[i] - // <= acc + (BASE - 1) + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) - // == 7 + 2 * 2**29 < 2 **32 - - res->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i + 1] - y[:i + 1] - // >> BITS_PER_LIMB * (i + 1) - } +void bn_subtract(const bignum256* x, const bignum256* y, bignum256* res) { + uint32_t acc = 1; + for(int i = 0; i < BN_LIMBS; i++) { + acc += (BN_BASE - 1) + x->val[i] - y->val[i]; + // acc neither overflows 32 bits nor underflows 0 + // Proof: + // acc + (BASE - 1) + x[i] - y[i] + // >= (BASE - 1) - y == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) + // == 0 + // acc + (BASE - 1) + x[i] - y[i] + // <= acc + (BASE - 1) + x[i] + // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + + // (2**BITS_PER_LIMB - 1) + // == 7 + 2 * 2**29 < 2 **32 + + res->val[i] = acc & BN_LIMB_MASK; + acc >>= BN_BITS_PER_LIMB; + // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 + + // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i + 1] - y[:i + 1] + // >> BITS_PER_LIMB * (i + 1) + } - // assert(acc == 1); // assert x >= y + // assert(acc == 1); // assert x >= y - // clang-format off + // clang-format off // acc == 1 // Proof: // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] >> BITS_PER_LIMB * LIMBS diff --git a/crypto/bignum.h b/crypto/bignum.h index f9213fbe76e..858613401d5 100644 --- a/crypto/bignum.h +++ b/crypto/bignum.h @@ -40,136 +40,156 @@ // Represents the number sum([val[i] * 2**(29*i) for i in range(9)) typedef struct { - uint32_t val[BN_LIMBS]; + uint32_t val[BN_LIMBS]; } bignum256; -static inline uint32_t read_be(const uint8_t *data) { - return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | - (((uint32_t)data[2]) << 8) | (((uint32_t)data[3])); +static inline uint32_t read_be(const uint8_t* data) { + return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | (((uint32_t)data[2]) << 8) | + (((uint32_t)data[3])); } -static inline void write_be(uint8_t *data, uint32_t x) { - data[0] = x >> 24; - data[1] = x >> 16; - data[2] = x >> 8; - data[3] = x; +static inline void write_be(uint8_t* data, uint32_t x) { + data[0] = x >> 24; + data[1] = x >> 16; + data[2] = x >> 8; + data[3] = x; } -static inline uint32_t read_le(const uint8_t *data) { - return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) | - (((uint32_t)data[1]) << 8) | (((uint32_t)data[0])); +static inline uint32_t read_le(const uint8_t* data) { + return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) | (((uint32_t)data[1]) << 8) | + (((uint32_t)data[0])); } -static inline void write_le(uint8_t *data, uint32_t x) { - data[3] = x >> 24; - data[2] = x >> 16; - data[1] = x >> 8; - data[0] = x; +static inline void write_le(uint8_t* data, uint32_t x) { + data[3] = x >> 24; + data[2] = x >> 16; + data[1] = x >> 8; + data[0] = x; } -void bn_read_be(const uint8_t *in_number, bignum256 *out_number); -void bn_write_be(const bignum256 *in_number, uint8_t *out_number); -void bn_read_le(const uint8_t *in_number, bignum256 *out_number); -void bn_write_le(const bignum256 *in_number, uint8_t *out_number); -void bn_read_uint32(uint32_t in_number, bignum256 *out_number); -void bn_read_uint64(uint64_t in_number, bignum256 *out_number); -int bn_bitcount(const bignum256 *x); -unsigned int bn_digitcount(const bignum256 *x); -void bn_zero(bignum256 *x); -void bn_one(bignum256 *x); -int bn_is_zero(const bignum256 *x); -int bn_is_one(const bignum256 *x); -int bn_is_less(const bignum256 *x, const bignum256 *y); -int bn_is_equal(const bignum256 *x, const bignum256 *y); -void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, - const bignum256 *falsecase); -void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime); -void bn_lshift(bignum256 *x); -void bn_rshift(bignum256 *x); -void bn_setbit(bignum256 *x, uint16_t i); -void bn_clearbit(bignum256 *x, uint16_t i); -uint32_t bn_testbit(const bignum256 *x, uint16_t i); -void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y); -void bn_mult_half(bignum256 *x, const bignum256 *prime); -void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime); -void bn_mod(bignum256 *x, const bignum256 *prime); -void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime); -void bn_fast_mod(bignum256 *x, const bignum256 *prime); -void bn_power_mod(const bignum256 *x, const bignum256 *e, - const bignum256 *prime, bignum256 *res); -void bn_sqrt(bignum256 *x, const bignum256 *prime); +void bn_read_be(const uint8_t* in_number, bignum256* out_number); +void bn_write_be(const bignum256* in_number, uint8_t* out_number); +void bn_read_le(const uint8_t* in_number, bignum256* out_number); +void bn_write_le(const bignum256* in_number, uint8_t* out_number); +void bn_read_uint32(uint32_t in_number, bignum256* out_number); +void bn_read_uint64(uint64_t in_number, bignum256* out_number); +int bn_bitcount(const bignum256* x); +unsigned int bn_digitcount(const bignum256* x); +void bn_zero(bignum256* x); +void bn_one(bignum256* x); +int bn_is_zero(const bignum256* x); +int bn_is_one(const bignum256* x); +int bn_is_less(const bignum256* x, const bignum256* y); +int bn_is_equal(const bignum256* x, const bignum256* y); +void bn_cmov( + bignum256* res, + volatile uint32_t cond, + const bignum256* truecase, + const bignum256* falsecase); +void bn_cnegate(volatile uint32_t cond, bignum256* x, const bignum256* prime); +void bn_lshift(bignum256* x); +void bn_rshift(bignum256* x); +void bn_setbit(bignum256* x, uint16_t i); +void bn_clearbit(bignum256* x, uint16_t i); +uint32_t bn_testbit(const bignum256* x, uint16_t i); +void bn_xor(bignum256* res, const bignum256* x, const bignum256* y); +void bn_mult_half(bignum256* x, const bignum256* prime); +void bn_mult_k(bignum256* x, uint8_t k, const bignum256* prime); +void bn_mod(bignum256* x, const bignum256* prime); +void bn_multiply(const bignum256* k, bignum256* x, const bignum256* prime); +void bn_fast_mod(bignum256* x, const bignum256* prime); +void bn_power_mod(const bignum256* x, const bignum256* e, const bignum256* prime, bignum256* res); +void bn_sqrt(bignum256* x, const bignum256* prime); uint32_t inverse_mod_power_two(uint32_t a, uint32_t n); -void bn_divide_base(bignum256 *x, const bignum256 *prime); -void bn_normalize(bignum256 *x); -void bn_add(bignum256 *x, const bignum256 *y); -void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime); -void bn_addi(bignum256 *x, uint32_t y); -void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime); -void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, - const bignum256 *prime); -void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res); -void bn_long_division(bignum256 *x, uint32_t d, bignum256 *q, uint32_t *r); -void bn_divmod58(bignum256 *x, uint32_t *r); -void bn_divmod1000(bignum256 *x, uint32_t *r); -void bn_inverse(bignum256 *x, const bignum256 *prime); -size_t bn_format(const bignum256 *amount, const char *prefix, - const char *suffix, unsigned int decimals, int exponent, - bool trailing, char thousands, char *output, - size_t output_length); +void bn_divide_base(bignum256* x, const bignum256* prime); +void bn_normalize(bignum256* x); +void bn_add(bignum256* x, const bignum256* y); +void bn_addmod(bignum256* x, const bignum256* y, const bignum256* prime); +void bn_addi(bignum256* x, uint32_t y); +void bn_subi(bignum256* x, uint32_t y, const bignum256* prime); +void bn_subtractmod(const bignum256* x, const bignum256* y, bignum256* res, const bignum256* prime); +void bn_subtract(const bignum256* x, const bignum256* y, bignum256* res); +void bn_long_division(bignum256* x, uint32_t d, bignum256* q, uint32_t* r); +void bn_divmod58(bignum256* x, uint32_t* r); +void bn_divmod1000(bignum256* x, uint32_t* r); +void bn_inverse(bignum256* x, const bignum256* prime); +size_t bn_format( + const bignum256* amount, + const char* prefix, + const char* suffix, + unsigned int decimals, + int exponent, + bool trailing, + char thousands, + char* output, + size_t output_length); // Returns (uint32_t) in_number // Assumes in_number < 2**32 // Assumes in_number is normalized -static inline uint32_t bn_write_uint32(const bignum256 *in_number) { - return in_number->val[0] | (in_number->val[1] << BN_BITS_PER_LIMB); +static inline uint32_t bn_write_uint32(const bignum256* in_number) { + return in_number->val[0] | (in_number->val[1] << BN_BITS_PER_LIMB); } // Returns (uint64_t) in_number // Assumes in_number < 2**64 // Assumes in_number is normalized -static inline uint64_t bn_write_uint64(const bignum256 *in_number) { - uint64_t acc; - acc = in_number->val[2]; - acc <<= BN_BITS_PER_LIMB; - acc |= in_number->val[1]; - acc <<= BN_BITS_PER_LIMB; - acc |= in_number->val[0]; - return acc; +static inline uint64_t bn_write_uint64(const bignum256* in_number) { + uint64_t acc; + acc = in_number->val[2]; + acc <<= BN_BITS_PER_LIMB; + acc |= in_number->val[1]; + acc <<= BN_BITS_PER_LIMB; + acc |= in_number->val[0]; + return acc; } // y = x -static inline void bn_copy(const bignum256 *x, bignum256 *y) { *y = *x; } +static inline void bn_copy(const bignum256* x, bignum256* y) { + *y = *x; +} // Returns x % 2 == 0 -static inline int bn_is_even(const bignum256 *x) { - return (x->val[0] & 1) == 0; +static inline int bn_is_even(const bignum256* x) { + return (x->val[0] & 1) == 0; } // Returns x % 2 == 0 -static inline int bn_is_odd(const bignum256 *x) { return (x->val[0] & 1) == 1; } - -static inline size_t bn_format_uint64(uint64_t amount, const char *prefix, - const char *suffix, unsigned int decimals, - int exponent, bool trailing, - char thousands, char *output, - size_t output_length) { - bignum256 bn_amount; - bn_read_uint64(amount, &bn_amount); - - return bn_format(&bn_amount, prefix, suffix, decimals, exponent, trailing, - thousands, output, output_length); +static inline int bn_is_odd(const bignum256* x) { + return (x->val[0] & 1) == 1; +} + +static inline size_t bn_format_uint64( + uint64_t amount, + const char* prefix, + const char* suffix, + unsigned int decimals, + int exponent, + bool trailing, + char thousands, + char* output, + size_t output_length) { + bignum256 bn_amount; + bn_read_uint64(amount, &bn_amount); + + return bn_format( + &bn_amount, prefix, suffix, decimals, exponent, trailing, thousands, output, output_length); } -static inline size_t bn_format_amount(uint64_t amount, const char *prefix, - const char *suffix, unsigned int decimals, - char *output, size_t output_length) { - return bn_format_uint64(amount, prefix, suffix, decimals, 0, false, ',', - output, output_length); +static inline size_t bn_format_amount( + uint64_t amount, + const char* prefix, + const char* suffix, + unsigned int decimals, + char* output, + size_t output_length) { + return bn_format_uint64( + amount, prefix, suffix, decimals, 0, false, ',', output, output_length); } #if USE_BN_PRINT -void bn_print(const bignum256 *x); -void bn_print_raw(const bignum256 *x); +void bn_print(const bignum256* x); +void bn_print_raw(const bignum256* x); #endif #endif diff --git a/crypto/bip32.c b/crypto/bip32.c index b8a787e2378..fcd722aee8a 100644 --- a/crypto/bip32.c +++ b/crypto/bip32.c @@ -33,15 +33,15 @@ #include "cardano.h" #include "curves.h" #include "ecdsa.h" -#include "ed25519-donna/ed25519-sha3.h" -#include "ed25519-donna/ed25519.h" +#include "ed25519_donna/ed25519_sha3.h" +#include "ed25519_donna/ed25519.h" #include "hmac.h" #include "nist256p1.h" #include "secp256k1.h" #include "sha2.h" #include "sha3.h" #if USE_KECCAK -#include "ed25519-donna/ed25519-keccak.h" +#include "ed25519_donna/ed25519_keccak.h" #endif #if USE_NEM #include "nem.h" @@ -86,280 +86,292 @@ const curve_info curve25519_info = { .hasher_script = HASHER_SHA2, }; -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) { - const curve_info *info = get_curve_by_name(curve); - if (info == 0) { - return 0; - } - if (public_key[0] != 0x02 && public_key[0] != 0x03) { // invalid pubkey - return 0; - } - out->curve = info; - out->depth = depth; - out->child_num = child_num; - memcpy(out->chain_code, chain_code, 32); - memzero(out->private_key, 32); - memzero(out->private_key_extension, 32); - memcpy(out->public_key, public_key, 33); - return 1; +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) { + const curve_info* info = get_curve_by_name(curve); + if(info == 0) { + return 0; + } + if(public_key[0] != 0x02 && public_key[0] != 0x03) { // invalid pubkey + return 0; + } + out->curve = info; + out->depth = depth; + out->child_num = child_num; + memcpy(out->chain_code, chain_code, 32); + memzero(out->private_key, 32); + memzero(out->private_key_extension, 32); + memcpy(out->public_key, public_key, 33); + return 1; } -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) { - bool failed = false; - const curve_info *info = get_curve_by_name(curve); - if (info == 0) { - failed = true; - } else if (info->params) { - bignum256 a = {0}; - bn_read_be(private_key, &a); - if (bn_is_zero(&a)) { // == 0 - failed = true; - } else { - if (!bn_is_less(&a, &info->params->order)) { // >= order +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) { + bool failed = false; + const curve_info* info = get_curve_by_name(curve); + if(info == 0) { failed = true; - } + } else if(info->params) { + bignum256 a = {0}; + bn_read_be(private_key, &a); + if(bn_is_zero(&a)) { // == 0 + failed = true; + } else { + if(!bn_is_less(&a, &info->params->order)) { // >= order + failed = true; + } + } + memzero(&a, sizeof(a)); } - memzero(&a, sizeof(a)); - } - if (failed) { - return 0; - } - - out->curve = info; - out->depth = depth; - out->child_num = child_num; - memcpy(out->chain_code, chain_code, 32); - memcpy(out->private_key, private_key, 32); - memzero(out->public_key, sizeof(out->public_key)); - memzero(out->private_key_extension, sizeof(out->private_key_extension)); - return 1; + if(failed) { + return 0; + } + + out->curve = info; + out->depth = depth; + out->child_num = child_num; + memcpy(out->chain_code, chain_code, 32); + memcpy(out->private_key, private_key, 32); + memzero(out->public_key, sizeof(out->public_key)); + memzero(out->private_key_extension, sizeof(out->private_key_extension)); + return 1; } -int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, - HDNode *out) { - static CONFIDENTIAL uint8_t I[32 + 32]; - memzero(out, sizeof(HDNode)); - out->depth = 0; - out->child_num = 0; - out->curve = get_curve_by_name(curve); - if (out->curve == 0) { - return 0; - } - static CONFIDENTIAL HMAC_SHA512_CTX ctx; - hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name, - strlen(out->curve->bip32_name)); - hmac_sha512_Update(&ctx, seed, seed_len); - hmac_sha512_Final(&ctx, I); - - if (out->curve->params) { - bignum256 a = {0}; - while (true) { - bn_read_be(I, &a); - if (!bn_is_zero(&a) // != 0 - && bn_is_less(&a, &out->curve->params->order)) { // < order - break; - } - hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name, - strlen(out->curve->bip32_name)); - hmac_sha512_Update(&ctx, I, sizeof(I)); - hmac_sha512_Final(&ctx, I); +int hdnode_from_seed(const uint8_t* seed, int seed_len, const char* curve, HDNode* out) { + static CONFIDENTIAL uint8_t I[32 + 32]; + memzero(out, sizeof(HDNode)); + out->depth = 0; + out->child_num = 0; + out->curve = get_curve_by_name(curve); + if(out->curve == 0) { + return 0; } - memzero(&a, sizeof(a)); - } - memcpy(out->private_key, I, 32); - memcpy(out->chain_code, I + 32, 32); - memzero(out->public_key, sizeof(out->public_key)); - memzero(I, sizeof(I)); - return 1; + static CONFIDENTIAL HMAC_SHA512_CTX ctx; + hmac_sha512_Init(&ctx, (const uint8_t*)out->curve->bip32_name, strlen(out->curve->bip32_name)); + hmac_sha512_Update(&ctx, seed, seed_len); + hmac_sha512_Final(&ctx, I); + + if(out->curve->params) { + bignum256 a = {0}; + while(true) { + bn_read_be(I, &a); + if(!bn_is_zero(&a) // != 0 + && bn_is_less(&a, &out->curve->params->order)) { // < order + break; + } + hmac_sha512_Init( + &ctx, (const uint8_t*)out->curve->bip32_name, strlen(out->curve->bip32_name)); + hmac_sha512_Update(&ctx, I, sizeof(I)); + hmac_sha512_Final(&ctx, I); + } + memzero(&a, sizeof(a)); + } + memcpy(out->private_key, I, 32); + memcpy(out->chain_code, I + 32, 32); + memzero(out->public_key, sizeof(out->public_key)); + memzero(I, sizeof(I)); + return 1; } -uint32_t hdnode_fingerprint(HDNode *node) { - uint8_t digest[32] = {0}; - uint32_t fingerprint = 0; +uint32_t hdnode_fingerprint(HDNode* node) { + uint8_t digest[32] = {0}; + uint32_t fingerprint = 0; - hdnode_fill_public_key(node); - hasher_Raw(node->curve->hasher_pubkey, node->public_key, 33, digest); - fingerprint = ((uint32_t)digest[0] << 24) + (digest[1] << 16) + - (digest[2] << 8) + digest[3]; - memzero(digest, sizeof(digest)); - return fingerprint; + hdnode_fill_public_key(node); + hasher_Raw(node->curve->hasher_pubkey, node->public_key, 33, digest); + fingerprint = ((uint32_t)digest[0] << 24) + (digest[1] << 16) + (digest[2] << 8) + digest[3]; + memzero(digest, sizeof(digest)); + return fingerprint; } -int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) { - static CONFIDENTIAL uint8_t data[1 + 32 + 4]; - static CONFIDENTIAL uint8_t I[32 + 32]; - static CONFIDENTIAL bignum256 a, b; +int hdnode_private_ckd_bip32(HDNode* inout, uint32_t i) { + static CONFIDENTIAL uint8_t data[1 + 32 + 4]; + static CONFIDENTIAL uint8_t I[32 + 32]; + static CONFIDENTIAL bignum256 a, b; #if USE_CARDANO - if (inout->curve == &ed25519_cardano_info) { - return 0; - } + if(inout->curve == &ed25519_cardano_info) { + return 0; + } #endif - if (i & 0x80000000) { // private derivation - data[0] = 0; - memcpy(data + 1, inout->private_key, 32); - } else { // public derivation - if (!inout->curve->params) { - return 0; + if(i & 0x80000000) { // private derivation + data[0] = 0; + memcpy(data + 1, inout->private_key, 32); + } else { // public derivation + if(!inout->curve->params) { + return 0; + } + if(hdnode_fill_public_key(inout) != 0) { + return 0; + } + memcpy(data, inout->public_key, 33); } - if (hdnode_fill_public_key(inout) != 0) { - return 0; + write_be(data + 33, i); + + bn_read_be(inout->private_key, &a); + + static CONFIDENTIAL HMAC_SHA512_CTX ctx; + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, sizeof(data)); + hmac_sha512_Final(&ctx, I); + + if(inout->curve->params) { + while(true) { + bool failed = false; + bn_read_be(I, &b); + if(!bn_is_less(&b, &inout->curve->params->order)) { // >= order + failed = true; + } else { + bn_add(&b, &a); + bn_mod(&b, &inout->curve->params->order); + if(bn_is_zero(&b)) { + failed = true; + } + } + + if(!failed) { + bn_write_be(&b, inout->private_key); + break; + } + + data[0] = 1; + memcpy(data + 1, I + 32, 32); + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, sizeof(data)); + hmac_sha512_Final(&ctx, I); + } + } else { + memcpy(inout->private_key, I, 32); } - memcpy(data, inout->public_key, 33); - } - write_be(data + 33, i); - - bn_read_be(inout->private_key, &a); - static CONFIDENTIAL HMAC_SHA512_CTX ctx; - hmac_sha512_Init(&ctx, inout->chain_code, 32); - hmac_sha512_Update(&ctx, data, sizeof(data)); - hmac_sha512_Final(&ctx, I); - - if (inout->curve->params) { - while (true) { - bool failed = false; - bn_read_be(I, &b); - if (!bn_is_less(&b, &inout->curve->params->order)) { // >= order - failed = true; - } else { - bn_add(&b, &a); - bn_mod(&b, &inout->curve->params->order); - if (bn_is_zero(&b)) { - failed = true; - } - } + memcpy(inout->chain_code, I + 32, 32); + inout->depth++; + inout->child_num = i; + memzero(inout->public_key, sizeof(inout->public_key)); - if (!failed) { - bn_write_be(&b, inout->private_key); - break; - } - - data[0] = 1; - memcpy(data + 1, I + 32, 32); - hmac_sha512_Init(&ctx, inout->chain_code, 32); - hmac_sha512_Update(&ctx, data, sizeof(data)); - hmac_sha512_Final(&ctx, I); - } - } else { - memcpy(inout->private_key, I, 32); - } - - memcpy(inout->chain_code, I + 32, 32); - inout->depth++; - inout->child_num = i; - memzero(inout->public_key, sizeof(inout->public_key)); - - // making sure to wipe our memory - memzero(&a, sizeof(a)); - memzero(&b, sizeof(b)); - memzero(I, sizeof(I)); - memzero(data, sizeof(data)); - return 1; + // making sure to wipe our memory + memzero(&a, sizeof(a)); + memzero(&b, sizeof(b)); + memzero(I, sizeof(I)); + memzero(data, sizeof(data)); + return 1; } -int hdnode_private_ckd(HDNode *inout, uint32_t i) { +int hdnode_private_ckd(HDNode* inout, uint32_t i) { #if USE_CARDANO - if (inout->curve == &ed25519_cardano_info) { - return hdnode_private_ckd_cardano(inout, i); - } else + if(inout->curve == &ed25519_cardano_info) { + return hdnode_private_ckd_cardano(inout, i); + } else #endif - { - return hdnode_private_ckd_bip32(inout, i); - } + { + return hdnode_private_ckd_bip32(inout, i); + } } -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) { - uint8_t data[(1 + 32) + 4] = {0}; - uint8_t I[32 + 32] = {0}; - bignum256 c = {0}; +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) { + uint8_t data[(1 + 32) + 4] = {0}; + uint8_t I[32 + 32] = {0}; + bignum256 c = {0}; + + if(i & 0x80000000) { // private derivation + return 0; + } - if (i & 0x80000000) { // private derivation - return 0; - } - - data[0] = 0x02 | (parent->y.val[0] & 0x01); - bn_write_be(&parent->x, data + 1); - write_be(data + 33, i); - - while (true) { - hmac_sha512(parent_chain_code, 32, data, sizeof(data), I); - bn_read_be(I, &c); - if (bn_is_less(&c, &curve->order)) { // < order - scalar_multiply(curve, &c, child); // b = c * G - point_add(curve, parent, child); // b = a + b - if (!point_is_infinity(child)) { - if (child_chain_code) { - memcpy(child_chain_code, I + 32, 32); + data[0] = 0x02 | (parent->y.val[0] & 0x01); + bn_write_be(&parent->x, data + 1); + write_be(data + 33, i); + + while(true) { + hmac_sha512(parent_chain_code, 32, data, sizeof(data), I); + bn_read_be(I, &c); + if(bn_is_less(&c, &curve->order)) { // < order + scalar_multiply(curve, &c, child); // b = c * G + point_add(curve, parent, child); // b = a + b + if(!point_is_infinity(child)) { + if(child_chain_code) { + memcpy(child_chain_code, I + 32, 32); + } + + // Wipe all stack data. + memzero(data, sizeof(data)); + memzero(I, sizeof(I)); + memzero(&c, sizeof(c)); + return 1; + } } - // Wipe all stack data. - memzero(data, sizeof(data)); - memzero(I, sizeof(I)); - memzero(&c, sizeof(c)); - return 1; - } + data[0] = 1; + memcpy(data + 1, I + 32, 32); } - - data[0] = 1; - memcpy(data + 1, I + 32, 32); - } } -int hdnode_public_ckd(HDNode *inout, uint32_t i) { - curve_point parent = {0}, child = {0}; +int hdnode_public_ckd(HDNode* inout, uint32_t i) { + curve_point parent = {0}, child = {0}; - if (!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &parent)) { - return 0; - } - if (!hdnode_public_ckd_cp(inout->curve->params, &parent, inout->chain_code, i, - &child, inout->chain_code)) { - return 0; - } - memzero(inout->private_key, 32); - inout->depth++; - inout->child_num = i; - inout->public_key[0] = 0x02 | (child.y.val[0] & 0x01); - bn_write_be(&child.x, inout->public_key + 1); - - // Wipe all stack data. - memzero(&parent, sizeof(parent)); - memzero(&child, sizeof(child)); - - return 1; + if(!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &parent)) { + return 0; + } + if(!hdnode_public_ckd_cp( + inout->curve->params, &parent, inout->chain_code, i, &child, inout->chain_code)) { + return 0; + } + memzero(inout->private_key, 32); + inout->depth++; + inout->child_num = i; + inout->public_key[0] = 0x02 | (child.y.val[0] & 0x01); + bn_write_be(&child.x, inout->public_key + 1); + + // Wipe all stack data. + memzero(&parent, sizeof(parent)); + memzero(&child, sizeof(child)); + + return 1; } -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) { - uint8_t child_pubkey[33] = {0}; - curve_point b = {0}; - - hdnode_public_ckd_cp(&secp256k1, pub, chain_code, i, &b, NULL); - child_pubkey[0] = 0x02 | (b.y.val[0] & 0x01); - bn_write_be(&b.x, child_pubkey + 1); - - switch (addrformat) { - case 1: // Segwit-in-P2SH - ecdsa_get_address_segwit_p2sh(child_pubkey, version, hasher_pubkey, - hasher_base58, addr, addrsize); - break; - default: // normal address - ecdsa_get_address(child_pubkey, version, hasher_pubkey, hasher_base58, - addr, addrsize); - break; - } +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) { + uint8_t child_pubkey[33] = {0}; + curve_point b = {0}; + + hdnode_public_ckd_cp(&secp256k1, pub, chain_code, i, &b, NULL); + child_pubkey[0] = 0x02 | (b.y.val[0] & 0x01); + bn_write_be(&b.x, child_pubkey + 1); + + switch(addrformat) { + case 1: // Segwit-in-P2SH + ecdsa_get_address_segwit_p2sh( + child_pubkey, version, hasher_pubkey, hasher_base58, addr, addrsize); + break; + default: // normal address + ecdsa_get_address(child_pubkey, version, hasher_pubkey, hasher_base58, addr, addrsize); + break; + } } #if USE_BIP32_CACHE @@ -368,455 +380,504 @@ static CONFIDENTIAL HDNode private_ckd_cache_root; static int private_ckd_cache_index = 0; static CONFIDENTIAL struct { - bool set; - size_t depth; - uint32_t i[BIP32_CACHE_MAXDEPTH]; - HDNode node; + bool set; + size_t depth; + uint32_t i[BIP32_CACHE_MAXDEPTH]; + HDNode node; } private_ckd_cache[BIP32_CACHE_SIZE]; void bip32_cache_clear(void) { - private_ckd_cache_root_set = false; - private_ckd_cache_index = 0; - memzero(&private_ckd_cache_root, sizeof(private_ckd_cache_root)); - memzero(private_ckd_cache, sizeof(private_ckd_cache)); + private_ckd_cache_root_set = false; + private_ckd_cache_index = 0; + memzero(&private_ckd_cache_root, sizeof(private_ckd_cache_root)); + memzero(private_ckd_cache, sizeof(private_ckd_cache)); } -int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, - uint32_t *fingerprint) { - if (i_count == 0) { - // no way how to compute parent fingerprint - return 1; - } - if (i_count == 1) { - if (fingerprint) { - *fingerprint = hdnode_fingerprint(inout); +int hdnode_private_ckd_cached( + HDNode* inout, + const uint32_t* i, + size_t i_count, + uint32_t* fingerprint) { + if(i_count == 0) { + // no way how to compute parent fingerprint + return 1; } - if (hdnode_private_ckd(inout, i[0]) == 0) return 0; - return 1; - } - - bool found = false; - // if root is not set or not the same - if (!private_ckd_cache_root_set || - memcmp(&private_ckd_cache_root, inout, sizeof(HDNode)) != 0) { - // clear the cache - private_ckd_cache_index = 0; - memzero(private_ckd_cache, sizeof(private_ckd_cache)); - // setup new root - memcpy(&private_ckd_cache_root, inout, sizeof(HDNode)); - private_ckd_cache_root_set = true; - } else { - // try to find parent - int j = 0; - for (j = 0; j < BIP32_CACHE_SIZE; j++) { - if (private_ckd_cache[j].set && - private_ckd_cache[j].depth == i_count - 1 && - memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == - 0 && - private_ckd_cache[j].node.curve == inout->curve) { - memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode)); - found = true; - break; - } + if(i_count == 1) { + if(fingerprint) { + *fingerprint = hdnode_fingerprint(inout); + } + if(hdnode_private_ckd(inout, i[0]) == 0) return 0; + return 1; } - } - // else derive parent - if (!found) { - size_t k = 0; - for (k = 0; k < i_count - 1; k++) { - if (hdnode_private_ckd(inout, i[k]) == 0) return 0; + bool found = false; + // if root is not set or not the same + if(!private_ckd_cache_root_set || + memcmp(&private_ckd_cache_root, inout, sizeof(HDNode)) != 0) { + // clear the cache + private_ckd_cache_index = 0; + memzero(private_ckd_cache, sizeof(private_ckd_cache)); + // setup new root + memcpy(&private_ckd_cache_root, inout, sizeof(HDNode)); + private_ckd_cache_root_set = true; + } else { + // try to find parent + int j = 0; + for(j = 0; j < BIP32_CACHE_SIZE; j++) { + if(private_ckd_cache[j].set && private_ckd_cache[j].depth == i_count - 1 && + memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == 0 && + private_ckd_cache[j].node.curve == inout->curve) { + memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode)); + found = true; + break; + } + } } - // and save it - memzero(&(private_ckd_cache[private_ckd_cache_index]), + + // else derive parent + if(!found) { + size_t k = 0; + for(k = 0; k < i_count - 1; k++) { + if(hdnode_private_ckd(inout, i[k]) == 0) return 0; + } + // and save it + memzero( + &(private_ckd_cache[private_ckd_cache_index]), sizeof(private_ckd_cache[private_ckd_cache_index])); - private_ckd_cache[private_ckd_cache_index].set = true; - private_ckd_cache[private_ckd_cache_index].depth = i_count - 1; - memcpy(private_ckd_cache[private_ckd_cache_index].i, i, - (i_count - 1) * sizeof(uint32_t)); - memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout, - sizeof(HDNode)); - private_ckd_cache_index = (private_ckd_cache_index + 1) % BIP32_CACHE_SIZE; - } - - if (fingerprint) { - *fingerprint = hdnode_fingerprint(inout); - } - if (hdnode_private_ckd(inout, i[i_count - 1]) == 0) return 0; - - return 1; + private_ckd_cache[private_ckd_cache_index].set = true; + private_ckd_cache[private_ckd_cache_index].depth = i_count - 1; + memcpy(private_ckd_cache[private_ckd_cache_index].i, i, (i_count - 1) * sizeof(uint32_t)); + memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout, sizeof(HDNode)); + private_ckd_cache_index = (private_ckd_cache_index + 1) % BIP32_CACHE_SIZE; + } + + if(fingerprint) { + *fingerprint = hdnode_fingerprint(inout); + } + if(hdnode_private_ckd(inout, i[i_count - 1]) == 0) return 0; + + return 1; } #endif -int hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) { - if (hdnode_fill_public_key(node) != 0) { - return 1; - } - ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey, - addr_raw); - return 0; +int hdnode_get_address_raw(HDNode* node, uint32_t version, uint8_t* addr_raw) { + if(hdnode_fill_public_key(node) != 0) { + return 1; + } + ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey, addr_raw); + return 0; } -int hdnode_get_address(HDNode *node, uint32_t version, char *addr, - int addrsize) { - if (hdnode_fill_public_key(node) != 0) { - return 1; - } - ecdsa_get_address(node->public_key, version, node->curve->hasher_pubkey, - node->curve->hasher_base58, addr, addrsize); - return 0; +int hdnode_get_address(HDNode* node, uint32_t version, char* addr, int addrsize) { + if(hdnode_fill_public_key(node) != 0) { + return 1; + } + ecdsa_get_address( + node->public_key, + version, + node->curve->hasher_pubkey, + node->curve->hasher_base58, + addr, + addrsize); + return 0; } -int hdnode_fill_public_key(HDNode *node) { - if (node->public_key[0] != 0) return 0; +int hdnode_fill_public_key(HDNode* node) { + if(node->public_key[0] != 0) return 0; #if USE_BIP32_25519_CURVES - if (node->curve->params) { - if (ecdsa_get_public_key33(node->curve->params, node->private_key, - node->public_key) != 0) { - return 1; - } - } else { - node->public_key[0] = 1; - if (node->curve == &ed25519_info) { - ed25519_publickey(node->private_key, node->public_key + 1); - } else if (node->curve == &ed25519_sha3_info) { - ed25519_publickey_sha3(node->private_key, node->public_key + 1); + if(node->curve->params) { + if(ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key) != 0) { + return 1; + } + } else { + node->public_key[0] = 1; + if(node->curve == &ed25519_info) { + ed25519_publickey(node->private_key, node->public_key + 1); + } else if(node->curve == &ed25519_sha3_info) { + ed25519_publickey_sha3(node->private_key, node->public_key + 1); #if USE_KECCAK - } else if (node->curve == &ed25519_keccak_info) { - ed25519_publickey_keccak(node->private_key, node->public_key + 1); + } else if(node->curve == &ed25519_keccak_info) { + ed25519_publickey_keccak(node->private_key, node->public_key + 1); #endif - } else if (node->curve == &curve25519_info) { - curve25519_scalarmult_basepoint(node->public_key + 1, node->private_key); + } else if(node->curve == &curve25519_info) { + curve25519_scalarmult_basepoint(node->public_key + 1, node->private_key); #if USE_CARDANO - } else if (node->curve == &ed25519_cardano_info) { - ed25519_publickey_ext(node->private_key, node->public_key + 1); + } else if(node->curve == &ed25519_cardano_info) { + ed25519_publickey_ext(node->private_key, node->public_key + 1); #endif + } } - } #else - if (ecdsa_get_public_key33(node->curve->params, node->private_key, - node->public_key) != 0) { - return 1; - } + if(ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key) != 0) { + return 1; + } #endif - return 0; + return 0; } #if USE_ETHEREUM -int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) { - uint8_t buf[65] = {0}; - //SHA3_CTX ctx = {0}; - SHA3_CTX *ctx = malloc(sizeof(SHA3_CTX)); - memzero(ctx, sizeof(SHA3_CTX)); - - /* get uncompressed public key */ - if (ecdsa_get_public_key65(node->curve->params, node->private_key, buf) != - 0) { - return 0; - } +int hdnode_get_ethereum_pubkeyhash(const HDNode* node, uint8_t* pubkeyhash) { + uint8_t buf[65] = {0}; + //SHA3_CTX ctx = {0}; + SHA3_CTX* ctx = malloc(sizeof(SHA3_CTX)); + memzero(ctx, sizeof(SHA3_CTX)); + + /* get uncompressed public key */ + if(ecdsa_get_public_key65(node->curve->params, node->private_key, buf) != 0) { + return 0; + } - /* compute sha3 of x and y coordinate without 04 prefix */ - sha3_256_Init(ctx); - sha3_Update(ctx, buf + 1, 64); - keccak_Final(ctx, buf); + /* compute sha3 of x and y coordinate without 04 prefix */ + sha3_256_Init(ctx); + sha3_Update(ctx, buf + 1, 64); + keccak_Final(ctx, buf); - memzero(ctx, sizeof(SHA3_CTX)); - free(ctx); + memzero(ctx, sizeof(SHA3_CTX)); + free(ctx); - /* result are the least significant 160 bits */ - memcpy(pubkeyhash, buf + 12, 20); + /* result are the least significant 160 bits */ + memcpy(pubkeyhash, buf + 12, 20); - return 1; + return 1; } #endif #if USE_NEM -int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address) { - if (node->curve != &ed25519_keccak_info) { - return 0; - } +int hdnode_get_nem_address(HDNode* node, uint8_t version, char* address) { + if(node->curve != &ed25519_keccak_info) { + return 0; + } - if (hdnode_fill_public_key(node) != 0) { - return 0; - } + if(hdnode_fill_public_key(node) != 0) { + return 0; + } - return nem_get_address(&node->public_key[1], version, address); + return nem_get_address(&node->public_key[1], version, 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) { - if (node->curve != &ed25519_keccak_info) { - return 0; - } +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) { + if(node->curve != &ed25519_keccak_info) { + return 0; + } - // sizeof(ed25519_public_key) == SHA3_256_DIGEST_LENGTH - if (mul == NULL) mul = shared_key; + // sizeof(ed25519_public_key) == SHA3_256_DIGEST_LENGTH + if(mul == NULL) mul = shared_key; - if (ed25519_scalarmult_keccak(mul, node->private_key, peer_public_key)) { - return 0; - } + if(ed25519_scalarmult_keccak(mul, node->private_key, peer_public_key)) { + return 0; + } - for (size_t i = 0; i < 32; i++) { - shared_key[i] = mul[i] ^ salt[i]; - } + for(size_t i = 0; i < 32; i++) { + shared_key[i] = mul[i] ^ salt[i]; + } - keccak_256(shared_key, 32, shared_key); - return 1; + keccak_256(shared_key, 32, shared_key); + return 1; } -int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, - const uint8_t *iv_immut, const uint8_t *salt, - const uint8_t *payload, size_t size, uint8_t *buffer) { - uint8_t last_block[AES_BLOCK_SIZE] = {0}; - uint8_t remainder = size % AES_BLOCK_SIZE; - - // Round down to last whole block - size -= remainder; - // Copy old last block - memcpy(last_block, &payload[size], remainder); - // Pad new last block with number of missing bytes - memset(&last_block[remainder], AES_BLOCK_SIZE - remainder, - AES_BLOCK_SIZE - remainder); - - // the IV gets mutated, so we make a copy not to touch the original - uint8_t iv[AES_BLOCK_SIZE] = {0}; - memcpy(iv, iv_immut, AES_BLOCK_SIZE); - - uint8_t shared_key[SHA3_256_DIGEST_LENGTH] = {0}; - if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { - return 0; - } +int hdnode_nem_encrypt( + const HDNode* node, + const ed25519_public_key public_key, + const uint8_t* iv_immut, + const uint8_t* salt, + const uint8_t* payload, + size_t size, + uint8_t* buffer) { + uint8_t last_block[AES_BLOCK_SIZE] = {0}; + uint8_t remainder = size % AES_BLOCK_SIZE; + + // Round down to last whole block + size -= remainder; + // Copy old last block + memcpy(last_block, &payload[size], remainder); + // Pad new last block with number of missing bytes + memset(&last_block[remainder], AES_BLOCK_SIZE - remainder, AES_BLOCK_SIZE - remainder); + + // the IV gets mutated, so we make a copy not to touch the original + uint8_t iv[AES_BLOCK_SIZE] = {0}; + memcpy(iv, iv_immut, AES_BLOCK_SIZE); + + uint8_t shared_key[SHA3_256_DIGEST_LENGTH] = {0}; + if(!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { + return 0; + } - aes_encrypt_ctx ctx = {0}; + aes_encrypt_ctx ctx = {0}; - int ret = aes_encrypt_key256(shared_key, &ctx); - memzero(shared_key, sizeof(shared_key)); + int ret = aes_encrypt_key256(shared_key, &ctx); + memzero(shared_key, sizeof(shared_key)); - if (ret != EXIT_SUCCESS) { - return 0; - } + if(ret != EXIT_SUCCESS) { + return 0; + } - if (aes_cbc_encrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { - return 0; - } + if(aes_cbc_encrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { + return 0; + } - if (aes_cbc_encrypt(last_block, &buffer[size], sizeof(last_block), iv, - &ctx) != EXIT_SUCCESS) { - return 0; - } + if(aes_cbc_encrypt(last_block, &buffer[size], sizeof(last_block), iv, &ctx) != EXIT_SUCCESS) { + return 0; + } - return 1; + return 1; } -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) { - uint8_t shared_key[SHA3_256_DIGEST_LENGTH] = {0}; - - if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { - return 0; - } +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) { + uint8_t shared_key[SHA3_256_DIGEST_LENGTH] = {0}; + + if(!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { + return 0; + } - aes_decrypt_ctx ctx = {0}; + aes_decrypt_ctx ctx = {0}; - int ret = aes_decrypt_key256(shared_key, &ctx); - memzero(shared_key, sizeof(shared_key)); + int ret = aes_decrypt_key256(shared_key, &ctx); + memzero(shared_key, sizeof(shared_key)); - if (ret != EXIT_SUCCESS) { - return 0; - } + if(ret != EXIT_SUCCESS) { + return 0; + } - if (aes_cbc_decrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { - return 0; - } + if(aes_cbc_decrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) { + return 0; + } - return 1; + return 1; } #endif // msg is a data to be signed // msg_len is the message length -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])) { - if (node->curve->params) { - return ecdsa_sign(node->curve->params, hasher_sign, node->private_key, msg, - msg_len, sig, pby, is_canonical); - } else if (node->curve == &curve25519_info) { - return 1; // signatures are not supported - } else { - if (node->curve == &ed25519_info) { - ed25519_sign(msg, msg_len, node->private_key, sig); - } else if (node->curve == &ed25519_sha3_info) { - ed25519_sign_sha3(msg, msg_len, node->private_key, sig); +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])) { + if(node->curve->params) { + return ecdsa_sign( + node->curve->params, + hasher_sign, + node->private_key, + msg, + msg_len, + sig, + pby, + is_canonical); + } else if(node->curve == &curve25519_info) { + return 1; // signatures are not supported + } else { + if(node->curve == &ed25519_info) { + ed25519_sign(msg, msg_len, node->private_key, sig); + } else if(node->curve == &ed25519_sha3_info) { + ed25519_sign_sha3(msg, msg_len, node->private_key, sig); #if USE_KECCAK - } else if (node->curve == &ed25519_keccak_info) { - ed25519_sign_keccak(msg, msg_len, node->private_key, sig); + } else if(node->curve == &ed25519_keccak_info) { + ed25519_sign_keccak(msg, msg_len, node->private_key, sig); #endif - } else { - return 1; // unknown or unsupported curve + } else { + return 1; // unknown or unsupported curve + } + return 0; } - return 0; - } } -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])) { - if (node->curve->params) { - return ecdsa_sign_digest(node->curve->params, node->private_key, digest, - sig, pby, is_canonical); - } else if (node->curve == &curve25519_info) { - return 1; // signatures are not supported - } else { - return hdnode_sign(node, digest, 32, 0, sig, pby, is_canonical); - } +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])) { + if(node->curve->params) { + return ecdsa_sign_digest( + node->curve->params, node->private_key, digest, sig, pby, is_canonical); + } else if(node->curve == &curve25519_info) { + return 1; // signatures are not supported + } else { + return hdnode_sign(node, digest, 32, 0, sig, pby, is_canonical); + } } -int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, - uint8_t *session_key, int *result_size) { - // Use elliptic curve Diffie-Helman to compute shared session key - if (node->curve->params) { - if (ecdh_multiply(node->curve->params, node->private_key, peer_public_key, - session_key) != 0) { - return 1; +int hdnode_get_shared_key( + const HDNode* node, + const uint8_t* peer_public_key, + uint8_t* session_key, + int* result_size) { + // Use elliptic curve Diffie-Helman to compute shared session key + if(node->curve->params) { + if(ecdh_multiply(node->curve->params, node->private_key, peer_public_key, session_key) != + 0) { + return 1; + } + *result_size = 65; + return 0; + } else if(node->curve == &curve25519_info) { + session_key[0] = 0x04; + if(peer_public_key[0] != 0x40) { + return 1; // Curve25519 public key should start with 0x40 byte. + } + curve25519_scalarmult(session_key + 1, node->private_key, peer_public_key + 1); + *result_size = 33; + return 0; + } else { + *result_size = 0; + return 1; // ECDH is not supported } - *result_size = 65; - return 0; - } else if (node->curve == &curve25519_info) { - session_key[0] = 0x04; - if (peer_public_key[0] != 0x40) { - return 1; // Curve25519 public key should start with 0x40 byte. - } - curve25519_scalarmult(session_key + 1, node->private_key, - peer_public_key + 1); - *result_size = 33; - return 0; - } else { - *result_size = 0; - return 1; // ECDH is not supported - } } -static int hdnode_serialize(const HDNode *node, uint32_t fingerprint, - uint32_t version, bool use_private, char *str, - int strsize) { - uint8_t node_data[78] = {0}; - write_be(node_data, version); - node_data[4] = node->depth; - write_be(node_data + 5, fingerprint); - write_be(node_data + 9, node->child_num); - memcpy(node_data + 13, node->chain_code, 32); - if (use_private) { - node_data[45] = 0; - memcpy(node_data + 46, node->private_key, 32); - } else { - memcpy(node_data + 45, node->public_key, 33); - } - int ret = base58_encode_check(node_data, sizeof(node_data), - node->curve->hasher_base58, str, strsize); - memzero(node_data, sizeof(node_data)); - return ret; +static int hdnode_serialize( + const HDNode* node, + uint32_t fingerprint, + uint32_t version, + bool use_private, + char* str, + int strsize) { + uint8_t node_data[78] = {0}; + write_be(node_data, version); + node_data[4] = node->depth; + write_be(node_data + 5, fingerprint); + write_be(node_data + 9, node->child_num); + memcpy(node_data + 13, node->chain_code, 32); + if(use_private) { + node_data[45] = 0; + memcpy(node_data + 46, node->private_key, 32); + } else { + memcpy(node_data + 45, node->public_key, 33); + } + int ret = base58_encode_check( + node_data, sizeof(node_data), node->curve->hasher_base58, str, strsize); + memzero(node_data, sizeof(node_data)); + return ret; } -int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, - uint32_t version, char *str, int strsize) { - return hdnode_serialize(node, fingerprint, version, false, str, strsize); +int hdnode_serialize_public( + const HDNode* node, + uint32_t fingerprint, + uint32_t version, + char* str, + int strsize) { + return hdnode_serialize(node, fingerprint, version, false, str, strsize); } -int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, - uint32_t version, char *str, int strsize) { - return hdnode_serialize(node, fingerprint, version, true, str, strsize); +int hdnode_serialize_private( + const HDNode* node, + uint32_t fingerprint, + uint32_t version, + char* str, + int strsize) { + return hdnode_serialize(node, fingerprint, version, true, str, strsize); } // check for validity of curve point in case of public data not performed -static int hdnode_deserialize(const char *str, uint32_t version, - bool use_private, const char *curve, HDNode *node, - uint32_t *fingerprint) { - uint8_t node_data[78] = {0}; - memzero(node, sizeof(HDNode)); - node->curve = get_curve_by_name(curve); - if (base58_decode_check(str, node->curve->hasher_base58, node_data, - sizeof(node_data)) != sizeof(node_data)) { - return -1; - } - uint32_t ver = read_be(node_data); - if (ver != version) { - return -3; // invalid version - } - if (use_private) { - // invalid data - if (node_data[45]) { - return -2; - } - memcpy(node->private_key, node_data + 46, 32); - memzero(node->public_key, sizeof(node->public_key)); - } else { - memzero(node->private_key, sizeof(node->private_key)); - memcpy(node->public_key, node_data + 45, 33); - } - node->depth = node_data[4]; - if (fingerprint) { - *fingerprint = read_be(node_data + 5); - } - node->child_num = read_be(node_data + 9); - memcpy(node->chain_code, node_data + 13, 32); - return 0; +static int hdnode_deserialize( + const char* str, + uint32_t version, + bool use_private, + const char* curve, + HDNode* node, + uint32_t* fingerprint) { + uint8_t node_data[78] = {0}; + memzero(node, sizeof(HDNode)); + node->curve = get_curve_by_name(curve); + if(base58_decode_check(str, node->curve->hasher_base58, node_data, sizeof(node_data)) != + sizeof(node_data)) { + return -1; + } + uint32_t ver = read_be(node_data); + if(ver != version) { + return -3; // invalid version + } + if(use_private) { + // invalid data + if(node_data[45]) { + return -2; + } + memcpy(node->private_key, node_data + 46, 32); + memzero(node->public_key, sizeof(node->public_key)); + } else { + memzero(node->private_key, sizeof(node->private_key)); + memcpy(node->public_key, node_data + 45, 33); + } + node->depth = node_data[4]; + if(fingerprint) { + *fingerprint = read_be(node_data + 5); + } + node->child_num = read_be(node_data + 9); + memcpy(node->chain_code, node_data + 13, 32); + return 0; } -int hdnode_deserialize_public(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint) { - return hdnode_deserialize(str, version, false, curve, node, fingerprint); +int hdnode_deserialize_public( + const char* str, + uint32_t version, + const char* curve, + HDNode* node, + uint32_t* fingerprint) { + return hdnode_deserialize(str, version, false, curve, node, fingerprint); } -int hdnode_deserialize_private(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint) { - return hdnode_deserialize(str, version, true, curve, node, fingerprint); +int hdnode_deserialize_private( + const char* str, + uint32_t version, + const char* curve, + HDNode* node, + uint32_t* fingerprint) { + return hdnode_deserialize(str, version, true, curve, node, fingerprint); } -const curve_info *get_curve_by_name(const char *curve_name) { - if (curve_name == 0) { - return 0; - } - if (strcmp(curve_name, SECP256K1_NAME) == 0) { - return &secp256k1_info; - } - if (strcmp(curve_name, SECP256K1_DECRED_NAME) == 0) { - return &secp256k1_decred_info; - } - if (strcmp(curve_name, SECP256K1_GROESTL_NAME) == 0) { - return &secp256k1_groestl_info; - } - if (strcmp(curve_name, SECP256K1_SMART_NAME) == 0) { - return &secp256k1_smart_info; - } - if (strcmp(curve_name, NIST256P1_NAME) == 0) { - return &nist256p1_info; - } - if (strcmp(curve_name, ED25519_NAME) == 0) { - return &ed25519_info; - } +const curve_info* get_curve_by_name(const char* curve_name) { + if(curve_name == 0) { + return 0; + } + if(strcmp(curve_name, SECP256K1_NAME) == 0) { + return &secp256k1_info; + } + if(strcmp(curve_name, SECP256K1_DECRED_NAME) == 0) { + return &secp256k1_decred_info; + } + if(strcmp(curve_name, SECP256K1_GROESTL_NAME) == 0) { + return &secp256k1_groestl_info; + } + if(strcmp(curve_name, SECP256K1_SMART_NAME) == 0) { + return &secp256k1_smart_info; + } + if(strcmp(curve_name, NIST256P1_NAME) == 0) { + return &nist256p1_info; + } + if(strcmp(curve_name, ED25519_NAME) == 0) { + return &ed25519_info; + } #if USE_CARDANO - if (strcmp(curve_name, ED25519_CARDANO_NAME) == 0) { - return &ed25519_cardano_info; - } + if(strcmp(curve_name, ED25519_CARDANO_NAME) == 0) { + return &ed25519_cardano_info; + } #endif - if (strcmp(curve_name, ED25519_SHA3_NAME) == 0) { - return &ed25519_sha3_info; - } + if(strcmp(curve_name, ED25519_SHA3_NAME) == 0) { + return &ed25519_sha3_info; + } #if USE_KECCAK - if (strcmp(curve_name, ED25519_KECCAK_NAME) == 0) { - return &ed25519_keccak_info; - } + if(strcmp(curve_name, ED25519_KECCAK_NAME) == 0) { + return &ed25519_keccak_info; + } #endif - if (strcmp(curve_name, CURVE25519_NAME) == 0) { - return &curve25519_info; - } - return 0; + if(strcmp(curve_name, CURVE25519_NAME) == 0) { + return &curve25519_info; + } + return 0; } diff --git a/crypto/bip32.h b/crypto/bip32.h index 4be5c448315..3e311484834 100644 --- a/crypto/bip32.h +++ b/crypto/bip32.h @@ -28,7 +28,7 @@ #include #include #include "ecdsa.h" -#include "ed25519-donna/ed25519.h" +#include "ed25519_donna/ed25519.h" #include "options.h" // Maximum length of a Base58Check-encoded extended public or private key. @@ -38,112 +38,165 @@ #define ADDRESS_MAXLEN 39 typedef struct { - const char *bip32_name; // string for generating BIP32 xprv from seed - const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519 + 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; + 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]; + 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 private_key[32]; + uint8_t private_key_extension[32]; - uint8_t public_key[33]; - const curve_info *curve; + 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); - -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); +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); + +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 void bip32_cache_clear(void); -int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, - uint32_t *fingerprint); +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); +uint32_t hdnode_fingerprint(HDNode* node); -int hdnode_fill_public_key(HDNode *node); +int hdnode_fill_public_key(HDNode* node); #if USE_ETHEREUM -int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash); +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); +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_public(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint); - -int hdnode_deserialize_private(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint); - -int hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw); -int hdnode_get_address(HDNode *node, uint32_t version, char *addr, - int addrsize); - -const curve_info *get_curve_by_name(const char *curve_name); +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_public( + const char* str, + uint32_t version, + const char* curve, + HDNode* node, + uint32_t* fingerprint); + +int hdnode_deserialize_private( + const char* str, + uint32_t version, + const char* curve, + HDNode* node, + uint32_t* fingerprint); + +int hdnode_get_address_raw(HDNode* node, uint32_t version, uint8_t* addr_raw); +int hdnode_get_address(HDNode* node, uint32_t version, char* addr, int addrsize); + +const curve_info* get_curve_by_name(const char* curve_name); #endif diff --git a/crypto/bip39.c b/crypto/bip39.c index 961be0d0437..c99fe76c900 100644 --- a/crypto/bip39.c +++ b/crypto/bip39.c @@ -37,251 +37,252 @@ static int bip39_cache_index = 0; static CONFIDENTIAL struct { - bool set; - char mnemonic[256]; - char passphrase[64]; - uint8_t seed[512 / 8]; + bool set; + char mnemonic[256]; + char passphrase[64]; + uint8_t seed[512 / 8]; } bip39_cache[BIP39_CACHE_SIZE]; void bip39_cache_clear(void) { - memzero(bip39_cache, sizeof(bip39_cache)); - bip39_cache_index = 0; + memzero(bip39_cache, sizeof(bip39_cache)); + bip39_cache_index = 0; } #endif -const char *mnemonic_generate(int strength) { - if (strength % 32 || strength < 128 || strength > 256) { - return 0; - } - uint8_t data[32] = {0}; - random_buffer(data, 32); - const char *r = mnemonic_from_data(data, strength / 8); - memzero(data, sizeof(data)); - return r; +const char* mnemonic_generate(int strength) { + if(strength % 32 || strength < 128 || strength > 256) { + return 0; + } + uint8_t data[32] = {0}; + random_buffer(data, 32); + const char* r = mnemonic_from_data(data, strength / 8); + memzero(data, sizeof(data)); + return r; } static CONFIDENTIAL char mnemo[24 * 10]; -const char *mnemonic_from_data(const uint8_t *data, int len) { - if (len % 4 || len < 16 || len > 32) { - return 0; - } +const char* mnemonic_from_data(const uint8_t* data, int len) { + if(len % 4 || len < 16 || len > 32) { + return 0; + } - uint8_t bits[32 + 1] = {0}; + uint8_t bits[32 + 1] = {0}; - sha256_Raw(data, len, bits); - // checksum - bits[len] = bits[0]; - // data - memcpy(bits, data, len); + sha256_Raw(data, len, bits); + // checksum + bits[len] = bits[0]; + // data + memcpy(bits, data, len); - int mlen = len * 3 / 4; + int mlen = len * 3 / 4; - int i = 0, j = 0, idx = 0; - char *p = mnemo; - for (i = 0; i < mlen; i++) { - idx = 0; - for (j = 0; j < 11; j++) { - idx <<= 1; - idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; + int i = 0, j = 0, idx = 0; + char* p = mnemo; + for(i = 0; i < mlen; i++) { + idx = 0; + for(j = 0; j < 11; j++) { + idx <<= 1; + idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; + } + strcpy(p, BIP39_WORDLIST_ENGLISH[idx]); + p += strlen(BIP39_WORDLIST_ENGLISH[idx]); + *p = (i < mlen - 1) ? ' ' : 0; + p++; } - strcpy(p, BIP39_WORDLIST_ENGLISH[idx]); - p += strlen(BIP39_WORDLIST_ENGLISH[idx]); - *p = (i < mlen - 1) ? ' ' : 0; - p++; - } - memzero(bits, sizeof(bits)); + memzero(bits, sizeof(bits)); - return mnemo; + return mnemo; } -void mnemonic_clear(void) { memzero(mnemo, sizeof(mnemo)); } - -int mnemonic_to_bits(const char *mnemonic, uint8_t *bits) { - if (!mnemonic) { - return 0; - } - - uint32_t i = 0, n = 0; +void mnemonic_clear(void) { + memzero(mnemo, sizeof(mnemo)); +} - while (mnemonic[i]) { - if (mnemonic[i] == ' ') { - n++; +int mnemonic_to_bits(const char* mnemonic, uint8_t* bits) { + if(!mnemonic) { + return 0; } - i++; - } - n++; - // check that number of words is valid for BIP-39: - // (a) between 128 and 256 bits of initial entropy (12 - 24 words) - // (b) number of bits divisible by 33 (1 checksum bit per 32 input bits) - // - that is, (n * 11) % 33 == 0, so n % 3 == 0 - if (n < 12 || n > 24 || (n % 3)) { - return 0; - } + uint32_t i = 0, n = 0; - char current_word[10] = {0}; - uint32_t j = 0, ki = 0, bi = 0; - uint8_t result[32 + 1] = {0}; + while(mnemonic[i]) { + if(mnemonic[i] == ' ') { + n++; + } + i++; + } + n++; - memzero(result, sizeof(result)); - i = 0; - while (mnemonic[i]) { - j = 0; - while (mnemonic[i] != ' ' && mnemonic[i] != 0) { - if (j >= sizeof(current_word) - 1) { + // check that number of words is valid for BIP-39: + // (a) between 128 and 256 bits of initial entropy (12 - 24 words) + // (b) number of bits divisible by 33 (1 checksum bit per 32 input bits) + // - that is, (n * 11) % 33 == 0, so n % 3 == 0 + if(n < 12 || n > 24 || (n % 3)) { return 0; - } - current_word[j] = mnemonic[i]; - i++; - j++; - } - current_word[j] = 0; - if (mnemonic[i] != 0) { - i++; } - int k = mnemonic_find_word(current_word); - if (k < 0) { // word not found - return 0; + + char current_word[10] = {0}; + uint32_t j = 0, ki = 0, bi = 0; + uint8_t result[32 + 1] = {0}; + + memzero(result, sizeof(result)); + i = 0; + while(mnemonic[i]) { + j = 0; + while(mnemonic[i] != ' ' && mnemonic[i] != 0) { + if(j >= sizeof(current_word) - 1) { + return 0; + } + current_word[j] = mnemonic[i]; + i++; + j++; + } + current_word[j] = 0; + if(mnemonic[i] != 0) { + i++; + } + int k = mnemonic_find_word(current_word); + if(k < 0) { // word not found + return 0; + } + for(ki = 0; ki < 11; ki++) { + if(k & (1 << (10 - ki))) { + result[bi / 8] |= 1 << (7 - (bi % 8)); + } + bi++; + } } - for (ki = 0; ki < 11; ki++) { - if (k & (1 << (10 - ki))) { - result[bi / 8] |= 1 << (7 - (bi % 8)); - } - bi++; + if(bi != n * 11) { + return 0; } - } - if (bi != n * 11) { - return 0; - } - memcpy(bits, result, sizeof(result)); - memzero(result, sizeof(result)); + memcpy(bits, result, sizeof(result)); + memzero(result, sizeof(result)); - // returns amount of entropy + checksum BITS - return n * 11; + // returns amount of entropy + checksum BITS + return n * 11; } -int mnemonic_check(const char *mnemonic) { - uint8_t bits[32 + 1] = {0}; - int mnemonic_bits_len = mnemonic_to_bits(mnemonic, bits); - if (mnemonic_bits_len != (12 * 11) && mnemonic_bits_len != (18 * 11) && - mnemonic_bits_len != (24 * 11)) { - return 0; - } - int words = mnemonic_bits_len / 11; +int mnemonic_check(const char* mnemonic) { + uint8_t bits[32 + 1] = {0}; + int mnemonic_bits_len = mnemonic_to_bits(mnemonic, bits); + if(mnemonic_bits_len != (12 * 11) && mnemonic_bits_len != (18 * 11) && + mnemonic_bits_len != (24 * 11)) { + return 0; + } + int words = mnemonic_bits_len / 11; - uint8_t checksum = bits[words * 4 / 3]; - sha256_Raw(bits, words * 4 / 3, bits); - if (words == 12) { - return (bits[0] & 0xF0) == (checksum & 0xF0); // compare first 4 bits - } else if (words == 18) { - return (bits[0] & 0xFC) == (checksum & 0xFC); // compare first 6 bits - } else if (words == 24) { - return bits[0] == checksum; // compare 8 bits - } - return 0; + uint8_t checksum = bits[words * 4 / 3]; + sha256_Raw(bits, words * 4 / 3, bits); + if(words == 12) { + return (bits[0] & 0xF0) == (checksum & 0xF0); // compare first 4 bits + } else if(words == 18) { + return (bits[0] & 0xFC) == (checksum & 0xFC); // compare first 6 bits + } else if(words == 24) { + return bits[0] == checksum; // compare 8 bits + } + return 0; } // passphrase must be at most 256 characters otherwise it would be truncated -void mnemonic_to_seed(const char *mnemonic, const char *passphrase, - uint8_t seed[512 / 8], - void (*progress_callback)(uint32_t current, - uint32_t total)) { - int mnemoniclen = strlen(mnemonic); - int passphraselen = strlen(passphrase); - if (passphraselen > 256) passphraselen = 256; +void mnemonic_to_seed( + const char* mnemonic, + const char* passphrase, + uint8_t seed[512 / 8], + void (*progress_callback)(uint32_t current, uint32_t total)) { + int mnemoniclen = strlen(mnemonic); + int passphraselen = strlen(passphrase); + if(passphraselen > 256) passphraselen = 256; #if USE_BIP39_CACHE - // check cache - if (mnemoniclen < 256 && passphraselen < 64) { - for (int i = 0; i < BIP39_CACHE_SIZE; i++) { - if (!bip39_cache[i].set) continue; - if (strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue; - if (strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue; - // found the correct entry - memcpy(seed, bip39_cache[i].seed, 512 / 8); - return; + // check cache + if(mnemoniclen < 256 && passphraselen < 64) { + for(int i = 0; i < BIP39_CACHE_SIZE; i++) { + if(!bip39_cache[i].set) continue; + if(strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue; + if(strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue; + // found the correct entry + memcpy(seed, bip39_cache[i].seed, 512 / 8); + return; + } } - } #endif - uint8_t salt[8 + 256] = {0}; - memcpy(salt, "mnemonic", 8); - memcpy(salt + 8, passphrase, passphraselen); - static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; - pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, mnemoniclen, salt, - passphraselen + 8, 1); - if (progress_callback) { - progress_callback(0, BIP39_PBKDF2_ROUNDS); - } - for (int i = 0; i < 16; i++) { - pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 16); - if (progress_callback) { - progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 16, - BIP39_PBKDF2_ROUNDS); + uint8_t salt[8 + 256] = {0}; + memcpy(salt, "mnemonic", 8); + memcpy(salt + 8, passphrase, passphraselen); + static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; + pbkdf2_hmac_sha512_Init( + &pctx, (const uint8_t*)mnemonic, mnemoniclen, salt, passphraselen + 8, 1); + if(progress_callback) { + progress_callback(0, BIP39_PBKDF2_ROUNDS); + } + for(int i = 0; i < 16; i++) { + pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 16); + if(progress_callback) { + progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 16, BIP39_PBKDF2_ROUNDS); + } } - } - pbkdf2_hmac_sha512_Final(&pctx, seed); - memzero(salt, sizeof(salt)); + pbkdf2_hmac_sha512_Final(&pctx, seed); + memzero(salt, sizeof(salt)); #if USE_BIP39_CACHE - // store to cache - if (mnemoniclen < 256 && passphraselen < 64) { - bip39_cache[bip39_cache_index].set = true; - strcpy(bip39_cache[bip39_cache_index].mnemonic, mnemonic); - strcpy(bip39_cache[bip39_cache_index].passphrase, passphrase); - memcpy(bip39_cache[bip39_cache_index].seed, seed, 512 / 8); - bip39_cache_index = (bip39_cache_index + 1) % BIP39_CACHE_SIZE; - } + // store to cache + if(mnemoniclen < 256 && passphraselen < 64) { + bip39_cache[bip39_cache_index].set = true; + strcpy(bip39_cache[bip39_cache_index].mnemonic, mnemonic); + strcpy(bip39_cache[bip39_cache_index].passphrase, passphrase); + memcpy(bip39_cache[bip39_cache_index].seed, seed, 512 / 8); + bip39_cache_index = (bip39_cache_index + 1) % BIP39_CACHE_SIZE; + } #endif } // binary search for finding the word in the wordlist -int mnemonic_find_word(const char *word) { - int lo = 0, hi = BIP39_WORD_COUNT - 1; - while (lo <= hi) { - int mid = lo + (hi - lo) / 2; - int cmp = strcmp(word, BIP39_WORDLIST_ENGLISH[mid]); - if (cmp == 0) { - return mid; - } - if (cmp > 0) { - lo = mid + 1; - } else { - hi = mid - 1; +int mnemonic_find_word(const char* word) { + int lo = 0, hi = BIP39_WORD_COUNT - 1; + while(lo <= hi) { + int mid = lo + (hi - lo) / 2; + int cmp = strcmp(word, BIP39_WORDLIST_ENGLISH[mid]); + if(cmp == 0) { + return mid; + } + if(cmp > 0) { + lo = mid + 1; + } else { + hi = mid - 1; + } } - } - return -1; + return -1; } -const char *mnemonic_complete_word(const char *prefix, int len) { - // we need to perform linear search, - // because we want to return the first match - for (int i = 0; i < BIP39_WORD_COUNT; i++) { - if (strncmp(BIP39_WORDLIST_ENGLISH[i], prefix, len) == 0) { - return BIP39_WORDLIST_ENGLISH[i]; +const char* mnemonic_complete_word(const char* prefix, int len) { + // we need to perform linear search, + // because we want to return the first match + for(int i = 0; i < BIP39_WORD_COUNT; i++) { + if(strncmp(BIP39_WORDLIST_ENGLISH[i], prefix, len) == 0) { + return BIP39_WORDLIST_ENGLISH[i]; + } } - } - return NULL; + return NULL; } -const char *mnemonic_get_word(int index) { - if (index >= 0 && index < BIP39_WORD_COUNT) { - return BIP39_WORDLIST_ENGLISH[index]; - } else { - return NULL; - } +const char* mnemonic_get_word(int index) { + if(index >= 0 && index < BIP39_WORD_COUNT) { + return BIP39_WORDLIST_ENGLISH[index]; + } else { + return NULL; + } } -uint32_t mnemonic_word_completion_mask(const char *prefix, int len) { - if (len <= 0) { - return 0x3ffffff; // all letters (bits 1-26 set) - } - uint32_t res = 0; - for (int i = 0; i < BIP39_WORD_COUNT; i++) { - const char *word = BIP39_WORDLIST_ENGLISH[i]; - if (strncmp(word, prefix, len) == 0 && word[len] >= 'a' && - word[len] <= 'z') { - res |= 1 << (word[len] - 'a'); +uint32_t mnemonic_word_completion_mask(const char* prefix, int len) { + if(len <= 0) { + return 0x3ffffff; // all letters (bits 1-26 set) + } + uint32_t res = 0; + for(int i = 0; i < BIP39_WORD_COUNT; i++) { + const char* word = BIP39_WORDLIST_ENGLISH[i]; + if(strncmp(word, prefix, len) == 0 && word[len] >= 'a' && word[len] <= 'z') { + res |= 1 << (word[len] - 'a'); + } } - } - return res; + return res; } diff --git a/crypto/bip39.h b/crypto/bip39.h index 3160e0ff4bc..5e29c83364a 100644 --- a/crypto/bip39.h +++ b/crypto/bip39.h @@ -36,25 +36,26 @@ void bip39_cache_clear(void); #endif -extern const char *const BIP39_WORDLIST_ENGLISH[BIP39_WORD_COUNT]; +extern const char* const BIP39_WORDLIST_ENGLISH[BIP39_WORD_COUNT]; -const char *mnemonic_generate(int strength); // strength in bits -const char *mnemonic_from_data(const uint8_t *data, int len); +const char* mnemonic_generate(int strength); // strength in bits +const char* mnemonic_from_data(const uint8_t* data, int len); void mnemonic_clear(void); -int mnemonic_check(const char *mnemonic); +int mnemonic_check(const char* mnemonic); -int mnemonic_to_bits(const char *mnemonic, uint8_t *bits); +int mnemonic_to_bits(const char* mnemonic, uint8_t* bits); // passphrase must be at most 256 characters otherwise it would be truncated -void mnemonic_to_seed(const char *mnemonic, const char *passphrase, - uint8_t seed[512 / 8], - void (*progress_callback)(uint32_t current, - uint32_t total)); - -int mnemonic_find_word(const char *word); -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); +void mnemonic_to_seed( + const char* mnemonic, + const char* passphrase, + uint8_t seed[512 / 8], + void (*progress_callback)(uint32_t current, uint32_t total)); + +int mnemonic_find_word(const char* word); +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 diff --git a/crypto/bip39_english.c b/crypto/bip39_english.c index 87b01aaf8fb..4b92b4c7f16 100644 --- a/crypto/bip39_english.c +++ b/crypto/bip39_english.c @@ -24,346 +24,260 @@ #include "bip39.h" const char* const BIP39_WORDLIST_ENGLISH[BIP39_WORD_COUNT] = { - "abandon", "ability", "able", "about", "above", "absent", - "absorb", "abstract", "absurd", "abuse", "access", "accident", - "account", "accuse", "achieve", "acid", "acoustic", "acquire", - "across", "act", "action", "actor", "actress", "actual", - "adapt", "add", "addict", "address", "adjust", "admit", - "adult", "advance", "advice", "aerobic", "affair", "afford", - "afraid", "again", "age", "agent", "agree", "ahead", - "aim", "air", "airport", "aisle", "alarm", "album", - "alcohol", "alert", "alien", "all", "alley", "allow", - "almost", "alone", "alpha", "already", "also", "alter", - "always", "amateur", "amazing", "among", "amount", "amused", - "analyst", "anchor", "ancient", "anger", "angle", "angry", - "animal", "ankle", "announce", "annual", "another", "answer", - "antenna", "antique", "anxiety", "any", "apart", "apology", - "appear", "apple", "approve", "april", "arch", "arctic", - "area", "arena", "argue", "arm", "armed", "armor", - "army", "around", "arrange", "arrest", "arrive", "arrow", - "art", "artefact", "artist", "artwork", "ask", "aspect", - "assault", "asset", "assist", "assume", "asthma", "athlete", - "atom", "attack", "attend", "attitude", "attract", "auction", - "audit", "august", "aunt", "author", "auto", "autumn", - "average", "avocado", "avoid", "awake", "aware", "away", - "awesome", "awful", "awkward", "axis", "baby", "bachelor", - "bacon", "badge", "bag", "balance", "balcony", "ball", - "bamboo", "banana", "banner", "bar", "barely", "bargain", - "barrel", "base", "basic", "basket", "battle", "beach", - "bean", "beauty", "because", "become", "beef", "before", - "begin", "behave", "behind", "believe", "below", "belt", - "bench", "benefit", "best", "betray", "better", "between", - "beyond", "bicycle", "bid", "bike", "bind", "biology", - "bird", "birth", "bitter", "black", "blade", "blame", - "blanket", "blast", "bleak", "bless", "blind", "blood", - "blossom", "blouse", "blue", "blur", "blush", "board", - "boat", "body", "boil", "bomb", "bone", "bonus", - "book", "boost", "border", "boring", "borrow", "boss", - "bottom", "bounce", "box", "boy", "bracket", "brain", - "brand", "brass", "brave", "bread", "breeze", "brick", - "bridge", "brief", "bright", "bring", "brisk", "broccoli", - "broken", "bronze", "broom", "brother", "brown", "brush", - "bubble", "buddy", "budget", "buffalo", "build", "bulb", - "bulk", "bullet", "bundle", "bunker", "burden", "burger", - "burst", "bus", "business", "busy", "butter", "buyer", - "buzz", "cabbage", "cabin", "cable", "cactus", "cage", - "cake", "call", "calm", "camera", "camp", "can", - "canal", "cancel", "candy", "cannon", "canoe", "canvas", - "canyon", "capable", "capital", "captain", "car", "carbon", - "card", "cargo", "carpet", "carry", "cart", "case", - "cash", "casino", "castle", "casual", "cat", "catalog", - "catch", "category", "cattle", "caught", "cause", "caution", - "cave", "ceiling", "celery", "cement", "census", "century", - "cereal", "certain", "chair", "chalk", "champion", "change", - "chaos", "chapter", "charge", "chase", "chat", "cheap", - "check", "cheese", "chef", "cherry", "chest", "chicken", - "chief", "child", "chimney", "choice", "choose", "chronic", - "chuckle", "chunk", "churn", "cigar", "cinnamon", "circle", - "citizen", "city", "civil", "claim", "clap", "clarify", - "claw", "clay", "clean", "clerk", "clever", "click", - "client", "cliff", "climb", "clinic", "clip", "clock", - "clog", "close", "cloth", "cloud", "clown", "club", - "clump", "cluster", "clutch", "coach", "coast", "coconut", - "code", "coffee", "coil", "coin", "collect", "color", - "column", "combine", "come", "comfort", "comic", "common", - "company", "concert", "conduct", "confirm", "congress", "connect", - "consider", "control", "convince", "cook", "cool", "copper", - "copy", "coral", "core", "corn", "correct", "cost", - "cotton", "couch", "country", "couple", "course", "cousin", - "cover", "coyote", "crack", "cradle", "craft", "cram", - "crane", "crash", "crater", "crawl", "crazy", "cream", - "credit", "creek", "crew", "cricket", "crime", "crisp", - "critic", "crop", "cross", "crouch", "crowd", "crucial", - "cruel", "cruise", "crumble", "crunch", "crush", "cry", - "crystal", "cube", "culture", "cup", "cupboard", "curious", - "current", "curtain", "curve", "cushion", "custom", "cute", - "cycle", "dad", "damage", "damp", "dance", "danger", - "daring", "dash", "daughter", "dawn", "day", "deal", - "debate", "debris", "decade", "december", "decide", "decline", - "decorate", "decrease", "deer", "defense", "define", "defy", - "degree", "delay", "deliver", "demand", "demise", "denial", - "dentist", "deny", "depart", "depend", "deposit", "depth", - "deputy", "derive", "describe", "desert", "design", "desk", - "despair", "destroy", "detail", "detect", "develop", "device", - "devote", "diagram", "dial", "diamond", "diary", "dice", - "diesel", "diet", "differ", "digital", "dignity", "dilemma", - "dinner", "dinosaur", "direct", "dirt", "disagree", "discover", - "disease", "dish", "dismiss", "disorder", "display", "distance", - "divert", "divide", "divorce", "dizzy", "doctor", "document", - "dog", "doll", "dolphin", "domain", "donate", "donkey", - "donor", "door", "dose", "double", "dove", "draft", - "dragon", "drama", "drastic", "draw", "dream", "dress", - "drift", "drill", "drink", "drip", "drive", "drop", - "drum", "dry", "duck", "dumb", "dune", "during", - "dust", "dutch", "duty", "dwarf", "dynamic", "eager", - "eagle", "early", "earn", "earth", "easily", "east", - "easy", "echo", "ecology", "economy", "edge", "edit", - "educate", "effort", "egg", "eight", "either", "elbow", - "elder", "electric", "elegant", "element", "elephant", "elevator", - "elite", "else", "embark", "embody", "embrace", "emerge", - "emotion", "employ", "empower", "empty", "enable", "enact", - "end", "endless", "endorse", "enemy", "energy", "enforce", - "engage", "engine", "enhance", "enjoy", "enlist", "enough", - "enrich", "enroll", "ensure", "enter", "entire", "entry", - "envelope", "episode", "equal", "equip", "era", "erase", - "erode", "erosion", "error", "erupt", "escape", "essay", - "essence", "estate", "eternal", "ethics", "evidence", "evil", - "evoke", "evolve", "exact", "example", "excess", "exchange", - "excite", "exclude", "excuse", "execute", "exercise", "exhaust", - "exhibit", "exile", "exist", "exit", "exotic", "expand", - "expect", "expire", "explain", "expose", "express", "extend", - "extra", "eye", "eyebrow", "fabric", "face", "faculty", - "fade", "faint", "faith", "fall", "false", "fame", - "family", "famous", "fan", "fancy", "fantasy", "farm", - "fashion", "fat", "fatal", "father", "fatigue", "fault", - "favorite", "feature", "february", "federal", "fee", "feed", - "feel", "female", "fence", "festival", "fetch", "fever", - "few", "fiber", "fiction", "field", "figure", "file", - "film", "filter", "final", "find", "fine", "finger", - "finish", "fire", "firm", "first", "fiscal", "fish", - "fit", "fitness", "fix", "flag", "flame", "flash", - "flat", "flavor", "flee", "flight", "flip", "float", - "flock", "floor", "flower", "fluid", "flush", "fly", - "foam", "focus", "fog", "foil", "fold", "follow", - "food", "foot", "force", "forest", "forget", "fork", - "fortune", "forum", "forward", "fossil", "foster", "found", - "fox", "fragile", "frame", "frequent", "fresh", "friend", - "fringe", "frog", "front", "frost", "frown", "frozen", - "fruit", "fuel", "fun", "funny", "furnace", "fury", - "future", "gadget", "gain", "galaxy", "gallery", "game", - "gap", "garage", "garbage", "garden", "garlic", "garment", - "gas", "gasp", "gate", "gather", "gauge", "gaze", - "general", "genius", "genre", "gentle", "genuine", "gesture", - "ghost", "giant", "gift", "giggle", "ginger", "giraffe", - "girl", "give", "glad", "glance", "glare", "glass", - "glide", "glimpse", "globe", "gloom", "glory", "glove", - "glow", "glue", "goat", "goddess", "gold", "good", - "goose", "gorilla", "gospel", "gossip", "govern", "gown", - "grab", "grace", "grain", "grant", "grape", "grass", - "gravity", "great", "green", "grid", "grief", "grit", - "grocery", "group", "grow", "grunt", "guard", "guess", - "guide", "guilt", "guitar", "gun", "gym", "habit", - "hair", "half", "hammer", "hamster", "hand", "happy", - "harbor", "hard", "harsh", "harvest", "hat", "have", - "hawk", "hazard", "head", "health", "heart", "heavy", - "hedgehog", "height", "hello", "helmet", "help", "hen", - "hero", "hidden", "high", "hill", "hint", "hip", - "hire", "history", "hobby", "hockey", "hold", "hole", - "holiday", "hollow", "home", "honey", "hood", "hope", - "horn", "horror", "horse", "hospital", "host", "hotel", - "hour", "hover", "hub", "huge", "human", "humble", - "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", - "hurt", "husband", "hybrid", "ice", "icon", "idea", - "identify", "idle", "ignore", "ill", "illegal", "illness", - "image", "imitate", "immense", "immune", "impact", "impose", - "improve", "impulse", "inch", "include", "income", "increase", - "index", "indicate", "indoor", "industry", "infant", "inflict", - "inform", "inhale", "inherit", "initial", "inject", "injury", - "inmate", "inner", "innocent", "input", "inquiry", "insane", - "insect", "inside", "inspire", "install", "intact", "interest", - "into", "invest", "invite", "involve", "iron", "island", - "isolate", "issue", "item", "ivory", "jacket", "jaguar", - "jar", "jazz", "jealous", "jeans", "jelly", "jewel", - "job", "join", "joke", "journey", "joy", "judge", - "juice", "jump", "jungle", "junior", "junk", "just", - "kangaroo", "keen", "keep", "ketchup", "key", "kick", - "kid", "kidney", "kind", "kingdom", "kiss", "kit", - "kitchen", "kite", "kitten", "kiwi", "knee", "knife", - "knock", "know", "lab", "label", "labor", "ladder", - "lady", "lake", "lamp", "language", "laptop", "large", - "later", "latin", "laugh", "laundry", "lava", "law", - "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", - "learn", "leave", "lecture", "left", "leg", "legal", - "legend", "leisure", "lemon", "lend", "length", "lens", - "leopard", "lesson", "letter", "level", "liar", "liberty", - "library", "license", "life", "lift", "light", "like", - "limb", "limit", "link", "lion", "liquid", "list", - "little", "live", "lizard", "load", "loan", "lobster", - "local", "lock", "logic", "lonely", "long", "loop", - "lottery", "loud", "lounge", "love", "loyal", "lucky", - "luggage", "lumber", "lunar", "lunch", "luxury", "lyrics", - "machine", "mad", "magic", "magnet", "maid", "mail", - "main", "major", "make", "mammal", "man", "manage", - "mandate", "mango", "mansion", "manual", "maple", "marble", - "march", "margin", "marine", "market", "marriage", "mask", - "mass", "master", "match", "material", "math", "matrix", - "matter", "maximum", "maze", "meadow", "mean", "measure", - "meat", "mechanic", "medal", "media", "melody", "melt", - "member", "memory", "mention", "menu", "mercy", "merge", - "merit", "merry", "mesh", "message", "metal", "method", - "middle", "midnight", "milk", "million", "mimic", "mind", - "minimum", "minor", "minute", "miracle", "mirror", "misery", - "miss", "mistake", "mix", "mixed", "mixture", "mobile", - "model", "modify", "mom", "moment", "monitor", "monkey", - "monster", "month", "moon", "moral", "more", "morning", - "mosquito", "mother", "motion", "motor", "mountain", "mouse", - "move", "movie", "much", "muffin", "mule", "multiply", - "muscle", "museum", "mushroom", "music", "must", "mutual", - "myself", "mystery", "myth", "naive", "name", "napkin", - "narrow", "nasty", "nation", "nature", "near", "neck", - "need", "negative", "neglect", "neither", "nephew", "nerve", - "nest", "net", "network", "neutral", "never", "news", - "next", "nice", "night", "noble", "noise", "nominee", - "noodle", "normal", "north", "nose", "notable", "note", - "nothing", "notice", "novel", "now", "nuclear", "number", - "nurse", "nut", "oak", "obey", "object", "oblige", - "obscure", "observe", "obtain", "obvious", "occur", "ocean", - "october", "odor", "off", "offer", "office", "often", - "oil", "okay", "old", "olive", "olympic", "omit", - "once", "one", "onion", "online", "only", "open", - "opera", "opinion", "oppose", "option", "orange", "orbit", - "orchard", "order", "ordinary", "organ", "orient", "original", - "orphan", "ostrich", "other", "outdoor", "outer", "output", - "outside", "oval", "oven", "over", "own", "owner", - "oxygen", "oyster", "ozone", "pact", "paddle", "page", - "pair", "palace", "palm", "panda", "panel", "panic", - "panther", "paper", "parade", "parent", "park", "parrot", - "party", "pass", "patch", "path", "patient", "patrol", - "pattern", "pause", "pave", "payment", "peace", "peanut", - "pear", "peasant", "pelican", "pen", "penalty", "pencil", - "people", "pepper", "perfect", "permit", "person", "pet", - "phone", "photo", "phrase", "physical", "piano", "picnic", - "picture", "piece", "pig", "pigeon", "pill", "pilot", - "pink", "pioneer", "pipe", "pistol", "pitch", "pizza", - "place", "planet", "plastic", "plate", "play", "please", - "pledge", "pluck", "plug", "plunge", "poem", "poet", - "point", "polar", "pole", "police", "pond", "pony", - "pool", "popular", "portion", "position", "possible", "post", - "potato", "pottery", "poverty", "powder", "power", "practice", - "praise", "predict", "prefer", "prepare", "present", "pretty", - "prevent", "price", "pride", "primary", "print", "priority", - "prison", "private", "prize", "problem", "process", "produce", - "profit", "program", "project", "promote", "proof", "property", - "prosper", "protect", "proud", "provide", "public", "pudding", - "pull", "pulp", "pulse", "pumpkin", "punch", "pupil", - "puppy", "purchase", "purity", "purpose", "purse", "push", - "put", "puzzle", "pyramid", "quality", "quantum", "quarter", - "question", "quick", "quit", "quiz", "quote", "rabbit", - "raccoon", "race", "rack", "radar", "radio", "rail", - "rain", "raise", "rally", "ramp", "ranch", "random", - "range", "rapid", "rare", "rate", "rather", "raven", - "raw", "razor", "ready", "real", "reason", "rebel", - "rebuild", "recall", "receive", "recipe", "record", "recycle", - "reduce", "reflect", "reform", "refuse", "region", "regret", - "regular", "reject", "relax", "release", "relief", "rely", - "remain", "remember", "remind", "remove", "render", "renew", - "rent", "reopen", "repair", "repeat", "replace", "report", - "require", "rescue", "resemble", "resist", "resource", "response", - "result", "retire", "retreat", "return", "reunion", "reveal", - "review", "reward", "rhythm", "rib", "ribbon", "rice", - "rich", "ride", "ridge", "rifle", "right", "rigid", - "ring", "riot", "ripple", "risk", "ritual", "rival", - "river", "road", "roast", "robot", "robust", "rocket", - "romance", "roof", "rookie", "room", "rose", "rotate", - "rough", "round", "route", "royal", "rubber", "rude", - "rug", "rule", "run", "runway", "rural", "sad", - "saddle", "sadness", "safe", "sail", "salad", "salmon", - "salon", "salt", "salute", "same", "sample", "sand", - "satisfy", "satoshi", "sauce", "sausage", "save", "say", - "scale", "scan", "scare", "scatter", "scene", "scheme", - "school", "science", "scissors", "scorpion", "scout", "scrap", - "screen", "script", "scrub", "sea", "search", "season", - "seat", "second", "secret", "section", "security", "seed", - "seek", "segment", "select", "sell", "seminar", "senior", - "sense", "sentence", "series", "service", "session", "settle", - "setup", "seven", "shadow", "shaft", "shallow", "share", - "shed", "shell", "sheriff", "shield", "shift", "shine", - "ship", "shiver", "shock", "shoe", "shoot", "shop", - "short", "shoulder", "shove", "shrimp", "shrug", "shuffle", - "shy", "sibling", "sick", "side", "siege", "sight", - "sign", "silent", "silk", "silly", "silver", "similar", - "simple", "since", "sing", "siren", "sister", "situate", - "six", "size", "skate", "sketch", "ski", "skill", - "skin", "skirt", "skull", "slab", "slam", "sleep", - "slender", "slice", "slide", "slight", "slim", "slogan", - "slot", "slow", "slush", "small", "smart", "smile", - "smoke", "smooth", "snack", "snake", "snap", "sniff", - "snow", "soap", "soccer", "social", "sock", "soda", - "soft", "solar", "soldier", "solid", "solution", "solve", - "someone", "song", "soon", "sorry", "sort", "soul", - "sound", "soup", "source", "south", "space", "spare", - "spatial", "spawn", "speak", "special", "speed", "spell", - "spend", "sphere", "spice", "spider", "spike", "spin", - "spirit", "split", "spoil", "sponsor", "spoon", "sport", - "spot", "spray", "spread", "spring", "spy", "square", - "squeeze", "squirrel", "stable", "stadium", "staff", "stage", - "stairs", "stamp", "stand", "start", "state", "stay", - "steak", "steel", "stem", "step", "stereo", "stick", - "still", "sting", "stock", "stomach", "stone", "stool", - "story", "stove", "strategy", "street", "strike", "strong", - "struggle", "student", "stuff", "stumble", "style", "subject", - "submit", "subway", "success", "such", "sudden", "suffer", - "sugar", "suggest", "suit", "summer", "sun", "sunny", - "sunset", "super", "supply", "supreme", "sure", "surface", - "surge", "surprise", "surround", "survey", "suspect", "sustain", - "swallow", "swamp", "swap", "swarm", "swear", "sweet", - "swift", "swim", "swing", "switch", "sword", "symbol", - "symptom", "syrup", "system", "table", "tackle", "tag", - "tail", "talent", "talk", "tank", "tape", "target", - "task", "taste", "tattoo", "taxi", "teach", "team", - "tell", "ten", "tenant", "tennis", "tent", "term", - "test", "text", "thank", "that", "theme", "then", - "theory", "there", "they", "thing", "this", "thought", - "three", "thrive", "throw", "thumb", "thunder", "ticket", - "tide", "tiger", "tilt", "timber", "time", "tiny", - "tip", "tired", "tissue", "title", "toast", "tobacco", - "today", "toddler", "toe", "together", "toilet", "token", - "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", - "tooth", "top", "topic", "topple", "torch", "tornado", - "tortoise", "toss", "total", "tourist", "toward", "tower", - "town", "toy", "track", "trade", "traffic", "tragic", - "train", "transfer", "trap", "trash", "travel", "tray", - "treat", "tree", "trend", "trial", "tribe", "trick", - "trigger", "trim", "trip", "trophy", "trouble", "truck", - "true", "truly", "trumpet", "trust", "truth", "try", - "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", - "turn", "turtle", "twelve", "twenty", "twice", "twin", - "twist", "two", "type", "typical", "ugly", "umbrella", - "unable", "unaware", "uncle", "uncover", "under", "undo", - "unfair", "unfold", "unhappy", "uniform", "unique", "unit", - "universe", "unknown", "unlock", "until", "unusual", "unveil", - "update", "upgrade", "uphold", "upon", "upper", "upset", - "urban", "urge", "usage", "use", "used", "useful", - "useless", "usual", "utility", "vacant", "vacuum", "vague", - "valid", "valley", "valve", "van", "vanish", "vapor", - "various", "vast", "vault", "vehicle", "velvet", "vendor", - "venture", "venue", "verb", "verify", "version", "very", - "vessel", "veteran", "viable", "vibrant", "vicious", "victory", - "video", "view", "village", "vintage", "violin", "virtual", - "virus", "visa", "visit", "visual", "vital", "vivid", - "vocal", "voice", "void", "volcano", "volume", "vote", - "voyage", "wage", "wagon", "wait", "walk", "wall", - "walnut", "want", "warfare", "warm", "warrior", "wash", - "wasp", "waste", "water", "wave", "way", "wealth", - "weapon", "wear", "weasel", "weather", "web", "wedding", - "weekend", "weird", "welcome", "west", "wet", "whale", - "what", "wheat", "wheel", "when", "where", "whip", - "whisper", "wide", "width", "wife", "wild", "will", - "win", "window", "wine", "wing", "wink", "winner", - "winter", "wire", "wisdom", "wise", "wish", "witness", - "wolf", "woman", "wonder", "wood", "wool", "word", - "work", "world", "worry", "worth", "wrap", "wreck", - "wrestle", "wrist", "write", "wrong", "yard", "year", - "yellow", "you", "young", "youth", "zebra", "zero", - "zone", "zoo", + "abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", + "absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid", + "acoustic", "acquire", "across", "act", "action", "actor", "actress", "actual", + "adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance", + "advice", "aerobic", "affair", "afford", "afraid", "again", "age", "agent", + "agree", "ahead", "aim", "air", "airport", "aisle", "alarm", "album", + "alcohol", "alert", "alien", "all", "alley", "allow", "almost", "alone", + "alpha", "already", "also", "alter", "always", "amateur", "amazing", "among", + "amount", "amused", "analyst", "anchor", "ancient", "anger", "angle", "angry", + "animal", "ankle", "announce", "annual", "another", "answer", "antenna", "antique", + "anxiety", "any", "apart", "apology", "appear", "apple", "approve", "april", + "arch", "arctic", "area", "arena", "argue", "arm", "armed", "armor", + "army", "around", "arrange", "arrest", "arrive", "arrow", "art", "artefact", + "artist", "artwork", "ask", "aspect", "assault", "asset", "assist", "assume", + "asthma", "athlete", "atom", "attack", "attend", "attitude", "attract", "auction", + "audit", "august", "aunt", "author", "auto", "autumn", "average", "avocado", + "avoid", "awake", "aware", "away", "awesome", "awful", "awkward", "axis", + "baby", "bachelor", "bacon", "badge", "bag", "balance", "balcony", "ball", + "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel", "base", + "basic", "basket", "battle", "beach", "bean", "beauty", "because", "become", + "beef", "before", "begin", "behave", "behind", "believe", "below", "belt", + "bench", "benefit", "best", "betray", "better", "between", "beyond", "bicycle", + "bid", "bike", "bind", "biology", "bird", "birth", "bitter", "black", + "blade", "blame", "blanket", "blast", "bleak", "bless", "blind", "blood", + "blossom", "blouse", "blue", "blur", "blush", "board", "boat", "body", + "boil", "bomb", "bone", "bonus", "book", "boost", "border", "boring", + "borrow", "boss", "bottom", "bounce", "box", "boy", "bracket", "brain", + "brand", "brass", "brave", "bread", "breeze", "brick", "bridge", "brief", + "bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom", "brother", + "brown", "brush", "bubble", "buddy", "budget", "buffalo", "build", "bulb", + "bulk", "bullet", "bundle", "bunker", "burden", "burger", "burst", "bus", + "business", "busy", "butter", "buyer", "buzz", "cabbage", "cabin", "cable", + "cactus", "cage", "cake", "call", "calm", "camera", "camp", "can", + "canal", "cancel", "candy", "cannon", "canoe", "canvas", "canyon", "capable", + "capital", "captain", "car", "carbon", "card", "cargo", "carpet", "carry", + "cart", "case", "cash", "casino", "castle", "casual", "cat", "catalog", + "catch", "category", "cattle", "caught", "cause", "caution", "cave", "ceiling", + "celery", "cement", "census", "century", "cereal", "certain", "chair", "chalk", + "champion", "change", "chaos", "chapter", "charge", "chase", "chat", "cheap", + "check", "cheese", "chef", "cherry", "chest", "chicken", "chief", "child", + "chimney", "choice", "choose", "chronic", "chuckle", "chunk", "churn", "cigar", + "cinnamon", "circle", "citizen", "city", "civil", "claim", "clap", "clarify", + "claw", "clay", "clean", "clerk", "clever", "click", "client", "cliff", + "climb", "clinic", "clip", "clock", "clog", "close", "cloth", "cloud", + "clown", "club", "clump", "cluster", "clutch", "coach", "coast", "coconut", + "code", "coffee", "coil", "coin", "collect", "color", "column", "combine", + "come", "comfort", "comic", "common", "company", "concert", "conduct", "confirm", + "congress", "connect", "consider", "control", "convince", "cook", "cool", "copper", + "copy", "coral", "core", "corn", "correct", "cost", "cotton", "couch", + "country", "couple", "course", "cousin", "cover", "coyote", "crack", "cradle", + "craft", "cram", "crane", "crash", "crater", "crawl", "crazy", "cream", + "credit", "creek", "crew", "cricket", "crime", "crisp", "critic", "crop", + "cross", "crouch", "crowd", "crucial", "cruel", "cruise", "crumble", "crunch", + "crush", "cry", "crystal", "cube", "culture", "cup", "cupboard", "curious", + "current", "curtain", "curve", "cushion", "custom", "cute", "cycle", "dad", + "damage", "damp", "dance", "danger", "daring", "dash", "daughter", "dawn", + "day", "deal", "debate", "debris", "decade", "december", "decide", "decline", + "decorate", "decrease", "deer", "defense", "define", "defy", "degree", "delay", + "deliver", "demand", "demise", "denial", "dentist", "deny", "depart", "depend", + "deposit", "depth", "deputy", "derive", "describe", "desert", "design", "desk", + "despair", "destroy", "detail", "detect", "develop", "device", "devote", "diagram", + "dial", "diamond", "diary", "dice", "diesel", "diet", "differ", "digital", + "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree", "discover", + "disease", "dish", "dismiss", "disorder", "display", "distance", "divert", "divide", + "divorce", "dizzy", "doctor", "document", "dog", "doll", "dolphin", "domain", + "donate", "donkey", "donor", "door", "dose", "double", "dove", "draft", + "dragon", "drama", "drastic", "draw", "dream", "dress", "drift", "drill", + "drink", "drip", "drive", "drop", "drum", "dry", "duck", "dumb", + "dune", "during", "dust", "dutch", "duty", "dwarf", "dynamic", "eager", + "eagle", "early", "earn", "earth", "easily", "east", "easy", "echo", + "ecology", "economy", "edge", "edit", "educate", "effort", "egg", "eight", + "either", "elbow", "elder", "electric", "elegant", "element", "elephant", "elevator", + "elite", "else", "embark", "embody", "embrace", "emerge", "emotion", "employ", + "empower", "empty", "enable", "enact", "end", "endless", "endorse", "enemy", + "energy", "enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough", + "enrich", "enroll", "ensure", "enter", "entire", "entry", "envelope", "episode", + "equal", "equip", "era", "erase", "erode", "erosion", "error", "erupt", + "escape", "essay", "essence", "estate", "eternal", "ethics", "evidence", "evil", + "evoke", "evolve", "exact", "example", "excess", "exchange", "excite", "exclude", + "excuse", "execute", "exercise", "exhaust", "exhibit", "exile", "exist", "exit", + "exotic", "expand", "expect", "expire", "explain", "expose", "express", "extend", + "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade", "faint", + "faith", "fall", "false", "fame", "family", "famous", "fan", "fancy", + "fantasy", "farm", "fashion", "fat", "fatal", "father", "fatigue", "fault", + "favorite", "feature", "february", "federal", "fee", "feed", "feel", "female", + "fence", "festival", "fetch", "fever", "few", "fiber", "fiction", "field", + "figure", "file", "film", "filter", "final", "find", "fine", "finger", + "finish", "fire", "firm", "first", "fiscal", "fish", "fit", "fitness", + "fix", "flag", "flame", "flash", "flat", "flavor", "flee", "flight", + "flip", "float", "flock", "floor", "flower", "fluid", "flush", "fly", + "foam", "focus", "fog", "foil", "fold", "follow", "food", "foot", + "force", "forest", "forget", "fork", "fortune", "forum", "forward", "fossil", + "foster", "found", "fox", "fragile", "frame", "frequent", "fresh", "friend", + "fringe", "frog", "front", "frost", "frown", "frozen", "fruit", "fuel", + "fun", "funny", "furnace", "fury", "future", "gadget", "gain", "galaxy", + "gallery", "game", "gap", "garage", "garbage", "garden", "garlic", "garment", + "gas", "gasp", "gate", "gather", "gauge", "gaze", "general", "genius", + "genre", "gentle", "genuine", "gesture", "ghost", "giant", "gift", "giggle", + "ginger", "giraffe", "girl", "give", "glad", "glance", "glare", "glass", + "glide", "glimpse", "globe", "gloom", "glory", "glove", "glow", "glue", + "goat", "goddess", "gold", "good", "goose", "gorilla", "gospel", "gossip", + "govern", "gown", "grab", "grace", "grain", "grant", "grape", "grass", + "gravity", "great", "green", "grid", "grief", "grit", "grocery", "group", + "grow", "grunt", "guard", "guess", "guide", "guilt", "guitar", "gun", + "gym", "habit", "hair", "half", "hammer", "hamster", "hand", "happy", + "harbor", "hard", "harsh", "harvest", "hat", "have", "hawk", "hazard", + "head", "health", "heart", "heavy", "hedgehog", "height", "hello", "helmet", + "help", "hen", "hero", "hidden", "high", "hill", "hint", "hip", + "hire", "history", "hobby", "hockey", "hold", "hole", "holiday", "hollow", + "home", "honey", "hood", "hope", "horn", "horror", "horse", "hospital", + "host", "hotel", "hour", "hover", "hub", "huge", "human", "humble", + "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", "hurt", "husband", + "hybrid", "ice", "icon", "idea", "identify", "idle", "ignore", "ill", + "illegal", "illness", "image", "imitate", "immense", "immune", "impact", "impose", + "improve", "impulse", "inch", "include", "income", "increase", "index", "indicate", + "indoor", "industry", "infant", "inflict", "inform", "inhale", "inherit", "initial", + "inject", "injury", "inmate", "inner", "innocent", "input", "inquiry", "insane", + "insect", "inside", "inspire", "install", "intact", "interest", "into", "invest", + "invite", "involve", "iron", "island", "isolate", "issue", "item", "ivory", + "jacket", "jaguar", "jar", "jazz", "jealous", "jeans", "jelly", "jewel", + "job", "join", "joke", "journey", "joy", "judge", "juice", "jump", + "jungle", "junior", "junk", "just", "kangaroo", "keen", "keep", "ketchup", + "key", "kick", "kid", "kidney", "kind", "kingdom", "kiss", "kit", + "kitchen", "kite", "kitten", "kiwi", "knee", "knife", "knock", "know", + "lab", "label", "labor", "ladder", "lady", "lake", "lamp", "language", + "laptop", "large", "later", "latin", "laugh", "laundry", "lava", "law", + "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", "learn", "leave", + "lecture", "left", "leg", "legal", "legend", "leisure", "lemon", "lend", + "length", "lens", "leopard", "lesson", "letter", "level", "liar", "liberty", + "library", "license", "life", "lift", "light", "like", "limb", "limit", + "link", "lion", "liquid", "list", "little", "live", "lizard", "load", + "loan", "lobster", "local", "lock", "logic", "lonely", "long", "loop", + "lottery", "loud", "lounge", "love", "loyal", "lucky", "luggage", "lumber", + "lunar", "lunch", "luxury", "lyrics", "machine", "mad", "magic", "magnet", + "maid", "mail", "main", "major", "make", "mammal", "man", "manage", + "mandate", "mango", "mansion", "manual", "maple", "marble", "march", "margin", + "marine", "market", "marriage", "mask", "mass", "master", "match", "material", + "math", "matrix", "matter", "maximum", "maze", "meadow", "mean", "measure", + "meat", "mechanic", "medal", "media", "melody", "melt", "member", "memory", + "mention", "menu", "mercy", "merge", "merit", "merry", "mesh", "message", + "metal", "method", "middle", "midnight", "milk", "million", "mimic", "mind", + "minimum", "minor", "minute", "miracle", "mirror", "misery", "miss", "mistake", + "mix", "mixed", "mixture", "mobile", "model", "modify", "mom", "moment", + "monitor", "monkey", "monster", "month", "moon", "moral", "more", "morning", + "mosquito", "mother", "motion", "motor", "mountain", "mouse", "move", "movie", + "much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom", "music", + "must", "mutual", "myself", "mystery", "myth", "naive", "name", "napkin", + "narrow", "nasty", "nation", "nature", "near", "neck", "need", "negative", + "neglect", "neither", "nephew", "nerve", "nest", "net", "network", "neutral", + "never", "news", "next", "nice", "night", "noble", "noise", "nominee", + "noodle", "normal", "north", "nose", "notable", "note", "nothing", "notice", + "novel", "now", "nuclear", "number", "nurse", "nut", "oak", "obey", + "object", "oblige", "obscure", "observe", "obtain", "obvious", "occur", "ocean", + "october", "odor", "off", "offer", "office", "often", "oil", "okay", + "old", "olive", "olympic", "omit", "once", "one", "onion", "online", + "only", "open", "opera", "opinion", "oppose", "option", "orange", "orbit", + "orchard", "order", "ordinary", "organ", "orient", "original", "orphan", "ostrich", + "other", "outdoor", "outer", "output", "outside", "oval", "oven", "over", + "own", "owner", "oxygen", "oyster", "ozone", "pact", "paddle", "page", + "pair", "palace", "palm", "panda", "panel", "panic", "panther", "paper", + "parade", "parent", "park", "parrot", "party", "pass", "patch", "path", + "patient", "patrol", "pattern", "pause", "pave", "payment", "peace", "peanut", + "pear", "peasant", "pelican", "pen", "penalty", "pencil", "people", "pepper", + "perfect", "permit", "person", "pet", "phone", "photo", "phrase", "physical", + "piano", "picnic", "picture", "piece", "pig", "pigeon", "pill", "pilot", + "pink", "pioneer", "pipe", "pistol", "pitch", "pizza", "place", "planet", + "plastic", "plate", "play", "please", "pledge", "pluck", "plug", "plunge", + "poem", "poet", "point", "polar", "pole", "police", "pond", "pony", + "pool", "popular", "portion", "position", "possible", "post", "potato", "pottery", + "poverty", "powder", "power", "practice", "praise", "predict", "prefer", "prepare", + "present", "pretty", "prevent", "price", "pride", "primary", "print", "priority", + "prison", "private", "prize", "problem", "process", "produce", "profit", "program", + "project", "promote", "proof", "property", "prosper", "protect", "proud", "provide", + "public", "pudding", "pull", "pulp", "pulse", "pumpkin", "punch", "pupil", + "puppy", "purchase", "purity", "purpose", "purse", "push", "put", "puzzle", + "pyramid", "quality", "quantum", "quarter", "question", "quick", "quit", "quiz", + "quote", "rabbit", "raccoon", "race", "rack", "radar", "radio", "rail", + "rain", "raise", "rally", "ramp", "ranch", "random", "range", "rapid", + "rare", "rate", "rather", "raven", "raw", "razor", "ready", "real", + "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record", "recycle", + "reduce", "reflect", "reform", "refuse", "region", "regret", "regular", "reject", + "relax", "release", "relief", "rely", "remain", "remember", "remind", "remove", + "render", "renew", "rent", "reopen", "repair", "repeat", "replace", "report", + "require", "rescue", "resemble", "resist", "resource", "response", "result", "retire", + "retreat", "return", "reunion", "reveal", "review", "reward", "rhythm", "rib", + "ribbon", "rice", "rich", "ride", "ridge", "rifle", "right", "rigid", + "ring", "riot", "ripple", "risk", "ritual", "rival", "river", "road", + "roast", "robot", "robust", "rocket", "romance", "roof", "rookie", "room", + "rose", "rotate", "rough", "round", "route", "royal", "rubber", "rude", + "rug", "rule", "run", "runway", "rural", "sad", "saddle", "sadness", + "safe", "sail", "salad", "salmon", "salon", "salt", "salute", "same", + "sample", "sand", "satisfy", "satoshi", "sauce", "sausage", "save", "say", + "scale", "scan", "scare", "scatter", "scene", "scheme", "school", "science", + "scissors", "scorpion", "scout", "scrap", "screen", "script", "scrub", "sea", + "search", "season", "seat", "second", "secret", "section", "security", "seed", + "seek", "segment", "select", "sell", "seminar", "senior", "sense", "sentence", + "series", "service", "session", "settle", "setup", "seven", "shadow", "shaft", + "shallow", "share", "shed", "shell", "sheriff", "shield", "shift", "shine", + "ship", "shiver", "shock", "shoe", "shoot", "shop", "short", "shoulder", + "shove", "shrimp", "shrug", "shuffle", "shy", "sibling", "sick", "side", + "siege", "sight", "sign", "silent", "silk", "silly", "silver", "similar", + "simple", "since", "sing", "siren", "sister", "situate", "six", "size", + "skate", "sketch", "ski", "skill", "skin", "skirt", "skull", "slab", + "slam", "sleep", "slender", "slice", "slide", "slight", "slim", "slogan", + "slot", "slow", "slush", "small", "smart", "smile", "smoke", "smooth", + "snack", "snake", "snap", "sniff", "snow", "soap", "soccer", "social", + "sock", "soda", "soft", "solar", "soldier", "solid", "solution", "solve", + "someone", "song", "soon", "sorry", "sort", "soul", "sound", "soup", + "source", "south", "space", "spare", "spatial", "spawn", "speak", "special", + "speed", "spell", "spend", "sphere", "spice", "spider", "spike", "spin", + "spirit", "split", "spoil", "sponsor", "spoon", "sport", "spot", "spray", + "spread", "spring", "spy", "square", "squeeze", "squirrel", "stable", "stadium", + "staff", "stage", "stairs", "stamp", "stand", "start", "state", "stay", + "steak", "steel", "stem", "step", "stereo", "stick", "still", "sting", + "stock", "stomach", "stone", "stool", "story", "stove", "strategy", "street", + "strike", "strong", "struggle", "student", "stuff", "stumble", "style", "subject", + "submit", "subway", "success", "such", "sudden", "suffer", "sugar", "suggest", + "suit", "summer", "sun", "sunny", "sunset", "super", "supply", "supreme", + "sure", "surface", "surge", "surprise", "surround", "survey", "suspect", "sustain", + "swallow", "swamp", "swap", "swarm", "swear", "sweet", "swift", "swim", + "swing", "switch", "sword", "symbol", "symptom", "syrup", "system", "table", + "tackle", "tag", "tail", "talent", "talk", "tank", "tape", "target", + "task", "taste", "tattoo", "taxi", "teach", "team", "tell", "ten", + "tenant", "tennis", "tent", "term", "test", "text", "thank", "that", + "theme", "then", "theory", "there", "they", "thing", "this", "thought", + "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide", "tiger", + "tilt", "timber", "time", "tiny", "tip", "tired", "tissue", "title", + "toast", "tobacco", "today", "toddler", "toe", "together", "toilet", "token", + "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", "tooth", "top", + "topic", "topple", "torch", "tornado", "tortoise", "toss", "total", "tourist", + "toward", "tower", "town", "toy", "track", "trade", "traffic", "tragic", + "train", "transfer", "trap", "trash", "travel", "tray", "treat", "tree", + "trend", "trial", "tribe", "trick", "trigger", "trim", "trip", "trophy", + "trouble", "truck", "true", "truly", "trumpet", "trust", "truth", "try", + "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", "turn", "turtle", + "twelve", "twenty", "twice", "twin", "twist", "two", "type", "typical", + "ugly", "umbrella", "unable", "unaware", "uncle", "uncover", "under", "undo", + "unfair", "unfold", "unhappy", "uniform", "unique", "unit", "universe", "unknown", + "unlock", "until", "unusual", "unveil", "update", "upgrade", "uphold", "upon", + "upper", "upset", "urban", "urge", "usage", "use", "used", "useful", + "useless", "usual", "utility", "vacant", "vacuum", "vague", "valid", "valley", + "valve", "van", "vanish", "vapor", "various", "vast", "vault", "vehicle", + "velvet", "vendor", "venture", "venue", "verb", "verify", "version", "very", + "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video", "view", + "village", "vintage", "violin", "virtual", "virus", "visa", "visit", "visual", + "vital", "vivid", "vocal", "voice", "void", "volcano", "volume", "vote", + "voyage", "wage", "wagon", "wait", "walk", "wall", "walnut", "want", + "warfare", "warm", "warrior", "wash", "wasp", "waste", "water", "wave", + "way", "wealth", "weapon", "wear", "weasel", "weather", "web", "wedding", + "weekend", "weird", "welcome", "west", "wet", "whale", "what", "wheat", + "wheel", "when", "where", "whip", "whisper", "wide", "width", "wife", + "wild", "will", "win", "window", "wine", "wing", "wink", "winner", + "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf", "woman", + "wonder", "wood", "wool", "word", "work", "world", "worry", "worth", + "wrap", "wreck", "wrestle", "wrist", "write", "wrong", "yard", "year", + "yellow", "you", "young", "youth", "zebra", "zero", "zone", "zoo", }; diff --git a/crypto/blake256.c b/crypto/blake256.c index a7cb843c1f2..dfe6213b631 100644 --- a/crypto/blake256.c +++ b/crypto/blake256.c @@ -14,221 +14,209 @@ #include -#define U8TO32_BIG(p) \ - (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ - ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) - -#define U32TO8_BIG(p, v) \ - (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ - (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); - -static const uint8_t sigma[][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, - {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, - {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, - {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, - {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, - {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, - {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, - {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } -}; - -static const uint32_t u256[16] = -{ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 -}; - -static const uint8_t padding[129] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static void blake256_compress( BLAKE256_CTX *S, const uint8_t *block ) -{ - uint32_t v[16] = {0}, m[16] = {0}, i = 0; -#define ROT(x,n) (((x)<<(32-n))|( (x)>>(n))) -#define G(a,b,c,d,e) \ - v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e+1]]) + v[b]; \ - v[d] = ROT( v[d] ^ v[a],16); \ - v[c] += v[d]; \ - v[b] = ROT( v[b] ^ v[c],12); \ - v[a] += (m[sigma[i][e+1]] ^ u256[sigma[i][e]])+v[b]; \ - v[d] = ROT( v[d] ^ v[a], 8); \ - v[c] += v[d]; \ - v[b] = ROT( v[b] ^ v[c], 7); - - for( i = 0; i < 16; ++i ) m[i] = U8TO32_BIG( block + i * 4 ); - - for( i = 0; i < 8; ++i ) v[i] = S->h[i]; - - v[ 8] = S->s[0] ^ u256[0]; - v[ 9] = S->s[1] ^ u256[1]; - v[10] = S->s[2] ^ u256[2]; - v[11] = S->s[3] ^ u256[3]; - v[12] = u256[4]; - v[13] = u256[5]; - v[14] = u256[6]; - v[15] = u256[7]; - - /* don't xor t when the block is only padding */ - if ( !S->nullt ) - { - v[12] ^= S->t[0]; - v[13] ^= S->t[0]; - v[14] ^= S->t[1]; - v[15] ^= S->t[1]; - } - - for( i = 0; i < 14; ++i ) - { - /* column step */ - G( 0, 4, 8, 12, 0 ); - G( 1, 5, 9, 13, 2 ); - G( 2, 6, 10, 14, 4 ); - G( 3, 7, 11, 15, 6 ); - /* diagonal step */ - G( 0, 5, 10, 15, 8 ); - G( 1, 6, 11, 12, 10 ); - G( 2, 7, 8, 13, 12 ); - G( 3, 4, 9, 14, 14 ); - } - - for( i = 0; i < 16; ++i ) S->h[i % 8] ^= v[i]; - - for( i = 0; i < 8 ; ++i ) S->h[i] ^= S->s[i % 4]; -} +#define U8TO32_BIG(p) \ + (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | ((uint32_t)((p)[2]) << 8) | \ + ((uint32_t)((p)[3]))) + +#define U32TO8_BIG(p, v) \ + (p)[0] = (uint8_t)((v) >> 24); \ + (p)[1] = (uint8_t)((v) >> 16); \ + (p)[2] = (uint8_t)((v) >> 8); \ + (p)[3] = (uint8_t)((v)); + +static const uint8_t sigma[][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}}; + +static const uint32_t u256[16] = { + 0x243f6a88, + 0x85a308d3, + 0x13198a2e, + 0x03707344, + 0xa4093822, + 0x299f31d0, + 0x082efa98, + 0xec4e6c89, + 0x452821e6, + 0x38d01377, + 0xbe5466cf, + 0x34e90c6c, + 0xc0ac29b7, + 0xc97c50dd, + 0x3f84d5b5, + 0xb5470917}; + +static const uint8_t padding[129] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static void blake256_compress(BLAKE256_CTX* S, const uint8_t* block) { + uint32_t v[16] = {0}, m[16] = {0}, i = 0; +#define ROT(x, n) (((x) << (32 - n)) | ((x) >> (n))) +#define G(a, b, c, d, e) \ + v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e + 1]]) + v[b]; \ + v[d] = ROT(v[d] ^ v[a], 16); \ + v[c] += v[d]; \ + v[b] = ROT(v[b] ^ v[c], 12); \ + v[a] += (m[sigma[i][e + 1]] ^ u256[sigma[i][e]]) + v[b]; \ + v[d] = ROT(v[d] ^ v[a], 8); \ + v[c] += v[d]; \ + v[b] = ROT(v[b] ^ v[c], 7); + + for(i = 0; i < 16; ++i) m[i] = U8TO32_BIG(block + i * 4); + + for(i = 0; i < 8; ++i) v[i] = S->h[i]; + + v[8] = S->s[0] ^ u256[0]; + v[9] = S->s[1] ^ u256[1]; + v[10] = S->s[2] ^ u256[2]; + v[11] = S->s[3] ^ u256[3]; + v[12] = u256[4]; + v[13] = u256[5]; + v[14] = u256[6]; + v[15] = u256[7]; + + /* don't xor t when the block is only padding */ + if(!S->nullt) { + v[12] ^= S->t[0]; + v[13] ^= S->t[0]; + v[14] ^= S->t[1]; + v[15] ^= S->t[1]; + } + for(i = 0; i < 14; ++i) { + /* column step */ + G(0, 4, 8, 12, 0); + G(1, 5, 9, 13, 2); + G(2, 6, 10, 14, 4); + G(3, 7, 11, 15, 6); + /* diagonal step */ + G(0, 5, 10, 15, 8); + G(1, 6, 11, 12, 10); + G(2, 7, 8, 13, 12); + G(3, 4, 9, 14, 14); + } -void blake256_Init( BLAKE256_CTX *S ) -{ - S->h[0] = 0x6a09e667; - S->h[1] = 0xbb67ae85; - S->h[2] = 0x3c6ef372; - S->h[3] = 0xa54ff53a; - S->h[4] = 0x510e527f; - S->h[5] = 0x9b05688c; - S->h[6] = 0x1f83d9ab; - S->h[7] = 0x5be0cd19; - S->t[0] = S->t[1] = S->buflen = S->nullt = 0; - S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; -} + for(i = 0; i < 16; ++i) S->h[i % 8] ^= v[i]; + for(i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4]; +} -void blake256_Update( BLAKE256_CTX *S, const uint8_t *in, size_t inlen ) -{ - size_t left = S->buflen; - size_t fill = 64 - left; - - /* data left and data received fill a block */ - if( left && ( inlen >= fill ) ) - { - memcpy( ( void * ) ( S->buf + left ), ( void * ) in, fill ); - S->t[0] += 512; - - if ( S->t[0] == 0 ) S->t[1]++; - - blake256_compress( S, S->buf ); - in += fill; - inlen -= fill; - left = 0; - } - - /* compress blocks of data received */ - while( inlen >= 64 ) - { - S->t[0] += 512; - - if ( S->t[0] == 0 ) S->t[1]++; - - blake256_compress( S, in ); - in += 64; - inlen -= 64; - } - - /* store any data left */ - if( inlen > 0 ) - { - memcpy( ( void * ) ( S->buf + left ), \ - ( void * ) in, ( size_t ) inlen ); - } - S->buflen = left + inlen; +void blake256_Init(BLAKE256_CTX* S) { + S->h[0] = 0x6a09e667; + S->h[1] = 0xbb67ae85; + S->h[2] = 0x3c6ef372; + S->h[3] = 0xa54ff53a; + S->h[4] = 0x510e527f; + S->h[5] = 0x9b05688c; + S->h[6] = 0x1f83d9ab; + S->h[7] = 0x5be0cd19; + S->t[0] = S->t[1] = S->buflen = S->nullt = 0; + S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; } +void blake256_Update(BLAKE256_CTX* S, const uint8_t* in, size_t inlen) { + size_t left = S->buflen; + size_t fill = 64 - left; + + /* data left and data received fill a block */ + if(left && (inlen >= fill)) { + memcpy((void*)(S->buf + left), (void*)in, fill); + S->t[0] += 512; -void blake256_Final( BLAKE256_CTX *S, uint8_t *out ) -{ - uint8_t msglen[8] = {0}, zo = 0x01, oo = 0x81; - uint32_t lo = S->t[0] + ( S->buflen << 3 ), hi = S->t[1]; + if(S->t[0] == 0) S->t[1]++; - /* support for hashing more than 2^32 bits */ - if ( lo < ( S->buflen << 3 ) ) hi++; + blake256_compress(S, S->buf); + in += fill; + inlen -= fill; + left = 0; + } - U32TO8_BIG( msglen + 0, hi ); - U32TO8_BIG( msglen + 4, lo ); + /* compress blocks of data received */ + while(inlen >= 64) { + S->t[0] += 512; - if ( S->buflen == 55 ) /* one padding byte */ - { - S->t[0] -= 8; - blake256_Update( S, &oo, 1 ); - } - else - { - if ( S->buflen < 55 ) /* enough space to fill the block */ - { - if ( !S->buflen ) S->nullt = 1; + if(S->t[0] == 0) S->t[1]++; - S->t[0] -= 440 - ( S->buflen << 3 ); - blake256_Update( S, padding, 55 - S->buflen ); + blake256_compress(S, in); + in += 64; + inlen -= 64; } - else /* need 2 compressions */ + + /* store any data left */ + if(inlen > 0) { + memcpy((void*)(S->buf + left), (void*)in, (size_t)inlen); + } + S->buflen = left + inlen; +} + +void blake256_Final(BLAKE256_CTX* S, uint8_t* out) { + uint8_t msglen[8] = {0}, zo = 0x01, oo = 0x81; + uint32_t lo = S->t[0] + (S->buflen << 3), hi = S->t[1]; + + /* support for hashing more than 2^32 bits */ + if(lo < (S->buflen << 3)) hi++; + + U32TO8_BIG(msglen + 0, hi); + U32TO8_BIG(msglen + 4, lo); + + if(S->buflen == 55) /* one padding byte */ { - S->t[0] -= 512 - ( S->buflen << 3 ); - blake256_Update( S, padding, 64 - S->buflen ); - S->t[0] -= 440; - blake256_Update( S, padding + 1, 55 ); - S->nullt = 1; + S->t[0] -= 8; + blake256_Update(S, &oo, 1); + } else { + if(S->buflen < 55) /* enough space to fill the block */ + { + if(!S->buflen) S->nullt = 1; + + S->t[0] -= 440 - (S->buflen << 3); + blake256_Update(S, padding, 55 - S->buflen); + } else /* need 2 compressions */ + { + S->t[0] -= 512 - (S->buflen << 3); + blake256_Update(S, padding, 64 - S->buflen); + S->t[0] -= 440; + blake256_Update(S, padding + 1, 55); + S->nullt = 1; + } + + blake256_Update(S, &zo, 1); + S->t[0] -= 8; } - blake256_Update( S, &zo, 1 ); - S->t[0] -= 8; - } - - S->t[0] -= 64; - blake256_Update( S, msglen, 8 ); - U32TO8_BIG( out + 0, S->h[0] ); - U32TO8_BIG( out + 4, S->h[1] ); - U32TO8_BIG( out + 8, S->h[2] ); - U32TO8_BIG( out + 12, S->h[3] ); - U32TO8_BIG( out + 16, S->h[4] ); - U32TO8_BIG( out + 20, S->h[5] ); - U32TO8_BIG( out + 24, S->h[6] ); - U32TO8_BIG( out + 28, S->h[7] ); + S->t[0] -= 64; + blake256_Update(S, msglen, 8); + U32TO8_BIG(out + 0, S->h[0]); + U32TO8_BIG(out + 4, S->h[1]); + U32TO8_BIG(out + 8, S->h[2]); + U32TO8_BIG(out + 12, S->h[3]); + U32TO8_BIG(out + 16, S->h[4]); + U32TO8_BIG(out + 20, S->h[5]); + U32TO8_BIG(out + 24, S->h[6]); + U32TO8_BIG(out + 28, S->h[7]); } - -void blake256( const uint8_t *in, size_t inlen, uint8_t *out ) -{ - BLAKE256_CTX S = {0}; - blake256_Init( &S ); - blake256_Update( &S, in, inlen ); - blake256_Final( &S, out ); +void blake256(const uint8_t* in, size_t inlen, uint8_t* out) { + BLAKE256_CTX S = {0}; + blake256_Init(&S); + blake256_Update(&S, in, inlen); + blake256_Final(&S, out); } diff --git a/crypto/blake256.h b/crypto/blake256.h index 2c68ae2ef8d..c02f7c00454 100644 --- a/crypto/blake256.h +++ b/crypto/blake256.h @@ -35,19 +35,19 @@ #include #define BLAKE256_DIGEST_LENGTH 32 -#define BLAKE256_BLOCK_LENGTH 64 +#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]; + 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_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 *); +void blake256(const uint8_t*, size_t, uint8_t*); #endif /* __BLAKE256_H__ */ diff --git a/crypto/blake2_common.h b/crypto/blake2_common.h index 39cefd72c19..369c7cc0f84 100644 --- a/crypto/blake2_common.h +++ b/crypto/blake2_common.h @@ -1,44 +1,46 @@ #include "byte_order.h" -static inline uint32_t load32(const void *src) { - uint32_t w; - memcpy(&w, src, sizeof w); +static inline uint32_t load32(const void* src) { + uint32_t w; + memcpy(&w, src, sizeof w); #if BYTE_ORDER == BIG_ENDIAN - REVERSE32(w, w); + REVERSE32(w, w); #endif - return w; + return w; } -static inline uint64_t load64(const void *src) { - uint64_t w; - memcpy(&w, src, sizeof w); +static inline uint64_t load64(const void* src) { + uint64_t w; + memcpy(&w, src, sizeof w); #if BYTE_ORDER == BIG_ENDIAN - REVERSE64(w, w); + REVERSE64(w, w); #endif - return w; + return w; } -static inline void store16(void *dst, uint16_t w) { memcpy(dst, &w, sizeof w); } +static inline void store16(void* dst, uint16_t w) { + memcpy(dst, &w, sizeof w); +} -static inline void store32(void *dst, uint32_t w) { +static inline void store32(void* dst, uint32_t w) { #if BYTE_ORDER == BIG_ENDIAN - REVERSE32(w, w); + REVERSE32(w, w); #endif - memcpy(dst, &w, sizeof w); + memcpy(dst, &w, sizeof w); } -static inline void store64(void *dst, uint64_t w) { +static inline void store64(void* dst, uint64_t w) { #if BYTE_ORDER == BIG_ENDIAN - REVERSE64(w, w); + REVERSE64(w, w); #endif - memcpy(dst, &w, sizeof w); + memcpy(dst, &w, sizeof w); } static inline uint32_t rotr32(const uint32_t w, const unsigned c) { - return (w >> c) | (w << (32 - 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)); + return (w >> c) | (w << (64 - c)); } diff --git a/crypto/blake2b.c b/crypto/blake2b.c index f0832c359db..1f92b66f294 100644 --- a/crypto/blake2b.c +++ b/crypto/blake2b.c @@ -19,306 +19,295 @@ #include "blake2_common.h" #include "memzero.h" -typedef struct blake2b_param__ -{ - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint32_t xof_length; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +typedef struct blake2b_param__ { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ } __attribute__((packed)) blake2b_param; -static const uint64_t blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -static const uint8_t blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - -static void blake2b_set_lastnode( blake2b_state *S ) -{ - S->f[1] = (uint64_t)-1; +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL}; + +static const uint8_t blake2b_sigma[12][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}}; + +static void blake2b_set_lastnode(blake2b_state* S) { + S->f[1] = (uint64_t)-1; } /* Some helper functions, not necessarily useful */ -static int blake2b_is_lastblock( const blake2b_state *S ) -{ - return S->f[0] != 0; +static int blake2b_is_lastblock(const blake2b_state* S) { + return S->f[0] != 0; } -static void blake2b_set_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_set_lastnode( S ); +static void blake2b_set_lastblock(blake2b_state* S) { + if(S->last_node) blake2b_set_lastnode(S); - S->f[0] = (uint64_t)-1; + S->f[0] = (uint64_t)-1; } -static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); +static void blake2b_increment_counter(blake2b_state* S, const uint64_t inc) { + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); } -static void blake2b_init0( blake2b_state *S ) -{ - size_t i = 0; - memzero( S, sizeof( blake2b_state ) ); +static void blake2b_init0(blake2b_state* S) { + size_t i = 0; + memzero(S, sizeof(blake2b_state)); - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + for(i = 0; i < 8; ++i) S->h[i] = blake2b_IV[i]; } /* init xors IV with input parameter block */ -int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - const uint8_t *p = ( const uint8_t * )( P ); - size_t i = 0; +int blake2b_init_param(blake2b_state* S, const blake2b_param* P) { + const uint8_t* p = (const uint8_t*)(P); + size_t i = 0; - blake2b_init0( S ); + blake2b_init0(S); - /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) - S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + /* IV XOR ParamBlock */ + for(i = 0; i < 8; ++i) S->h[i] ^= load64(p + sizeof(S->h[i]) * i); - S->outlen = P->digest_length; - return 0; + S->outlen = P->digest_length; + return 0; } - /* Sequential blake2b initialization */ -int blake2b_Init( blake2b_state *S, size_t outlen ) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - return blake2b_init_param( S, P ); +int blake2b_Init(blake2b_state* S, size_t outlen) { + blake2b_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store32(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + memzero(P->reserved, sizeof(P->reserved)); + memzero(P->salt, sizeof(P->salt)); + memzero(P->personal, sizeof(P->personal)); + return blake2b_init_param(S, P); } -int blake2b_InitPersonal( blake2b_state *S, size_t outlen, const void *personal, size_t personal_len) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - if ( ( !personal ) || ( personal_len != BLAKE2B_PERSONALBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); - return blake2b_init_param( S, P ); +int blake2b_InitPersonal( + blake2b_state* S, + size_t outlen, + const void* personal, + size_t personal_len) { + blake2b_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; + if((!personal) || (personal_len != BLAKE2B_PERSONALBYTES)) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store32(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + memzero(P->reserved, sizeof(P->reserved)); + memzero(P->salt, sizeof(P->salt)); + memcpy(P->personal, personal, BLAKE2B_PERSONALBYTES); + return blake2b_init_param(S, P); } -int blake2b_InitKey( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - - if( blake2b_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2B_BLOCKBYTES] = {0}; - memzero( block, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2b_Update( S, block, BLAKE2B_BLOCKBYTES ); - memzero( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; +int blake2b_InitKey(blake2b_state* S, size_t outlen, const void* key, size_t keylen) { + blake2b_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; + + if(!key || !keylen || keylen > BLAKE2B_KEYBYTES) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store32(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + memzero(P->reserved, sizeof(P->reserved)); + memzero(P->salt, sizeof(P->salt)); + memzero(P->personal, sizeof(P->personal)); + + if(blake2b_init_param(S, P) < 0) return -1; + + { + uint8_t block[BLAKE2B_BLOCKBYTES] = {0}; + memzero(block, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); + blake2b_Update(S, block, BLAKE2B_BLOCKBYTES); + memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; } -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - uint64_t m[16] = {0}; - uint64_t v[16] = {0}; - size_t i = 0; - - for( i = 0; i < 16; ++i ) { - m[i] = load64( block + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = blake2b_IV[4] ^ S->t[0]; - v[13] = blake2b_IV[5] ^ S->t[1]; - v[14] = blake2b_IV[6] ^ S->f[0]; - v[15] = blake2b_IV[7] ^ S->f[1]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while(0) + +static void blake2b_compress(blake2b_state* S, const uint8_t block[BLAKE2B_BLOCKBYTES]) { + uint64_t m[16] = {0}; + uint64_t v[16] = {0}; + size_t i = 0; + + for(i = 0; i < 16; ++i) { + m[i] = load64(block + i * sizeof(m[i])); + } + + for(i = 0; i < 8; ++i) { + v[i] = S->h[i]; + } + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + + for(i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } } #undef G #undef ROUND -int blake2b_Update( blake2b_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - if( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = BLAKE2B_BLOCKBYTES - left; - if( inlen > fill ) - { - S->buflen = 0; - memcpy( S->buf + left, in, fill ); /* Fill buffer */ - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); /* Compress */ - in += fill; inlen -= fill; - while(inlen > BLAKE2B_BLOCKBYTES) { - blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); - blake2b_compress( S, in ); - in += BLAKE2B_BLOCKBYTES; - inlen -= BLAKE2B_BLOCKBYTES; - } +int blake2b_Update(blake2b_state* S, const void* pin, size_t inlen) { + const unsigned char* in = (const unsigned char*)pin; + if(inlen > 0) { + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + if(inlen > fill) { + S->buflen = 0; + memcpy(S->buf + left, in, fill); /* Fill buffer */ + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); /* Compress */ + in += fill; + inlen -= fill; + while(inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, in); + in += BLAKE2B_BLOCKBYTES; + inlen -= BLAKE2B_BLOCKBYTES; + } + } + memcpy(S->buf + S->buflen, in, inlen); + S->buflen += inlen; } - memcpy( S->buf + S->buflen, in, inlen ); - S->buflen += inlen; - } - return 0; + return 0; } -int blake2b_Final( blake2b_state *S, void *out, size_t outlen ) -{ - uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; - size_t i = 0; +int blake2b_Final(blake2b_state* S, void* out, size_t outlen) { + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + size_t i = 0; - if( out == NULL || outlen < S->outlen ) - return -1; + if(out == NULL || outlen < S->outlen) return -1; - if( blake2b_is_lastblock( S ) ) - return -1; + if(blake2b_is_lastblock(S)) return -1; - blake2b_increment_counter( S, S->buflen ); - blake2b_set_lastblock( S ); - memzero( S->buf + S->buflen, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ - blake2b_compress( S, S->buf ); + blake2b_increment_counter(S, S->buflen); + blake2b_set_lastblock(S); + memzero(S->buf + S->buflen, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ + blake2b_compress(S, S->buf); - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + for(i = 0; i < 8; ++i) /* Output full hash to temp buffer */ + store64(buffer + sizeof(S->h[i]) * i, S->h[i]); - memcpy( out, buffer, S->outlen ); - memzero(buffer, sizeof(buffer)); - return 0; + memcpy(out, buffer, S->outlen); + memzero(buffer, sizeof(buffer)); + return 0; } -int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen) -{ +int blake2b(const uint8_t* msg, uint32_t msg_len, void* out, size_t outlen) { BLAKE2B_CTX ctx; - if (0 != blake2b_Init(&ctx, outlen)) return -1; - if (0 != blake2b_Update(&ctx, msg, msg_len)) return -1; - if (0 != blake2b_Final(&ctx, out, outlen)) return -1; + if(0 != blake2b_Init(&ctx, outlen)) return -1; + if(0 != blake2b_Update(&ctx, msg, msg_len)) return -1; + if(0 != blake2b_Final(&ctx, out, outlen)) return -1; return 0; } -int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, 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) { BLAKE2B_CTX ctx; - if (0 != blake2b_InitKey(&ctx, outlen, key, keylen)) return -1; - if (0 != blake2b_Update(&ctx, msg, msg_len)) return -1; - if (0 != blake2b_Final(&ctx, out, outlen)) return -1; + if(0 != blake2b_InitKey(&ctx, outlen, key, keylen)) return -1; + if(0 != blake2b_Update(&ctx, msg, msg_len)) return -1; + if(0 != blake2b_Final(&ctx, out, outlen)) return -1; return 0; } diff --git a/crypto/blake2b.h b/crypto/blake2b.h index 1a43e92d1ec..5a47a912c85 100644 --- a/crypto/blake2b.h +++ b/crypto/blake2b.h @@ -4,38 +4,46 @@ #include #include -enum blake2b_constant -{ +enum blake2b_constant { BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, BLAKE2B_PERSONALBYTES = 16 }; -typedef struct __blake2b_state -{ +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; + 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 +#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_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); +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 diff --git a/crypto/blake2s.c b/crypto/blake2s.c index 2c060a63726..0e75ef7c6ca 100644 --- a/crypto/blake2s.c +++ b/crypto/blake2s.c @@ -19,300 +19,292 @@ #include "blake2_common.h" #include "memzero.h" -typedef struct blake2s_param__ -{ - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint16_t xof_length; /* 14 */ - uint8_t node_depth; /* 15 */ - uint8_t inner_length; /* 16 */ +typedef struct blake2s_param__ { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint16_t xof_length; /* 14 */ + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ /* uint8_t reserved[0]; */ - uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ - uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ } __attribute__((packed)) blake2s_param; -static const uint32_t blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +static const uint32_t blake2s_IV[8] = { + 0x6A09E667UL, + 0xBB67AE85UL, + 0x3C6EF372UL, + 0xA54FF53AUL, + 0x510E527FUL, + 0x9B05688CUL, + 0x1F83D9ABUL, + 0x5BE0CD19UL}; + +static const uint8_t blake2s_sigma[10][16] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, }; -static const uint8_t blake2s_sigma[10][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - -static void blake2s_set_lastnode( blake2s_state *S ) -{ - S->f[1] = (uint32_t)-1; +static void blake2s_set_lastnode(blake2s_state* S) { + S->f[1] = (uint32_t)-1; } /* Some helper functions, not necessarily useful */ -static int blake2s_is_lastblock( const blake2s_state *S ) -{ - return S->f[0] != 0; +static int blake2s_is_lastblock(const blake2s_state* S) { + return S->f[0] != 0; } -static void blake2s_set_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_set_lastnode( S ); +static void blake2s_set_lastblock(blake2s_state* S) { + if(S->last_node) blake2s_set_lastnode(S); - S->f[0] = (uint32_t)-1; + S->f[0] = (uint32_t)-1; } -static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); +static void blake2s_increment_counter(blake2s_state* S, const uint32_t inc) { + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); } -static void blake2s_init0( blake2s_state *S ) -{ - size_t i = 0; - memzero( S, sizeof( blake2s_state ) ); +static void blake2s_init0(blake2s_state* S) { + size_t i = 0; + memzero(S, sizeof(blake2s_state)); - for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + for(i = 0; i < 8; ++i) S->h[i] = blake2s_IV[i]; } /* init2 xors IV with input parameter block */ -int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ - const unsigned char *p = ( const unsigned char * )( P ); - size_t i = 0; +int blake2s_init_param(blake2s_state* S, const blake2s_param* P) { + const unsigned char* p = (const unsigned char*)(P); + size_t i = 0; - blake2s_init0( S ); + blake2s_init0(S); - /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) - S->h[i] ^= load32( &p[i * 4] ); + /* IV XOR ParamBlock */ + for(i = 0; i < 8; ++i) S->h[i] ^= load32(&p[i * 4]); - S->outlen = P->digest_length; - return 0; + S->outlen = P->digest_length; + return 0; } - /* Sequential blake2s initialization */ -int blake2s_Init( blake2s_state *S, size_t outlen ) -{ - blake2s_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - return blake2s_init_param( S, P ); +int blake2s_Init(blake2s_state* S, size_t outlen) { + blake2s_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2S_OUTBYTES)) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store16(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + /* memzero(P->reserved, sizeof(P->reserved) ); */ + memzero(P->salt, sizeof(P->salt)); + memzero(P->personal, sizeof(P->personal)); + return blake2s_init_param(S, P); } -int blake2s_InitPersonal( blake2s_state *S, size_t outlen, const void *personal, size_t personal_len) -{ - blake2s_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - if ( ( !personal ) || ( personal_len != BLAKE2S_PERSONALBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); - return blake2s_init_param( S, P ); +int blake2s_InitPersonal( + blake2s_state* S, + size_t outlen, + const void* personal, + size_t personal_len) { + blake2s_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2S_OUTBYTES)) return -1; + if((!personal) || (personal_len != BLAKE2S_PERSONALBYTES)) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store16(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + /* memzero(P->reserved, sizeof(P->reserved) ); */ + memzero(P->salt, sizeof(P->salt)); + memcpy(P->personal, personal, BLAKE2S_PERSONALBYTES); + return blake2s_init_param(S, P); } +int blake2s_InitKey(blake2s_state* S, size_t outlen, const void* key, size_t keylen) { + blake2s_param P[1] = {0}; + + if((!outlen) || (outlen > BLAKE2S_OUTBYTES)) return -1; -int blake2s_InitKey( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - - if( blake2s_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2S_BLOCKBYTES] = {0}; - memzero( block, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2s_Update( S, block, BLAKE2S_BLOCKBYTES ); - memzero( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; + if(!key || !keylen || keylen > BLAKE2S_KEYBYTES) return -1; + + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; + P->fanout = 1; + P->depth = 1; + store32(&P->leaf_length, 0); + store32(&P->node_offset, 0); + store16(&P->xof_length, 0); + P->node_depth = 0; + P->inner_length = 0; + /* memzero(P->reserved, sizeof(P->reserved) ); */ + memzero(P->salt, sizeof(P->salt)); + memzero(P->personal, sizeof(P->personal)); + + if(blake2s_init_param(S, P) < 0) return -1; + + { + uint8_t block[BLAKE2S_BLOCKBYTES] = {0}; + memzero(block, BLAKE2S_BLOCKBYTES); + memcpy(block, key, keylen); + blake2s_Update(S, block, BLAKE2S_BLOCKBYTES); + memzero(block, BLAKE2S_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; } -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2s_sigma[r][2*i+0]]; \ - d = rotr32(d ^ a, 16); \ - c = c + d; \ - b = rotr32(b ^ c, 12); \ - a = a + b + m[blake2s_sigma[r][2*i+1]]; \ - d = rotr32(d ^ a, 8); \ - c = c + d; \ - b = rotr32(b ^ c, 7); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) -{ - uint32_t m[16] = {0}; - uint32_t v[16] = {0}; - size_t i = 0; - - for( i = 0; i < 16; ++i ) { - m[i] = load32( in + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2s_IV[0]; - v[ 9] = blake2s_IV[1]; - v[10] = blake2s_IV[2]; - v[11] = blake2s_IV[3]; - v[12] = S->t[0] ^ blake2s_IV[4]; - v[13] = S->t[1] ^ blake2s_IV[5]; - v[14] = S->f[0] ^ blake2s_IV[6]; - v[15] = S->f[1] ^ blake2s_IV[7]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while(0) + +static void blake2s_compress(blake2s_state* S, const uint8_t in[BLAKE2S_BLOCKBYTES]) { + uint32_t m[16] = {0}; + uint32_t v[16] = {0}; + size_t i = 0; + + for(i = 0; i < 16; ++i) { + m[i] = load32(in + i * sizeof(m[i])); + } + + for(i = 0; i < 8; ++i) { + v[i] = S->h[i]; + } + + v[8] = blake2s_IV[0]; + v[9] = blake2s_IV[1]; + v[10] = blake2s_IV[2]; + v[11] = blake2s_IV[3]; + v[12] = S->t[0] ^ blake2s_IV[4]; + v[13] = S->t[1] ^ blake2s_IV[5]; + v[14] = S->f[0] ^ blake2s_IV[6]; + v[15] = S->f[1] ^ blake2s_IV[7]; + + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + + for(i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } } #undef G #undef ROUND -int blake2s_Update( blake2s_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - if( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = BLAKE2S_BLOCKBYTES - left; - if( inlen > fill ) - { - S->buflen = 0; - memcpy( S->buf + left, in, fill ); /* Fill buffer */ - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); /* Compress */ - in += fill; inlen -= fill; - while(inlen > BLAKE2S_BLOCKBYTES) { - blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); - blake2s_compress( S, in ); - in += BLAKE2S_BLOCKBYTES; - inlen -= BLAKE2S_BLOCKBYTES; - } +int blake2s_Update(blake2s_state* S, const void* pin, size_t inlen) { + const unsigned char* in = (const unsigned char*)pin; + if(inlen > 0) { + size_t left = S->buflen; + size_t fill = BLAKE2S_BLOCKBYTES - left; + if(inlen > fill) { + S->buflen = 0; + memcpy(S->buf + left, in, fill); /* Fill buffer */ + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress(S, S->buf); /* Compress */ + in += fill; + inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress(S, in); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } + } + memcpy(S->buf + S->buflen, in, inlen); + S->buflen += inlen; } - memcpy( S->buf + S->buflen, in, inlen ); - S->buflen += inlen; - } - return 0; + return 0; } -int blake2s_Final( blake2s_state *S, void *out, size_t outlen ) -{ - uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; - size_t i = 0; +int blake2s_Final(blake2s_state* S, void* out, size_t outlen) { + uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + size_t i = 0; - if( out == NULL || outlen < S->outlen ) - return -1; + if(out == NULL || outlen < S->outlen) return -1; - if( blake2s_is_lastblock( S ) ) - return -1; + if(blake2s_is_lastblock(S)) return -1; - blake2s_increment_counter( S, ( uint32_t )S->buflen ); - blake2s_set_lastblock( S ); - memzero( S->buf + S->buflen, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ - blake2s_compress( S, S->buf ); + blake2s_increment_counter(S, (uint32_t)S->buflen); + blake2s_set_lastblock(S); + memzero(S->buf + S->buflen, BLAKE2S_BLOCKBYTES - S->buflen); /* Padding */ + blake2s_compress(S, S->buf); - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + for(i = 0; i < 8; ++i) /* Output full hash to temp buffer */ + store32(buffer + sizeof(S->h[i]) * i, S->h[i]); - memcpy( out, buffer, outlen ); - memzero(buffer, sizeof(buffer)); - return 0; + memcpy(out, buffer, outlen); + memzero(buffer, sizeof(buffer)); + return 0; } -int blake2s(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen) -{ +int blake2s(const uint8_t* msg, uint32_t msg_len, void* out, size_t outlen) { BLAKE2S_CTX ctx; - if (0 != blake2s_Init(&ctx, outlen)) return -1; - if (0 != blake2s_Update(&ctx, msg, msg_len)) return -1; - if (0 != blake2s_Final(&ctx, out, outlen)) return -1; + if(0 != blake2s_Init(&ctx, outlen)) return -1; + if(0 != blake2s_Update(&ctx, msg, msg_len)) return -1; + if(0 != blake2s_Final(&ctx, out, outlen)) return -1; return 0; } -int blake2s_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, 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) { BLAKE2S_CTX ctx; - if (0 != blake2s_InitKey(&ctx, outlen, key, keylen)) return -1; - if (0 != blake2s_Update(&ctx, msg, msg_len)) return -1; - if (0 != blake2s_Final(&ctx, out, outlen)) return -1; + if(0 != blake2s_InitKey(&ctx, outlen, key, keylen)) return -1; + if(0 != blake2s_Update(&ctx, msg, msg_len)) return -1; + if(0 != blake2s_Final(&ctx, out, outlen)) return -1; return 0; } diff --git a/crypto/blake2s.h b/crypto/blake2s.h index 57991bc9132..452090693dc 100644 --- a/crypto/blake2s.h +++ b/crypto/blake2s.h @@ -4,38 +4,46 @@ #include #include -enum blake2s_constant -{ +enum blake2s_constant { BLAKE2S_BLOCKBYTES = 64, - BLAKE2S_OUTBYTES = 32, - BLAKE2S_KEYBYTES = 32, - BLAKE2S_SALTBYTES = 8, + BLAKE2S_OUTBYTES = 32, + BLAKE2S_KEYBYTES = 32, + BLAKE2S_SALTBYTES = 8, BLAKE2S_PERSONALBYTES = 8 }; -typedef struct __blake2s_state -{ +typedef struct __blake2s_state { uint32_t h[8]; uint32_t t[2]; uint32_t f[2]; - uint8_t buf[BLAKE2S_BLOCKBYTES]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; uint32_t buflen; - uint8_t outlen; - uint8_t last_node; + 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 +#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_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); +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 diff --git a/crypto/byte_order.h b/crypto/byte_order.h index 33d2164bc6f..8484f434964 100644 --- a/crypto/byte_order.h +++ b/crypto/byte_order.h @@ -39,21 +39,19 @@ #define BYTE_ORDER LITTLE_ENDIAN #endif -#define REVERSE32(w, x) \ - { \ - uint32_t tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ - } +#define REVERSE32(w, x) \ + { \ + uint32_t tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ + } -#define REVERSE64(w, x) \ - { \ - uint64_t tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ - } +#define REVERSE64(w, x) \ + { \ + uint64_t tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | ((tmp & 0x0000ffff0000ffffULL) << 16); \ + } #endif diff --git a/crypto/cardano.c b/crypto/cardano.c index 485d6514a4d..8542799a784 100644 --- a/crypto/cardano.c +++ b/crypto/cardano.c @@ -48,259 +48,260 @@ const curve_info ed25519_cardano_info = { .hasher_script = HASHER_SHA2, }; -static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst) { - uint8_t prev_acc = 0; - for (int i = 0; i < bytes; i++) { - dst[i] = (src[i] << 3) + (prev_acc & 0x7); - prev_acc = src[i] >> 5; - } - dst[bytes] = src[bytes - 1] >> 5; +static void scalar_multiply8(const uint8_t* src, int bytes, uint8_t* dst) { + uint8_t prev_acc = 0; + for(int i = 0; i < bytes; i++) { + dst[i] = (src[i] << 3) + (prev_acc & 0x7); + prev_acc = src[i] >> 5; + } + dst[bytes] = src[bytes - 1] >> 5; } -static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2, - uint8_t *dst) { - uint16_t r = 0; - for (int i = 0; i < 32; i++) { - r = r + (uint16_t)src1[i] + (uint16_t)src2[i]; - dst[i] = r & 0xff; - r >>= 8; - } +static void scalar_add_256bits(const uint8_t* src1, const uint8_t* src2, uint8_t* dst) { + uint16_t r = 0; + for(int i = 0; i < 32; i++) { + r = r + (uint16_t)src1[i] + (uint16_t)src2[i]; + dst[i] = r & 0xff; + r >>= 8; + } } static void cardano_ed25519_tweak_bits(uint8_t private_key[32]) { - private_key[0] &= 0xf8; - private_key[31] &= 0x1f; - private_key[31] |= 0x40; + private_key[0] &= 0xf8; + private_key[31] &= 0x1f; + private_key[31] |= 0x40; } -int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) { - if (inout->curve != &ed25519_cardano_info) { - return 0; - } - - if (inout->depth >= CARDANO_MAX_NODE_DEPTH) { - return 0; - } - - // checks for hardened/non-hardened derivation, keysize 32 means we are - // dealing with public key and thus non-h, keysize 64 is for private key - int keysize = 32; - if (index & 0x80000000) { - keysize = 64; - } - - static CONFIDENTIAL uint8_t data[1 + 64 + 4]; - static CONFIDENTIAL uint8_t z[32 + 32]; - static CONFIDENTIAL uint8_t priv_key[64]; - static CONFIDENTIAL uint8_t res_key[64]; - - write_le(data + keysize + 1, index); - - memcpy(priv_key, inout->private_key, 32); - memcpy(priv_key + 32, inout->private_key_extension, 32); - - if (keysize == 64) { // private derivation - data[0] = 0; - memcpy(data + 1, inout->private_key, 32); - memcpy(data + 1 + 32, inout->private_key_extension, 32); - } else { // public derivation - if (hdnode_fill_public_key(inout) != 0) { - return 0; +int hdnode_private_ckd_cardano(HDNode* inout, uint32_t index) { + if(inout->curve != &ed25519_cardano_info) { + return 0; + } + + if(inout->depth >= CARDANO_MAX_NODE_DEPTH) { + return 0; + } + + // checks for hardened/non-hardened derivation, keysize 32 means we are + // dealing with public key and thus non-h, keysize 64 is for private key + int keysize = 32; + if(index & 0x80000000) { + keysize = 64; + } + + static CONFIDENTIAL uint8_t data[1 + 64 + 4]; + static CONFIDENTIAL uint8_t z[32 + 32]; + static CONFIDENTIAL uint8_t priv_key[64]; + static CONFIDENTIAL uint8_t res_key[64]; + + write_le(data + keysize + 1, index); + + memcpy(priv_key, inout->private_key, 32); + memcpy(priv_key + 32, inout->private_key_extension, 32); + + if(keysize == 64) { // private derivation + data[0] = 0; + memcpy(data + 1, inout->private_key, 32); + memcpy(data + 1 + 32, inout->private_key_extension, 32); + } else { // public derivation + if(hdnode_fill_public_key(inout) != 0) { + return 0; + } + data[0] = 2; + memcpy(data + 1, inout->public_key + 1, 32); + } + + static CONFIDENTIAL HMAC_SHA512_CTX ctx; + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, 1 + keysize + 4); + hmac_sha512_Final(&ctx, z); + + static CONFIDENTIAL uint8_t zl8[32]; + memzero(zl8, 32); + + /* get 8 * Zl */ + scalar_multiply8(z, 28, zl8); + /* Kl = 8*Zl + parent(K)l */ + scalar_add_256bits(zl8, priv_key, res_key); + + /* Kr = Zr + parent(K)r */ + scalar_add_256bits(z + 32, priv_key + 32, res_key + 32); + + memcpy(inout->private_key, res_key, 32); + memcpy(inout->private_key_extension, res_key + 32, 32); + + if(keysize == 64) { + data[0] = 1; + } else { + data[0] = 3; } - data[0] = 2; - memcpy(data + 1, inout->public_key + 1, 32); - } - - static CONFIDENTIAL HMAC_SHA512_CTX ctx; - hmac_sha512_Init(&ctx, inout->chain_code, 32); - hmac_sha512_Update(&ctx, data, 1 + keysize + 4); - hmac_sha512_Final(&ctx, z); - - static CONFIDENTIAL uint8_t zl8[32]; - memzero(zl8, 32); - - /* get 8 * Zl */ - scalar_multiply8(z, 28, zl8); - /* Kl = 8*Zl + parent(K)l */ - scalar_add_256bits(zl8, priv_key, res_key); - - /* Kr = Zr + parent(K)r */ - scalar_add_256bits(z + 32, priv_key + 32, res_key + 32); - - memcpy(inout->private_key, res_key, 32); - memcpy(inout->private_key_extension, res_key + 32, 32); - - if (keysize == 64) { - data[0] = 1; - } else { - data[0] = 3; - } - hmac_sha512_Init(&ctx, inout->chain_code, 32); - hmac_sha512_Update(&ctx, data, 1 + keysize + 4); - hmac_sha512_Final(&ctx, z); - - memcpy(inout->chain_code, z + 32, 32); - inout->depth++; - inout->child_num = index; - memzero(inout->public_key, sizeof(inout->public_key)); - - // making sure to wipe our memory - memzero(z, sizeof(z)); - memzero(data, sizeof(data)); - memzero(priv_key, sizeof(priv_key)); - memzero(res_key, sizeof(res_key)); - return 1; + hmac_sha512_Init(&ctx, inout->chain_code, 32); + hmac_sha512_Update(&ctx, data, 1 + keysize + 4); + hmac_sha512_Final(&ctx, z); + + memcpy(inout->chain_code, z + 32, 32); + inout->depth++; + inout->child_num = index; + memzero(inout->public_key, sizeof(inout->public_key)); + + // making sure to wipe our memory + memzero(z, sizeof(z)); + memzero(data, sizeof(data)); + memzero(priv_key, sizeof(priv_key)); + memzero(res_key, sizeof(res_key)); + return 1; } -int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], - HDNode *out) { - memzero(out, sizeof(HDNode)); - out->depth = 0; - out->child_num = 0; - out->curve = &ed25519_cardano_info; - memcpy(out->private_key, secret, 32); - memcpy(out->private_key_extension, secret + 32, 32); - memcpy(out->chain_code, secret + 64, 32); +int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], HDNode* out) { + memzero(out, sizeof(HDNode)); + out->depth = 0; + out->child_num = 0; + out->curve = &ed25519_cardano_info; + memcpy(out->private_key, secret, 32); + memcpy(out->private_key_extension, secret + 32, 32); + memcpy(out->chain_code, secret + 64, 32); - cardano_ed25519_tweak_bits(out->private_key); + cardano_ed25519_tweak_bits(out->private_key); - out->public_key[0] = 0; - if (hdnode_fill_public_key(out) != 0) { - return 0; - } + out->public_key[0] = 0; + if(hdnode_fill_public_key(out) != 0) { + return 0; + } - return 1; + return 1; } // Derives the root Cardano secret from a master secret, aka seed, as defined in // SLIP-0023. -int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]) { - static CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH]; - static CONFIDENTIAL HMAC_SHA512_CTX ctx; +int secret_from_seed_cardano_slip23( + const uint8_t* seed, + int seed_len, + uint8_t secret_out[CARDANO_SECRET_LENGTH]) { + static CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH]; + static CONFIDENTIAL HMAC_SHA512_CTX ctx; - hmac_sha512_Init(&ctx, (const uint8_t *)ED25519_CARDANO_NAME, - strlen(ED25519_CARDANO_NAME)); - hmac_sha512_Update(&ctx, seed, seed_len); - hmac_sha512_Final(&ctx, I); + hmac_sha512_Init(&ctx, (const uint8_t*)ED25519_CARDANO_NAME, strlen(ED25519_CARDANO_NAME)); + hmac_sha512_Update(&ctx, seed, seed_len); + hmac_sha512_Final(&ctx, I); - sha512_Raw(I, 32, secret_out); + sha512_Raw(I, 32, secret_out); - memcpy(secret_out + SHA512_DIGEST_LENGTH, I + 32, 32); - cardano_ed25519_tweak_bits(secret_out); + memcpy(secret_out + SHA512_DIGEST_LENGTH, I + 32, 32); + cardano_ed25519_tweak_bits(secret_out); - memzero(I, sizeof(I)); - memzero(&ctx, sizeof(ctx)); - return 1; + memzero(I, sizeof(I)); + memzero(&ctx, sizeof(ctx)); + return 1; } // Derives the root Cardano secret from a BIP-32 master secret via the Ledger // derivation: // https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Ledger.md -int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]) { - static CONFIDENTIAL uint8_t chain_code[SHA256_DIGEST_LENGTH]; - static CONFIDENTIAL uint8_t root_key[SHA512_DIGEST_LENGTH]; - static CONFIDENTIAL HMAC_SHA256_CTX ctx; - static CONFIDENTIAL HMAC_SHA512_CTX sctx; - - const uint8_t *intermediate_result = seed; - int intermediate_result_len = seed_len; - do { - // STEP 1: derive a master secret like in BIP-32/SLIP-10 - hmac_sha512_Init(&sctx, (const uint8_t *)ED25519_SEED_NAME, - strlen(ED25519_SEED_NAME)); - hmac_sha512_Update(&sctx, intermediate_result, intermediate_result_len); - hmac_sha512_Final(&sctx, root_key); - - // STEP 2: check that the resulting key does not have a particular bit set, - // otherwise iterate like in SLIP-10 - intermediate_result = root_key; - intermediate_result_len = sizeof(root_key); - } while (root_key[31] & 0x20); - - // STEP 3: calculate the chain code as a HMAC-SHA256 of "\x01" + seed, - // key is "ed25519 seed" - hmac_sha256_Init(&ctx, (const unsigned char *)ED25519_SEED_NAME, - strlen(ED25519_SEED_NAME)); - hmac_sha256_Update(&ctx, (const unsigned char *)"\x01", 1); - hmac_sha256_Update(&ctx, seed, seed_len); - hmac_sha256_Final(&ctx, chain_code); - - // STEP 4: extract information into output - _Static_assert( - SHA512_DIGEST_LENGTH + SHA256_DIGEST_LENGTH == CARDANO_SECRET_LENGTH, - "Invalid configuration of Cardano secret size"); - memcpy(secret_out, root_key, SHA512_DIGEST_LENGTH); - memcpy(secret_out + SHA512_DIGEST_LENGTH, chain_code, SHA256_DIGEST_LENGTH); - - // STEP 5: tweak bits of the private key - cardano_ed25519_tweak_bits(secret_out); - - memzero(&ctx, sizeof(ctx)); - memzero(&sctx, sizeof(sctx)); - memzero(root_key, sizeof(root_key)); - memzero(chain_code, sizeof(chain_code)); - return 1; +int secret_from_seed_cardano_ledger( + const uint8_t* seed, + int seed_len, + uint8_t secret_out[CARDANO_SECRET_LENGTH]) { + static CONFIDENTIAL uint8_t chain_code[SHA256_DIGEST_LENGTH]; + static CONFIDENTIAL uint8_t root_key[SHA512_DIGEST_LENGTH]; + static CONFIDENTIAL HMAC_SHA256_CTX ctx; + static CONFIDENTIAL HMAC_SHA512_CTX sctx; + + const uint8_t* intermediate_result = seed; + int intermediate_result_len = seed_len; + do { + // STEP 1: derive a master secret like in BIP-32/SLIP-10 + hmac_sha512_Init(&sctx, (const uint8_t*)ED25519_SEED_NAME, strlen(ED25519_SEED_NAME)); + hmac_sha512_Update(&sctx, intermediate_result, intermediate_result_len); + hmac_sha512_Final(&sctx, root_key); + + // STEP 2: check that the resulting key does not have a particular bit set, + // otherwise iterate like in SLIP-10 + intermediate_result = root_key; + intermediate_result_len = sizeof(root_key); + } while(root_key[31] & 0x20); + + // STEP 3: calculate the chain code as a HMAC-SHA256 of "\x01" + seed, + // key is "ed25519 seed" + hmac_sha256_Init(&ctx, (const unsigned char*)ED25519_SEED_NAME, strlen(ED25519_SEED_NAME)); + hmac_sha256_Update(&ctx, (const unsigned char*)"\x01", 1); + hmac_sha256_Update(&ctx, seed, seed_len); + hmac_sha256_Final(&ctx, chain_code); + + // STEP 4: extract information into output + _Static_assert( + SHA512_DIGEST_LENGTH + SHA256_DIGEST_LENGTH == CARDANO_SECRET_LENGTH, + "Invalid configuration of Cardano secret size"); + memcpy(secret_out, root_key, SHA512_DIGEST_LENGTH); + memcpy(secret_out + SHA512_DIGEST_LENGTH, chain_code, SHA256_DIGEST_LENGTH); + + // STEP 5: tweak bits of the private key + cardano_ed25519_tweak_bits(secret_out); + + memzero(&ctx, sizeof(ctx)); + memzero(&sctx, sizeof(sctx)); + memzero(root_key, sizeof(root_key)); + memzero(chain_code, sizeof(chain_code)); + return 1; } #define CARDANO_ICARUS_STEPS 32 _Static_assert( CARDANO_ICARUS_PBKDF2_ROUNDS % CARDANO_ICARUS_STEPS == 0, "CARDANO_ICARUS_STEPS does not divide CARDANO_ICARUS_PBKDF2_ROUNDS"); -#define CARDANO_ICARUS_ROUNDS_PER_STEP \ - (CARDANO_ICARUS_PBKDF2_ROUNDS / CARDANO_ICARUS_STEPS) +#define CARDANO_ICARUS_ROUNDS_PER_STEP (CARDANO_ICARUS_PBKDF2_ROUNDS / CARDANO_ICARUS_STEPS) // Derives the root Cardano HDNode from a passphrase and the entropy encoded in // a BIP-0039 mnemonic using the Icarus derivation scheme, aka V2 derivation // scheme: // https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Icarus.md int secret_from_entropy_cardano_icarus( - const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len, + const uint8_t* pass, + int pass_len, + const uint8_t* entropy, + int entropy_len, uint8_t secret_out[CARDANO_SECRET_LENGTH], void (*progress_callback)(uint32_t, uint32_t)) { - static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; - static CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH]; - uint32_t progress = 0; - - // PASS 1: first 64 bytes - pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 1); - if (progress_callback) { - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) { - pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); - if (progress_callback) { - progress += CARDANO_ICARUS_ROUNDS_PER_STEP; - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); + static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; + static CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH]; + uint32_t progress = 0; + + // PASS 1: first 64 bytes + pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 1); + if(progress_callback) { + progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); + } + for(int i = 0; i < CARDANO_ICARUS_STEPS; i++) { + pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); + if(progress_callback) { + progress += CARDANO_ICARUS_ROUNDS_PER_STEP; + progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); + } + } + pbkdf2_hmac_sha512_Final(&pctx, digest); + + memcpy(secret_out, digest, SHA512_DIGEST_LENGTH); + + // PASS 2: remaining 32 bytes + pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 2); + if(progress_callback) { + progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); } - } - pbkdf2_hmac_sha512_Final(&pctx, digest); - - memcpy(secret_out, digest, SHA512_DIGEST_LENGTH); - - // PASS 2: remaining 32 bytes - pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 2); - if (progress_callback) { - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) { - pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); - if (progress_callback) { - progress += CARDANO_ICARUS_ROUNDS_PER_STEP; - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); + for(int i = 0; i < CARDANO_ICARUS_STEPS; i++) { + pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); + if(progress_callback) { + progress += CARDANO_ICARUS_ROUNDS_PER_STEP; + progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); + } } - } - pbkdf2_hmac_sha512_Final(&pctx, digest); + pbkdf2_hmac_sha512_Final(&pctx, digest); - memcpy(secret_out + SHA512_DIGEST_LENGTH, digest, - CARDANO_SECRET_LENGTH - SHA512_DIGEST_LENGTH); + memcpy( + secret_out + SHA512_DIGEST_LENGTH, digest, CARDANO_SECRET_LENGTH - SHA512_DIGEST_LENGTH); - cardano_ed25519_tweak_bits(secret_out); + cardano_ed25519_tweak_bits(secret_out); - memzero(&pctx, sizeof(pctx)); - memzero(digest, sizeof(digest)); - return 1; + memzero(&pctx, sizeof(pctx)); + memzero(digest, sizeof(digest)); + return 1; } -#endif // USE_CARDANO +#endif // USE_CARDANO diff --git a/crypto/cardano.h b/crypto/cardano.h index b5a8b0b39ee..761ce978cca 100644 --- a/crypto/cardano.h +++ b/crypto/cardano.h @@ -35,20 +35,26 @@ extern const curve_info ed25519_cardano_info; -int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i); +int hdnode_private_ckd_cardano(HDNode* inout, uint32_t i); int secret_from_entropy_cardano_icarus( - const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len, + const uint8_t* pass, + int pass_len, + const uint8_t* entropy, + int entropy_len, uint8_t secret_out[CARDANO_SECRET_LENGTH], void (*progress_callback)(uint32_t current, uint32_t total)); -int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]); -int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]); +int secret_from_seed_cardano_ledger( + const uint8_t* seed, + int seed_len, + uint8_t secret_out[CARDANO_SECRET_LENGTH]); +int secret_from_seed_cardano_slip23( + const uint8_t* seed, + int seed_len, + uint8_t secret_out[CARDANO_SECRET_LENGTH]); -int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], - HDNode *out); +int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], HDNode* out); -#endif // USE_CARDANO +#endif // USE_CARDANO -#endif // __CARDANO_H__ +#endif // __CARDANO_H__ diff --git a/crypto/cash_addr.c b/crypto/cash_addr.c index 2488844519d..31656c88872 100644 --- a/crypto/cash_addr.c +++ b/crypto/cash_addr.c @@ -32,158 +32,157 @@ #define CHECKSUM_SIZE 8 uint64_t cashaddr_polymod_step(uint64_t pre) { - uint8_t b = pre >> 35; - return ((pre & 0x7FFFFFFFFULL) << 5) ^ (-((b >> 0) & 1) & 0x98f2bc8e61ULL) ^ - (-((b >> 1) & 1) & 0x79b76d99e2ULL) ^ - (-((b >> 2) & 1) & 0xf33e5fb3c4ULL) ^ - (-((b >> 3) & 1) & 0xae2eabe2a8ULL) ^ - (-((b >> 4) & 1) & 0x1e4f43e470ULL); + uint8_t b = pre >> 35; + return ((pre & 0x7FFFFFFFFULL) << 5) ^ (-((b >> 0) & 1) & 0x98f2bc8e61ULL) ^ + (-((b >> 1) & 1) & 0x79b76d99e2ULL) ^ (-((b >> 2) & 1) & 0xf33e5fb3c4ULL) ^ + (-((b >> 3) & 1) & 0xae2eabe2a8ULL) ^ (-((b >> 4) & 1) & 0x1e4f43e470ULL); } static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; static const int8_t charset_rev[128] = { - -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, 15, -1, 10, 17, 21, 20, 26, 30, 7, - 5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, - 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, - -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, - 3, 16, 11, 28, 12, 14, 6, 4, 2, -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, + -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, -1, 29, + -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, + 6, 4, 2, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, + 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1}; -int cash_encode(char* output, const char* hrp, const uint8_t* data, - size_t data_len) { - uint64_t chk = 1; - size_t i = 0; - while (hrp[i] != 0) { - int ch = hrp[i]; - if (ch < 33 || ch > 126) { - return 0; +int cash_encode(char* output, const char* hrp, const uint8_t* data, size_t data_len) { + uint64_t chk = 1; + size_t i = 0; + while(hrp[i] != 0) { + int ch = hrp[i]; + if(ch < 33 || ch > 126) { + return 0; + } + *(output++) = ch; + chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); + ++i; + } + if(i + 1 + data_len + CHECKSUM_SIZE > MAX_CASHADDR_SIZE) { + return 0; } - *(output++) = ch; - chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); - ++i; - } - if (i + 1 + data_len + CHECKSUM_SIZE > MAX_CASHADDR_SIZE) { - return 0; - } - chk = cashaddr_polymod_step(chk); - *(output++) = ':'; - for (i = 0; i < data_len; ++i) { - if (*data >> 5) return 0; - chk = cashaddr_polymod_step(chk) ^ (*data); - *(output++) = charset[*(data++)]; - } - for (i = 0; i < CHECKSUM_SIZE; ++i) { chk = cashaddr_polymod_step(chk); - } - chk ^= 1; - for (i = 0; i < CHECKSUM_SIZE; ++i) { - *(output++) = charset[(chk >> ((CHECKSUM_SIZE - 1 - i) * 5)) & 0x1f]; - } - *output = 0; - return 1; + *(output++) = ':'; + for(i = 0; i < data_len; ++i) { + if(*data >> 5) return 0; + chk = cashaddr_polymod_step(chk) ^ (*data); + *(output++) = charset[*(data++)]; + } + for(i = 0; i < CHECKSUM_SIZE; ++i) { + chk = cashaddr_polymod_step(chk); + } + chk ^= 1; + for(i = 0; i < CHECKSUM_SIZE; ++i) { + *(output++) = charset[(chk >> ((CHECKSUM_SIZE - 1 - i) * 5)) & 0x1f]; + } + *output = 0; + return 1; } int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) { - uint64_t chk = 1; - size_t i = 0; - size_t input_len = strlen(input); - size_t hrp_len = 0; - int have_lower = 0, have_upper = 0; - if (input_len < CHECKSUM_SIZE || input_len > MAX_CASHADDR_SIZE) { - return 0; - } - *data_len = 0; - while (*data_len < input_len && input[(input_len - 1) - *data_len] != ':') { - ++(*data_len); - } - hrp_len = input_len - (1 + *data_len); - if (1 + *data_len >= input_len || hrp_len > MAX_HRP_SIZE || - *data_len < CHECKSUM_SIZE || - *data_len > CHECKSUM_SIZE + MAX_BASE32_SIZE) { - return 0; - } - // subtract checksum - *(data_len) -= CHECKSUM_SIZE; - for (i = 0; i < hrp_len; ++i) { - int ch = input[i]; - if (ch < 33 || ch > 126) { - return 0; + uint64_t chk = 1; + size_t i = 0; + size_t input_len = strlen(input); + size_t hrp_len = 0; + int have_lower = 0, have_upper = 0; + if(input_len < CHECKSUM_SIZE || input_len > MAX_CASHADDR_SIZE) { + return 0; } - if (ch >= 'a' && ch <= 'z') { - have_lower = 1; - } else if (ch >= 'A' && ch <= 'Z') { - have_upper = 1; - ch = (ch - 'A') + 'a'; + *data_len = 0; + while(*data_len < input_len && input[(input_len - 1) - *data_len] != ':') { + ++(*data_len); } - hrp[i] = ch; - chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); - } - hrp[i] = 0; - chk = cashaddr_polymod_step(chk); - ++i; - while (i < input_len) { - int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; - if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; - if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; - if (v == -1) { - return 0; + hrp_len = input_len - (1 + *data_len); + if(1 + *data_len >= input_len || hrp_len > MAX_HRP_SIZE || *data_len < CHECKSUM_SIZE || + *data_len > CHECKSUM_SIZE + MAX_BASE32_SIZE) { + return 0; } - chk = cashaddr_polymod_step(chk) ^ v; - if (i + CHECKSUM_SIZE < input_len) { - data[i - (1 + hrp_len)] = v; + // subtract checksum + *(data_len) -= CHECKSUM_SIZE; + for(i = 0; i < hrp_len; ++i) { + int ch = input[i]; + if(ch < 33 || ch > 126) { + return 0; + } + if(ch >= 'a' && ch <= 'z') { + have_lower = 1; + } else if(ch >= 'A' && ch <= 'Z') { + have_upper = 1; + ch = (ch - 'A') + 'a'; + } + hrp[i] = ch; + chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); } + hrp[i] = 0; + chk = cashaddr_polymod_step(chk); ++i; - } - if (have_lower && have_upper) { - return 0; - } - return chk == 1; + while(i < input_len) { + int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; + if(input[i] >= 'a' && input[i] <= 'z') have_lower = 1; + if(input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; + if(v == -1) { + return 0; + } + chk = cashaddr_polymod_step(chk) ^ v; + if(i + CHECKSUM_SIZE < input_len) { + data[i - (1 + hrp_len)] = v; + } + ++i; + } + if(have_lower && have_upper) { + return 0; + } + return chk == 1; } -static int convert_bits(uint8_t* out, size_t* outlen, int outbits, - const uint8_t* in, size_t inlen, int inbits, int pad) { - uint32_t val = 0; - int bits = 0; - uint32_t maxv = (((uint32_t)1) << outbits) - 1; - while (inlen--) { - val = (val << inbits) | *(in++); - bits += inbits; - while (bits >= outbits) { - bits -= outbits; - out[(*outlen)++] = (val >> bits) & maxv; +static int convert_bits( + uint8_t* out, + size_t* outlen, + int outbits, + const uint8_t* in, + size_t inlen, + int inbits, + int pad) { + uint32_t val = 0; + int bits = 0; + uint32_t maxv = (((uint32_t)1) << outbits) - 1; + while(inlen--) { + val = (val << inbits) | *(in++); + bits += inbits; + while(bits >= outbits) { + bits -= outbits; + out[(*outlen)++] = (val >> bits) & maxv; + } } - } - if (pad) { - if (bits) { - out[(*outlen)++] = (val << (outbits - bits)) & maxv; + if(pad) { + if(bits) { + out[(*outlen)++] = (val << (outbits - bits)) & maxv; + } + } else if(((val << (outbits - bits)) & maxv) || bits >= inbits) { + return 0; } - } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { - return 0; - } - return 1; + return 1; } -int cash_addr_encode(char* output, const char* hrp, const uint8_t* data, - size_t data_len) { - uint8_t base32[MAX_BASE32_SIZE] = {0}; - size_t base32len = 0; - if (data_len < 2 || data_len > MAX_DATA_SIZE) return 0; - convert_bits(base32, &base32len, 5, data, data_len, 8, 1); - return cash_encode(output, hrp, base32, base32len); +int cash_addr_encode(char* output, const char* hrp, const uint8_t* data, size_t data_len) { + uint8_t base32[MAX_BASE32_SIZE] = {0}; + size_t base32len = 0; + if(data_len < 2 || data_len > MAX_DATA_SIZE) return 0; + convert_bits(base32, &base32len, 5, data, data_len, 8, 1); + return cash_encode(output, hrp, base32, base32len); } -int cash_addr_decode(uint8_t* witdata, size_t* witdata_len, const char* hrp, - const char* addr) { - uint8_t data[MAX_BASE32_SIZE] = {0}; - char hrp_actual[MAX_HRP_SIZE + 1] = {0}; - size_t data_len = 0; - if (!cash_decode(hrp_actual, data, &data_len, addr)) return 0; - if (data_len == 0 || data_len > MAX_BASE32_SIZE) return 0; - if (strncmp(hrp, hrp_actual, MAX_HRP_SIZE + 1) != 0) return 0; - *witdata_len = 0; - if (!convert_bits(witdata, witdata_len, 8, data, data_len, 5, 0)) return 0; - if (*witdata_len < 2 || *witdata_len > MAX_DATA_SIZE) return 0; - return 1; +int cash_addr_decode(uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { + uint8_t data[MAX_BASE32_SIZE] = {0}; + char hrp_actual[MAX_HRP_SIZE + 1] = {0}; + size_t data_len = 0; + if(!cash_decode(hrp_actual, data, &data_len, addr)) return 0; + if(data_len == 0 || data_len > MAX_BASE32_SIZE) return 0; + if(strncmp(hrp, hrp_actual, MAX_HRP_SIZE + 1) != 0) return 0; + *witdata_len = 0; + if(!convert_bits(witdata, witdata_len, 8, data, data_len, 5, 0)) return 0; + if(*witdata_len < 2 || *witdata_len > MAX_DATA_SIZE) return 0; + return 1; } diff --git a/crypto/cash_addr.h b/crypto/cash_addr.h index fd7dd44f8be..5590b5b8740 100644 --- a/crypto/cash_addr.h +++ b/crypto/cash_addr.h @@ -34,8 +34,7 @@ * prog_len: Number of data bytes in prog. * Returns 1 if successful. */ -int cash_addr_encode(char *output, const char *hrp, const uint8_t *prog, - size_t prog_len); +int cash_addr_encode(char* output, const char* hrp, const uint8_t* prog, size_t prog_len); /** Decode a CashAddr address * @@ -46,8 +45,7 @@ int cash_addr_encode(char *output, const char *hrp, const uint8_t *prog, * readable part that is expected (chain/network specific). addr: Pointer to * the null-terminated address. Returns 1 if successful. */ -int cash_addr_decode(uint8_t *prog, size_t *prog_len, const char *hrp, - const char *addr); +int cash_addr_decode(uint8_t* prog, size_t* prog_len, const char* hrp, const char* addr); /** Encode a Cash string * @@ -58,8 +56,7 @@ int cash_addr_decode(uint8_t *prog, size_t *prog_len, const char *hrp, * data_len: Length of the data array. * Returns 1 if successful. */ -int cash_encode(char *output, const char *hrp, const uint8_t *data, - size_t data_len); +int cash_encode(char* output, const char* hrp, const uint8_t* data, size_t data_len); /** Decode a Cash string * @@ -72,6 +69,6 @@ int cash_encode(char *output, const char *hrp, const uint8_t *data, * In: input: Pointer to a null-terminated Cash string. * Returns 1 if succesful. */ -int cash_decode(char *hrp, uint8_t *data, size_t *data_len, const char *input); +int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input); #endif diff --git a/crypto/chacha20poly1305/chacha20poly1305.c b/crypto/chacha20poly1305/chacha20poly1305.c index 4012dd056f0..281dd465a55 100644 --- a/crypto/chacha20poly1305/chacha20poly1305.c +++ b/crypto/chacha20poly1305/chacha20poly1305.c @@ -3,14 +3,17 @@ // than performance. #include "chacha20poly1305.h" -#include "ecrypt-portable.h" +#include "ecrypt_portable.h" -void hchacha20(ECRYPT_ctx *x,u8 *c); +void hchacha20(ECRYPT_ctx* x, u8* c); // Initialize the XChaCha20 + Poly1305 context for encryption or decryption // using a 32 byte key and 24 byte nonce. The key and the first 16 bytes of // the nonce are used as input to HChaCha20 to derive the Chacha20 key. -void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_t nonce[24]) { +void xchacha20poly1305_init( + chacha20poly1305_ctx* ctx, + const uint8_t key[32], + const uint8_t nonce[24]) { unsigned char subkey[32] = {0}; unsigned char block0[64] = {0}; ECRYPT_ctx tmp = {0}; @@ -27,7 +30,7 @@ void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], co // Initialize Chacha20 with the newly generated key and // the last 8 bytes of the nonce. ECRYPT_keysetup(&ctx->chacha20, subkey, 256, 16); - ECRYPT_ivsetup(&ctx->chacha20, nonce+16); + ECRYPT_ivsetup(&ctx->chacha20, nonce + 16); // Encrypt 64 bytes of zeros and use the first 32 bytes // as the Poly1305 key. @@ -37,24 +40,24 @@ void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], co // Encrypt n bytes of plaintext where n must be evenly divisible by the // Chacha20 blocksize of 64, except for the final n bytes of plaintext. -void chacha20poly1305_encrypt(chacha20poly1305_ctx *ctx, const uint8_t *in, uint8_t *out, size_t n) { +void chacha20poly1305_encrypt(chacha20poly1305_ctx* ctx, const uint8_t* in, uint8_t* out, size_t n) { ECRYPT_encrypt_bytes(&ctx->chacha20, in, out, n); poly1305_update(&ctx->poly1305, out, n); } // Decrypt n bytes of ciphertext where n must be evenly divisible by the // Chacha20 blocksize of 64, except for the final n bytes of ciphertext. -void chacha20poly1305_decrypt(chacha20poly1305_ctx *ctx, const uint8_t *in, uint8_t *out, size_t n) { +void chacha20poly1305_decrypt(chacha20poly1305_ctx* ctx, const uint8_t* in, uint8_t* out, size_t n) { poly1305_update(&ctx->poly1305, in, n); ECRYPT_encrypt_bytes(&ctx->chacha20, in, out, n); } // Include authenticated data in the Poly1305 MAC. -void chacha20poly1305_auth(chacha20poly1305_ctx *ctx, const uint8_t *in, size_t n) { +void chacha20poly1305_auth(chacha20poly1305_ctx* ctx, const uint8_t* in, size_t n) { poly1305_update(&ctx->poly1305, in, n); } // Compute NaCl secretbox-style Poly1305 MAC. -void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16]) { +void chacha20poly1305_finish(chacha20poly1305_ctx* ctx, uint8_t mac[16]) { poly1305_finish(&ctx->poly1305, mac); } diff --git a/crypto/chacha20poly1305/chacha20poly1305.h b/crypto/chacha20poly1305/chacha20poly1305.h index 1f501f12eee..803772b7daf 100644 --- a/crypto/chacha20poly1305/chacha20poly1305.h +++ b/crypto/chacha20poly1305/chacha20poly1305.h @@ -2,18 +2,21 @@ #define CHACHA20POLY1305_H #include -#include "ecrypt-sync.h" -#include "poly1305-donna.h" +#include "ecrypt_sync.h" +#include "poly1305_donna.h" typedef struct { - ECRYPT_ctx chacha20; + ECRYPT_ctx chacha20; poly1305_context poly1305; } chacha20poly1305_ctx; -void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_t nonce[24]); -void chacha20poly1305_encrypt(chacha20poly1305_ctx *ctx, const uint8_t *in, uint8_t *out, size_t n); -void chacha20poly1305_decrypt(chacha20poly1305_ctx *ctx, const uint8_t *in, uint8_t *out, size_t n); -void chacha20poly1305_auth(chacha20poly1305_ctx *ctx, const uint8_t *in, size_t n); -void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16]); +void xchacha20poly1305_init( + chacha20poly1305_ctx* ctx, + const uint8_t key[32], + const uint8_t nonce[24]); +void chacha20poly1305_encrypt(chacha20poly1305_ctx* ctx, const uint8_t* in, uint8_t* out, size_t n); +void chacha20poly1305_decrypt(chacha20poly1305_ctx* ctx, const uint8_t* in, uint8_t* out, size_t n); +void chacha20poly1305_auth(chacha20poly1305_ctx* ctx, const uint8_t* in, size_t n); +void chacha20poly1305_finish(chacha20poly1305_ctx* ctx, uint8_t mac[16]); #endif // CHACHA20POLY1305_H diff --git a/crypto/chacha20poly1305/chacha_merged.c b/crypto/chacha20poly1305/chacha_merged.c index f5c37fa8a90..ee228b471aa 100644 --- a/crypto/chacha20poly1305/chacha_merged.c +++ b/crypto/chacha20poly1305/chacha_merged.c @@ -4,249 +4,248 @@ D. J. Bernstein Public domain. */ -#include "ecrypt-sync.h" -#include "ecrypt-portable.h" - -#define ROTATE(v,c) (ROTL32(v,c)) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ - a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ - c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); - -void ECRYPT_init(void) -{ - return; +#include "ecrypt_sync.h" +#include "ecrypt_portable.h" + +#define ROTATE(v, c) (ROTL32(v, c)) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v), 1)) + +#define QUARTERROUND(a, b, c, d) \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 7); + +void ECRYPT_init(void) { + return; } static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; -void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits) -{ - (void)ivbits; - const char *constants = (const char *)0; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - x->input[8] = U8TO32_LITTLE(k + 0); - x->input[9] = U8TO32_LITTLE(k + 4); - x->input[10] = U8TO32_LITTLE(k + 8); - x->input[11] = U8TO32_LITTLE(k + 12); - x->input[0] = U8TO32_LITTLE(constants + 0); - x->input[1] = U8TO32_LITTLE(constants + 4); - x->input[2] = U8TO32_LITTLE(constants + 8); - x->input[3] = U8TO32_LITTLE(constants + 12); +void ECRYPT_keysetup(ECRYPT_ctx* x, const u8* k, u32 kbits, u32 ivbits) { + (void)ivbits; + const char* constants = (const char*)0; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if(kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); } -void ECRYPT_ivsetup(ECRYPT_ctx *x,const u8 *iv) -{ - x->input[12] = 0; - x->input[13] = 0; - x->input[14] = U8TO32_LITTLE(iv + 0); - x->input[15] = U8TO32_LITTLE(iv + 4); +void ECRYPT_ivsetup(ECRYPT_ctx* x, const u8* iv) { + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); } -void ECRYPT_ctrsetup(ECRYPT_ctx *x,const u8 *ctr) -{ - x->input[12] = U8TO32_LITTLE(ctr + 0); - x->input[13] = U8TO32_LITTLE(ctr + 4); +void ECRYPT_ctrsetup(ECRYPT_ctx* x, const u8* ctr) { + x->input[12] = U8TO32_LITTLE(ctr + 0); + x->input[13] = U8TO32_LITTLE(ctr + 4); } -void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes) -{ - u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; - u32 j0 = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0, j7 = 0, j8 = 0, j9 = 0, j10 = 0, j11 = 0, j12 = 0, j13 = 0, j14 = 0, j15 = 0; - u8 *ctarget = 0; - u8 tmp[64] = {0}; - int i = 0; - - if (!bytes) return; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for (;;) { - if (bytes < 64) { - for (i = 0;i < (int)bytes;++i) tmp[i] = m[i]; - m = tmp; - ctarget = c; - c = tmp; - } - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); - - x0 = XOR(x0,U8TO32_LITTLE(m + 0)); - x1 = XOR(x1,U8TO32_LITTLE(m + 4)); - x2 = XOR(x2,U8TO32_LITTLE(m + 8)); - x3 = XOR(x3,U8TO32_LITTLE(m + 12)); - x4 = XOR(x4,U8TO32_LITTLE(m + 16)); - x5 = XOR(x5,U8TO32_LITTLE(m + 20)); - x6 = XOR(x6,U8TO32_LITTLE(m + 24)); - x7 = XOR(x7,U8TO32_LITTLE(m + 28)); - x8 = XOR(x8,U8TO32_LITTLE(m + 32)); - x9 = XOR(x9,U8TO32_LITTLE(m + 36)); - x10 = XOR(x10,U8TO32_LITTLE(m + 40)); - x11 = XOR(x11,U8TO32_LITTLE(m + 44)); - x12 = XOR(x12,U8TO32_LITTLE(m + 48)); - x13 = XOR(x13,U8TO32_LITTLE(m + 52)); - x14 = XOR(x14,U8TO32_LITTLE(m + 56)); - x15 = XOR(x15,U8TO32_LITTLE(m + 60)); - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x4); - U32TO8_LITTLE(c + 20,x5); - U32TO8_LITTLE(c + 24,x6); - U32TO8_LITTLE(c + 28,x7); - U32TO8_LITTLE(c + 32,x8); - U32TO8_LITTLE(c + 36,x9); - U32TO8_LITTLE(c + 40,x10); - U32TO8_LITTLE(c + 44,x11); - U32TO8_LITTLE(c + 48,x12); - U32TO8_LITTLE(c + 52,x13); - U32TO8_LITTLE(c + 56,x14); - U32TO8_LITTLE(c + 60,x15); - - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0;i < (int)bytes;++i) ctarget[i] = c[i]; - } - x->input[12] = j12; - x->input[13] = j13; - return; +void ECRYPT_encrypt_bytes(ECRYPT_ctx* x, const u8* m, u8* c, u32 bytes) { + u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, + x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; + u32 j0 = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0, j7 = 0, j8 = 0, j9 = 0, j10 = 0, + j11 = 0, j12 = 0, j13 = 0, j14 = 0, j15 = 0; + u8* ctarget = 0; + u8 tmp[64] = {0}; + int i = 0; + + if(!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for(;;) { + if(bytes < 64) { + for(i = 0; i < (int)bytes; ++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for(i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + x0 = XOR(x0, U8TO32_LITTLE(m + 0)); + x1 = XOR(x1, U8TO32_LITTLE(m + 4)); + x2 = XOR(x2, U8TO32_LITTLE(m + 8)); + x3 = XOR(x3, U8TO32_LITTLE(m + 12)); + x4 = XOR(x4, U8TO32_LITTLE(m + 16)); + x5 = XOR(x5, U8TO32_LITTLE(m + 20)); + x6 = XOR(x6, U8TO32_LITTLE(m + 24)); + x7 = XOR(x7, U8TO32_LITTLE(m + 28)); + x8 = XOR(x8, U8TO32_LITTLE(m + 32)); + x9 = XOR(x9, U8TO32_LITTLE(m + 36)); + x10 = XOR(x10, U8TO32_LITTLE(m + 40)); + x11 = XOR(x11, U8TO32_LITTLE(m + 44)); + x12 = XOR(x12, U8TO32_LITTLE(m + 48)); + x13 = XOR(x13, U8TO32_LITTLE(m + 52)); + x14 = XOR(x14, U8TO32_LITTLE(m + 56)); + x15 = XOR(x15, U8TO32_LITTLE(m + 60)); + + j12 = PLUSONE(j12); + if(!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0, x0); + U32TO8_LITTLE(c + 4, x1); + U32TO8_LITTLE(c + 8, x2); + U32TO8_LITTLE(c + 12, x3); + U32TO8_LITTLE(c + 16, x4); + U32TO8_LITTLE(c + 20, x5); + U32TO8_LITTLE(c + 24, x6); + U32TO8_LITTLE(c + 28, x7); + U32TO8_LITTLE(c + 32, x8); + U32TO8_LITTLE(c + 36, x9); + U32TO8_LITTLE(c + 40, x10); + U32TO8_LITTLE(c + 44, x11); + U32TO8_LITTLE(c + 48, x12); + U32TO8_LITTLE(c + 52, x13); + U32TO8_LITTLE(c + 56, x14); + U32TO8_LITTLE(c + 60, x15); + + if(bytes <= 64) { + if(bytes < 64) { + for(i = 0; i < (int)bytes; ++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; + m += 64; } - bytes -= 64; - c += 64; - m += 64; - } } -void ECRYPT_decrypt_bytes(ECRYPT_ctx *x,const u8 *c,u8 *m,u32 bytes) -{ - ECRYPT_encrypt_bytes(x,c,m,bytes); +void ECRYPT_decrypt_bytes(ECRYPT_ctx* x, const u8* c, u8* m, u32 bytes) { + ECRYPT_encrypt_bytes(x, c, m, bytes); } -void ECRYPT_keystream_bytes(ECRYPT_ctx *x,u8 *stream,u32 bytes) -{ - u32 i = 0; - for (i = 0;i < bytes;++i) stream[i] = 0; - ECRYPT_encrypt_bytes(x,stream,stream,bytes); +void ECRYPT_keystream_bytes(ECRYPT_ctx* x, u8* stream, u32 bytes) { + u32 i = 0; + for(i = 0; i < bytes; ++i) stream[i] = 0; + ECRYPT_encrypt_bytes(x, stream, stream, bytes); } -void hchacha20(ECRYPT_ctx *x,u8 *c) -{ - u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; - int i = 0; - - x0 = x->input[0]; - x1 = x->input[1]; - x2 = x->input[2]; - x3 = x->input[3]; - x4 = x->input[4]; - x5 = x->input[5]; - x6 = x->input[6]; - x7 = x->input[7]; - x8 = x->input[8]; - x9 = x->input[9]; - x10 = x->input[10]; - x11 = x->input[11]; - x12 = x->input[12]; - x13 = x->input[13]; - x14 = x->input[14]; - x15 = x->input[15]; - - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) +void hchacha20(ECRYPT_ctx* x, u8* c) { + u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, + x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; + int i = 0; + + x0 = x->input[0]; + x1 = x->input[1]; + x2 = x->input[2]; + x3 = x->input[3]; + x4 = x->input[4]; + x5 = x->input[5]; + x6 = x->input[6]; + x7 = x->input[7]; + x8 = x->input[8]; + x9 = x->input[9]; + x10 = x->input[10]; + x11 = x->input[11]; + x12 = x->input[12]; + x13 = x->input[13]; + x14 = x->input[14]; + x15 = x->input[15]; + + for(i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) } - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x12); - U32TO8_LITTLE(c + 20,x13); - U32TO8_LITTLE(c + 24,x14); - U32TO8_LITTLE(c + 28,x15); + U32TO8_LITTLE(c + 0, x0); + U32TO8_LITTLE(c + 4, x1); + U32TO8_LITTLE(c + 8, x2); + U32TO8_LITTLE(c + 12, x3); + U32TO8_LITTLE(c + 16, x12); + U32TO8_LITTLE(c + 20, x13); + U32TO8_LITTLE(c + 24, x14); + U32TO8_LITTLE(c + 28, x15); } diff --git a/crypto/chacha20poly1305/ecrypt-portable.h b/crypto/chacha20poly1305/ecrypt-portable.h deleted file mode 100644 index e5276d846b9..00000000000 --- a/crypto/chacha20poly1305/ecrypt-portable.h +++ /dev/null @@ -1,275 +0,0 @@ -/* ecrypt-portable.h */ - -/* - * WARNING: the conversions defined below are implemented as macros, - * and should be used carefully. They should NOT be used with - * parameters which perform some action. E.g., the following two lines - * are not equivalent: - * - * 1) ++x; y = ROTL32(x, n); - * 2) y = ROTL32(++x, n); - */ - -/* - * *** Please do not edit this file. *** - * - * The default macros can be overridden for specific architectures by - * editing 'ecrypt-machine.h'. - */ - -#ifndef ECRYPT_PORTABLE -#define ECRYPT_PORTABLE - -#include "ecrypt-config.h" -#include "ecrypt-types.h" - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros are used to obtain exact-width results. - */ - -#define U8V(v) ((u8)(v) & U8C(0xFF)) -#define U16V(v) ((u16)(v) & U16C(0xFFFF)) -#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) -#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros return words with their bits rotated over n - * positions to the left/right. - */ - -#define ECRYPT_DEFAULT_ROT - -#define ROTL8(v, n) \ - (U8V((v) << (n)) | ((v) >> (8 - (n)))) - -#define ROTL16(v, n) \ - (U16V((v) << (n)) | ((v) >> (16 - (n)))) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define ROTL64(v, n) \ - (U64V((v) << (n)) | ((v) >> (64 - (n)))) - -#define ROTR8(v, n) ROTL8(v, 8 - (n)) -#define ROTR16(v, n) ROTL16(v, 16 - (n)) -#define ROTR32(v, n) ROTL32(v, 32 - (n)) -#define ROTR64(v, n) ROTL64(v, 64 - (n)) - -#include "ecrypt-machine.h" - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros return a word with bytes in reverse order. - */ - -#define ECRYPT_DEFAULT_SWAP - -#define SWAP16(v) \ - ROTL16(v, 8) - -#define SWAP32(v) \ - ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ - (ROTL32(v, 24) & U32C(0xFF00FF00))) - -#ifdef ECRYPT_NATIVE64 -#define SWAP64(v) \ - ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ - (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ - (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ - (ROTL64(v, 56) & U64C(0xFF000000FF000000))) -#else -#define SWAP64(v) \ - (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) -#endif - -#include "ecrypt-machine.h" - -#define ECRYPT_DEFAULT_WTOW - -#ifdef ECRYPT_LITTLE_ENDIAN -#define U16TO16_LITTLE(v) (v) -#define U32TO32_LITTLE(v) (v) -#define U64TO64_LITTLE(v) (v) - -#define U16TO16_BIG(v) SWAP16(v) -#define U32TO32_BIG(v) SWAP32(v) -#define U64TO64_BIG(v) SWAP64(v) -#endif - -#ifdef ECRYPT_BIG_ENDIAN -#define U16TO16_LITTLE(v) SWAP16(v) -#define U32TO32_LITTLE(v) SWAP32(v) -#define U64TO64_LITTLE(v) SWAP64(v) - -#define U16TO16_BIG(v) (v) -#define U32TO32_BIG(v) (v) -#define U64TO64_BIG(v) (v) -#endif - -#include "ecrypt-machine.h" - -/* - * The following macros load words from an array of bytes with - * different types of endianness, and vice versa. - */ - -#define ECRYPT_DEFAULT_BTOW - -#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) - -#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) -#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) -#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) - -#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) -#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) -#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) - -#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) -#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) -#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) - -#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) -#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) -#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) - -#else - -#define U8TO16_LITTLE(p) \ - (((u16)((p)[0]) ) | \ - ((u16)((p)[1]) << 8)) - -#define U8TO32_LITTLE(p) \ - (((u32)((p)[0]) ) | \ - ((u32)((p)[1]) << 8) | \ - ((u32)((p)[2]) << 16) | \ - ((u32)((p)[3]) << 24)) - -#ifdef ECRYPT_NATIVE64 -#define U8TO64_LITTLE(p) \ - (((u64)((p)[0]) ) | \ - ((u64)((p)[1]) << 8) | \ - ((u64)((p)[2]) << 16) | \ - ((u64)((p)[3]) << 24) | \ - ((u64)((p)[4]) << 32) | \ - ((u64)((p)[5]) << 40) | \ - ((u64)((p)[6]) << 48) | \ - ((u64)((p)[7]) << 56)) -#else -#define U8TO64_LITTLE(p) \ - ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) -#endif - -#define U8TO16_BIG(p) \ - (((u16)((p)[0]) << 8) | \ - ((u16)((p)[1]) )) - -#define U8TO32_BIG(p) \ - (((u32)((p)[0]) << 24) | \ - ((u32)((p)[1]) << 16) | \ - ((u32)((p)[2]) << 8) | \ - ((u32)((p)[3]) )) - -#ifdef ECRYPT_NATIVE64 -#define U8TO64_BIG(p) \ - (((u64)((p)[0]) << 56) | \ - ((u64)((p)[1]) << 48) | \ - ((u64)((p)[2]) << 40) | \ - ((u64)((p)[3]) << 32) | \ - ((u64)((p)[4]) << 24) | \ - ((u64)((p)[5]) << 16) | \ - ((u64)((p)[6]) << 8) | \ - ((u64)((p)[7]) )) -#else -#define U8TO64_BIG(p) \ - (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) -#endif - -#define U16TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - } while (0) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#ifdef ECRYPT_NATIVE64 -#define U64TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - (p)[4] = U8V((v) >> 32); \ - (p)[5] = U8V((v) >> 40); \ - (p)[6] = U8V((v) >> 48); \ - (p)[7] = U8V((v) >> 56); \ - } while (0) -#else -#define U64TO8_LITTLE(p, v) \ - do { \ - U32TO8_LITTLE((p), U32V((v) )); \ - U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ - } while (0) -#endif - -#define U16TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - } while (0) - -#define U32TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) >> 24); \ - (p)[1] = U8V((v) >> 16); \ - (p)[2] = U8V((v) >> 8); \ - (p)[3] = U8V((v) ); \ - } while (0) - -#ifdef ECRYPT_NATIVE64 -#define U64TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) >> 56); \ - (p)[1] = U8V((v) >> 48); \ - (p)[2] = U8V((v) >> 40); \ - (p)[3] = U8V((v) >> 32); \ - (p)[4] = U8V((v) >> 24); \ - (p)[5] = U8V((v) >> 16); \ - (p)[6] = U8V((v) >> 8); \ - (p)[7] = U8V((v) ); \ - } while (0) -#else -#define U64TO8_BIG(p, v) \ - do { \ - U32TO8_BIG((p), U32V((v) >> 32)); \ - U32TO8_BIG((p) + 4, U32V((v) )); \ - } while (0) -#endif - -#endif - -#include "ecrypt-machine.h" - -/* ------------------------------------------------------------------------- */ - -#define AT_LEAST_ONE(n) (((n) < 1) ? 1 : (n)) - -#define ALIGN(t, v, n) \ - union { t b[n]; MAXT l[AT_LEAST_ONE(n * sizeof(t) / sizeof(MAXT))]; } v - -/* ------------------------------------------------------------------------- */ - -#endif diff --git a/crypto/chacha20poly1305/ecrypt-config.h b/crypto/chacha20poly1305/ecrypt_config.h similarity index 70% rename from crypto/chacha20poly1305/ecrypt-config.h rename to crypto/chacha20poly1305/ecrypt_config.h index 0749df73083..40a3a484a5b 100644 --- a/crypto/chacha20poly1305/ecrypt-config.h +++ b/crypto/chacha20poly1305/ecrypt_config.h @@ -1,4 +1,4 @@ -/* ecrypt-config.h */ +/* ecrypt_config.h */ /* *** Normally, it should not be necessary to edit this file. *** */ @@ -12,19 +12,19 @@ /* * The LITTLE endian machines: */ -#if defined(__ultrix) /* Older MIPS */ +#if defined(__ultrix) /* Older MIPS */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(__alpha) /* Alpha */ +#elif defined(__alpha) /* Alpha */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(i386) /* x86 (gcc) */ +#elif defined(i386) /* x86 (gcc) */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(__i386) /* x86 (gcc) */ +#elif defined(__i386) /* x86 (gcc) */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(__x86_64) /* x86_64 (gcc) */ +#elif defined(__x86_64) /* x86_64 (gcc) */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(_M_IX86) /* x86 (MSC, Borland) */ +#elif defined(_M_IX86) /* x86 (MSC, Borland) */ #define ECRYPT_LITTLE_ENDIAN -#elif defined(_MSC_VER) /* x86 (surely MSC) */ +#elif defined(_MSC_VER) /* x86 (surely MSC) */ #define ECRYPT_LITTLE_ENDIAN #elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ #define ECRYPT_LITTLE_ENDIAN @@ -32,27 +32,27 @@ /* * The BIG endian machines: */ -#elif defined(__sparc) /* Newer Sparc's */ +#elif defined(__sparc) /* Newer Sparc's */ #define ECRYPT_BIG_ENDIAN -#elif defined(__powerpc__) /* PowerPC */ +#elif defined(__powerpc__) /* PowerPC */ #define ECRYPT_BIG_ENDIAN -#elif defined(__ppc__) /* PowerPC */ +#elif defined(__ppc__) /* PowerPC */ #define ECRYPT_BIG_ENDIAN -#elif defined(__hppa) /* HP-PA */ +#elif defined(__hppa) /* HP-PA */ #define ECRYPT_BIG_ENDIAN /* * Finally machines with UNKNOWN endianness: */ -#elif defined (_AIX) /* RS6000 */ +#elif defined(_AIX) /* RS6000 */ #define ECRYPT_UNKNOWN -#elif defined(__aux) /* 68K */ +#elif defined(__aux) /* 68K */ #define ECRYPT_UNKNOWN -#elif defined(__dgux) /* 88K (but P6 in latest boxes) */ +#elif defined(__dgux) /* 88K (but P6 in latest boxes) */ #define ECRYPT_UNKNOWN -#elif defined(__sgi) /* Newer MIPS */ +#elif defined(__sgi) /* Newer MIPS */ #define ECRYPT_UNKNOWN -#else /* Any other processor */ +#else /* Any other processor */ #define ECRYPT_UNKNOWN #endif @@ -71,30 +71,30 @@ /* --- check char --- */ -#if (UCHAR_MAX / 0xFU > 0xFU) +#if(UCHAR_MAX / 0xFU > 0xFU) #ifndef I8T #define I8T char #define U8C(v) (v##U) -#if (UCHAR_MAX == 0xFFU) +#if(UCHAR_MAX == 0xFFU) #define ECRYPT_I8T_IS_BYTE #endif #endif -#if (UCHAR_MAX / 0xFFU > 0xFFU) +#if(UCHAR_MAX / 0xFFU > 0xFFU) #ifndef I16T #define I16T char #define U16C(v) (v##U) #endif -#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) +#if(UCHAR_MAX / 0xFFFFU > 0xFFFFU) #ifndef I32T #define I32T char #define U32C(v) (v##U) #endif -#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#if(UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) #ifndef I64T #define I64T char #define U64C(v) (v##U) @@ -108,30 +108,30 @@ /* --- check short --- */ -#if (USHRT_MAX / 0xFU > 0xFU) +#if(USHRT_MAX / 0xFU > 0xFU) #ifndef I8T #define I8T short #define U8C(v) (v##U) -#if (USHRT_MAX == 0xFFU) +#if(USHRT_MAX == 0xFFU) #define ECRYPT_I8T_IS_BYTE #endif #endif -#if (USHRT_MAX / 0xFFU > 0xFFU) +#if(USHRT_MAX / 0xFFU > 0xFFU) #ifndef I16T #define I16T short #define U16C(v) (v##U) #endif -#if (USHRT_MAX / 0xFFFFU > 0xFFFFU) +#if(USHRT_MAX / 0xFFFFU > 0xFFFFU) #ifndef I32T #define I32T short #define U32C(v) (v##U) #endif -#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#if(USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) #ifndef I64T #define I64T short #define U64C(v) (v##U) @@ -145,30 +145,30 @@ /* --- check int --- */ -#if (UINT_MAX / 0xFU > 0xFU) +#if(UINT_MAX / 0xFU > 0xFU) #ifndef I8T #define I8T int #define U8C(v) (v##U) -#if (ULONG_MAX == 0xFFU) +#if(ULONG_MAX == 0xFFU) #define ECRYPT_I8T_IS_BYTE #endif #endif -#if (UINT_MAX / 0xFFU > 0xFFU) +#if(UINT_MAX / 0xFFU > 0xFFU) #ifndef I16T #define I16T int #define U16C(v) (v##U) #endif -#if (UINT_MAX / 0xFFFFU > 0xFFFFU) +#if(UINT_MAX / 0xFFFFU > 0xFFFFU) #ifndef I32T #define I32T int #define U32C(v) (v##U) #endif -#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#if(UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) #ifndef I64T #define I64T int #define U64C(v) (v##U) @@ -182,30 +182,30 @@ /* --- check long --- */ -#if (ULONG_MAX / 0xFUL > 0xFUL) +#if(ULONG_MAX / 0xFUL > 0xFUL) #ifndef I8T #define I8T long #define U8C(v) (v##UL) -#if (ULONG_MAX == 0xFFUL) +#if(ULONG_MAX == 0xFFUL) #define ECRYPT_I8T_IS_BYTE #endif #endif -#if (ULONG_MAX / 0xFFUL > 0xFFUL) +#if(ULONG_MAX / 0xFFUL > 0xFFUL) #ifndef I16T #define I16T long #define U16C(v) (v##UL) #endif -#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) +#if(ULONG_MAX / 0xFFFFUL > 0xFFFFUL) #ifndef I32T #define I32T long #define U32C(v) (v##UL) #endif -#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) +#if(ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) #ifndef I64T #define I64T long #define U64C(v) (v##UL) @@ -221,30 +221,30 @@ #ifdef ULLONG_MAX -#if (ULLONG_MAX / 0xFULL > 0xFULL) +#if(ULLONG_MAX / 0xFULL > 0xFULL) #ifndef I8T #define I8T long long #define U8C(v) (v##ULL) -#if (ULLONG_MAX == 0xFFULL) +#if(ULLONG_MAX == 0xFFULL) #define ECRYPT_I8T_IS_BYTE #endif #endif -#if (ULLONG_MAX / 0xFFULL > 0xFFULL) +#if(ULLONG_MAX / 0xFFULL > 0xFFULL) #ifndef I16T #define I16T long long #define U16C(v) (v##ULL) #endif -#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) +#if(ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) #ifndef I32T #define I32T long long #define U32C(v) (v##ULL) #endif -#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) +#if(ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) #ifndef I64T #define I64T long long #define U64C(v) (v##ULL) diff --git a/crypto/chacha20poly1305/ecrypt-machine.h b/crypto/chacha20poly1305/ecrypt_machine.h similarity index 72% rename from crypto/chacha20poly1305/ecrypt-machine.h rename to crypto/chacha20poly1305/ecrypt_machine.h index d006bedec16..6773c25719c 100644 --- a/crypto/chacha20poly1305/ecrypt-machine.h +++ b/crypto/chacha20poly1305/ecrypt_machine.h @@ -1,7 +1,7 @@ -/* ecrypt-machine.h */ +/* ecrypt_machine.h */ /* - * This file is included by 'ecrypt-portable.h'. It allows to override + * This file is included by 'ecrypt_portable.h'. It allows to override * the default macros for specific platforms. Please carefully check * the machine code generated by your compiler (with optimisations * turned on) before deciding to edit this file. @@ -9,11 +9,11 @@ /* ------------------------------------------------------------------------- */ -#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) +#if(defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) #define ECRYPT_MACHINE_ROT -#if (defined(WIN32) && defined(_MSC_VER)) +#if(defined(WIN32) && defined(_MSC_VER)) #undef ROTL32 #undef ROTR32 @@ -22,7 +22,7 @@ #include -#pragma intrinsic(_lrotl) /* compile rotations "inline" */ +#pragma intrinsic(_lrotl) /* compile rotations "inline" */ #pragma intrinsic(_lrotr) #define ROTL32(v, n) _lrotl(v, n) @@ -36,7 +36,7 @@ /* ------------------------------------------------------------------------- */ -#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) +#if(defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) #define ECRYPT_MACHINE_SWAP diff --git a/crypto/chacha20poly1305/ecrypt_portable.h b/crypto/chacha20poly1305/ecrypt_portable.h new file mode 100644 index 00000000000..f5d5001140f --- /dev/null +++ b/crypto/chacha20poly1305/ecrypt_portable.h @@ -0,0 +1,246 @@ +/* ecrypt_portable.h */ + +/* + * WARNING: the conversions defined below are implemented as macros, + * and should be used carefully. They should NOT be used with + * parameters which perform some action. E.g., the following two lines + * are not equivalent: + * + * 1) ++x; y = ROTL32(x, n); + * 2) y = ROTL32(++x, n); + */ + +/* + * *** Please do not edit this file. *** + * + * The default macros can be overridden for specific architectures by + * editing 'ecrypt_machine.h'. + */ + +#ifndef ECRYPT_PORTABLE +#define ECRYPT_PORTABLE + +#include "ecrypt_config.h" +#include "ecrypt_types.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros are used to obtain exact-width results. + */ + +#define U8V(v) ((u8)(v)&U8C(0xFF)) +#define U16V(v) ((u16)(v)&U16C(0xFFFF)) +#define U32V(v) ((u32)(v)&U32C(0xFFFFFFFF)) +#define U64V(v) ((u64)(v)&U64C(0xFFFFFFFFFFFFFFFF)) + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return words with their bits rotated over n + * positions to the left/right. + */ + +#define ECRYPT_DEFAULT_ROT + +#define ROTL8(v, n) (U8V((v) << (n)) | ((v) >> (8 - (n)))) + +#define ROTL16(v, n) (U16V((v) << (n)) | ((v) >> (16 - (n)))) + +#define ROTL32(v, n) (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define ROTL64(v, n) (U64V((v) << (n)) | ((v) >> (64 - (n)))) + +#define ROTR8(v, n) ROTL8(v, 8 - (n)) +#define ROTR16(v, n) ROTL16(v, 16 - (n)) +#define ROTR32(v, n) ROTL32(v, 32 - (n)) +#define ROTR64(v, n) ROTL64(v, 64 - (n)) + +#include "ecrypt_machine.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return a word with bytes in reverse order. + */ + +#define ECRYPT_DEFAULT_SWAP + +#define SWAP16(v) ROTL16(v, 8) + +#define SWAP32(v) ((ROTL32(v, 8) & U32C(0x00FF00FF)) | (ROTL32(v, 24) & U32C(0xFF00FF00))) + +#ifdef ECRYPT_NATIVE64 +#define SWAP64(v) \ + ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ + (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | (ROTL64(v, 56) & U64C(0xFF000000FF000000))) +#else +#define SWAP64(v) (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) +#endif + +#include "ecrypt_machine.h" + +#define ECRYPT_DEFAULT_WTOW + +#ifdef ECRYPT_LITTLE_ENDIAN +#define U16TO16_LITTLE(v) (v) +#define U32TO32_LITTLE(v) (v) +#define U64TO64_LITTLE(v) (v) + +#define U16TO16_BIG(v) SWAP16(v) +#define U32TO32_BIG(v) SWAP32(v) +#define U64TO64_BIG(v) SWAP64(v) +#endif + +#ifdef ECRYPT_BIG_ENDIAN +#define U16TO16_LITTLE(v) SWAP16(v) +#define U32TO32_LITTLE(v) SWAP32(v) +#define U64TO64_LITTLE(v) SWAP64(v) + +#define U16TO16_BIG(v) (v) +#define U32TO32_BIG(v) (v) +#define U64TO64_BIG(v) (v) +#endif + +#include "ecrypt_machine.h" + +/* + * The following macros load words from an array of bytes with + * different types of endianness, and vice versa. + */ + +#define ECRYPT_DEFAULT_BTOW + +#if(!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) + +#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) +#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) +#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) + +#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) +#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) +#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) + +#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) +#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) +#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) + +#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) +#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) +#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) + +#else + +#define U8TO16_LITTLE(p) (((u16)((p)[0])) | ((u16)((p)[1]) << 8)) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0])) | ((u32)((p)[1]) << 8) | ((u32)((p)[2]) << 16) | ((u32)((p)[3]) << 24)) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_LITTLE(p) \ + (((u64)((p)[0])) | ((u64)((p)[1]) << 8) | ((u64)((p)[2]) << 16) | ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | ((u64)((p)[5]) << 40) | ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) +#else +#define U8TO64_LITTLE(p) ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) +#endif + +#define U8TO16_BIG(p) (((u16)((p)[0]) << 8) | ((u16)((p)[1]))) + +#define U8TO32_BIG(p) \ + (((u32)((p)[0]) << 24) | ((u32)((p)[1]) << 16) | ((u32)((p)[2]) << 8) | ((u32)((p)[3]))) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_BIG(p) \ + (((u64)((p)[0]) << 56) | ((u64)((p)[1]) << 48) | ((u64)((p)[2]) << 40) | \ + ((u64)((p)[3]) << 32) | ((u64)((p)[4]) << 24) | ((u64)((p)[5]) << 16) | \ + ((u64)((p)[6]) << 8) | ((u64)((p)[7]))) +#else +#define U8TO64_BIG(p) (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) +#endif + +#define U16TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v)); \ + (p)[1] = U8V((v) >> 8); \ + } while(0) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v)); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while(0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v)); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + (p)[4] = U8V((v) >> 32); \ + (p)[5] = U8V((v) >> 40); \ + (p)[6] = U8V((v) >> 48); \ + (p)[7] = U8V((v) >> 56); \ + } while(0) +#else +#define U64TO8_LITTLE(p, v) \ + do { \ + U32TO8_LITTLE((p), U32V((v))); \ + U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ + } while(0) +#endif + +#define U16TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v)); \ + (p)[1] = U8V((v) >> 8); \ + } while(0) + +#define U32TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 24); \ + (p)[1] = U8V((v) >> 16); \ + (p)[2] = U8V((v) >> 8); \ + (p)[3] = U8V((v)); \ + } while(0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 56); \ + (p)[1] = U8V((v) >> 48); \ + (p)[2] = U8V((v) >> 40); \ + (p)[3] = U8V((v) >> 32); \ + (p)[4] = U8V((v) >> 24); \ + (p)[5] = U8V((v) >> 16); \ + (p)[6] = U8V((v) >> 8); \ + (p)[7] = U8V((v)); \ + } while(0) +#else +#define U64TO8_BIG(p, v) \ + do { \ + U32TO8_BIG((p), U32V((v) >> 32)); \ + U32TO8_BIG((p) + 4, U32V((v))); \ + } while(0) +#endif + +#endif + +#include "ecrypt_machine.h" + +/* ------------------------------------------------------------------------- */ + +#define AT_LEAST_ONE(n) (((n) < 1) ? 1 : (n)) + +#define ALIGN(t, v, n) \ + union { \ + t b[n]; \ + MAXT l[AT_LEAST_ONE(n * sizeof(t) / sizeof(MAXT))]; \ + } v + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/crypto/chacha20poly1305/ecrypt-sync.h b/crypto/chacha20poly1305/ecrypt_sync.h similarity index 72% rename from crypto/chacha20poly1305/ecrypt-sync.h rename to crypto/chacha20poly1305/ecrypt_sync.h index efce9dde273..f51608f9af4 100644 --- a/crypto/chacha20poly1305/ecrypt-sync.h +++ b/crypto/chacha20poly1305/ecrypt_sync.h @@ -1,6 +1,6 @@ #define ECRYPT_VARIANT 1 #define ECRYPT_API -/* ecrypt-sync.h */ +/* ecrypt_sync.h */ /* * Header file for synchronous stream ciphers without authentication @@ -12,7 +12,7 @@ #ifndef ECRYPT_SYNC #define ECRYPT_SYNC -#include "ecrypt-types.h" +#include "ecrypt_types.h" /* ------------------------------------------------------------------------- */ @@ -39,11 +39,11 @@ * All sizes are in bits. */ -#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ -#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ +#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ +#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ -#define ECRYPT_MAXIVSIZE 64 /* [edit] */ -#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ +#define ECRYPT_MAXIVSIZE 64 /* [edit] */ +#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ /* ------------------------------------------------------------------------- */ @@ -54,10 +54,9 @@ * internal state of your cipher. */ -typedef struct -{ - u32 input[16]; /* could be compressed */ - /* +typedef struct { + u32 input[16]; /* could be compressed */ + /* * [edit] * * Put here all state variable needed during the encryption process. @@ -81,10 +80,10 @@ void ECRYPT_init(void); * above. */ void ECRYPT_keysetup( - ECRYPT_ctx* ctx, - const u8* key, - u32 keysize, /* Key size in bits. */ - u32 ivsize); /* IV size in bits. */ + ECRYPT_ctx* ctx, + const u8* key, + u32 keysize, /* Key size in bits. */ + u32 ivsize); /* IV size in bits. */ /* * IV setup. After having called ECRYPT_keysetup(), the user is @@ -92,18 +91,14 @@ void ECRYPT_keysetup( * encrypt/decrypt different messages with the same key but different * IV's. ECRYPT_ivsetup() also sets block counter to zero. */ -void ECRYPT_ivsetup( - ECRYPT_ctx* ctx, - const u8* iv); +void ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv); /* * Block counter setup. It is used only for special purposes, * since block counter is usually initialized with ECRYPT_ivsetup. * ECRYPT_ctrsetup has to be called after ECRYPT_ivsetup. */ -void ECRYPT_ctrsetup( - ECRYPT_ctx* ctx, - const u8* ctr); +void ECRYPT_ctrsetup(ECRYPT_ctx* ctx, const u8* ctr); /* * Encryption/decryption of arbitrary length messages. @@ -144,16 +139,16 @@ void ECRYPT_ctrsetup( */ void ECRYPT_encrypt_bytes( - ECRYPT_ctx* ctx, - const u8* plaintext, - u8* ciphertext, - u32 msglen); /* Message length in bytes. */ + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 msglen); /* Message length in bytes. */ void ECRYPT_decrypt_bytes( - ECRYPT_ctx* ctx, - const u8* ciphertext, - u8* plaintext, - u32 msglen); /* Message length in bytes. */ + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* Message length in bytes. */ /* ------------------------------------------------------------------------- */ @@ -171,9 +166,9 @@ void ECRYPT_decrypt_bytes( #ifdef ECRYPT_GENERATES_KEYSTREAM void ECRYPT_keystream_bytes( - ECRYPT_ctx* ctx, - u8* keystream, - u32 length); /* Length of keystream in bytes. */ + ECRYPT_ctx* ctx, + u8* keystream, + u32 length); /* Length of keystream in bytes. */ #endif @@ -194,21 +189,21 @@ void ECRYPT_keystream_bytes( * "ecrypt-sync.c". If you want to implement them differently, please * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. */ -#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ +#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ void ECRYPT_encrypt_packet( - ECRYPT_ctx* ctx, - const u8* iv, - const u8* plaintext, - u8* ciphertext, - u32 msglen); + ECRYPT_ctx* ctx, + const u8* iv, + const u8* plaintext, + u8* ciphertext, + u32 msglen); void ECRYPT_decrypt_packet( - ECRYPT_ctx* ctx, - const u8* iv, - const u8* ciphertext, - u8* plaintext, - u32 msglen); + ECRYPT_ctx* ctx, + const u8* iv, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* * Encryption/decryption of blocks. @@ -219,47 +214,44 @@ void ECRYPT_decrypt_packet( * declared below. */ -#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ +#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ -#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ +#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ #ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS -#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ - ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ - (blocks) * ECRYPT_BLOCKLENGTH) +#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ + ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, (blocks)*ECRYPT_BLOCKLENGTH) -#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ - ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ - (blocks) * ECRYPT_BLOCKLENGTH) +#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ + ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, (blocks)*ECRYPT_BLOCKLENGTH) #ifdef ECRYPT_GENERATES_KEYSTREAM -#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ - ECRYPT_keystream_bytes(ctx, keystream, \ - (blocks) * ECRYPT_BLOCKLENGTH) +#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ + ECRYPT_keystream_bytes(ctx, keystream, (blocks)*ECRYPT_BLOCKLENGTH) #endif #else void ECRYPT_encrypt_blocks( - ECRYPT_ctx* ctx, - const u8* plaintext, - u8* ciphertext, - u32 blocks); /* Message length in blocks. */ + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 blocks); /* Message length in blocks. */ void ECRYPT_decrypt_blocks( - ECRYPT_ctx* ctx, - const u8* ciphertext, - u8* plaintext, - u32 blocks); /* Message length in blocks. */ + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 blocks); /* Message length in blocks. */ #ifdef ECRYPT_GENERATES_KEYSTREAM void ECRYPT_keystream_blocks( - ECRYPT_ctx* ctx, - const u8* keystream, - u32 blocks); /* Keystream length in blocks. */ + ECRYPT_ctx* ctx, + const u8* keystream, + u32 blocks); /* Keystream length in blocks. */ #endif @@ -275,13 +267,13 @@ void ECRYPT_keystream_blocks( * 10). Note also that all variants should have exactly the same * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). */ -#define ECRYPT_MAXVARIANT 1 /* [edit] */ +#define ECRYPT_MAXVARIANT 1 /* [edit] */ #ifndef ECRYPT_VARIANT #define ECRYPT_VARIANT 1 #endif -#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) +#if(ECRYPT_VARIANT > ECRYPT_MAXVARIANT) #error this variant does not exist #endif diff --git a/crypto/chacha20poly1305/ecrypt-types.h b/crypto/chacha20poly1305/ecrypt_types.h similarity index 88% rename from crypto/chacha20poly1305/ecrypt-types.h rename to crypto/chacha20poly1305/ecrypt_types.h index e608e220a00..2d1a4197590 100644 --- a/crypto/chacha20poly1305/ecrypt-types.h +++ b/crypto/chacha20poly1305/ecrypt_types.h @@ -1,16 +1,16 @@ -/* ecrypt-types.h */ +/* ecrypt_types.h */ /* * *** Please do not edit this file. *** * * The default macros can be overridden for specific architectures by - * editing 'ecrypt-machine.h'. + * editing 'ecrypt_machine.h'. */ #ifndef ECRYPT_TYPES #define ECRYPT_TYPES -#include "ecrypt-config.h" +#include "ecrypt_config.h" /* ------------------------------------------------------------------------- */ @@ -25,7 +25,7 @@ * s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 * * The selection of minimum-width integer types is taken care of by - * 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit + * 'ecrypt_config.h'. Note: to enable 64-bit types on 32-bit * compilers, it might be necessary to switch from ISO C90 mode to ISO * C99 mode (e.g., gcc -std=c99). */ diff --git a/crypto/chacha20poly1305/poly1305-donna-32.h b/crypto/chacha20poly1305/poly1305-donna-32.h deleted file mode 100644 index 6a570f06e1b..00000000000 --- a/crypto/chacha20poly1305/poly1305-donna-32.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition -*/ - -#if defined(_MSC_VER) - #define POLY1305_NOINLINE __declspec(noinline) -#elif defined(__GNUC__) - #define POLY1305_NOINLINE __attribute__((noinline)) -#else - #define POLY1305_NOINLINE -#endif - -#define poly1305_block_size 16 - -/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ -typedef struct poly1305_state_internal_t { - unsigned long r[5]; - unsigned long h[5]; - unsigned long pad[4]; - size_t leftover; - unsigned char buffer[poly1305_block_size]; - unsigned char final; -} poly1305_state_internal_t; - -/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ -static unsigned long -U8TO32(const unsigned char *p) { - return - (((unsigned long)(p[0] & 0xff) ) | - ((unsigned long)(p[1] & 0xff) << 8) | - ((unsigned long)(p[2] & 0xff) << 16) | - ((unsigned long)(p[3] & 0xff) << 24)); -} - -/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ -static void -U32TO8(unsigned char *p, unsigned long v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; -} - -void -poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff; - st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03; - st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff; - st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff; - st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; - - /* h = 0 */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; - - /* save pad for later */ - st->pad[0] = U8TO32(&key[16]); - st->pad[1] = U8TO32(&key[20]); - st->pad[2] = U8TO32(&key[24]); - st->pad[3] = U8TO32(&key[28]); - - st->leftover = 0; - st->final = 0; -} - -static void -poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { - const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ - unsigned long r0,r1,r2,r3,r4; - unsigned long s1,s2,s3,s4; - unsigned long h0,h1,h2,h3,h4; - unsigned long long d0,d1,d2,d3,d4; - unsigned long c; - - r0 = st->r[0]; - r1 = st->r[1]; - r2 = st->r[2]; - r3 = st->r[3]; - r4 = st->r[4]; - - s1 = r1 * 5; - s2 = r2 * 5; - s3 = r3 * 5; - s4 = r4 * 5; - - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; - - while (bytes >= poly1305_block_size) { - /* h += m[i] */ - h0 += (U8TO32(m+ 0) ) & 0x3ffffff; - h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; - h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; - h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; - h4 += (U8TO32(m+12) >> 8) | hibit; - - /* h *= r */ - d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1); - d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2); - d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3); - d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4); - d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0); - - /* (partial) h %= p */ - c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff; - d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff; - d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff; - d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff; - d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff; - h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; - h1 += c; - - m += poly1305_block_size; - bytes -= poly1305_block_size; - } - - st->h[0] = h0; - st->h[1] = h1; - st->h[2] = h2; - st->h[3] = h3; - st->h[4] = h4; -} - -POLY1305_NOINLINE void -poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - unsigned long h0,h1,h2,h3,h4,c; - unsigned long g0,g1,g2,g3,g4; - unsigned long long f; - unsigned long mask; - - /* process the remaining block */ - if (st->leftover) { - size_t i = st->leftover; - st->buffer[i++] = 1; - for (; i < poly1305_block_size; i++) - st->buffer[i] = 0; - st->final = 1; - poly1305_blocks(st, st->buffer, poly1305_block_size); - } - - /* fully carry h */ - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; - - c = h1 >> 26; h1 = h1 & 0x3ffffff; - h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; - h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; - h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; - h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; - h1 += c; - - /* compute h + -p */ - g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; - g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; - g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; - g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; - g4 = h4 + c - (1UL << 26); - - /* select h if h < p, or h + -p if h >= p */ - mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; - g0 &= mask; - g1 &= mask; - g2 &= mask; - g3 &= mask; - g4 &= mask; - mask = ~mask; - h0 = (h0 & mask) | g0; - h1 = (h1 & mask) | g1; - h2 = (h2 & mask) | g2; - h3 = (h3 & mask) | g3; - h4 = (h4 & mask) | g4; - - /* h = h % (2^128) */ - h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; - h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; - h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; - h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; - - /* mac = (h + pad) % (2^128) */ - f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f; - f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f; - f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f; - f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f; - - U32TO8(mac + 0, h0); - U32TO8(mac + 4, h1); - U32TO8(mac + 8, h2); - U32TO8(mac + 12, h3); - - /* zero out the state */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; - st->r[0] = 0; - st->r[1] = 0; - st->r[2] = 0; - st->r[3] = 0; - st->r[4] = 0; - st->pad[0] = 0; - st->pad[1] = 0; - st->pad[2] = 0; - st->pad[3] = 0; -} - diff --git a/crypto/chacha20poly1305/poly1305-donna.c b/crypto/chacha20poly1305/poly1305-donna.c deleted file mode 100644 index bb6e7a3ec77..00000000000 --- a/crypto/chacha20poly1305/poly1305-donna.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "poly1305-donna.h" -#include "poly1305-donna-32.h" - -void -poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - size_t i = 0; - - /* handle leftover */ - if (st->leftover) { - size_t want = (poly1305_block_size - st->leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - st->buffer[st->leftover + i] = m[i]; - bytes -= want; - m += want; - st->leftover += want; - if (st->leftover < poly1305_block_size) - return; - poly1305_blocks(st, st->buffer, poly1305_block_size); - st->leftover = 0; - } - - /* process full blocks */ - if (bytes >= poly1305_block_size) { - size_t want = (bytes & ~(poly1305_block_size - 1)); - poly1305_blocks(st, m, want); - m += want; - bytes -= want; - } - - /* store leftover */ - if (bytes) { - for (i = 0; i < bytes; i++) - st->buffer[st->leftover + i] = m[i]; - st->leftover += bytes; - } -} - -void -poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]) { - poly1305_context ctx = {0}; - poly1305_init(&ctx, key); - poly1305_update(&ctx, m, bytes); - poly1305_finish(&ctx, mac); -} - -int -poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]) { - size_t i = 0; - unsigned int dif = 0; - for (i = 0; i < 16; i++) - dif |= (mac1[i] ^ mac2[i]); - dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1); - return (dif & 1); -} - - -/* test a few basic operations */ -int -poly1305_power_on_self_test(void) { - /* example from nacl */ - static const unsigned char nacl_key[32] = { - 0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91, - 0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25, - 0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65, - 0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80, - }; - - static const unsigned char nacl_msg[131] = { - 0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73, - 0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce, - 0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4, - 0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a, - 0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b, - 0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72, - 0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2, - 0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38, - 0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a, - 0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae, - 0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea, - 0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda, - 0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde, - 0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3, - 0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6, - 0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74, - 0xe3,0x55,0xa5 - }; - - static const unsigned char nacl_mac[16] = { - 0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5, - 0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 - }; - - /* generates a final value of (2^130 - 2) == 3 */ - static const unsigned char wrap_key[32] = { - 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }; - - static const unsigned char wrap_msg[16] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff - }; - - static const unsigned char wrap_mac[16] = { - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }; - - /* - mac of the macs of messages of length 0 to 256, where the key and messages - have all their values set to the length - */ - static const unsigned char total_key[32] = { - 0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff - }; - - static const unsigned char total_mac[16] = { - 0x64,0xaf,0xe2,0xe8,0xd6,0xad,0x7b,0xbd, - 0xd2,0x87,0xf9,0x7c,0x44,0x62,0x3d,0x39 - }; - - poly1305_context ctx = {0}; - poly1305_context total_ctx = {0}; - unsigned char all_key[32] = {0}; - unsigned char all_msg[256] = {0}; - unsigned char mac[16] = {0}; - size_t i = 0, j = 0; - int result = 1; - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key); - result &= poly1305_verify(nacl_mac, mac); - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_init(&ctx, nacl_key); - poly1305_update(&ctx, nacl_msg + 0, 32); - poly1305_update(&ctx, nacl_msg + 32, 64); - poly1305_update(&ctx, nacl_msg + 96, 16); - poly1305_update(&ctx, nacl_msg + 112, 8); - poly1305_update(&ctx, nacl_msg + 120, 4); - poly1305_update(&ctx, nacl_msg + 124, 2); - poly1305_update(&ctx, nacl_msg + 126, 1); - poly1305_update(&ctx, nacl_msg + 127, 1); - poly1305_update(&ctx, nacl_msg + 128, 1); - poly1305_update(&ctx, nacl_msg + 129, 1); - poly1305_update(&ctx, nacl_msg + 130, 1); - poly1305_finish(&ctx, mac); - result &= poly1305_verify(nacl_mac, mac); - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key); - result &= poly1305_verify(wrap_mac, mac); - - poly1305_init(&total_ctx, total_key); - for (i = 0; i < 256; i++) { - /* set key and message to 'i,i,i..' */ - for (j = 0; j < sizeof(all_key); j++) - all_key[j] = i; - for (j = 0; j < i; j++) - all_msg[j] = i; - poly1305_auth(mac, all_msg, i, all_key); - poly1305_update(&total_ctx, mac, 16); - } - poly1305_finish(&total_ctx, mac); - result &= poly1305_verify(total_mac, mac); - - return result; -} diff --git a/crypto/chacha20poly1305/poly1305-donna.h b/crypto/chacha20poly1305/poly1305-donna.h deleted file mode 100644 index 94e23533f21..00000000000 --- a/crypto/chacha20poly1305/poly1305-donna.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef POLY1305_DONNA_H -#define POLY1305_DONNA_H - -#include - -typedef struct poly1305_context { - size_t aligner; - unsigned char opaque[136]; -} poly1305_context; - -void poly1305_init(poly1305_context *ctx, const unsigned char key[32]); -void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes); -void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]); -void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]); - -int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]); -int poly1305_power_on_self_test(void); - -#endif /* POLY1305_DONNA_H */ - diff --git a/crypto/chacha20poly1305/poly1305_donna.c b/crypto/chacha20poly1305/poly1305_donna.c new file mode 100644 index 00000000000..4ab35312760 --- /dev/null +++ b/crypto/chacha20poly1305/poly1305_donna.c @@ -0,0 +1,208 @@ +#include "poly1305_donna.h" +#include "poly1305_donna_32.h" + +void poly1305_update(poly1305_context* ctx, const unsigned char* m, size_t bytes) { + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + size_t i = 0; + + /* handle leftover */ + if(st->leftover) { + size_t want = (poly1305_block_size - st->leftover); + if(want > bytes) want = bytes; + for(i = 0; i < want; i++) st->buffer[st->leftover + i] = m[i]; + bytes -= want; + m += want; + st->leftover += want; + if(st->leftover < poly1305_block_size) return; + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if(bytes >= poly1305_block_size) { + size_t want = (bytes & ~(poly1305_block_size - 1)); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if(bytes) { + for(i = 0; i < bytes; i++) st->buffer[st->leftover + i] = m[i]; + st->leftover += bytes; + } +} + +void poly1305_auth( + unsigned char mac[16], + const unsigned char* m, + size_t bytes, + const unsigned char key[32]) { + poly1305_context ctx = {0}; + poly1305_init(&ctx, key); + poly1305_update(&ctx, m, bytes); + poly1305_finish(&ctx, mac); +} + +int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]) { + size_t i = 0; + unsigned int dif = 0; + for(i = 0; i < 16; i++) dif |= (mac1[i] ^ mac2[i]); + dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1); + return (dif & 1); +} + +/* test a few basic operations */ +int poly1305_power_on_self_test(void) { + /* example from nacl */ + static const unsigned char nacl_key[32] = { + 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, 0x6d, 0x11, 0xc2, + 0xcb, 0x21, 0x4d, 0x3c, 0x25, 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, + 0x4e, 0x65, 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80, + }; + + static const unsigned char nacl_msg[131] = { + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, + 0xce, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, + 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11, 0xec, + 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, + 0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, + 0x45, 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, + 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, 0x56, + 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5}; + + static const unsigned char nacl_mac[16] = { + 0xf3, + 0xff, + 0xc7, + 0x70, + 0x3f, + 0x94, + 0x00, + 0xe5, + 0x2a, + 0x7d, + 0xfb, + 0x4b, + 0x3d, + 0x33, + 0x05, + 0xd9}; + + /* generates a final value of (2^130 - 2) == 3 */ + static const unsigned char wrap_key[32] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const unsigned char wrap_msg[16] = { + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff}; + + static const unsigned char wrap_mac[16] = { + 0x03, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + }; + + /* + mac of the macs of messages of length 0 to 256, where the key and messages + have all their values set to the length + */ + static const unsigned char total_key[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + static const unsigned char total_mac[16] = { + 0x64, + 0xaf, + 0xe2, + 0xe8, + 0xd6, + 0xad, + 0x7b, + 0xbd, + 0xd2, + 0x87, + 0xf9, + 0x7c, + 0x44, + 0x62, + 0x3d, + 0x39}; + + poly1305_context ctx = {0}; + poly1305_context total_ctx = {0}; + unsigned char all_key[32] = {0}; + unsigned char all_msg[256] = {0}; + unsigned char mac[16] = {0}; + size_t i = 0, j = 0; + int result = 1; + + for(i = 0; i < sizeof(mac); i++) mac[i] = 0; + poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key); + result &= poly1305_verify(nacl_mac, mac); + + for(i = 0; i < sizeof(mac); i++) mac[i] = 0; + poly1305_init(&ctx, nacl_key); + poly1305_update(&ctx, nacl_msg + 0, 32); + poly1305_update(&ctx, nacl_msg + 32, 64); + poly1305_update(&ctx, nacl_msg + 96, 16); + poly1305_update(&ctx, nacl_msg + 112, 8); + poly1305_update(&ctx, nacl_msg + 120, 4); + poly1305_update(&ctx, nacl_msg + 124, 2); + poly1305_update(&ctx, nacl_msg + 126, 1); + poly1305_update(&ctx, nacl_msg + 127, 1); + poly1305_update(&ctx, nacl_msg + 128, 1); + poly1305_update(&ctx, nacl_msg + 129, 1); + poly1305_update(&ctx, nacl_msg + 130, 1); + poly1305_finish(&ctx, mac); + result &= poly1305_verify(nacl_mac, mac); + + for(i = 0; i < sizeof(mac); i++) mac[i] = 0; + poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key); + result &= poly1305_verify(wrap_mac, mac); + + poly1305_init(&total_ctx, total_key); + for(i = 0; i < 256; i++) { + /* set key and message to 'i,i,i..' */ + for(j = 0; j < sizeof(all_key); j++) all_key[j] = i; + for(j = 0; j < i; j++) all_msg[j] = i; + poly1305_auth(mac, all_msg, i, all_key); + poly1305_update(&total_ctx, mac, 16); + } + poly1305_finish(&total_ctx, mac); + result &= poly1305_verify(total_mac, mac); + + return result; +} diff --git a/crypto/chacha20poly1305/poly1305_donna.h b/crypto/chacha20poly1305/poly1305_donna.h new file mode 100644 index 00000000000..108dee1f6d5 --- /dev/null +++ b/crypto/chacha20poly1305/poly1305_donna.h @@ -0,0 +1,23 @@ +#ifndef POLY1305_DONNA_H +#define POLY1305_DONNA_H + +#include + +typedef struct poly1305_context { + size_t aligner; + unsigned char opaque[136]; +} poly1305_context; + +void poly1305_init(poly1305_context* ctx, const unsigned char key[32]); +void poly1305_update(poly1305_context* ctx, const unsigned char* m, size_t bytes); +void poly1305_finish(poly1305_context* ctx, unsigned char mac[16]); +void poly1305_auth( + unsigned char mac[16], + const unsigned char* m, + size_t bytes, + const unsigned char key[32]); + +int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]); +int poly1305_power_on_self_test(void); + +#endif /* POLY1305_DONNA_H */ diff --git a/crypto/chacha20poly1305/poly1305_donna_32.h b/crypto/chacha20poly1305/poly1305_donna_32.h new file mode 100644 index 00000000000..c2289bb988d --- /dev/null +++ b/crypto/chacha20poly1305/poly1305_donna_32.h @@ -0,0 +1,252 @@ +/* + poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition +*/ + +#if defined(_MSC_VER) +#define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) +#define POLY1305_NOINLINE __attribute__((noinline)) +#else +#define POLY1305_NOINLINE +#endif + +#define poly1305_block_size 16 + +/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + size_t leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ +static unsigned long U8TO32(const unsigned char* p) { + return ( + ((unsigned long)(p[0] & 0xff)) | ((unsigned long)(p[1] & 0xff) << 8) | + ((unsigned long)(p[2] & 0xff) << 16) | ((unsigned long)(p[3] & 0xff) << 24)); +} + +/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ +static void U32TO8(unsigned char* p, unsigned long v) { + p[0] = (v)&0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; +} + +void poly1305_init(poly1305_context* ctx, const unsigned char key[32]) { + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + st->r[0] = (U8TO32(&key[0])) & 0x3ffffff; + st->r[1] = (U8TO32(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (U8TO32(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (U8TO32(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = U8TO32(&key[16]); + st->pad[1] = U8TO32(&key[20]); + st->pad[2] = U8TO32(&key[24]); + st->pad[3] = U8TO32(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void poly1305_blocks(poly1305_state_internal_t* st, const unsigned char* m, size_t bytes) { + const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while(bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (U8TO32(m + 0)) & 0x3ffffff; + h1 += (U8TO32(m + 3) >> 2) & 0x3ffffff; + h2 += (U8TO32(m + 6) >> 4) & 0x3ffffff; + h3 += (U8TO32(m + 9) >> 6) & 0x3ffffff; + h4 += (U8TO32(m + 12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + + ((unsigned long long)h4 * s1); + d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + + ((unsigned long long)h4 * s2); + d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + + ((unsigned long long)h4 * s3); + d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + + ((unsigned long long)h4 * s4); + d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + + ((unsigned long long)h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long)(d0 >> 26); + h0 = (unsigned long)d0 & 0x3ffffff; + d1 += c; + c = (unsigned long)(d1 >> 26); + h1 = (unsigned long)d1 & 0x3ffffff; + d2 += c; + c = (unsigned long)(d2 >> 26); + h2 = (unsigned long)d2 & 0x3ffffff; + d3 += c; + c = (unsigned long)(d3 >> 26); + h3 = (unsigned long)d3 & 0x3ffffff; + d4 += c; + c = (unsigned long)(d4 >> 26); + h4 = (unsigned long)d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +POLY1305_NOINLINE void poly1305_finish(poly1305_context* ctx, unsigned char mac[16]) { + poly1305_state_internal_t* st = (poly1305_state_internal_t*)ctx; + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if(st->leftover) { + size_t i = st->leftover; + st->buffer[i++] = 1; + for(; i < poly1305_block_size; i++) st->buffer[i] = 0; + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long)h0 + st->pad[0]; + h0 = (unsigned long)f; + f = (unsigned long long)h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long)f; + f = (unsigned long long)h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long)f; + f = (unsigned long long)h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long)f; + + U32TO8(mac + 0, h0); + U32TO8(mac + 4, h1); + U32TO8(mac + 8, h2); + U32TO8(mac + 12, h3); + + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; +} diff --git a/crypto/chacha20poly1305/rfc7539.c b/crypto/chacha20poly1305/rfc7539.c index 94e5f0b2336..f26026fbc57 100644 --- a/crypto/chacha20poly1305/rfc7539.c +++ b/crypto/chacha20poly1305/rfc7539.c @@ -3,11 +3,11 @@ #include #include "rfc7539.h" -#include "ecrypt-portable.h" +#include "ecrypt_portable.h" // Initialize the ChaCha20 + Poly1305 context for encryption or decryption // using a 32 byte key and 12 byte nonce as in the RFC 7539 style. -void rfc7539_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_t nonce[12]) { +void rfc7539_init(chacha20poly1305_ctx* ctx, const uint8_t key[32], const uint8_t nonce[12]) { unsigned char block0[64] = {0}; ECRYPT_keysetup(&ctx->chacha20, key, 256, 16); @@ -25,23 +25,21 @@ void rfc7539_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_ // Include authenticated data in the Poly1305 MAC using the RFC 7539 // style with 16 byte padding. This must only be called once and prior // to encryption or decryption. -void rfc7539_auth(chacha20poly1305_ctx *ctx, const uint8_t *in, size_t n) { +void rfc7539_auth(chacha20poly1305_ctx* ctx, const uint8_t* in, size_t n) { uint8_t padding[16] = {0}; poly1305_update(&ctx->poly1305, in, n); - if (n % 16 != 0) - poly1305_update(&ctx->poly1305, padding, 16 - n%16); + if(n % 16 != 0) poly1305_update(&ctx->poly1305, padding, 16 - n % 16); } // Compute RFC 7539-style Poly1305 MAC. -void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16]) { +void rfc7539_finish(chacha20poly1305_ctx* ctx, int64_t alen, int64_t plen, uint8_t mac[16]) { uint8_t padding[16] = {0}; uint8_t lengths[16] = {0}; memcpy(lengths, &alen, sizeof(int64_t)); memcpy(lengths + 8, &plen, sizeof(int64_t)); - if (plen % 16 != 0) - poly1305_update(&ctx->poly1305, padding, 16 - plen%16); + if(plen % 16 != 0) poly1305_update(&ctx->poly1305, padding, 16 - plen % 16); poly1305_update(&ctx->poly1305, lengths, 16); poly1305_finish(&ctx->poly1305, mac); diff --git a/crypto/chacha20poly1305/rfc7539.h b/crypto/chacha20poly1305/rfc7539.h index 75e3d1d7ee2..262dc433bba 100644 --- a/crypto/chacha20poly1305/rfc7539.h +++ b/crypto/chacha20poly1305/rfc7539.h @@ -3,8 +3,8 @@ #include "chacha20poly1305.h" -void rfc7539_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_t nonce[12]); -void rfc7539_auth(chacha20poly1305_ctx *ctx, const uint8_t *in, size_t n); -void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16]); +void rfc7539_init(chacha20poly1305_ctx* ctx, const uint8_t key[32], const uint8_t nonce[12]); +void rfc7539_auth(chacha20poly1305_ctx* ctx, const uint8_t* in, size_t n); +void rfc7539_finish(chacha20poly1305_ctx* ctx, int64_t alen, int64_t plen, uint8_t mac[16]); #endif // RFC7539_H diff --git a/crypto/chacha_drbg.c b/crypto/chacha_drbg.c index 663b1a355cb..fe9b5fd405f 100644 --- a/crypto/chacha_drbg.c +++ b/crypto/chacha_drbg.c @@ -23,7 +23,7 @@ #include #include -#include "chacha20poly1305/ecrypt-portable.h" +#include "chacha20poly1305/ecrypt_portable.h" #include "memzero.h" #include "sha2.h" @@ -31,96 +31,101 @@ #define CHACHA_DRBG_COUNTER_LENGTH 8 #define CHACHA_DRBG_IV_LENGTH 8 #define CHACHA_DRBG_SEED_LENGTH \ - (CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH + CHACHA_DRBG_IV_LENGTH) + (CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH + CHACHA_DRBG_IV_LENGTH) #define MAX(a, b) (a) > (b) ? (a) : (b) -static void derivation_function(const uint8_t *input1, size_t input1_length, - const uint8_t *input2, size_t input2_length, - uint8_t *output, size_t output_length) { - // Implementation of Hash_df from NIST SP 800-90A - uint32_t block_count = (output_length - 1) / SHA256_DIGEST_LENGTH + 1; - size_t partial_block_length = output_length % SHA256_DIGEST_LENGTH; - assert(block_count <= 255); - - uint32_t output_length_bits = output_length * 8; +static void derivation_function( + const uint8_t* input1, + size_t input1_length, + const uint8_t* input2, + size_t input2_length, + uint8_t* output, + size_t output_length) { + // Implementation of Hash_df from NIST SP 800-90A + uint32_t block_count = (output_length - 1) / SHA256_DIGEST_LENGTH + 1; + size_t partial_block_length = output_length % SHA256_DIGEST_LENGTH; + assert(block_count <= 255); + + uint32_t output_length_bits = output_length * 8; #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(output_length_bits, output_length_bits); + REVERSE32(output_length_bits, output_length_bits); #endif - SHA256_CTX ctx = {0}; - - for (uint8_t counter = 1; counter <= block_count; counter++) { - sha256_Init(&ctx); - sha256_Update(&ctx, &counter, sizeof(counter)); - sha256_Update(&ctx, (uint8_t *)&output_length_bits, - sizeof(output_length_bits)); - sha256_Update(&ctx, input1, input1_length); - sha256_Update(&ctx, input2, input2_length); - - if (counter != block_count || partial_block_length == 0) { - sha256_Final(&ctx, output); - output += SHA256_DIGEST_LENGTH; - } else { // last block is partial - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - sha256_Final(&ctx, digest); - memcpy(output, digest, partial_block_length); - memzero(digest, sizeof(digest)); + SHA256_CTX ctx = {0}; + + for(uint8_t counter = 1; counter <= block_count; counter++) { + sha256_Init(&ctx); + sha256_Update(&ctx, &counter, sizeof(counter)); + sha256_Update(&ctx, (uint8_t*)&output_length_bits, sizeof(output_length_bits)); + sha256_Update(&ctx, input1, input1_length); + sha256_Update(&ctx, input2, input2_length); + + if(counter != block_count || partial_block_length == 0) { + sha256_Final(&ctx, output); + output += SHA256_DIGEST_LENGTH; + } else { // last block is partial + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + sha256_Final(&ctx, digest); + memcpy(output, digest, partial_block_length); + memzero(digest, sizeof(digest)); + } } - } - memzero(&ctx, sizeof(ctx)); + memzero(&ctx, sizeof(ctx)); } -void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *nonce, - size_t nonce_length) { - uint8_t buffer[MAX(CHACHA_DRBG_KEY_LENGTH, CHACHA_DRBG_IV_LENGTH)] = {0}; - ECRYPT_keysetup(&ctx->chacha_ctx, buffer, CHACHA_DRBG_KEY_LENGTH * 8, - CHACHA_DRBG_IV_LENGTH * 8); - ECRYPT_ivsetup(&ctx->chacha_ctx, buffer); - - chacha_drbg_reseed(ctx, entropy, entropy_length, nonce, nonce_length); +void chacha_drbg_init( + CHACHA_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t entropy_length, + const uint8_t* nonce, + size_t nonce_length) { + uint8_t buffer[MAX(CHACHA_DRBG_KEY_LENGTH, CHACHA_DRBG_IV_LENGTH)] = {0}; + ECRYPT_keysetup( + &ctx->chacha_ctx, buffer, CHACHA_DRBG_KEY_LENGTH * 8, CHACHA_DRBG_IV_LENGTH * 8); + ECRYPT_ivsetup(&ctx->chacha_ctx, buffer); + + chacha_drbg_reseed(ctx, entropy, entropy_length, nonce, nonce_length); } -static void chacha_drbg_update(CHACHA_DRBG_CTX *ctx, - const uint8_t data[CHACHA_DRBG_SEED_LENGTH]) { - uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; +static void chacha_drbg_update(CHACHA_DRBG_CTX* ctx, const uint8_t data[CHACHA_DRBG_SEED_LENGTH]) { + uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; - if (data) - ECRYPT_encrypt_bytes(&ctx->chacha_ctx, data, seed, CHACHA_DRBG_SEED_LENGTH); - else - ECRYPT_keystream_bytes(&ctx->chacha_ctx, seed, CHACHA_DRBG_SEED_LENGTH); + if(data) + ECRYPT_encrypt_bytes(&ctx->chacha_ctx, data, seed, CHACHA_DRBG_SEED_LENGTH); + else + ECRYPT_keystream_bytes(&ctx->chacha_ctx, seed, CHACHA_DRBG_SEED_LENGTH); - ECRYPT_keysetup(&ctx->chacha_ctx, seed, CHACHA_DRBG_KEY_LENGTH * 8, - CHACHA_DRBG_IV_LENGTH * 8); + ECRYPT_keysetup(&ctx->chacha_ctx, seed, CHACHA_DRBG_KEY_LENGTH * 8, CHACHA_DRBG_IV_LENGTH * 8); - ECRYPT_ivsetup(&ctx->chacha_ctx, - seed + CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH); + ECRYPT_ivsetup(&ctx->chacha_ctx, seed + CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH); - ECRYPT_ctrsetup(&ctx->chacha_ctx, seed + CHACHA_DRBG_KEY_LENGTH); + ECRYPT_ctrsetup(&ctx->chacha_ctx, seed + CHACHA_DRBG_KEY_LENGTH); - memzero(seed, sizeof(seed)); + memzero(seed, sizeof(seed)); } -void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, - size_t output_length) { - assert(output_length < 65536); - assert(ctx->reseed_counter + 1 != 0); +void chacha_drbg_generate(CHACHA_DRBG_CTX* ctx, uint8_t* output, size_t output_length) { + assert(output_length < 65536); + assert(ctx->reseed_counter + 1 != 0); - ECRYPT_keystream_bytes(&ctx->chacha_ctx, output, output_length); - chacha_drbg_update(ctx, NULL); - ctx->reseed_counter++; + ECRYPT_keystream_bytes(&ctx->chacha_ctx, output, output_length); + chacha_drbg_update(ctx, NULL); + ctx->reseed_counter++; } -void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *additional_input, - size_t additional_input_length) { - uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; - derivation_function(entropy, entropy_length, additional_input, - additional_input_length, seed, sizeof(seed)); - chacha_drbg_update(ctx, seed); - memzero(seed, sizeof(seed)); - - ctx->reseed_counter = 1; +void chacha_drbg_reseed( + CHACHA_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t entropy_length, + const uint8_t* additional_input, + size_t additional_input_length) { + uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; + derivation_function( + entropy, entropy_length, additional_input, additional_input_length, seed, sizeof(seed)); + chacha_drbg_update(ctx, seed); + memzero(seed, sizeof(seed)); + + ctx->reseed_counter = 1; } diff --git a/crypto/chacha_drbg.h b/crypto/chacha_drbg.h index 83e2d0b421d..740c11c6ccf 100644 --- a/crypto/chacha_drbg.h +++ b/crypto/chacha_drbg.h @@ -33,22 +33,27 @@ // block_count blocks of hash function in derivation_function. There is no need // the input to have this length, it's just an optimalization. #define CHACHA_DRBG_OPTIMAL_RESEED_LENGTH(block_count) \ - ((block_count)*SHA256_BLOCK_LENGTH - 1 - 4 - 9) + ((block_count)*SHA256_BLOCK_LENGTH - 1 - 4 - 9) // 1 = sizeof(counter), 4 = sizeof(output_length) in // derivation_function, 9 is length of SHA256 padding of message // aligned to bytes typedef struct _CHACHA_DRBG_CTX { - ECRYPT_ctx chacha_ctx; - uint32_t reseed_counter; + ECRYPT_ctx chacha_ctx; + uint32_t reseed_counter; } CHACHA_DRBG_CTX; -void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *nonce, - size_t nonce_length); -void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, - size_t output_length); -void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *additional_input, - size_t additional_input_length); -#endif // __CHACHA_DRBG__ +void chacha_drbg_init( + CHACHA_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t entropy_length, + const uint8_t* nonce, + size_t nonce_length); +void chacha_drbg_generate(CHACHA_DRBG_CTX* ctx, uint8_t* output, size_t output_length); +void chacha_drbg_reseed( + CHACHA_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t entropy_length, + const uint8_t* additional_input, + size_t additional_input_length); +#endif // __CHACHA_DRBG__ diff --git a/crypto/check_mem.h b/crypto/check_mem.h index be8a43cd629..ef8f8c79a5a 100644 --- a/crypto/check_mem.h +++ b/crypto/check_mem.h @@ -3,25 +3,29 @@ #if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION < 11 -#define _ck_assert_mem(X, Y, L, OP) do { \ - const char* _ck_x = (const char*)(void*)(X); \ - const char* _ck_y = (const char*)(void*)(Y); \ - size_t _ck_l = (L); \ - char _ck_x_str[129]; \ - char _ck_y_str[129]; \ - static char _ck_hexdigits[] = "0123456789abcdef"; \ - size_t _ck_i; \ - for (_ck_i = 0; _ck_i < ((_ck_l > 64) ? 64 : _ck_l); _ck_i++) { \ - _ck_x_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_x[_ck_i] >> 4) & 0xF]; \ - _ck_y_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_y[_ck_i] >> 4) & 0xF]; \ - _ck_x_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_x[_ck_i] & 0xF]; \ - _ck_y_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_y[_ck_i] & 0xF]; \ - } \ - _ck_x_str[_ck_i * 2] = 0; \ - _ck_y_str[_ck_i * 2] = 0; \ - ck_assert_msg(0 OP memcmp(_ck_y, _ck_x, _ck_l), \ - "Assertion '"#X#OP#Y"' failed: "#X"==\"%s\", "#Y"==\"%s\"", _ck_x_str, _ck_y_str); \ -} while (0) +#define _ck_assert_mem(X, Y, L, OP) \ + do { \ + const char* _ck_x = (const char*)(void*)(X); \ + const char* _ck_y = (const char*)(void*)(Y); \ + size_t _ck_l = (L); \ + char _ck_x_str[129]; \ + char _ck_y_str[129]; \ + static char _ck_hexdigits[] = "0123456789abcdef"; \ + size_t _ck_i; \ + for(_ck_i = 0; _ck_i < ((_ck_l > 64) ? 64 : _ck_l); _ck_i++) { \ + _ck_x_str[_ck_i * 2] = _ck_hexdigits[(_ck_x[_ck_i] >> 4) & 0xF]; \ + _ck_y_str[_ck_i * 2] = _ck_hexdigits[(_ck_y[_ck_i] >> 4) & 0xF]; \ + _ck_x_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_x[_ck_i] & 0xF]; \ + _ck_y_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_y[_ck_i] & 0xF]; \ + } \ + _ck_x_str[_ck_i * 2] = 0; \ + _ck_y_str[_ck_i * 2] = 0; \ + ck_assert_msg( \ + 0 OP memcmp(_ck_y, _ck_x, _ck_l), \ + "Assertion '" #X #OP #Y "' failed: " #X "==\"%s\", " #Y "==\"%s\"", \ + _ck_x_str, \ + _ck_y_str); \ + } while(0) #define ck_assert_mem_eq(X, Y, L) _ck_assert_mem(X, Y, L, ==) #define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, Y, L, !=) diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c index f9ff33faf3a..80ab76b493b 100644 --- a/crypto/ecdsa.c +++ b/crypto/ecdsa.c @@ -38,199 +38,197 @@ #include "secp256k1.h" // Set cp2 = cp1 -void point_copy(const curve_point *cp1, curve_point *cp2) { *cp2 = *cp1; } +void point_copy(const curve_point* cp1, curve_point* cp2) { + *cp2 = *cp1; +} // cp2 = cp1 + cp2 -void point_add(const ecdsa_curve *curve, const curve_point *cp1, - curve_point *cp2) { - bignum256 lambda = {0}, inv = {0}, xr = {0}, yr = {0}; - - if (point_is_infinity(cp1)) { - return; - } - if (point_is_infinity(cp2)) { - point_copy(cp1, cp2); - return; - } - if (point_is_equal(cp1, cp2)) { - point_double(curve, cp2); - return; - } - if (point_is_negative_of(cp1, cp2)) { - point_set_infinity(cp2); - return; - } - - // lambda = (y2 - y1) / (x2 - x1) - bn_subtractmod(&(cp2->x), &(cp1->x), &inv, &curve->prime); - bn_inverse(&inv, &curve->prime); - bn_subtractmod(&(cp2->y), &(cp1->y), &lambda, &curve->prime); - bn_multiply(&inv, &lambda, &curve->prime); - - // xr = lambda^2 - x1 - x2 - xr = lambda; - bn_multiply(&xr, &xr, &curve->prime); - yr = cp1->x; - bn_addmod(&yr, &(cp2->x), &curve->prime); - bn_subtractmod(&xr, &yr, &xr, &curve->prime); - bn_fast_mod(&xr, &curve->prime); - bn_mod(&xr, &curve->prime); - - // yr = lambda (x1 - xr) - y1 - bn_subtractmod(&(cp1->x), &xr, &yr, &curve->prime); - bn_multiply(&lambda, &yr, &curve->prime); - bn_subtractmod(&yr, &(cp1->y), &yr, &curve->prime); - bn_fast_mod(&yr, &curve->prime); - bn_mod(&yr, &curve->prime); - - cp2->x = xr; - cp2->y = yr; +void point_add(const ecdsa_curve* curve, const curve_point* cp1, curve_point* cp2) { + bignum256 lambda = {0}, inv = {0}, xr = {0}, yr = {0}; + + if(point_is_infinity(cp1)) { + return; + } + if(point_is_infinity(cp2)) { + point_copy(cp1, cp2); + return; + } + if(point_is_equal(cp1, cp2)) { + point_double(curve, cp2); + return; + } + if(point_is_negative_of(cp1, cp2)) { + point_set_infinity(cp2); + return; + } + + // lambda = (y2 - y1) / (x2 - x1) + bn_subtractmod(&(cp2->x), &(cp1->x), &inv, &curve->prime); + bn_inverse(&inv, &curve->prime); + bn_subtractmod(&(cp2->y), &(cp1->y), &lambda, &curve->prime); + bn_multiply(&inv, &lambda, &curve->prime); + + // xr = lambda^2 - x1 - x2 + xr = lambda; + bn_multiply(&xr, &xr, &curve->prime); + yr = cp1->x; + bn_addmod(&yr, &(cp2->x), &curve->prime); + bn_subtractmod(&xr, &yr, &xr, &curve->prime); + bn_fast_mod(&xr, &curve->prime); + bn_mod(&xr, &curve->prime); + + // yr = lambda (x1 - xr) - y1 + bn_subtractmod(&(cp1->x), &xr, &yr, &curve->prime); + bn_multiply(&lambda, &yr, &curve->prime); + bn_subtractmod(&yr, &(cp1->y), &yr, &curve->prime); + bn_fast_mod(&yr, &curve->prime); + bn_mod(&yr, &curve->prime); + + cp2->x = xr; + cp2->y = yr; } // cp = cp + cp -void point_double(const ecdsa_curve *curve, curve_point *cp) { - bignum256 lambda = {0}, xr = {0}, yr = {0}; - - if (point_is_infinity(cp)) { - return; - } - if (bn_is_zero(&(cp->y))) { - point_set_infinity(cp); - return; - } - - // lambda = (3 x^2 + a) / (2 y) - lambda = cp->y; - bn_mult_k(&lambda, 2, &curve->prime); - bn_fast_mod(&lambda, &curve->prime); - bn_mod(&lambda, &curve->prime); - bn_inverse(&lambda, &curve->prime); - - xr = cp->x; - bn_multiply(&xr, &xr, &curve->prime); - bn_mult_k(&xr, 3, &curve->prime); - bn_subi(&xr, -curve->a, &curve->prime); - bn_multiply(&xr, &lambda, &curve->prime); - - // xr = lambda^2 - 2*x - xr = lambda; - bn_multiply(&xr, &xr, &curve->prime); - yr = cp->x; - bn_lshift(&yr); - bn_subtractmod(&xr, &yr, &xr, &curve->prime); - bn_fast_mod(&xr, &curve->prime); - bn_mod(&xr, &curve->prime); - - // yr = lambda (x - xr) - y - bn_subtractmod(&(cp->x), &xr, &yr, &curve->prime); - bn_multiply(&lambda, &yr, &curve->prime); - bn_subtractmod(&yr, &(cp->y), &yr, &curve->prime); - bn_fast_mod(&yr, &curve->prime); - bn_mod(&yr, &curve->prime); - - cp->x = xr; - cp->y = yr; +void point_double(const ecdsa_curve* curve, curve_point* cp) { + bignum256 lambda = {0}, xr = {0}, yr = {0}; + + if(point_is_infinity(cp)) { + return; + } + if(bn_is_zero(&(cp->y))) { + point_set_infinity(cp); + return; + } + + // lambda = (3 x^2 + a) / (2 y) + lambda = cp->y; + bn_mult_k(&lambda, 2, &curve->prime); + bn_fast_mod(&lambda, &curve->prime); + bn_mod(&lambda, &curve->prime); + bn_inverse(&lambda, &curve->prime); + + xr = cp->x; + bn_multiply(&xr, &xr, &curve->prime); + bn_mult_k(&xr, 3, &curve->prime); + bn_subi(&xr, -curve->a, &curve->prime); + bn_multiply(&xr, &lambda, &curve->prime); + + // xr = lambda^2 - 2*x + xr = lambda; + bn_multiply(&xr, &xr, &curve->prime); + yr = cp->x; + bn_lshift(&yr); + bn_subtractmod(&xr, &yr, &xr, &curve->prime); + bn_fast_mod(&xr, &curve->prime); + bn_mod(&xr, &curve->prime); + + // yr = lambda (x - xr) - y + bn_subtractmod(&(cp->x), &xr, &yr, &curve->prime); + bn_multiply(&lambda, &yr, &curve->prime); + bn_subtractmod(&yr, &(cp->y), &yr, &curve->prime); + bn_fast_mod(&yr, &curve->prime); + bn_mod(&yr, &curve->prime); + + cp->x = xr; + cp->y = yr; } // set point to internal representation of point at infinity -void point_set_infinity(curve_point *p) { - bn_zero(&(p->x)); - bn_zero(&(p->y)); +void point_set_infinity(curve_point* p) { + bn_zero(&(p->x)); + bn_zero(&(p->y)); } // return true iff p represent point at infinity // both coords are zero in internal representation -int point_is_infinity(const curve_point *p) { - return bn_is_zero(&(p->x)) && bn_is_zero(&(p->y)); +int point_is_infinity(const curve_point* p) { + return bn_is_zero(&(p->x)) && bn_is_zero(&(p->y)); } // return true iff both points are equal -int point_is_equal(const curve_point *p, const curve_point *q) { - return bn_is_equal(&(p->x), &(q->x)) && bn_is_equal(&(p->y), &(q->y)); +int point_is_equal(const curve_point* p, const curve_point* q) { + return bn_is_equal(&(p->x), &(q->x)) && bn_is_equal(&(p->y), &(q->y)); } // returns true iff p == -q // expects p and q be valid points on curve other than point at infinity -int point_is_negative_of(const curve_point *p, const curve_point *q) { - // if P == (x, y), then -P would be (x, -y) on this curve - if (!bn_is_equal(&(p->x), &(q->x))) { - return 0; - } +int point_is_negative_of(const curve_point* p, const curve_point* q) { + // if P == (x, y), then -P would be (x, -y) on this curve + if(!bn_is_equal(&(p->x), &(q->x))) { + return 0; + } - // we shouldn't hit this for a valid point - if (bn_is_zero(&(p->y))) { - return 0; - } + // we shouldn't hit this for a valid point + if(bn_is_zero(&(p->y))) { + return 0; + } - return !bn_is_equal(&(p->y), &(q->y)); + return !bn_is_equal(&(p->y), &(q->y)); } typedef struct jacobian_curve_point { - bignum256 x, y, z; + bignum256 x, y, z; } jacobian_curve_point; // generate random K for signing/side-channel noise -static void generate_k_random(bignum256 *k, const bignum256 *prime) { - do { - int i = 0; - for (i = 0; i < 8; i++) { - k->val[i] = random32() & ((1u << BN_BITS_PER_LIMB) - 1); - } - k->val[8] = random32() & ((1u << BN_BITS_LAST_LIMB) - 1); - // check that k is in range and not zero. - } while (bn_is_zero(k) || !bn_is_less(k, prime)); +static void generate_k_random(bignum256* k, const bignum256* prime) { + do { + int i = 0; + for(i = 0; i < 8; i++) { + k->val[i] = random32() & ((1u << BN_BITS_PER_LIMB) - 1); + } + k->val[8] = random32() & ((1u << BN_BITS_LAST_LIMB) - 1); + // check that k is in range and not zero. + } while(bn_is_zero(k) || !bn_is_less(k, prime)); } -void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp, - const bignum256 *prime) { - // randomize z coordinate - generate_k_random(&jp->z, prime); +void curve_to_jacobian(const curve_point* p, jacobian_curve_point* jp, const bignum256* prime) { + // randomize z coordinate + generate_k_random(&jp->z, prime); - jp->x = jp->z; - bn_multiply(&jp->z, &jp->x, prime); - // x = z^2 - jp->y = jp->x; - bn_multiply(&jp->z, &jp->y, prime); - // y = z^3 + jp->x = jp->z; + bn_multiply(&jp->z, &jp->x, prime); + // x = z^2 + jp->y = jp->x; + bn_multiply(&jp->z, &jp->y, prime); + // y = z^3 - bn_multiply(&p->x, &jp->x, prime); - bn_multiply(&p->y, &jp->y, prime); + bn_multiply(&p->x, &jp->x, prime); + bn_multiply(&p->y, &jp->y, prime); } -void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p, - const bignum256 *prime) { - p->y = jp->z; - bn_inverse(&p->y, prime); - // p->y = z^-1 - p->x = p->y; - bn_multiply(&p->x, &p->x, prime); - // p->x = z^-2 - bn_multiply(&p->x, &p->y, prime); - // p->y = z^-3 - bn_multiply(&jp->x, &p->x, prime); - // p->x = jp->x * z^-2 - bn_multiply(&jp->y, &p->y, prime); - // p->y = jp->y * z^-3 - bn_mod(&p->x, prime); - bn_mod(&p->y, prime); +void jacobian_to_curve(const jacobian_curve_point* jp, curve_point* p, const bignum256* prime) { + p->y = jp->z; + bn_inverse(&p->y, prime); + // p->y = z^-1 + p->x = p->y; + bn_multiply(&p->x, &p->x, prime); + // p->x = z^-2 + bn_multiply(&p->x, &p->y, prime); + // p->y = z^-3 + bn_multiply(&jp->x, &p->x, prime); + // p->x = jp->x * z^-2 + bn_multiply(&jp->y, &p->y, prime); + // p->y = jp->y * z^-3 + bn_mod(&p->x, prime); + bn_mod(&p->y, prime); } -void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, - const ecdsa_curve *curve) { - bignum256 r = {0}, h = {0}, r2 = {0}; - bignum256 hcby = {0}, hsqx = {0}; - bignum256 xz = {0}, yz = {0}, az = {0}; - int is_doubling = 0; - const bignum256 *prime = &curve->prime; - int a = curve->a; +void point_jacobian_add(const curve_point* p1, jacobian_curve_point* p2, const ecdsa_curve* curve) { + bignum256 r = {0}, h = {0}, r2 = {0}; + bignum256 hcby = {0}, hsqx = {0}; + bignum256 xz = {0}, yz = {0}, az = {0}; + int is_doubling = 0; + const bignum256* prime = &curve->prime; + int a = curve->a; - assert(-3 <= a && a <= 0); + assert(-3 <= a && a <= 0); - /* First we bring p1 to the same denominator: + /* First we bring p1 to the same denominator: * x1' := x1 * z2^2 * y1' := y1 * z2^3 */ - /* + /* * lambda = ((y1' - y2)/z2^3) / ((x1' - x2)/z2^2) * = (y1' - y2) / (x1' - x2) z2 * x3/z3^2 = lambda^2 - (x1' + x2)/z2^2 @@ -251,95 +249,95 @@ void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, * and y3 = 1/2 r * (2x3 - h^2*(x1' + x2)) + h^3*(y1' + y2) */ - /* h = x1 - x2 + /* h = x1 - x2 * r = y1 - y2 * x3 = r^2 - h^3 - 2*h^2*x2 * y3 = r*(h^2*x2 - x3) - h^3*y2 * z3 = h*z2 */ - xz = p2->z; - bn_multiply(&xz, &xz, prime); // xz = z2^2 - yz = p2->z; - bn_multiply(&xz, &yz, prime); // yz = z2^3 - - if (a != 0) { - az = xz; - bn_multiply(&az, &az, prime); // az = z2^4 - bn_mult_k(&az, -a, prime); // az = -az2^4 - } - - bn_multiply(&p1->x, &xz, prime); // xz = x1' = x1*z2^2; - h = xz; - bn_subtractmod(&h, &p2->x, &h, prime); - bn_fast_mod(&h, prime); - // h = x1' - x2; - - bn_add(&xz, &p2->x); - // xz = x1' + x2 - - // check for h == 0 % prime. Note that h never normalizes to - // zero, since h = x1' + 2*prime - x2 > 0 and a positive - // multiple of prime is always normalized to prime by - // bn_fast_mod. - is_doubling = bn_is_equal(&h, prime); - - bn_multiply(&p1->y, &yz, prime); // yz = y1' = y1*z2^3; - bn_subtractmod(&yz, &p2->y, &r, prime); - // r = y1' - y2; - - bn_add(&yz, &p2->y); - // yz = y1' + y2 - - r2 = p2->x; - bn_multiply(&r2, &r2, prime); - bn_mult_k(&r2, 3, prime); - - if (a != 0) { - // subtract -a z2^4, i.e, add a z2^4 - bn_subtractmod(&r2, &az, &r2, prime); - } - bn_cmov(&r, is_doubling, &r2, &r); - bn_cmov(&h, is_doubling, &yz, &h); - - // hsqx = h^2 - hsqx = h; - bn_multiply(&hsqx, &hsqx, prime); - - // hcby = h^3 - hcby = h; - bn_multiply(&hsqx, &hcby, prime); - - // hsqx = h^2 * (x1 + x2) - bn_multiply(&xz, &hsqx, prime); - - // hcby = h^3 * (y1 + y2) - bn_multiply(&yz, &hcby, prime); - - // z3 = h*z2 - bn_multiply(&h, &p2->z, prime); - - // x3 = r^2 - h^2 (x1 + x2) - p2->x = r; - bn_multiply(&p2->x, &p2->x, prime); - bn_subtractmod(&p2->x, &hsqx, &p2->x, prime); - bn_fast_mod(&p2->x, prime); - - // y3 = 1/2 (r*(h^2 (x1 + x2) - 2x3) - h^3 (y1 + y2)) - bn_subtractmod(&hsqx, &p2->x, &p2->y, prime); - bn_subtractmod(&p2->y, &p2->x, &p2->y, prime); - bn_multiply(&r, &p2->y, prime); - bn_subtractmod(&p2->y, &hcby, &p2->y, prime); - bn_mult_half(&p2->y, prime); - bn_fast_mod(&p2->y, prime); + xz = p2->z; + bn_multiply(&xz, &xz, prime); // xz = z2^2 + yz = p2->z; + bn_multiply(&xz, &yz, prime); // yz = z2^3 + + if(a != 0) { + az = xz; + bn_multiply(&az, &az, prime); // az = z2^4 + bn_mult_k(&az, -a, prime); // az = -az2^4 + } + + bn_multiply(&p1->x, &xz, prime); // xz = x1' = x1*z2^2; + h = xz; + bn_subtractmod(&h, &p2->x, &h, prime); + bn_fast_mod(&h, prime); + // h = x1' - x2; + + bn_add(&xz, &p2->x); + // xz = x1' + x2 + + // check for h == 0 % prime. Note that h never normalizes to + // zero, since h = x1' + 2*prime - x2 > 0 and a positive + // multiple of prime is always normalized to prime by + // bn_fast_mod. + is_doubling = bn_is_equal(&h, prime); + + bn_multiply(&p1->y, &yz, prime); // yz = y1' = y1*z2^3; + bn_subtractmod(&yz, &p2->y, &r, prime); + // r = y1' - y2; + + bn_add(&yz, &p2->y); + // yz = y1' + y2 + + r2 = p2->x; + bn_multiply(&r2, &r2, prime); + bn_mult_k(&r2, 3, prime); + + if(a != 0) { + // subtract -a z2^4, i.e, add a z2^4 + bn_subtractmod(&r2, &az, &r2, prime); + } + bn_cmov(&r, is_doubling, &r2, &r); + bn_cmov(&h, is_doubling, &yz, &h); + + // hsqx = h^2 + hsqx = h; + bn_multiply(&hsqx, &hsqx, prime); + + // hcby = h^3 + hcby = h; + bn_multiply(&hsqx, &hcby, prime); + + // hsqx = h^2 * (x1 + x2) + bn_multiply(&xz, &hsqx, prime); + + // hcby = h^3 * (y1 + y2) + bn_multiply(&yz, &hcby, prime); + + // z3 = h*z2 + bn_multiply(&h, &p2->z, prime); + + // x3 = r^2 - h^2 (x1 + x2) + p2->x = r; + bn_multiply(&p2->x, &p2->x, prime); + bn_subtractmod(&p2->x, &hsqx, &p2->x, prime); + bn_fast_mod(&p2->x, prime); + + // y3 = 1/2 (r*(h^2 (x1 + x2) - 2x3) - h^3 (y1 + y2)) + bn_subtractmod(&hsqx, &p2->x, &p2->y, prime); + bn_subtractmod(&p2->y, &p2->x, &p2->y, prime); + bn_multiply(&r, &p2->y, prime); + bn_subtractmod(&p2->y, &hcby, &p2->y, prime); + bn_mult_half(&p2->y, prime); + bn_fast_mod(&p2->y, prime); } -void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) { - bignum256 az4 = {0}, m = {0}, msq = {0}, ysq = {0}, xysq = {0}; - const bignum256 *prime = &curve->prime; +void point_jacobian_double(jacobian_curve_point* p, const ecdsa_curve* curve) { + bignum256 az4 = {0}, m = {0}, msq = {0}, ysq = {0}, xysq = {0}; + const bignum256* prime = &curve->prime; - assert(-3 <= curve->a && curve->a <= 0); - /* usual algorithm: + assert(-3 <= curve->a && curve->a <= 0); + /* usual algorithm: * * lambda = (3((x/z^2)^2 + a) / 2y/z^3) = (3x^2 + az^4)/2yz * x3/z3^2 = lambda^2 - 2x/z^2 @@ -357,176 +355,179 @@ void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) { * = m * (xy^2 - x3) - y^4 */ - /* m = (3*x^2 + a z^4) / 2 + /* m = (3*x^2 + a z^4) / 2 * x3 = m^2 - 2*xy^2 * y3 = m*(xy^2 - x3) - 8y^4 * z3 = y*z */ - m = p->x; - bn_multiply(&m, &m, prime); - bn_mult_k(&m, 3, prime); - - az4 = p->z; - bn_multiply(&az4, &az4, prime); - bn_multiply(&az4, &az4, prime); - bn_mult_k(&az4, -curve->a, prime); - bn_subtractmod(&m, &az4, &m, prime); - bn_mult_half(&m, prime); - - // msq = m^2 - msq = m; - bn_multiply(&msq, &msq, prime); - // ysq = y^2 - ysq = p->y; - bn_multiply(&ysq, &ysq, prime); - // xysq = xy^2 - xysq = p->x; - bn_multiply(&ysq, &xysq, prime); - - // z3 = yz - bn_multiply(&p->y, &p->z, prime); - - // x3 = m^2 - 2*xy^2 - p->x = xysq; - bn_lshift(&p->x); - bn_fast_mod(&p->x, prime); - bn_subtractmod(&msq, &p->x, &p->x, prime); - bn_fast_mod(&p->x, prime); - - // y3 = m*(xy^2 - x3) - y^4 - bn_subtractmod(&xysq, &p->x, &p->y, prime); - bn_multiply(&m, &p->y, prime); - bn_multiply(&ysq, &ysq, prime); - bn_subtractmod(&p->y, &ysq, &p->y, prime); - bn_fast_mod(&p->y, prime); + m = p->x; + bn_multiply(&m, &m, prime); + bn_mult_k(&m, 3, prime); + + az4 = p->z; + bn_multiply(&az4, &az4, prime); + bn_multiply(&az4, &az4, prime); + bn_mult_k(&az4, -curve->a, prime); + bn_subtractmod(&m, &az4, &m, prime); + bn_mult_half(&m, prime); + + // msq = m^2 + msq = m; + bn_multiply(&msq, &msq, prime); + // ysq = y^2 + ysq = p->y; + bn_multiply(&ysq, &ysq, prime); + // xysq = xy^2 + xysq = p->x; + bn_multiply(&ysq, &xysq, prime); + + // z3 = yz + bn_multiply(&p->y, &p->z, prime); + + // x3 = m^2 - 2*xy^2 + p->x = xysq; + bn_lshift(&p->x); + bn_fast_mod(&p->x, prime); + bn_subtractmod(&msq, &p->x, &p->x, prime); + bn_fast_mod(&p->x, prime); + + // y3 = m*(xy^2 - x3) - y^4 + bn_subtractmod(&xysq, &p->x, &p->y, prime); + bn_multiply(&m, &p->y, prime); + bn_multiply(&ysq, &ysq, prime); + bn_subtractmod(&p->y, &ysq, &p->y, prime); + bn_fast_mod(&p->y, prime); } // res = k * p // returns 0 on success -int point_multiply(const ecdsa_curve *curve, const bignum256 *k, - const curve_point *p, curve_point *res) { - // this algorithm is loosely based on - // Katsuyuki Okeya and Tsuyoshi Takagi, The Width-w NAF Method Provides - // Small Memory and Fast Elliptic Scalar Multiplications Secure against - // Side Channel Attacks. - if (!bn_is_less(k, &curve->order)) { - return 1; - } - - int i = 0, j = 0; - static CONFIDENTIAL bignum256 a; - uint32_t *aptr = NULL; - uint32_t abits = 0; - int ashift = 0; - uint32_t is_even = (k->val[0] & 1) - 1; - uint32_t bits = {0}, sign = {0}, nsign = {0}; - static CONFIDENTIAL jacobian_curve_point jres; - curve_point pmult[8] = {0}; - const bignum256 *prime = &curve->prime; - - // is_even = 0xffffffff if k is even, 0 otherwise. - - // add 2^256. - // make number odd: subtract curve->order if even - uint32_t tmp = 1; - uint32_t is_non_zero = 0; - for (j = 0; j < 8; j++) { +int point_multiply( + const ecdsa_curve* curve, + const bignum256* k, + const curve_point* p, + curve_point* res) { + // this algorithm is loosely based on + // Katsuyuki Okeya and Tsuyoshi Takagi, The Width-w NAF Method Provides + // Small Memory and Fast Elliptic Scalar Multiplications Secure against + // Side Channel Attacks. + if(!bn_is_less(k, &curve->order)) { + return 1; + } + + int i = 0, j = 0; + static CONFIDENTIAL bignum256 a; + uint32_t* aptr = NULL; + uint32_t abits = 0; + int ashift = 0; + uint32_t is_even = (k->val[0] & 1) - 1; + uint32_t bits = {0}, sign = {0}, nsign = {0}; + static CONFIDENTIAL jacobian_curve_point jres; + curve_point pmult[8] = {0}; + const bignum256* prime = &curve->prime; + + // is_even = 0xffffffff if k is even, 0 otherwise. + + // add 2^256. + // make number odd: subtract curve->order if even + uint32_t tmp = 1; + uint32_t is_non_zero = 0; + for(j = 0; j < 8; j++) { + is_non_zero |= k->val[j]; + tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); + a.val[j] = tmp & (BN_BASE - 1); + tmp >>= BN_BITS_PER_LIMB; + } is_non_zero |= k->val[j]; - tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); - a.val[j] = tmp & (BN_BASE - 1); - tmp >>= BN_BITS_PER_LIMB; - } - is_non_zero |= k->val[j]; - a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); - assert((a.val[0] & 1) != 0); - - // special case 0*p: just return zero. We don't care about constant time. - if (!is_non_zero) { - point_set_infinity(res); - return 1; - } - - // Now a = k + 2^256 (mod curve->order) and a is odd. - // - // The idea is to bring the new a into the form. - // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. - // a[0] is odd, since a is odd. If a[i] would be even, we can - // add 1 to it and subtract 16 from a[i-1]. Afterwards, - // a[64] = 1, which is the 2^256 that we added before. - // - // Since k = a - 2^256 (mod curve->order), we can compute - // k*p = sum_{i=0..63} a[i] 16^i * p - // - // We compute |a[i]| * p in advance for all possible - // values of |a[i]| * p. pmult[i] = (2*i+1) * p - // We compute p, 3*p, ..., 15*p and store it in the table pmult. - // store p^2 temporarily in pmult[7] - pmult[7] = *p; - point_double(curve, &pmult[7]); - // compute 3*p, etc by repeatedly adding p^2. - pmult[0] = *p; - for (i = 1; i < 8; i++) { - pmult[i] = pmult[7]; - point_add(curve, &pmult[i - 1], &pmult[i]); - } - - // now compute res = sum_{i=0..63} a[i] * 16^i * p step by step, - // starting with i = 63. - // initialize jres = |a[63]| * p. - // Note that a[i] = a>>(4*i) & 0xf if (a&0x10) != 0 - // and - (16 - (a>>(4*i) & 0xf)) otherwise. We can compute this as - // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 - // since a is odd. - aptr = &a.val[8]; - abits = *aptr; - ashift = 256 - (BN_BITS_PER_LIMB * 8) - 4; - bits = abits >> ashift; - sign = (bits >> 4) - 1; - bits ^= sign; - bits &= 15; - curve_to_jacobian(&pmult[bits >> 1], &jres, prime); - for (i = 62; i >= 0; i--) { - // sign = sign(a[i+1]) (0xffffffff for negative, 0 for positive) - // invariant jres = (-1)^sign sum_{j=i+1..63} (a[j] * 16^{j-i-1} * p) - // abits >> (ashift - 4) = lowbits(a >> (i*4)) - - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - - // get lowest 5 bits of a >> (i*4). - ashift -= 4; - if (ashift < 0) { - // the condition only depends on the iteration number and - // leaks no private information to a side-channel. - bits = abits << (-ashift); - abits = *(--aptr); - ashift += BN_BITS_PER_LIMB; - bits |= abits >> ashift; - } else { - bits = abits >> ashift; + a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); + assert((a.val[0] & 1) != 0); + + // special case 0*p: just return zero. We don't care about constant time. + if(!is_non_zero) { + point_set_infinity(res); + return 1; } - bits &= 31; - nsign = (bits >> 4) - 1; - bits ^= nsign; - bits &= 15; - // negate last result to make signs of this round and the - // last round equal. - bn_cnegate((sign ^ nsign) & 1, &jres.z, prime); + // Now a = k + 2^256 (mod curve->order) and a is odd. + // + // The idea is to bring the new a into the form. + // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. + // a[0] is odd, since a is odd. If a[i] would be even, we can + // add 1 to it and subtract 16 from a[i-1]. Afterwards, + // a[64] = 1, which is the 2^256 that we added before. + // + // Since k = a - 2^256 (mod curve->order), we can compute + // k*p = sum_{i=0..63} a[i] 16^i * p + // + // We compute |a[i]| * p in advance for all possible + // values of |a[i]| * p. pmult[i] = (2*i+1) * p + // We compute p, 3*p, ..., 15*p and store it in the table pmult. + // store p^2 temporarily in pmult[7] + pmult[7] = *p; + point_double(curve, &pmult[7]); + // compute 3*p, etc by repeatedly adding p^2. + pmult[0] = *p; + for(i = 1; i < 8; i++) { + pmult[i] = pmult[7]; + point_add(curve, &pmult[i - 1], &pmult[i]); + } - // add odd factor - point_jacobian_add(&pmult[bits >> 1], &jres, curve); - sign = nsign; - } - bn_cnegate(sign & 1, &jres.z, prime); - jacobian_to_curve(&jres, res, prime); - memzero(&a, sizeof(a)); - memzero(&jres, sizeof(jres)); + // now compute res = sum_{i=0..63} a[i] * 16^i * p step by step, + // starting with i = 63. + // initialize jres = |a[63]| * p. + // Note that a[i] = a>>(4*i) & 0xf if (a&0x10) != 0 + // and - (16 - (a>>(4*i) & 0xf)) otherwise. We can compute this as + // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 + // since a is odd. + aptr = &a.val[8]; + abits = *aptr; + ashift = 256 - (BN_BITS_PER_LIMB * 8) - 4; + bits = abits >> ashift; + sign = (bits >> 4) - 1; + bits ^= sign; + bits &= 15; + curve_to_jacobian(&pmult[bits >> 1], &jres, prime); + for(i = 62; i >= 0; i--) { + // sign = sign(a[i+1]) (0xffffffff for negative, 0 for positive) + // invariant jres = (-1)^sign sum_{j=i+1..63} (a[j] * 16^{j-i-1} * p) + // abits >> (ashift - 4) = lowbits(a >> (i*4)) + + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + point_jacobian_double(&jres, curve); + + // get lowest 5 bits of a >> (i*4). + ashift -= 4; + if(ashift < 0) { + // the condition only depends on the iteration number and + // leaks no private information to a side-channel. + bits = abits << (-ashift); + abits = *(--aptr); + ashift += BN_BITS_PER_LIMB; + bits |= abits >> ashift; + } else { + bits = abits >> ashift; + } + bits &= 31; + nsign = (bits >> 4) - 1; + bits ^= nsign; + bits &= 15; + + // negate last result to make signs of this round and the + // last round equal. + bn_cnegate((sign ^ nsign) & 1, &jres.z, prime); + + // add odd factor + point_jacobian_add(&pmult[bits >> 1], &jres, curve); + sign = nsign; + } + bn_cnegate(sign & 1, &jres.z, prime); + jacobian_to_curve(&jres, res, prime); + memzero(&a, sizeof(a)); + memzero(&jres, sizeof(jres)); - return 0; + return 0; } #if USE_PRECOMPUTED_CP @@ -534,140 +535,145 @@ int point_multiply(const ecdsa_curve *curve, const bignum256 *k, // res = k * G // k must be a normalized number with 0 <= k < curve->order // returns 0 on success -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res) { - if (!bn_is_less(k, &curve->order)) { - return 1; - } - - int i = {0}, j = {0}; - static CONFIDENTIAL bignum256 a; - uint32_t is_even = (k->val[0] & 1) - 1; - uint32_t lowbits = 0; - static CONFIDENTIAL jacobian_curve_point jres; - const bignum256 *prime = &curve->prime; - - // is_even = 0xffffffff if k is even, 0 otherwise. - - // add 2^256. - // make number odd: subtract curve->order if even - uint32_t tmp = 1; - uint32_t is_non_zero = 0; - for (j = 0; j < 8; j++) { +int scalar_multiply(const ecdsa_curve* curve, const bignum256* k, curve_point* res) { + if(!bn_is_less(k, &curve->order)) { + return 1; + } + + int i = {0}, j = {0}; + static CONFIDENTIAL bignum256 a; + uint32_t is_even = (k->val[0] & 1) - 1; + uint32_t lowbits = 0; + static CONFIDENTIAL jacobian_curve_point jres; + const bignum256* prime = &curve->prime; + + // is_even = 0xffffffff if k is even, 0 otherwise. + + // add 2^256. + // make number odd: subtract curve->order if even + uint32_t tmp = 1; + uint32_t is_non_zero = 0; + for(j = 0; j < 8; j++) { + is_non_zero |= k->val[j]; + tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); + a.val[j] = tmp & (BN_BASE - 1); + tmp >>= BN_BITS_PER_LIMB; + } is_non_zero |= k->val[j]; - tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); - a.val[j] = tmp & (BN_BASE - 1); - tmp >>= BN_BITS_PER_LIMB; - } - is_non_zero |= k->val[j]; - a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); - assert((a.val[0] & 1) != 0); - - // special case 0*G: just return zero. We don't care about constant time. - if (!is_non_zero) { - point_set_infinity(res); - return 0; - } - - // Now a = k + 2^256 (mod curve->order) and a is odd. - // - // The idea is to bring the new a into the form. - // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. - // a[0] is odd, since a is odd. If a[i] would be even, we can - // add 1 to it and subtract 16 from a[i-1]. Afterwards, - // a[64] = 1, which is the 2^256 that we added before. - // - // Since k = a - 2^256 (mod curve->order), we can compute - // k*G = sum_{i=0..63} a[i] 16^i * G - // - // We have a big table curve->cp that stores all possible - // values of |a[i]| 16^i * G. - // curve->cp[i][j] = (2*j+1) * 16^i * G - - // now compute res = sum_{i=0..63} a[i] * 16^i * G step by step. - // initial res = |a[0]| * G. Note that a[0] = a & 0xf if (a&0x10) != 0 - // and - (16 - (a & 0xf)) otherwise. We can compute this as - // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 - // since a is odd. - lowbits = a.val[0] & ((1 << 5) - 1); - lowbits ^= (lowbits >> 4) - 1; - lowbits &= 15; - curve_to_jacobian(&curve->cp[0][lowbits >> 1], &jres, prime); - for (i = 1; i < 64; i++) { - // invariant res = sign(a[i-1]) sum_{j=0..i-1} (a[j] * 16^j * G) - - // shift a by 4 places. - for (j = 0; j < 8; j++) { - a.val[j] = - (a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << (BN_BITS_PER_LIMB - 4)); + a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); + assert((a.val[0] & 1) != 0); + + // special case 0*G: just return zero. We don't care about constant time. + if(!is_non_zero) { + point_set_infinity(res); + return 0; } - a.val[j] >>= 4; - // a = old(a)>>(4*i) - // a is even iff sign(a[i-1]) = -1 + // Now a = k + 2^256 (mod curve->order) and a is odd. + // + // The idea is to bring the new a into the form. + // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. + // a[0] is odd, since a is odd. If a[i] would be even, we can + // add 1 to it and subtract 16 from a[i-1]. Afterwards, + // a[64] = 1, which is the 2^256 that we added before. + // + // Since k = a - 2^256 (mod curve->order), we can compute + // k*G = sum_{i=0..63} a[i] 16^i * G + // + // We have a big table curve->cp that stores all possible + // values of |a[i]| 16^i * G. + // curve->cp[i][j] = (2*j+1) * 16^i * G + + // now compute res = sum_{i=0..63} a[i] * 16^i * G step by step. + // initial res = |a[0]| * G. Note that a[0] = a & 0xf if (a&0x10) != 0 + // and - (16 - (a & 0xf)) otherwise. We can compute this as + // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 + // since a is odd. lowbits = a.val[0] & ((1 << 5) - 1); lowbits ^= (lowbits >> 4) - 1; lowbits &= 15; - // negate last result to make signs of this round and the - // last round equal. - bn_cnegate(~lowbits & 1, &jres.y, prime); - - // add odd factor - point_jacobian_add(&curve->cp[i][lowbits >> 1], &jres, curve); - } - bn_cnegate(~(a.val[0] >> 4) & 1, &jres.y, prime); - jacobian_to_curve(&jres, res, prime); - memzero(&a, sizeof(a)); - memzero(&jres, sizeof(jres)); - - return 0; + curve_to_jacobian(&curve->cp[0][lowbits >> 1], &jres, prime); + for(i = 1; i < 64; i++) { + // invariant res = sign(a[i-1]) sum_{j=0..i-1} (a[j] * 16^j * G) + + // shift a by 4 places. + for(j = 0; j < 8; j++) { + a.val[j] = (a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << (BN_BITS_PER_LIMB - 4)); + } + a.val[j] >>= 4; + // a = old(a)>>(4*i) + // a is even iff sign(a[i-1]) = -1 + + lowbits = a.val[0] & ((1 << 5) - 1); + lowbits ^= (lowbits >> 4) - 1; + lowbits &= 15; + // negate last result to make signs of this round and the + // last round equal. + bn_cnegate(~lowbits & 1, &jres.y, prime); + + // add odd factor + point_jacobian_add(&curve->cp[i][lowbits >> 1], &jres, curve); + } + bn_cnegate(~(a.val[0] >> 4) & 1, &jres.y, prime); + jacobian_to_curve(&jres, res, prime); + memzero(&a, sizeof(a)); + memzero(&jres, sizeof(jres)); + + return 0; } #else -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res) { - return point_multiply(curve, k, &curve->G, res); +int scalar_multiply(const ecdsa_curve* curve, const bignum256* k, curve_point* res) { + return point_multiply(curve, k, &curve->G, res); } #endif -int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *pub_key, uint8_t *session_key) { - curve_point point = {0}; - if (!ecdsa_read_pubkey(curve, pub_key, &point)) { - return 1; - } +int ecdh_multiply( + const ecdsa_curve* curve, + const uint8_t* priv_key, + const uint8_t* pub_key, + uint8_t* session_key) { + curve_point point = {0}; + if(!ecdsa_read_pubkey(curve, pub_key, &point)) { + return 1; + } - bignum256 k = {0}; - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - return 2; - } + bignum256 k = {0}; + bn_read_be(priv_key, &k); + if(bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { + // Invalid private key. + return 2; + } - point_multiply(curve, &k, &point, &point); - memzero(&k, sizeof(k)); + point_multiply(curve, &k, &point, &point); + memzero(&k, sizeof(k)); - session_key[0] = 0x04; - bn_write_be(&point.x, session_key + 1); - bn_write_be(&point.y, session_key + 33); - memzero(&point, sizeof(point)); + session_key[0] = 0x04; + bn_write_be(&point.x, session_key + 1); + bn_write_be(&point.y, session_key + 33); + memzero(&point, sizeof(point)); - return 0; + return 0; } // msg is a data to be signed // msg_len is the message length -int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, - uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])) { - uint8_t hash[32] = {0}; - hasher_Raw(hasher_sign, msg, msg_len, hash); - int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical); - memzero(hash, sizeof(hash)); - return res; +int ecdsa_sign( + const ecdsa_curve* curve, + HasherType hasher_sign, + const uint8_t* priv_key, + const uint8_t* msg, + uint32_t msg_len, + uint8_t* sig, + uint8_t* pby, + int (*is_canonical)(uint8_t by, uint8_t sig[64])) { + uint8_t hash[32] = {0}; + hasher_Raw(hasher_sign, msg, msg_len, hash); + int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical); + memzero(hash, sizeof(hash)); + return res; } // uses secp256k1 curve @@ -676,290 +682,308 @@ int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, // digest is 32 bytes of digest // is_canonical is an optional function that checks if the signature // conforms to additional coin-specific rules. -int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *digest, uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])) { - int i = 0; - curve_point R = {0}; - bignum256 k = {0}, z = {0}, randk = {0}; - bignum256 *s = &R.y; - uint8_t by; // signature recovery byte +int ecdsa_sign_digest( + const ecdsa_curve* curve, + const uint8_t* priv_key, + const uint8_t* digest, + uint8_t* sig, + uint8_t* pby, + int (*is_canonical)(uint8_t by, uint8_t sig[64])) { + int i = 0; + curve_point R = {0}; + bignum256 k = {0}, z = {0}, randk = {0}; + bignum256* s = &R.y; + uint8_t by; // signature recovery byte #if USE_RFC6979 - rfc6979_state rng = {0}; - init_rfc6979(priv_key, digest, curve, &rng); + rfc6979_state rng = {0}; + init_rfc6979(priv_key, digest, curve, &rng); #endif - bn_read_be(digest, &z); - if (bn_is_zero(&z)) { - // The probability of the digest being all-zero by chance is infinitesimal, - // so this is most likely an indication of a bug. Furthermore, the signature - // has no value, because in this case it can be easily forged for any public - // key, see ecdsa_verify_digest(). - return 1; - } + bn_read_be(digest, &z); + if(bn_is_zero(&z)) { + // The probability of the digest being all-zero by chance is infinitesimal, + // so this is most likely an indication of a bug. Furthermore, the signature + // has no value, because in this case it can be easily forged for any public + // key, see ecdsa_verify_digest(). + return 1; + } - for (i = 0; i < 10000; i++) { + for(i = 0; i < 10000; i++) { #if USE_RFC6979 - // generate K deterministically - generate_k_rfc6979(&k, &rng); - // if k is too big or too small, we don't like it - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - continue; - } + // generate K deterministically + generate_k_rfc6979(&k, &rng); + // if k is too big or too small, we don't like it + if(bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { + continue; + } #else - // generate random number k - generate_k_random(&k, &curve->order); + // generate random number k + generate_k_random(&k, &curve->order); #endif - // compute k*G - scalar_multiply(curve, &k, &R); - by = R.y.val[0] & 1; - // r = (rx mod n) - if (!bn_is_less(&R.x, &curve->order)) { - bn_subtract(&R.x, &curve->order, &R.x); - by |= 2; - } - // if r is zero, we retry - if (bn_is_zero(&R.x)) { - continue; - } - - bn_read_be(priv_key, s); - if (bn_is_zero(s) || !bn_is_less(s, &curve->order)) { - // Invalid private key. - return 2; - } - - // randomize operations to counter side-channel attacks - generate_k_random(&randk, &curve->order); - bn_multiply(&randk, &k, &curve->order); // k*rand - bn_inverse(&k, &curve->order); // (k*rand)^-1 - bn_multiply(&R.x, s, &curve->order); // R.x*priv - bn_add(s, &z); // R.x*priv + z - bn_multiply(&k, s, &curve->order); // (k*rand)^-1 (R.x*priv + z) - bn_multiply(&randk, s, &curve->order); // k^-1 (R.x*priv + z) - bn_mod(s, &curve->order); - // if s is zero, we retry - if (bn_is_zero(s)) { - continue; - } - - // if S > order/2 => S = -S - if (bn_is_less(&curve->order_half, s)) { - bn_subtract(&curve->order, s, s); - by ^= 1; - } - // we are done, R.x and s is the result signature - bn_write_be(&R.x, sig); - bn_write_be(s, sig + 32); - - // check if the signature is acceptable or retry - if (is_canonical && !is_canonical(by, sig)) { - continue; - } - - if (pby) { - *pby = by; + // compute k*G + scalar_multiply(curve, &k, &R); + by = R.y.val[0] & 1; + // r = (rx mod n) + if(!bn_is_less(&R.x, &curve->order)) { + bn_subtract(&R.x, &curve->order, &R.x); + by |= 2; + } + // if r is zero, we retry + if(bn_is_zero(&R.x)) { + continue; + } + + bn_read_be(priv_key, s); + if(bn_is_zero(s) || !bn_is_less(s, &curve->order)) { + // Invalid private key. + return 2; + } + + // randomize operations to counter side-channel attacks + generate_k_random(&randk, &curve->order); + bn_multiply(&randk, &k, &curve->order); // k*rand + bn_inverse(&k, &curve->order); // (k*rand)^-1 + bn_multiply(&R.x, s, &curve->order); // R.x*priv + bn_add(s, &z); // R.x*priv + z + bn_multiply(&k, s, &curve->order); // (k*rand)^-1 (R.x*priv + z) + bn_multiply(&randk, s, &curve->order); // k^-1 (R.x*priv + z) + bn_mod(s, &curve->order); + // if s is zero, we retry + if(bn_is_zero(s)) { + continue; + } + + // if S > order/2 => S = -S + if(bn_is_less(&curve->order_half, s)) { + bn_subtract(&curve->order, s, s); + by ^= 1; + } + // we are done, R.x and s is the result signature + bn_write_be(&R.x, sig); + bn_write_be(s, sig + 32); + + // check if the signature is acceptable or retry + if(is_canonical && !is_canonical(by, sig)) { + continue; + } + + if(pby) { + *pby = by; + } + + memzero(&k, sizeof(k)); + memzero(&randk, sizeof(randk)); +#if USE_RFC6979 + memzero(&rng, sizeof(rng)); +#endif + return 0; } + // Too many retries without a valid signature + // -> fail with an error memzero(&k, sizeof(k)); memzero(&randk, sizeof(randk)); #if USE_RFC6979 memzero(&rng, sizeof(rng)); #endif - return 0; - } - - // Too many retries without a valid signature - // -> fail with an error - memzero(&k, sizeof(k)); - memzero(&randk, sizeof(randk)); -#if USE_RFC6979 - memzero(&rng, sizeof(rng)); -#endif - return -1; + return -1; } // returns 0 on success -int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key) { - curve_point R = {0}; - bignum256 k = {0}; - - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - memzero(pub_key, 33); - return -1; - } +int ecdsa_get_public_key33(const ecdsa_curve* curve, const uint8_t* priv_key, uint8_t* pub_key) { + curve_point R = {0}; + bignum256 k = {0}; + + bn_read_be(priv_key, &k); + if(bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { + // Invalid private key. + memzero(pub_key, 33); + return -1; + } - // compute k*G - if (scalar_multiply(curve, &k, &R) != 0) { + // compute k*G + if(scalar_multiply(curve, &k, &R) != 0) { + memzero(&k, sizeof(k)); + return 1; + } + pub_key[0] = 0x02 | (R.y.val[0] & 0x01); + bn_write_be(&R.x, pub_key + 1); + memzero(&R, sizeof(R)); memzero(&k, sizeof(k)); - return 1; - } - pub_key[0] = 0x02 | (R.y.val[0] & 0x01); - bn_write_be(&R.x, pub_key + 1); - memzero(&R, sizeof(R)); - memzero(&k, sizeof(k)); - return 0; + return 0; } // returns 0 on success -int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key) { - curve_point R = {0}; - bignum256 k = {0}; - - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - memzero(pub_key, 65); - return -1; - } +int ecdsa_get_public_key65(const ecdsa_curve* curve, const uint8_t* priv_key, uint8_t* pub_key) { + curve_point R = {0}; + bignum256 k = {0}; + + bn_read_be(priv_key, &k); + if(bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { + // Invalid private key. + memzero(pub_key, 65); + return -1; + } - // compute k*G - if (scalar_multiply(curve, &k, &R) != 0) { + // compute k*G + if(scalar_multiply(curve, &k, &R) != 0) { + memzero(&k, sizeof(k)); + return 1; + } + pub_key[0] = 0x04; + bn_write_be(&R.x, pub_key + 1); + bn_write_be(&R.y, pub_key + 33); + memzero(&R, sizeof(R)); memzero(&k, sizeof(k)); - return 1; - } - pub_key[0] = 0x04; - bn_write_be(&R.x, pub_key + 1); - bn_write_be(&R.y, pub_key + 33); - memzero(&R, sizeof(R)); - memzero(&k, sizeof(k)); - return 0; + return 0; } -int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - uint8_t *uncompressed) { - curve_point pub = {0}; +int ecdsa_uncompress_pubkey( + const ecdsa_curve* curve, + const uint8_t* pub_key, + uint8_t* uncompressed) { + curve_point pub = {0}; - if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { - return 0; - } + if(!ecdsa_read_pubkey(curve, pub_key, &pub)) { + return 0; + } - uncompressed[0] = 4; - bn_write_be(&pub.x, uncompressed + 1); - bn_write_be(&pub.y, uncompressed + 33); + uncompressed[0] = 4; + bn_write_be(&pub.x, uncompressed + 1); + bn_write_be(&pub.y, uncompressed + 33); - return 1; + return 1; } -void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, - uint8_t *pubkeyhash) { - uint8_t h[HASHER_DIGEST_LENGTH] = {0}; - if (pub_key[0] == 0x04) { // uncompressed format - hasher_Raw(hasher_pubkey, pub_key, 65, h); - } else if (pub_key[0] == 0x00) { // point at infinity - hasher_Raw(hasher_pubkey, pub_key, 1, h); - } else { // expecting compressed format - hasher_Raw(hasher_pubkey, pub_key, 33, h); - } - memcpy(pubkeyhash, h, 20); - memzero(h, sizeof(h)); +void ecdsa_get_pubkeyhash(const uint8_t* pub_key, HasherType hasher_pubkey, uint8_t* pubkeyhash) { + uint8_t h[HASHER_DIGEST_LENGTH] = {0}; + if(pub_key[0] == 0x04) { // uncompressed format + hasher_Raw(hasher_pubkey, pub_key, 65, h); + } else if(pub_key[0] == 0x00) { // point at infinity + hasher_Raw(hasher_pubkey, pub_key, 1, h); + } else { // expecting compressed format + hasher_Raw(hasher_pubkey, pub_key, 33, h); + } + memcpy(pubkeyhash, h, 20); + memzero(h, sizeof(h)); } -void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, uint8_t *addr_raw) { - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, addr_raw); - ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, addr_raw + prefix_len); +void ecdsa_get_address_raw( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + uint8_t* addr_raw) { + size_t prefix_len = address_prefix_bytes_len(version); + address_write_prefix_bytes(version, addr_raw); + ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, addr_raw + prefix_len); } -void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, HasherType hasher_base58, - char *addr, int addrsize) { - uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - ecdsa_get_address_raw(pub_key, version, hasher_pubkey, raw); - base58_encode_check(raw, 20 + prefix_len, hasher_base58, addr, addrsize); - // not as important to clear this one, but we might as well - memzero(raw, sizeof(raw)); +void ecdsa_get_address( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + HasherType hasher_base58, + char* addr, + int addrsize) { + uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; + size_t prefix_len = address_prefix_bytes_len(version); + ecdsa_get_address_raw(pub_key, version, hasher_pubkey, raw); + base58_encode_check(raw, 20 + prefix_len, hasher_base58, addr, addrsize); + // not as important to clear this one, but we might as well + memzero(raw, sizeof(raw)); } -void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - uint8_t *addr_raw) { - uint8_t buf[32 + 2] = {0}; - buf[0] = 0; // version byte - buf[1] = 20; // push 20 bytes - ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, buf + 2); - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, addr_raw); - hasher_Raw(hasher_pubkey, buf, 22, addr_raw + prefix_len); +void ecdsa_get_address_segwit_p2sh_raw( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + uint8_t* addr_raw) { + uint8_t buf[32 + 2] = {0}; + buf[0] = 0; // version byte + buf[1] = 20; // push 20 bytes + ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, buf + 2); + size_t prefix_len = address_prefix_bytes_len(version); + address_write_prefix_bytes(version, addr_raw); + hasher_Raw(hasher_pubkey, buf, 22, addr_raw + prefix_len); } -void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize) { - uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - ecdsa_get_address_segwit_p2sh_raw(pub_key, version, hasher_pubkey, raw); - base58_encode_check(raw, prefix_len + 20, hasher_base58, addr, addrsize); - memzero(raw, sizeof(raw)); +void ecdsa_get_address_segwit_p2sh( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + HasherType hasher_base58, + char* addr, + int addrsize) { + uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; + size_t prefix_len = address_prefix_bytes_len(version); + ecdsa_get_address_segwit_p2sh_raw(pub_key, version, hasher_pubkey, raw); + base58_encode_check(raw, prefix_len + 20, hasher_base58, addr, addrsize); + memzero(raw, sizeof(raw)); } -void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, - HasherType hasher_base58, char *wif, int wifsize) { - uint8_t wif_raw[MAX_WIF_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, wif_raw); - memcpy(wif_raw + prefix_len, priv_key, 32); - wif_raw[prefix_len + 32] = 0x01; - base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_base58, wif, - wifsize); - // private keys running around our stack can cause trouble - memzero(wif_raw, sizeof(wif_raw)); +void ecdsa_get_wif( + const uint8_t* priv_key, + uint32_t version, + HasherType hasher_base58, + char* wif, + int wifsize) { + uint8_t wif_raw[MAX_WIF_RAW_SIZE] = {0}; + size_t prefix_len = address_prefix_bytes_len(version); + address_write_prefix_bytes(version, wif_raw); + memcpy(wif_raw + prefix_len, priv_key, 32); + wif_raw[prefix_len + 32] = 0x01; + base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_base58, wif, wifsize); + // private keys running around our stack can cause trouble + memzero(wif_raw, sizeof(wif_raw)); } -int ecdsa_address_decode(const char *addr, uint32_t version, - HasherType hasher_base58, uint8_t *out) { - if (!addr) return 0; - int prefix_len = address_prefix_bytes_len(version); - return base58_decode_check(addr, hasher_base58, out, 20 + prefix_len) == - 20 + prefix_len && - address_check_prefix(out, version); +int ecdsa_address_decode( + const char* addr, + uint32_t version, + HasherType hasher_base58, + uint8_t* out) { + if(!addr) return 0; + int prefix_len = address_prefix_bytes_len(version); + return base58_decode_check(addr, hasher_base58, out, 20 + prefix_len) == 20 + prefix_len && + address_check_prefix(out, version); } -void compress_coords(const curve_point *cp, uint8_t *compressed) { - compressed[0] = bn_is_odd(&cp->y) ? 0x03 : 0x02; - bn_write_be(&cp->x, compressed + 1); +void compress_coords(const curve_point* cp, uint8_t* compressed) { + compressed[0] = bn_is_odd(&cp->y) ? 0x03 : 0x02; + bn_write_be(&cp->x, compressed + 1); } -void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, - const bignum256 *x, bignum256 *y) { - // y^2 = x^3 + a*x + b - memcpy(y, x, sizeof(bignum256)); // y is x - bn_multiply(x, y, &curve->prime); // y is x^2 - bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a - bn_multiply(x, y, &curve->prime); // y is x^3 + ax - bn_add(y, &curve->b); // y is x^3 + ax + b - bn_sqrt(y, &curve->prime); // y = sqrt(y) - if ((odd & 0x01) != (y->val[0] & 1)) { - bn_subtract(&curve->prime, y, y); // y = -y - } +void uncompress_coords(const ecdsa_curve* curve, uint8_t odd, const bignum256* x, bignum256* y) { + // y^2 = x^3 + a*x + b + memcpy(y, x, sizeof(bignum256)); // y is x + bn_multiply(x, y, &curve->prime); // y is x^2 + bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a + bn_multiply(x, y, &curve->prime); // y is x^3 + ax + bn_add(y, &curve->b); // y is x^3 + ax + b + bn_sqrt(y, &curve->prime); // y = sqrt(y) + if((odd & 0x01) != (y->val[0] & 1)) { + bn_subtract(&curve->prime, y, y); // y = -y + } } -int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - curve_point *pub) { - if (!curve) { - curve = &secp256k1; - } - if (pub_key[0] == 0x04) { - bn_read_be(pub_key + 1, &(pub->x)); - bn_read_be(pub_key + 33, &(pub->y)); - return ecdsa_validate_pubkey(curve, pub); - } - if (pub_key[0] == 0x02 || pub_key[0] == 0x03) { // compute missing y coords - bn_read_be(pub_key + 1, &(pub->x)); - uncompress_coords(curve, pub_key[0], &(pub->x), &(pub->y)); - return ecdsa_validate_pubkey(curve, pub); - } - // error - return 0; +int ecdsa_read_pubkey(const ecdsa_curve* curve, const uint8_t* pub_key, curve_point* pub) { + if(!curve) { + curve = &secp256k1; + } + if(pub_key[0] == 0x04) { + bn_read_be(pub_key + 1, &(pub->x)); + bn_read_be(pub_key + 33, &(pub->y)); + return ecdsa_validate_pubkey(curve, pub); + } + if(pub_key[0] == 0x02 || pub_key[0] == 0x03) { // compute missing y coords + bn_read_be(pub_key + 1, &(pub->x)); + uncompress_coords(curve, pub_key[0], &(pub->x), &(pub->y)); + return ecdsa_validate_pubkey(curve, pub); + } + // error + return 0; } // Verifies that: @@ -968,37 +992,36 @@ int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, // - pub is on the curve. // We assume that all curves using this code have cofactor 1, so there is no // need to verify that pub is a scalar multiple of G. -int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub) { - bignum256 y_2 = {0}, x3_ax_b = {0}; +int ecdsa_validate_pubkey(const ecdsa_curve* curve, const curve_point* pub) { + bignum256 y_2 = {0}, x3_ax_b = {0}; - if (point_is_infinity(pub)) { - return 0; - } + if(point_is_infinity(pub)) { + return 0; + } - if (!bn_is_less(&(pub->x), &curve->prime) || - !bn_is_less(&(pub->y), &curve->prime)) { - return 0; - } + if(!bn_is_less(&(pub->x), &curve->prime) || !bn_is_less(&(pub->y), &curve->prime)) { + return 0; + } - memcpy(&y_2, &(pub->y), sizeof(bignum256)); - memcpy(&x3_ax_b, &(pub->x), sizeof(bignum256)); + memcpy(&y_2, &(pub->y), sizeof(bignum256)); + memcpy(&x3_ax_b, &(pub->x), sizeof(bignum256)); - // y^2 - bn_multiply(&(pub->y), &y_2, &curve->prime); - bn_mod(&y_2, &curve->prime); + // y^2 + bn_multiply(&(pub->y), &y_2, &curve->prime); + bn_mod(&y_2, &curve->prime); - // x^3 + ax + b - bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^2 - bn_subi(&x3_ax_b, -curve->a, &curve->prime); // x^2 + a - bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^3 + ax - bn_addmod(&x3_ax_b, &curve->b, &curve->prime); // x^3 + ax + b - bn_mod(&x3_ax_b, &curve->prime); + // x^3 + ax + b + bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^2 + bn_subi(&x3_ax_b, -curve->a, &curve->prime); // x^2 + a + bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^3 + ax + bn_addmod(&x3_ax_b, &curve->b, &curve->prime); // x^3 + ax + b + bn_mod(&x3_ax_b, &curve->prime); - if (!bn_is_equal(&x3_ax_b, &y_2)) { - return 0; - } + if(!bn_is_equal(&x3_ax_b, &y_2)) { + return 0; + } - return 1; + return 1; } // uses secp256k1 curve @@ -1007,245 +1030,255 @@ int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub) { // msg is a data that was signed // msg_len is the message length -int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, - uint32_t msg_len) { - uint8_t hash[32] = {0}; - hasher_Raw(hasher_sign, msg, msg_len, hash); - int res = ecdsa_verify_digest(curve, pub_key, sig, hash); - memzero(hash, sizeof(hash)); - return res; +int ecdsa_verify( + const ecdsa_curve* curve, + HasherType hasher_sign, + const uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* msg, + uint32_t msg_len) { + uint8_t hash[32] = {0}; + hasher_Raw(hasher_sign, msg, msg_len, hash); + int res = ecdsa_verify_digest(curve, pub_key, sig, hash); + memzero(hash, sizeof(hash)); + return res; } // Compute public key from signature and recovery id. // returns 0 if the key is successfully recovered -int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest, - int recid) { - bignum256 r = {0}, s = {0}, e = {0}; - curve_point cp = {0}, cp2 = {0}; - - // read r and s - bn_read_be(sig, &r); - bn_read_be(sig + 32, &s); - if (!bn_is_less(&r, &curve->order) || bn_is_zero(&r)) { - return 1; - } - if (!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { - return 1; - } - // cp = R = k * G (k is secret nonce when signing) - memcpy(&cp.x, &r, sizeof(bignum256)); - if (recid & 2) { - bn_add(&cp.x, &curve->order); - if (!bn_is_less(&cp.x, &curve->prime)) { - return 1; +int ecdsa_recover_pub_from_sig( + const ecdsa_curve* curve, + uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* digest, + int recid) { + bignum256 r = {0}, s = {0}, e = {0}; + curve_point cp = {0}, cp2 = {0}; + + // read r and s + bn_read_be(sig, &r); + bn_read_be(sig + 32, &s); + if(!bn_is_less(&r, &curve->order) || bn_is_zero(&r)) { + return 1; } - } - // compute y from x - uncompress_coords(curve, recid & 1, &cp.x, &cp.y); - if (!ecdsa_validate_pubkey(curve, &cp)) { - return 1; - } - // e = -digest - bn_read_be(digest, &e); - bn_mod(&e, &curve->order); - bn_subtract(&curve->order, &e, &e); - // r = r^-1 - bn_inverse(&r, &curve->order); - // e = -digest * r^-1 - bn_multiply(&r, &e, &curve->order); - bn_mod(&e, &curve->order); - // s = s * r^-1 - bn_multiply(&r, &s, &curve->order); - bn_mod(&s, &curve->order); - // cp = s * r^-1 * k * G - point_multiply(curve, &s, &cp, &cp); - // cp2 = -digest * r^-1 * G - scalar_multiply(curve, &e, &cp2); - // cp = (s * r^-1 * k - digest * r^-1) * G = Pub - point_add(curve, &cp2, &cp); - // The point at infinity is not considered to be a valid public key. - if (point_is_infinity(&cp)) { - return 1; - } - pub_key[0] = 0x04; - bn_write_be(&cp.x, pub_key + 1); - bn_write_be(&cp.y, pub_key + 33); - return 0; + if(!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { + return 1; + } + // cp = R = k * G (k is secret nonce when signing) + memcpy(&cp.x, &r, sizeof(bignum256)); + if(recid & 2) { + bn_add(&cp.x, &curve->order); + if(!bn_is_less(&cp.x, &curve->prime)) { + return 1; + } + } + // compute y from x + uncompress_coords(curve, recid & 1, &cp.x, &cp.y); + if(!ecdsa_validate_pubkey(curve, &cp)) { + return 1; + } + // e = -digest + bn_read_be(digest, &e); + bn_mod(&e, &curve->order); + bn_subtract(&curve->order, &e, &e); + // r = r^-1 + bn_inverse(&r, &curve->order); + // e = -digest * r^-1 + bn_multiply(&r, &e, &curve->order); + bn_mod(&e, &curve->order); + // s = s * r^-1 + bn_multiply(&r, &s, &curve->order); + bn_mod(&s, &curve->order); + // cp = s * r^-1 * k * G + point_multiply(curve, &s, &cp, &cp); + // cp2 = -digest * r^-1 * G + scalar_multiply(curve, &e, &cp2); + // cp = (s * r^-1 * k - digest * r^-1) * G = Pub + point_add(curve, &cp2, &cp); + // The point at infinity is not considered to be a valid public key. + if(point_is_infinity(&cp)) { + return 1; + } + pub_key[0] = 0x04; + bn_write_be(&cp.x, pub_key + 1); + bn_write_be(&cp.y, pub_key + 33); + return 0; } // returns 0 if verification succeeded -int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest) { - curve_point pub = {0}, res = {0}; - bignum256 r = {0}, s = {0}, z = {0}; - int result = 0; - - if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { - result = 1; - } - - if (result == 0) { - bn_read_be(sig, &r); - bn_read_be(sig + 32, &s); - bn_read_be(digest, &z); - if (bn_is_zero(&r) || bn_is_zero(&s) || (!bn_is_less(&r, &curve->order)) || - (!bn_is_less(&s, &curve->order))) { - result = 2; +int ecdsa_verify_digest( + const ecdsa_curve* curve, + const uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* digest) { + curve_point pub = {0}, res = {0}; + bignum256 r = {0}, s = {0}, z = {0}; + int result = 0; + + if(!ecdsa_read_pubkey(curve, pub_key, &pub)) { + result = 1; } - if (bn_is_zero(&z)) { - // The digest was all-zero. The probability of this happening by chance is - // infinitesimal, but it could be induced by a fault injection. In this - // case the signature (r,s) can be forged by taking r := (t * Q).x mod n - // and s := r * t^-1 mod n for any t in [1, n-1]. We fail verification, - // because there is no guarantee that the signature was created by the - // owner of the private key. - result = 3; + + if(result == 0) { + bn_read_be(sig, &r); + bn_read_be(sig + 32, &s); + bn_read_be(digest, &z); + if(bn_is_zero(&r) || bn_is_zero(&s) || (!bn_is_less(&r, &curve->order)) || + (!bn_is_less(&s, &curve->order))) { + result = 2; + } + if(bn_is_zero(&z)) { + // The digest was all-zero. The probability of this happening by chance is + // infinitesimal, but it could be induced by a fault injection. In this + // case the signature (r,s) can be forged by taking r := (t * Q).x mod n + // and s := r * t^-1 mod n for any t in [1, n-1]. We fail verification, + // because there is no guarantee that the signature was created by the + // owner of the private key. + result = 3; + } } - } - if (result == 0) { - bn_inverse(&s, &curve->order); // s = s^-1 - bn_multiply(&s, &z, &curve->order); // z = z * s [u1 = z * s^-1 mod n] - bn_mod(&z, &curve->order); - } + if(result == 0) { + bn_inverse(&s, &curve->order); // s = s^-1 + bn_multiply(&s, &z, &curve->order); // z = z * s [u1 = z * s^-1 mod n] + bn_mod(&z, &curve->order); + } - if (result == 0) { - bn_multiply(&r, &s, &curve->order); // s = r * s [u2 = r * s^-1 mod n] - bn_mod(&s, &curve->order); - scalar_multiply(curve, &z, &res); // res = z * G [= u1 * G] - point_multiply(curve, &s, &pub, &pub); // pub = s * pub [= u2 * Q] - point_add(curve, &pub, &res); // res = pub + res [R = u1 * G + u2 * Q] - if (point_is_infinity(&res)) { - // R == Infinity - result = 4; + if(result == 0) { + bn_multiply(&r, &s, &curve->order); // s = r * s [u2 = r * s^-1 mod n] + bn_mod(&s, &curve->order); + scalar_multiply(curve, &z, &res); // res = z * G [= u1 * G] + point_multiply(curve, &s, &pub, &pub); // pub = s * pub [= u2 * Q] + point_add(curve, &pub, &res); // res = pub + res [R = u1 * G + u2 * Q] + if(point_is_infinity(&res)) { + // R == Infinity + result = 4; + } } - } - - if (result == 0) { - bn_mod(&(res.x), &curve->order); - if (!bn_is_equal(&res.x, &r)) { - // R.x != r - // signature does not match - result = 5; + + if(result == 0) { + bn_mod(&(res.x), &curve->order); + if(!bn_is_equal(&res.x, &r)) { + // R.x != r + // signature does not match + result = 5; + } } - } - memzero(&pub, sizeof(pub)); - memzero(&res, sizeof(res)); - memzero(&r, sizeof(r)); - memzero(&s, sizeof(s)); - memzero(&z, sizeof(z)); + memzero(&pub, sizeof(pub)); + memzero(&res, sizeof(res)); + memzero(&r, sizeof(r)); + memzero(&s, sizeof(s)); + memzero(&z, sizeof(z)); - // all OK - return result; + // all OK + return result; } -int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der) { - int i = 0; - uint8_t *p = der, *len = NULL, *len1 = NULL, *len2 = NULL; - *p = 0x30; - p++; // sequence - *p = 0x00; - len = p; - p++; // len(sequence) - - *p = 0x02; - p++; // integer - *p = 0x00; - len1 = p; - p++; // len(integer) - - // process R - i = 0; - while (i < 31 && sig[i] == 0) { - i++; - } // skip leading zeroes - if (sig[i] >= 0x80) { // put zero in output if MSB set +int ecdsa_sig_to_der(const uint8_t* sig, uint8_t* der) { + int i = 0; + uint8_t *p = der, *len = NULL, *len1 = NULL, *len2 = NULL; + *p = 0x30; + p++; // sequence *p = 0x00; - p++; - *len1 = *len1 + 1; - } - while (i < 32) { // copy bytes to output - *p = sig[i]; - p++; - *len1 = *len1 + 1; - i++; - } - - *p = 0x02; - p++; // integer - *p = 0x00; - len2 = p; - p++; // len(integer) - - // process S - i = 32; - while (i < 63 && sig[i] == 0) { - i++; - } // skip leading zeroes - if (sig[i] >= 0x80) { // put zero in output if MSB set + len = p; + p++; // len(sequence) + + *p = 0x02; + p++; // integer *p = 0x00; - p++; - *len2 = *len2 + 1; - } - while (i < 64) { // copy bytes to output - *p = sig[i]; - p++; - *len2 = *len2 + 1; - i++; - } - - *len = *len1 + *len2 + 4; - return *len + 2; + len1 = p; + p++; // len(integer) + + // process R + i = 0; + while(i < 31 && sig[i] == 0) { + i++; + } // skip leading zeroes + if(sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; + p++; + *len1 = *len1 + 1; + } + while(i < 32) { // copy bytes to output + *p = sig[i]; + p++; + *len1 = *len1 + 1; + i++; + } + + *p = 0x02; + p++; // integer + *p = 0x00; + len2 = p; + p++; // len(integer) + + // process S + i = 32; + while(i < 63 && sig[i] == 0) { + i++; + } // skip leading zeroes + if(sig[i] >= 0x80) { // put zero in output if MSB set + *p = 0x00; + p++; + *len2 = *len2 + 1; + } + while(i < 64) { // copy bytes to output + *p = sig[i]; + p++; + *len2 = *len2 + 1; + i++; + } + + *len = *len1 + *len2 + 4; + return *len + 2; } // Parse a DER-encoded signature. We don't check whether the encoded integers // satisfy DER requirements regarding leading zeros. -int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]) { - memzero(sig, 64); - - // Check sequence header. - if (der_len < 2 || der_len > 72 || der[0] != 0x30 || der[1] != der_len - 2) { - return 1; - } - - // Read two DER-encoded integers. - size_t pos = 2; - for (int i = 0; i < 2; ++i) { - // Check integer header. - if (der_len < pos + 2 || der[pos] != 0x02) { - return 1; - } +int ecdsa_sig_from_der(const uint8_t* der, size_t der_len, uint8_t sig[64]) { + memzero(sig, 64); - // Locate the integer. - size_t int_len = der[pos + 1]; - pos += 2; - if (pos + int_len > der_len) { - return 1; + // Check sequence header. + if(der_len < 2 || der_len > 72 || der[0] != 0x30 || der[1] != der_len - 2) { + return 1; } - // Skip a possible leading zero. - if (int_len != 0 && der[pos] == 0) { - int_len--; - pos++; + // Read two DER-encoded integers. + size_t pos = 2; + for(int i = 0; i < 2; ++i) { + // Check integer header. + if(der_len < pos + 2 || der[pos] != 0x02) { + return 1; + } + + // Locate the integer. + size_t int_len = der[pos + 1]; + pos += 2; + if(pos + int_len > der_len) { + return 1; + } + + // Skip a possible leading zero. + if(int_len != 0 && der[pos] == 0) { + int_len--; + pos++; + } + + // Copy the integer to the output, making sure it fits. + if(int_len > 32) { + return 1; + } + memcpy(sig + 32 * (i + 1) - int_len, der + pos, int_len); + + // Move on to the next one. + pos += int_len; } - // Copy the integer to the output, making sure it fits. - if (int_len > 32) { - return 1; + // Check that there are no trailing elements in the sequence. + if(pos != der_len) { + return 1; } - memcpy(sig + 32 * (i + 1) - int_len, der + pos, int_len); - // Move on to the next one. - pos += int_len; - } - - // Check that there are no trailing elements in the sequence. - if (pos != der_len) { - return 1; - } - - return 0; + return 0; } diff --git a/crypto/ecdsa.h b/crypto/ecdsa.h index 7b951d236e5..26192aa0847 100644 --- a/crypto/ecdsa.h +++ b/crypto/ecdsa.h @@ -31,19 +31,19 @@ // curve point x and y typedef struct { - bignum256 x, y; + bignum256 x, y; } curve_point; typedef struct { - bignum256 prime; // prime order of the finite field - curve_point G; // initial curve point - bignum256 order; // order of G - bignum256 order_half; // order of G divided by 2 - int a; // coefficient 'a' of the elliptic curve - bignum256 b; // coefficient 'b' of the elliptic curve + bignum256 prime; // prime order of the finite field + curve_point G; // initial curve point + bignum256 order; // order of G + bignum256 order_half; // order of G divided by 2 + int a; // coefficient 'a' of the elliptic curve + bignum256 b; // coefficient 'b' of the elliptic curve #if USE_PRECOMPUTED_CP - const curve_point cp[64][8]; + const curve_point cp[64][8]; #endif } ecdsa_curve; @@ -61,68 +61,107 @@ typedef struct { // (4 + 32 + 1 + 4 [checksum]) * 8 / log2(58) plus NUL. #define MAX_WIF_SIZE (57) -void point_copy(const curve_point *cp1, curve_point *cp2); -void point_add(const ecdsa_curve *curve, const curve_point *cp1, - curve_point *cp2); -void point_double(const ecdsa_curve *curve, curve_point *cp); -int point_multiply(const ecdsa_curve *curve, const bignum256 *k, - const curve_point *p, curve_point *res); -void point_set_infinity(curve_point *p); -int point_is_infinity(const curve_point *p); -int point_is_equal(const curve_point *p, const curve_point *q); -int point_is_negative_of(const curve_point *p, const curve_point *q); -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res); -int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *pub_key, uint8_t *session_key); -void compress_coords(const curve_point *cp, uint8_t *compressed); -void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, - const bignum256 *x, bignum256 *y); -int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - uint8_t *uncompressed); +void point_copy(const curve_point* cp1, curve_point* cp2); +void point_add(const ecdsa_curve* curve, const curve_point* cp1, curve_point* cp2); +void point_double(const ecdsa_curve* curve, curve_point* cp); +int point_multiply( + const ecdsa_curve* curve, + const bignum256* k, + const curve_point* p, + curve_point* res); +void point_set_infinity(curve_point* p); +int point_is_infinity(const curve_point* p); +int point_is_equal(const curve_point* p, const curve_point* q); +int point_is_negative_of(const curve_point* p, const curve_point* q); +int scalar_multiply(const ecdsa_curve* curve, const bignum256* k, curve_point* res); +int ecdh_multiply( + const ecdsa_curve* curve, + const uint8_t* priv_key, + const uint8_t* pub_key, + uint8_t* session_key); +void compress_coords(const curve_point* cp, uint8_t* compressed); +void uncompress_coords(const ecdsa_curve* curve, uint8_t odd, const bignum256* x, bignum256* y); +int ecdsa_uncompress_pubkey( + const ecdsa_curve* curve, + const uint8_t* pub_key, + uint8_t* uncompressed); -int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, - uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])); -int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *digest, uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])); -int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key); -int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key); -void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, - uint8_t *pubkeyhash); -void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, uint8_t *addr_raw); -void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, HasherType hasher_base58, - char *addr, int addrsize); -void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - uint8_t *addr_raw); -void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize); -void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, - HasherType hasher_base58, char *wif, int wifsize); +int ecdsa_sign( + const ecdsa_curve* curve, + HasherType hasher_sign, + const uint8_t* priv_key, + const uint8_t* msg, + uint32_t msg_len, + uint8_t* sig, + uint8_t* pby, + int (*is_canonical)(uint8_t by, uint8_t sig[64])); +int ecdsa_sign_digest( + const ecdsa_curve* curve, + const uint8_t* priv_key, + const uint8_t* digest, + uint8_t* sig, + uint8_t* pby, + int (*is_canonical)(uint8_t by, uint8_t sig[64])); +int ecdsa_get_public_key33(const ecdsa_curve* curve, const uint8_t* priv_key, uint8_t* pub_key); +int ecdsa_get_public_key65(const ecdsa_curve* curve, const uint8_t* priv_key, uint8_t* pub_key); +void ecdsa_get_pubkeyhash(const uint8_t* pub_key, HasherType hasher_pubkey, uint8_t* pubkeyhash); +void ecdsa_get_address_raw( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + uint8_t* addr_raw); +void ecdsa_get_address( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + HasherType hasher_base58, + char* addr, + int addrsize); +void ecdsa_get_address_segwit_p2sh_raw( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + uint8_t* addr_raw); +void ecdsa_get_address_segwit_p2sh( + const uint8_t* pub_key, + uint32_t version, + HasherType hasher_pubkey, + HasherType hasher_base58, + char* addr, + int addrsize); +void ecdsa_get_wif( + const uint8_t* priv_key, + uint32_t version, + HasherType hasher_base58, + char* wif, + int wifsize); -int ecdsa_address_decode(const char *addr, uint32_t version, - HasherType hasher_base58, uint8_t *out); -int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - curve_point *pub); -int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub); -int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, - uint32_t msg_len); -int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest); -int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest, - int recid); -int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der); -int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]); +int ecdsa_address_decode( + const char* addr, + uint32_t version, + HasherType hasher_base58, + uint8_t* out); +int ecdsa_read_pubkey(const ecdsa_curve* curve, const uint8_t* pub_key, curve_point* pub); +int ecdsa_validate_pubkey(const ecdsa_curve* curve, const curve_point* pub); +int ecdsa_verify( + const ecdsa_curve* curve, + HasherType hasher_sign, + const uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* msg, + uint32_t msg_len); +int ecdsa_verify_digest( + const ecdsa_curve* curve, + const uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* digest); +int ecdsa_recover_pub_from_sig( + const ecdsa_curve* curve, + uint8_t* pub_key, + const uint8_t* sig, + const uint8_t* digest, + int recid); +int ecdsa_sig_to_der(const uint8_t* sig, uint8_t* der); +int ecdsa_sig_from_der(const uint8_t* der, size_t der_len, uint8_t sig[64]); #endif diff --git a/crypto/ed25519-donna/curve25519-donna-32bit.c b/crypto/ed25519-donna/curve25519-donna-32bit.c deleted file mode 100644 index 5a09710be96..00000000000 --- a/crypto/ed25519-donna/curve25519-donna-32bit.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - 32 bit integer curve25519 implementation -*/ - -#include "ed25519-donna.h" - -static const uint32_t reduce_mask_25 = (1 << 25) - 1; -static const uint32_t reduce_mask_26 = (1 << 26) - 1; - -/* out = in */ -void curve25519_copy(bignum25519 out, const bignum25519 in) { - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; - out[4] = in[4]; - out[5] = in[5]; - out[6] = in[6]; - out[7] = in[7]; - out[8] = in[8]; - out[9] = in[9]; -} - -/* out = a + b */ -void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - out[6] = a[6] + b[6]; - out[7] = a[7] + b[7]; - out[8] = a[8] + b[8]; - out[9] = a[9] + b[9]; -} - -void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* multiples of p */ -static const uint32_t twoP0 = 0x07ffffda; -static const uint32_t twoP13579 = 0x03fffffe; -static const uint32_t twoP2468 = 0x07fffffe; -static const uint32_t fourP0 = 0x0fffffb4; -static const uint32_t fourP13579 = 0x07fffffc; -static const uint32_t fourP2468 = 0x0ffffffc; - -/* out = a - b */ -void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = twoP2468 + a[4] - b[4] + c; - out[5] = twoP13579 + a[5] - b[5] ; - out[6] = twoP2468 + a[6] - b[6] ; - out[7] = twoP13579 + a[7] - b[7] ; - out[8] = twoP2468 + a[8] - b[8] ; - out[9] = twoP13579 + a[9] - b[9] ; -} - -/* out = in * scalar */ -void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) { - uint64_t a = 0; - uint32_t c = 0; - a = mul32x32_64(in[0], scalar); out[0] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[1], scalar) + c; out[1] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[2], scalar) + c; out[2] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[3], scalar) + c; out[3] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[4], scalar) + c; out[4] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[5], scalar) + c; out[5] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[6], scalar) + c; out[6] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[7], scalar) + c; out[7] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[8], scalar) + c; out[8] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[9], scalar) + c; out[9] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - out[0] += c * 19; -} - -/* out = a - b, where a is the result of a basic op (add,sub) */ -void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* out = -a */ -void curve25519_neg(bignum25519 out, const bignum25519 a) { - uint32_t c = 0; - out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* out = a * b */ -#define curve25519_mul_noinline curve25519_mul -void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0, s6 = 0, s7 = 0, s8 = 0, s9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = b[0]; - r1 = b[1]; - r2 = b[2]; - r3 = b[3]; - r4 = b[4]; - r5 = b[5]; - r6 = b[6]; - r7 = b[7]; - r8 = b[8]; - r9 = b[9]; - - s0 = a[0]; - s1 = a[1]; - s2 = a[2]; - s3 = a[3]; - s4 = a[4]; - s5 = a[5]; - s6 = a[6]; - s7 = a[7]; - s8 = a[8]; - s9 = a[9]; - - m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); - m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); - m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); - m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); - m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); - - r1 *= 2; - r3 *= 2; - r5 *= 2; - r7 *= 2; - - m0 = mul32x32_64(r0, s0); - m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); - m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); - m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); - m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); - - r1 *= 19; - r2 *= 19; - r3 = (r3 / 2) * 19; - r4 *= 19; - r5 = (r5 / 2) * 19; - r6 *= 19; - r7 = (r7 / 2) * 19; - r8 *= 19; - r9 *= 19; - - m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); - m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); - m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); - m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); - - r3 *= 2; - r5 *= 2; - r7 *= 2; - r9 *= 2; - - m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); - m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); - m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); - m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); - m8 += (mul32x32_64(r9, s9)); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* out = in * in */ -void curve25519_square(bignum25519 out, const bignum25519 in) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - r5 = in[5]; - r6 = in[6]; - r7 = in[7]; - r8 = in[8]; - r9 = in[9]; - - m0 = mul32x32_64(r0, r0); - r0 *= 2; - m1 = mul32x32_64(r0, r1); - m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); - r1 *= 2; - m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); - m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); - r2 *= 2; - m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); - m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); - r3 *= 2; - m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); - m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); - m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); - - d6 = r6 * 19; - d7 = r7 * 2 * 19; - d8 = r8 * 19; - d9 = r9 * 2 * 19; - - m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); - m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); - m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); - m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); - m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); - m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); - m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); - m7 += (mul32x32_64(d9, r8 )); - m8 += (mul32x32_64(d9, r9 )); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* out = in ^ (2 * count) */ -void curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - r5 = in[5]; - r6 = in[6]; - r7 = in[7]; - r8 = in[8]; - r9 = in[9]; - - do { - m0 = mul32x32_64(r0, r0); - r0 *= 2; - m1 = mul32x32_64(r0, r1); - m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); - r1 *= 2; - m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); - m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); - r2 *= 2; - m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); - m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); - r3 *= 2; - m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); - m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); - m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); - - d6 = r6 * 19; - d7 = r7 * 2 * 19; - d8 = r8 * 19; - d9 = r9 * 2 * 19; - - m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); - m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); - m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); - m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); - m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); - m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); - m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); - m7 += (mul32x32_64(d9, r8 )); - m8 += (mul32x32_64(d9, r9 )); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - } while (--count); - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* Take a little-endian, 32-byte number and expand it into polynomial form */ -void curve25519_expand(bignum25519 out, const unsigned char in[32]) { - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; - #define F(s) \ - ((((uint32_t)in[s + 0]) ) | \ - (((uint32_t)in[s + 1]) << 8) | \ - (((uint32_t)in[s + 2]) << 16) | \ - (((uint32_t)in[s + 3]) << 24)) - x0 = F(0); - x1 = F(4); - x2 = F(8); - x3 = F(12); - x4 = F(16); - x5 = F(20); - x6 = F(24); - x7 = F(28); - #undef F - - out[0] = ( x0 ) & reduce_mask_26; - out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; - out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; - out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; - out[4] = (( x3) >> 6) & reduce_mask_26; - out[5] = ( x4 ) & reduce_mask_25; - out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; - out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; - out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; - out[9] = (( x7) >> 6) & reduce_mask_25; /* ignore the top bit */ -} - -/* Take a fully reduced polynomial form number and contract it into a - * little-endian, 32-byte array - */ -void curve25519_contract(unsigned char out[32], const bignum25519 in) { - bignum25519 f = {0}; - curve25519_copy(f, in); - - #define carry_pass() \ - f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ - f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ - f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ - f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ - f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ - f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ - f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ - f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ - f[9] += f[8] >> 26; f[8] &= reduce_mask_26; - - #define carry_pass_full() \ - carry_pass() \ - f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; - - #define carry_pass_final() \ - carry_pass() \ - f[9] &= reduce_mask_25; - - carry_pass_full() - carry_pass_full() - - /* now t is between 0 and 2^255-1, properly carried. */ - /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ - f[0] += 19; - carry_pass_full() - - /* now between 19 and 2^255-1 in both cases, and offset by 19. */ - f[0] += (reduce_mask_26 + 1) - 19; - f[1] += (reduce_mask_25 + 1) - 1; - f[2] += (reduce_mask_26 + 1) - 1; - f[3] += (reduce_mask_25 + 1) - 1; - f[4] += (reduce_mask_26 + 1) - 1; - f[5] += (reduce_mask_25 + 1) - 1; - f[6] += (reduce_mask_26 + 1) - 1; - f[7] += (reduce_mask_25 + 1) - 1; - f[8] += (reduce_mask_26 + 1) - 1; - f[9] += (reduce_mask_25 + 1) - 1; - - /* now between 2^255 and 2^256-20, and offset by 2^255. */ - carry_pass_final() - - #undef carry_pass - #undef carry_full - #undef carry_final - - f[1] <<= 2; - f[2] <<= 3; - f[3] <<= 5; - f[4] <<= 6; - f[6] <<= 1; - f[7] <<= 3; - f[8] <<= 4; - f[9] <<= 6; - - #define F(i, s) \ - out[s+0] |= (unsigned char )(f[i] & 0xff); \ - out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \ - out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \ - out[s+3] = (unsigned char )((f[i] >> 24) & 0xff); - - out[0] = 0; - out[16] = 0; - F(0,0); - F(1,3); - F(2,6); - F(3,9); - F(4,12); - F(5,16); - F(6,19); - F(7,22); - F(8,25); - F(9,28); - #undef F -} - -/* if (iswap) swap(a, b) */ -void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) { - const uint32_t swap = (uint32_t)(-(int32_t)iswap); - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0; - - x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; - x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; - x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; - x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; - x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; - x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5; - x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6; - x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7; - x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8; - x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9; -} - -void curve25519_set(bignum25519 r, uint32_t x){ - r[0] = x & reduce_mask_26; x >>= 26; - r[1] = x & reduce_mask_25; - r[2] = 0; - r[3] = 0; - r[4] = 0; - r[5] = 0; - r[6] = 0; - r[7] = 0; - r[8] = 0; - r[9] = 0; -} - -void curve25519_set_d(bignum25519 r){ - curve25519_copy(r, ge25519_ecd); -} - -void curve25519_set_2d(bignum25519 r){ - curve25519_copy(r, ge25519_ec2d); -} - -void curve25519_set_sqrtneg1(bignum25519 r){ - curve25519_copy(r, ge25519_sqrtneg1); -} - -int curve25519_isnegative(const bignum25519 f) { - unsigned char s[32] = {0}; - curve25519_contract(s, f); - return s[0] & 1; -} - -int curve25519_isnonzero(const bignum25519 f) { - unsigned char s[32] = {0}; - curve25519_contract(s, f); - return ((((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | - s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | - s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | - s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1) & 0x1; -} - -void curve25519_reduce(bignum25519 out, const bignum25519 in) { - uint32_t c = 0; - out[0] = in[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = in[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = in[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = in[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = in[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = in[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = in[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = in[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = in[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = in[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_divpowm1(bignum25519 r, const bignum25519 u, const bignum25519 v) { - bignum25519 v3={0}, uv7={0}, t0={0}, t1={0}, t2={0}; - int i = 0; - - curve25519_square(v3, v); - curve25519_mul(v3, v3, v); /* v3 = v^3 */ - curve25519_square(uv7, v3); - curve25519_mul(uv7, uv7, v); - curve25519_mul(uv7, uv7, u); /* uv7 = uv^7 */ - - /*fe_pow22523(uv7, uv7);*/ - /* From fe_pow22523.c */ - - curve25519_square(t0, uv7); - curve25519_square(t1, t0); - curve25519_square(t1, t1); - curve25519_mul(t1, uv7, t1); - curve25519_mul(t0, t0, t1); - curve25519_square(t0, t0); - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 4; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 9; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t1, t1, t0); - curve25519_square(t2, t1); - for (i = 0; i < 19; ++i) { - curve25519_square(t2, t2); - } - curve25519_mul(t1, t2, t1); - for (i = 0; i < 10; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 49; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t1, t1, t0); - curve25519_square(t2, t1); - for (i = 0; i < 99; ++i) { - curve25519_square(t2, t2); - } - curve25519_mul(t1, t2, t1); - for (i = 0; i < 50; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t0, t0); - curve25519_square(t0, t0); - curve25519_mul(t0, t0, uv7); - - /* End fe_pow22523.c */ - /* t0 = (uv^7)^((q-5)/8) */ - curve25519_mul(t0, t0, v3); - curve25519_mul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ -} - -void curve25519_expand_reduce(bignum25519 out, const unsigned char in[32]) { - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; -#define F(s) \ - ((((uint32_t)in[s + 0]) ) | \ - (((uint32_t)in[s + 1]) << 8) | \ - (((uint32_t)in[s + 2]) << 16) | \ - (((uint32_t)in[s + 3]) << 24)) - x0 = F(0); - x1 = F(4); - x2 = F(8); - x3 = F(12); - x4 = F(16); - x5 = F(20); - x6 = F(24); - x7 = F(28); -#undef F - - out[0] = ( x0 ) & reduce_mask_26; - out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; - out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; - out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; - out[4] = (( x3) >> 6) & reduce_mask_26; - out[5] = ( x4 ) & reduce_mask_25; - out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; - out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; - out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; - out[9] = (( x7) >> 6); // & reduce_mask_25; /* ignore the top bit */ - out[0] += 19 * (out[9] >> 25); - out[9] &= reduce_mask_25; -} diff --git a/crypto/ed25519-donna/curve25519-donna-helpers.c b/crypto/ed25519-donna/curve25519-donna-helpers.c deleted file mode 100644 index b18500aab60..00000000000 --- a/crypto/ed25519-donna/curve25519-donna-helpers.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - Curve25519 implementation agnostic helpers -*/ - -#include "ed25519-donna.h" - -/* - * In: b = 2^5 - 2^0 - * Out: b = 2^250 - 2^0 - */ -void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { - bignum25519 ALIGN(16) t0 = {0}, c = {0}; - - /* 2^5 - 2^0 */ /* b */ - /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); - /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); - /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); - /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); - /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); - /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); - /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); - /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); - /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); - /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); - /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); - /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); - /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); - /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); -} - -/* - * z^(p - 2) = z(2^255 - 21) - */ -void curve25519_recip(bignum25519 out, const bignum25519 z) { - bignum25519 ALIGN(16) a = {0}, t0 = {0}, b = {0}; - - /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ - /* 8 */ curve25519_square_times(t0, a, 2); - /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ - /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ - /* 22 */ curve25519_square_times(t0, a, 1); - /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); - /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); - /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); - /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); -} - -/* - * z^((p-5)/8) = z^(2^252 - 3) - */ -void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { - bignum25519 ALIGN(16) b,c,t0; - - /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ - /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ - /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ - /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ - /* 22 */ curve25519_square_times(t0, c, 1); - /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); - /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); - /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); - /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); -} diff --git a/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c b/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c deleted file mode 100644 index 85a5d14b316..00000000000 --- a/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "ed25519-donna.h" -#include "ed25519.h" - -/* Calculates nQ where Q is the x-coordinate of a point on the curve - * - * mypublic: the packed little endian x coordinate of the resulting curve point - * n: a little endian, 32-byte number - * basepoint: a packed little endian point of the curve - */ - -void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint) { - bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx = {0}; - bignum25519 q = {0}, qx = {0}, qpqx = {0}, qqx = {0}, zzz = {0}, zmone = {0}; - size_t bit = 0, lastbit = 0; - int32_t i = 0; - - curve25519_expand(q, basepoint); - curve25519_copy(nqx, q); - - /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and - start pre-swapped on bit 254 */ - lastbit = 1; - - /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ - for (i = 253; i >= 2; i--) { - curve25519_add(qx, nqx, nqz); - curve25519_sub(nqz, nqx, nqz); - curve25519_add(qpqx, nqpqx, nqpqz); - curve25519_sub(nqpqz, nqpqx, nqpqz); - curve25519_mul(nqpqx, qpqx, nqz); - curve25519_mul(nqpqz, qx, nqpqz); - curve25519_add(qqx, nqpqx, nqpqz); - curve25519_sub(nqpqz, nqpqx, nqpqz); - curve25519_square(nqpqz, nqpqz); - curve25519_square(nqpqx, qqx); - curve25519_mul(nqpqz, nqpqz, q); - curve25519_square(qx, qx); - curve25519_square(nqz, nqz); - curve25519_mul(nqx, qx, nqz); - curve25519_sub(nqz, qx, nqz); - curve25519_scalar_product(zzz, nqz, 121665); - curve25519_add(zzz, zzz, qx); - curve25519_mul(nqz, nqz, zzz); - - bit = (n[i/8] >> (i & 7)) & 1; - curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit); - curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit); - lastbit = bit; - } - - /* the final 3 bits are always zero, so we only need to double */ - for (i = 0; i < 3; i++) { - curve25519_add(qx, nqx, nqz); - curve25519_sub(nqz, nqx, nqz); - curve25519_square(qx, qx); - curve25519_square(nqz, nqz); - curve25519_mul(nqx, qx, nqz); - curve25519_sub(nqz, qx, nqz); - curve25519_scalar_product(zzz, nqz, 121665); - curve25519_add(zzz, zzz, qx); - curve25519_mul(nqz, nqz, zzz); - } - - curve25519_recip(zmone, nqz); - curve25519_mul(nqz, nqx, zmone); - curve25519_contract(mypublic, nqz); -} diff --git a/crypto/ed25519-donna/ed25519-donna-32bit-tables.c b/crypto/ed25519-donna/ed25519-donna-32bit-tables.c deleted file mode 100644 index fd2236b0500..00000000000 --- a/crypto/ed25519-donna/ed25519-donna-32bit-tables.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "ed25519-donna.h" - -const ge25519 ALIGN(16) ge25519_basepoint = { - {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db}, - {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999}, - {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}, - {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c} -}; - -/* - d -*/ - -const bignum25519 ALIGN(16) ge25519_ecd = { - 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3 -}; - -const bignum25519 ALIGN(16) ge25519_ec2d = { - 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67 -}; - -/* - sqrt(-1) -*/ - -const bignum25519 ALIGN(16) ge25519_sqrtneg1 = { - 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92 -}; - -const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = { - {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}}, - {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}}, - {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}}, - {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}}, - {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}}, - {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}}, - {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}}, - {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}}, - {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}}, - {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}}, - {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}}, - {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}}, - {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}}, - {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}}, - {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}}, - {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}}, - {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}}, - {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}}, - {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}}, - {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}}, - {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}}, - {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}}, - {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}}, - {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}}, - {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}}, - {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}}, - {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}}, - {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}}, - {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}}, - {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}}, - {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}}, - {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}} -}; diff --git a/crypto/ed25519-donna/ed25519-donna-basepoint-table.c b/crypto/ed25519-donna/ed25519-donna-basepoint-table.c deleted file mode 100644 index cd5d187281e..00000000000 --- a/crypto/ed25519-donna/ed25519-donna-basepoint-table.c +++ /dev/null @@ -1,261 +0,0 @@ -#include "ed25519-donna.h" - -/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ -const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = { - {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, - {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, - {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, - {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, - {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, - {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, - {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, - {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, - {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, - {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, - {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, - {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, - {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, - {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, - {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, - {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, - {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, - {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, - {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, - {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, - {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, - {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, - {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, - {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, - {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, - {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, - {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, - {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, - {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, - {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, - {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, - {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, - {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, - {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, - {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, - {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, - {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, - {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, - {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, - {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, - {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, - {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, - {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, - {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, - {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, - {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, - {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, - {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, - {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, - {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, - {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, - {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, - {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, - {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, - {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, - {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, - {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, - {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, - {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, - {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, - {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, - {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, - {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, - {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, - {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, - {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, - {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, - {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, - {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, - {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, - {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, - {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, - {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, - {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, - {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, - {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, - {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, - {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, - {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, - {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, - {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, - {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, - {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, - {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, - {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, - {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, - {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, - {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, - {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, - {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, - {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, - {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, - {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, - {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, - {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, - {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, - {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, - {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, - {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, - {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, - {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, - {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, - {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, - {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, - {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, - {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, - {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, - {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, - {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, - {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, - {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, - {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, - {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, - {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, - {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, - {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, - {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, - {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, - {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, - {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, - {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, - {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, - {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, - {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, - {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, - {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, - {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, - {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, - {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, - {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, - {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, - {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, - {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, - {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, - {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, - {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, - {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, - {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, - {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, - {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, - {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, - {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, - {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, - {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, - {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, - {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, - {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, - {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, - {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, - {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, - {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, - {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, - {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, - {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, - {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, - {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, - {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, - {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, - {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, - {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, - {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, - {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, - {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, - {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, - {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, - {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, - {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, - {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, - {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, - {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, - {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, - {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, - {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, - {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, - {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, - {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, - {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, - {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, - {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, - {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, - {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, - {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, - {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, - {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, - {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, - {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, - {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, - {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, - {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, - {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, - {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, - {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, - {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, - {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, - {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, - {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, - {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, - {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, - {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, - {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, - {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, - {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, - {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, - {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, - {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, - {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, - {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, - {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, - {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, - {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, - {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, - {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, - {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, - {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, - {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, - {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, - {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, - {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, - {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, - {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, - {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, - {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, - {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, - {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, - {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, - {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, - {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, - {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, - {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, - {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, - {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, - {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, - {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, - {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, - {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, - {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, - {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, - {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, - {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, - {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, - {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, - {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, - {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, - {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, - {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, - {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, - {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, - {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, - {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, - {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, - {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, - {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, - {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, - {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, - {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, - {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} -}; diff --git a/crypto/ed25519-donna/ed25519-donna-impl-base.c b/crypto/ed25519-donna/ed25519-donna-impl-base.c deleted file mode 100644 index 317ee6c68d7..00000000000 --- a/crypto/ed25519-donna/ed25519-donna-impl-base.c +++ /dev/null @@ -1,730 +0,0 @@ -#include -#include "ed25519-donna.h" -#include "../memzero.h" - -/* sqrt(x) is such an integer y that 0 <= y <= p - 1, y % 2 = 0, and y^2 = x (mod p). */ -/* d = -121665 / 121666 */ -#if !defined(NDEBUG) -static const bignum25519 ALIGN(16) fe_d = { - 0x35978a3, 0x0d37284, 0x3156ebd, 0x06a0a0e, 0x001c029, 0x179e898, 0x3a03cbb, 0x1ce7198, 0x2e2b6ff, 0x1480db3}; /* d */ -#endif -static const bignum25519 ALIGN(16) fe_sqrtm1 = { - 0x20ea0b0, 0x186c9d2, 0x08f189d, 0x035697f, 0x0bd0c60, 0x1fbd7a7, 0x2804c9e, 0x1e16569, 0x004fc1d, 0x0ae0c92}; /* sqrt(-1) */ -//static const bignum25519 ALIGN(16) fe_d2 = { -// 0x2b2f159, 0x1a6e509, 0x22add7a, 0x0d4141d, 0x0038052, 0x0f3d130, 0x3407977, 0x19ce331, 0x1c56dff, 0x0901b67}; /* 2 * d */ - -/* A = 2 * (1 - d) / (1 + d) = 486662 */ -static const bignum25519 ALIGN(16) fe_ma2 = { - 0x33de3c9, 0x1fff236, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff}; /* -A^2 */ -static const bignum25519 ALIGN(16) fe_ma = { - 0x3f892e7, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff}; /* -A */ -static const bignum25519 ALIGN(16) fe_fffb1 = { - 0x1e3bdff, 0x025a2b3, 0x18e5bab, 0x0ba36ac, 0x0b9afed, 0x004e61c, 0x31d645f, 0x09d1bea, 0x102529e, 0x0063810}; /* sqrt(-2 * A * (A + 2)) */ -static const bignum25519 ALIGN(16) fe_fffb2 = { - 0x383650d, 0x066df27, 0x10405a4, 0x1cfdd48, 0x2b887f2, 0x1e9a041, 0x1d7241f, 0x0612dc5, 0x35fba5d, 0x0cbe787}; /* sqrt(2 * A * (A + 2)) */ -static const bignum25519 ALIGN(16) fe_fffb3 = { - 0x0cfd387, 0x1209e3a, 0x3bad4fc, 0x18ad34d, 0x2ff6c02, 0x0f25d12, 0x15cdfe0, 0x0e208ed, 0x32eb3df, 0x062d7bb}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ -static const bignum25519 ALIGN(16) fe_fffb4 = { - 0x2b39186, 0x14640ed, 0x14930a7, 0x04509fa, 0x3b91bf0, 0x0f7432e, 0x07a443f, 0x17f24d8, 0x031067d, 0x0690fcc}; /* sqrt(sqrt(-1) * A * (A + 2)) */ - - -/* - Timing safe memory compare -*/ -int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) { - size_t differentbits = 0; - while (len--) - differentbits |= (*x++ ^ *y++); - return (int) (1 & ((differentbits - 1) >> 8)); -} - -/* - conversions -*/ - -void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { - curve25519_mul(r->x, p->x, p->t); - curve25519_mul(r->y, p->y, p->z); - curve25519_mul(r->z, p->z, p->t); -} - -void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { - curve25519_mul(r->x, p->x, p->t); - curve25519_mul(r->y, p->y, p->z); - curve25519_mul(r->z, p->z, p->t); - curve25519_mul(r->t, p->x, p->y); -} - -void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { - curve25519_sub(p->ysubx, r->y, r->x); - curve25519_add(p->xaddy, r->y, r->x); - curve25519_copy(p->z, r->z); - curve25519_mul(p->t2d, r->t, ge25519_ec2d); -} - -/* - adding & doubling -*/ - -void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_square(a, p->x); - curve25519_square(b, p->y); - curve25519_square(c, p->z); - curve25519_add_reduce(c, c, c); - curve25519_add(r->x, p->x, p->y); - curve25519_square(r->x, r->x); - curve25519_add(r->y, b, a); - curve25519_sub(r->z, b, a); - curve25519_sub_after_basic(r->x, r->x, r->y); - curve25519_sub_after_basic(r->t, c, r->z); -} - -#ifndef ED25519_NO_PRECOMP -void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) { - const bignum25519 *qb = (const bignum25519 *)q; - bignum25519 *rb = (bignum25519 *)r; - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ - curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ - curve25519_add(r->y, r->x, a); - curve25519_sub(r->x, r->x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_add_reduce(r->t, p->z, p->z); - curve25519_copy(r->z, r->t); - curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ - curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ -} -#endif - -void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) { - const bignum25519 *qb = (const bignum25519 *)q; - bignum25519 *rb = (bignum25519 *)r; - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ - curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ - curve25519_add(r->y, r->x, a); - curve25519_sub(r->x, r->x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_mul(r->t, p->z, q->z); - curve25519_add_reduce(r->t, r->t, r->t); - curve25519_copy(r->z, r->t); - curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ - curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ -} - -void ge25519_double_partial(ge25519 *r, const ge25519 *p) { - ge25519_p1p1 t = {0}; - ge25519_double_p1p1(&t, p); - ge25519_p1p1_to_partial(r, &t); -} - -void ge25519_double(ge25519 *r, const ge25519 *p) { - ge25519_p1p1 t = {0}; - ge25519_double_p1p1(&t, p); - ge25519_p1p1_to_full(r, &t); -} - -void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { - bignum25519 a = {0}, b = {0}, c = {0}, e = {0}, f = {0}, g = {0}, h = {0}; - - curve25519_sub(a, r->y, r->x); - curve25519_add(b, r->y, r->x); - curve25519_mul(a, a, q->ysubx); - curve25519_mul(e, b, q->xaddy); - curve25519_add(h, e, a); - curve25519_sub(e, e, a); - curve25519_mul(c, r->t, q->t2d); - curve25519_add(f, r->z, r->z); - curve25519_add_after_basic(g, f, c); - curve25519_sub_after_basic(f, f, c); - curve25519_mul(r->x, e, f); - curve25519_mul(r->y, h, g); - curve25519_mul(r->z, g, f); - curve25519_mul(r->t, e, h); -} - -void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { - bignum25519 a = {0}, b = {0}, c = {0}, x = {0}, y = {0}, z = {0}, t = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, q->ysubx); - curve25519_mul(x, b, q->xaddy); - curve25519_add(y, x, a); - curve25519_sub(x, x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_mul(t, p->z, q->z); - curve25519_add(t, t, t); - curve25519_add_after_basic(z, t, c); - curve25519_sub_after_basic(t, t, c); - curve25519_mul(r->xaddy, x, t); - curve25519_mul(r->ysubx, y, z); - curve25519_mul(r->z, z, t); - curve25519_mul(r->t2d, x, y); - curve25519_copy(y, r->ysubx); - curve25519_sub(r->ysubx, r->ysubx, r->xaddy); - curve25519_add(r->xaddy, r->xaddy, y); - curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); -} - - -/* - pack & unpack -*/ - -void ge25519_pack(unsigned char r[32], const ge25519 *p) { - bignum25519 tx = {0}, ty = {0}, zi = {0}; - unsigned char parity[32] = {0}; - curve25519_recip(zi, p->z); - curve25519_mul(tx, p->x, zi); - curve25519_mul(ty, p->y, zi); - curve25519_contract(r, ty); - curve25519_contract(parity, tx); - r[31] ^= ((parity[0] & 1) << 7); -} - -int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) { - const unsigned char zero[32] = {0}; - const bignum25519 one = {1}; - unsigned char parity = p[31] >> 7; - unsigned char check[32] = {0}; - bignum25519 t = {0}, root = {0}, num = {0}, den = {0}, d3 = {0}; - - curve25519_expand(r->y, p); - curve25519_copy(r->z, one); - curve25519_square(num, r->y); /* x = y^2 */ - curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ - curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ - curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ - - /* Computation of sqrt(num/den) */ - /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ - curve25519_square(t, den); - curve25519_mul(d3, t, den); - curve25519_square(r->x, d3); - curve25519_mul(r->x, r->x, den); - curve25519_mul(r->x, r->x, num); - curve25519_pow_two252m3(r->x, r->x); - - /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ - curve25519_mul(r->x, r->x, d3); - curve25519_mul(r->x, r->x, num); - - /* 3. Check if either of the roots works: */ - curve25519_square(t, r->x); - curve25519_mul(t, t, den); - curve25519_sub_reduce(root, t, num); - curve25519_contract(check, root); - if (!ed25519_verify(check, zero, 32)) { - curve25519_add_reduce(t, t, num); - curve25519_contract(check, t); - if (!ed25519_verify(check, zero, 32)) - return 0; - curve25519_mul(r->x, r->x, ge25519_sqrtneg1); - } - - curve25519_contract(check, r->x); - if ((check[0] & 1) == parity) { - curve25519_copy(t, r->x); - curve25519_neg(r->x, t); - } - curve25519_mul(r->t, r->x, r->y); - return 1; -} - -/* - scalarmults -*/ - -void ge25519_set_neutral(ge25519 *r) -{ - memzero(r, sizeof(ge25519)); - r->y[0] = 1; - r->z[0] = 1; -} - -#define S1_SWINDOWSIZE 5 -#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) -#ifdef ED25519_NO_PRECOMP -#define S2_SWINDOWSIZE 5 -#else -#define S2_SWINDOWSIZE 7 -#endif -#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) - -/* computes [s1]p1 + [s2]base */ -void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { - signed char slide1[256] = {0}, slide2[256] = {0}; - ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; -#ifdef ED25519_NO_PRECOMP - ge25519_pniels pre2[S2_TABLE_SIZE] = {0}; -#endif - ge25519 dp = {0}; - ge25519_p1p1 t = {0}; - int32_t i = 0; - - memzero(&t, sizeof(ge25519_p1p1)); - contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); - contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); - - ge25519_double(&dp, p1); - ge25519_full_to_pniels(pre1, p1); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre1[i+1], &dp, &pre1[i]); - -#ifdef ED25519_NO_PRECOMP - ge25519_double(&dp, &ge25519_basepoint); - ge25519_full_to_pniels(pre2, &ge25519_basepoint); - for (i = 0; i < S2_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre2[i+1], &dp, &pre2[i]); -#endif - - ge25519_set_neutral(r); - - i = 255; - while ((i >= 0) && !(slide1[i] | slide2[i])) - i--; - - for (; i >= 0; i--) { - ge25519_double_p1p1(&t, r); - - if (slide1[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); - } - - if (slide2[i]) { - ge25519_p1p1_to_full(r, &t); -#ifdef ED25519_NO_PRECOMP - ge25519_pnielsadd_p1p1(&t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); -#else - ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); -#endif - } - - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); - memzero(slide2, sizeof(slide2)); -} - -/* computes [s1]p1 + [s2]p2 */ -#if USE_MONERO -void ge25519_double_scalarmult_vartime2(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2) { - signed char slide1[256] = {0}, slide2[256] = {0}; - ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; - ge25519_pniels pre2[S1_TABLE_SIZE] = {0}; - ge25519 dp = {0}; - ge25519_p1p1 t = {0}; - int32_t i = 0; - - memzero(&t, sizeof(ge25519_p1p1)); - contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); - contract256_slidingwindow_modm(slide2, s2, S1_SWINDOWSIZE); - - ge25519_double(&dp, p1); - ge25519_full_to_pniels(pre1, p1); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre1[i+1], &dp, &pre1[i]); - - ge25519_double(&dp, p2); - ge25519_full_to_pniels(pre2, p2); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre2[i+1], &dp, &pre2[i]); - - ge25519_set_neutral(r); - - i = 255; - while ((i >= 0) && !(slide1[i] | slide2[i])) - i--; - - for (; i >= 0; i--) { - ge25519_double_p1p1(&t, r); - - if (slide1[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); - } - - if (slide2[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); - } - - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); - memzero(slide2, sizeof(slide2)); -} -#endif - -/* - * The following conditional move stuff uses conditional moves. - * I will check on which compilers this works, and provide suitable - * workarounds for those where it doesn't. - * - * This works on gcc 4.x and above with -O3. Don't use -O2, this will - * cause the code to not generate conditional moves. Don't use any -march= - * with less than i686 on x86 - */ -static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) { - long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; - for(; p= 0; i--) { - int k=abs(slide1[i]); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_p1p1(&t, r); - ge25519_move_conditional_pniels_array(&pre, pre1, k, 9); - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7); - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); -} - -void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { - bignum25519 neg = {0}; - uint32_t sign = (uint32_t)((unsigned char)b >> 7); - uint32_t mask = ~(sign - 1); - uint32_t u = (b + mask) ^ mask; - - /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ - uint8_t packed[96] = {0}; - packed[0] = 1; - packed[32] = 1; - - ge25519_move_conditional_niels_array((ge25519_niels *)packed, &table[pos*8], u-1, 8); - - /* expand in to t */ - curve25519_expand(t->ysubx, packed + 0); - curve25519_expand(t->xaddy, packed + 32); - curve25519_expand(t->t2d , packed + 64); - - /* adjust for sign */ - curve25519_swap_conditional(t->ysubx, t->xaddy, sign); - curve25519_neg(neg, t->t2d); - curve25519_swap_conditional(t->t2d, neg, sign); -} - -/* computes [s]basepoint */ -void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) { - signed char b[64] = {0}; - uint32_t i = 0; - ge25519_niels t = {0}; - - contract256_window4_modm(b, s); - - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); - curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); - curve25519_add_reduce(r->y, t.xaddy, t.ysubx); - memzero(r->z, sizeof(bignum25519)); - curve25519_copy(r->t, t.t2d); - r->z[0] = 2; - for (i = 3; i < 64; i += 2) { - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); - ge25519_nielsadd2(r, &t); - } - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double(r, r); - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); - curve25519_mul(t.t2d, t.t2d, ge25519_ecd); - ge25519_nielsadd2(r, &t); - for(i = 2; i < 64; i += 2) { - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); - ge25519_nielsadd2(r, &t); - } -} - -int ge25519_check(const ge25519 *r){ - /* return (z % q != 0 and - x * y % q == z * t % q and - (y * y - x * x - z * z - ed25519.d * t * t) % q == 0) - */ - - bignum25519 z={0}, lhs={0}, rhs={0}, tmp={0}, res={0}; - curve25519_reduce(z, r->z); - - curve25519_mul(lhs, r->x, r->y); - curve25519_mul(rhs, r->z, r->t); - curve25519_sub_reduce(lhs, lhs, rhs); - - curve25519_square(res, r->y); - curve25519_square(tmp, r->x); - curve25519_sub_reduce(res, res, tmp); - curve25519_square(tmp, r->z); - curve25519_sub_reduce(res, res, tmp); - curve25519_square(tmp, r->t); - curve25519_mul(tmp, tmp, ge25519_ecd); - curve25519_sub_reduce(res, res, tmp); - - const int c1 = curve25519_isnonzero(z); - const int c2 = curve25519_isnonzero(lhs); - const int c3 = curve25519_isnonzero(res); - return c1 & (c2^0x1) & (c3^0x1); -} - -int ge25519_eq(const ge25519 *a, const ge25519 *b){ - int eq = 1; - bignum25519 t1={0}, t2={0}; - - eq &= ge25519_check(a); - eq &= ge25519_check(b); - - curve25519_mul(t1, a->x, b->z); - curve25519_mul(t2, b->x, a->z); - curve25519_sub_reduce(t1, t1, t2); - eq &= curve25519_isnonzero(t1) ^ 1; - - curve25519_mul(t1, a->y, b->z); - curve25519_mul(t2, b->y, a->z); - curve25519_sub_reduce(t1, t1, t2); - eq &= curve25519_isnonzero(t1) ^ 1; - - return eq; -} - -void ge25519_copy(ge25519 *dst, const ge25519 *src){ - curve25519_copy(dst->x, src->x); - curve25519_copy(dst->y, src->y); - curve25519_copy(dst->z, src->z); - curve25519_copy(dst->t, src->t); -} - -void ge25519_set_base(ge25519 *r){ - ge25519_copy(r, &ge25519_basepoint); -} - -void ge25519_mul8(ge25519 *r, const ge25519 *t) { - ge25519_double_partial(r, t); - ge25519_double_partial(r, r); - ge25519_double(r, r); -} - -void ge25519_neg_partial(ge25519 *r){ - curve25519_neg(r->x, r->x); -} - -void ge25519_neg_full(ge25519 *r){ - curve25519_neg(r->x, r->x); - curve25519_neg(r->t, r->t); -} - -void ge25519_reduce(ge25519 *r, const ge25519 *t){ - curve25519_reduce(r->x, t->x); - curve25519_reduce(r->y, t->y); - curve25519_reduce(r->z, t->z); - curve25519_reduce(r->t, t->t); -} - -void ge25519_norm(ge25519 *r, const ge25519 * t){ - bignum25519 zinv = {0}; - curve25519_recip(zinv, t->z); - curve25519_mul(r->x, t->x, zinv); - curve25519_mul(r->y, t->y, zinv); - curve25519_mul(r->t, r->x, r->y); - curve25519_set(r->z, 1); -} - -void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q, unsigned char signbit) { - ge25519_pniels P_ni = {0}; - ge25519_p1p1 P_11 = {0}; - - ge25519_full_to_pniels(&P_ni, q); - ge25519_pnielsadd_p1p1(&P_11, p, &P_ni, signbit); - ge25519_p1p1_to_full(r, &P_11); -} - -void ge25519_fromfe_frombytes_vartime(ge25519 *r, const unsigned char *s){ - bignum25519 u={0}, v={0}, w={0}, x={0}, y={0}, z={0}; - unsigned char sign = 0; - - curve25519_expand_reduce(u, s); - - curve25519_square(v, u); - curve25519_add_reduce(v, v, v); /* 2 * u^2 */ - curve25519_set(w, 1); - curve25519_add_reduce(w, v, w); /* w = 2 * u^2 + 1 */ - - curve25519_square(x, w); /* w^2 */ - curve25519_mul(y, fe_ma2, v); /* -2 * A^2 * u^2 */ - curve25519_add_reduce(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ - - curve25519_divpowm1(r->x, w, x); /* (w / x)^(m + 1) */ - curve25519_square(y, r->x); - curve25519_mul(x, y, x); - curve25519_sub_reduce(y, w, x); - curve25519_copy(z, fe_ma); - - if (curve25519_isnonzero(y)) { - curve25519_add_reduce(y, w, x); - if (curve25519_isnonzero(y)) { - goto negative; - } else { - curve25519_mul(r->x, r->x, fe_fffb1); - } - } else { - curve25519_mul(r->x, r->x, fe_fffb2); - } - curve25519_mul(r->x, r->x, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ - curve25519_mul(z, z, v); /* -2 * A * u^2 */ - sign = 0; - goto setsign; -negative: - curve25519_mul(x, x, fe_sqrtm1); - curve25519_sub_reduce(y, w, x); - if (curve25519_isnonzero(y)) { - assert((curve25519_add_reduce(y, w, x), !curve25519_isnonzero(y))); - curve25519_mul(r->x, r->x, fe_fffb3); - } else { - curve25519_mul(r->x, r->x, fe_fffb4); - } - /* r->x = sqrt(A * (A + 2) * w / x) */ - /* z = -A */ - sign = 1; -setsign: - if (curve25519_isnegative(r->x) != sign) { - assert(curve25519_isnonzero(r->x)); - curve25519_neg(r->x, r->x); - } - curve25519_add_reduce(r->z, z, w); - curve25519_sub_reduce(r->y, z, w); - curve25519_mul(r->x, r->x, r->z); - - // Partial form, saving from T coord computation . - // Later is mul8 discarding T anyway. - // rt = ((rx * ry % q) * inv(rz)) % q - // curve25519_mul(x, r->x, r->y); - // curve25519_recip(z, r->z); - // curve25519_mul(r->t, x, z); - -#if !defined(NDEBUG) - { - bignum25519 check_x={0}, check_y={0}, check_iz={0}, check_v={0}; - curve25519_recip(check_iz, r->z); - curve25519_mul(check_x, r->x, check_iz); - curve25519_mul(check_y, r->y, check_iz); - curve25519_square(check_x, check_x); - curve25519_square(check_y, check_y); - curve25519_mul(check_v, check_x, check_y); - curve25519_mul(check_v, fe_d, check_v); - curve25519_add_reduce(check_v, check_v, check_x); - curve25519_sub_reduce(check_v, check_v, check_y); - curve25519_set(check_x, 1); - curve25519_add_reduce(check_v, check_v, check_x); - assert(!curve25519_isnonzero(check_v)); - } -#endif -} - -int ge25519_unpack_vartime(ge25519 *r, const unsigned char *s){ - int res = ge25519_unpack_negative_vartime(r, s); - ge25519_neg_full(r); - return res; -} - -void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s){ - ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s); -} diff --git a/crypto/ed25519-donna/ed25519-donna-impl-base.h b/crypto/ed25519-donna/ed25519-donna-impl-base.h deleted file mode 100644 index 4001678c62c..00000000000 --- a/crypto/ed25519-donna/ed25519-donna-impl-base.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - Timing safe memory compare -*/ -int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len); - -/* - conversions -*/ - -void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p); - -void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p); - -void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r); - -/* - adding & doubling -*/ - -void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p); - -#ifndef ED25519_NO_PRECOMP -void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit); -#endif - -/* computes [s1]p1 + [s2]p2 */ -//#if USE_MONERO -void ge25519_double_scalarmult_vartime2(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2); -//#endif - -void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit); - -void ge25519_double_partial(ge25519 *r, const ge25519 *p); - -void ge25519_double(ge25519 *r, const ge25519 *p); - -void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q); - -void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q); - - -/* - pack & unpack -*/ - -void ge25519_pack(unsigned char r[32], const ge25519 *p); - -int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]); - -/* - scalarmults -*/ - -void ge25519_set_neutral(ge25519 *r); - -/* computes [s1]p1 + [s2]base */ -void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2); - -/* computes [s1]p1, constant time */ -void ge25519_scalarmult(ge25519 *r, const ge25519 *p1, const bignum256modm s1); - -void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b); - -/* computes [s]basepoint */ -void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s); - -/* check if r is on curve */ -int ge25519_check(const ge25519 *r); - -/* a == b */ -int ge25519_eq(const ge25519 *a, const ge25519 *b); - -/* copies one point to another */ -void ge25519_copy(ge25519 *dst, const ge25519 *src); - -/* sets B point to r */ -void ge25519_set_base(ge25519 *r); - -/* 8*P */ -void ge25519_mul8(ge25519 *r, const ge25519 *t); - -/* -P */ -void ge25519_neg_partial(ge25519 *r); - -/* -P */ -void ge25519_neg_full(ge25519 *r); - -/* reduce all coords */ -void ge25519_reduce(ge25519 *r, const ge25519 *t); - -/* normalizes coords. (x, y, 1, x*y) */ -void ge25519_norm(ge25519 *r, const ge25519 * t); - -/* Simple addition */ -void ge25519_add(ge25519 *r, const ge25519 *a, const ge25519 *b, unsigned char signbit); - -/* point from bytes, used in H_p() */ -void ge25519_fromfe_frombytes_vartime(ge25519 *r, const unsigned char *s); - -/* point from bytes */ -int ge25519_unpack_vartime(ge25519 *r, const unsigned char *s); - -/* aG, wrapper for niels base mult. */ -void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s); diff --git a/crypto/ed25519-donna/ed25519-donna-portable.h b/crypto/ed25519-donna/ed25519-donna-portable.h deleted file mode 100644 index ceeb557418c..00000000000 --- a/crypto/ed25519-donna/ed25519-donna-portable.h +++ /dev/null @@ -1,24 +0,0 @@ -#define mul32x32_64(a,b) (((uint64_t)(a))*(b)) - -#include -#include -#include - -#define DONNA_INLINE -#undef ALIGN -#define ALIGN(x) __attribute__((aligned(x))) - -static inline void U32TO8_LE(unsigned char *p, const uint32_t v) { - p[0] = (unsigned char)(v ); - p[1] = (unsigned char)(v >> 8); - p[2] = (unsigned char)(v >> 16); - p[3] = (unsigned char)(v >> 24); -} - -static inline uint32_t U8TO32_LE(const unsigned char *p) { - return - (((uint32_t)(p[0]) ) | - ((uint32_t)(p[1]) << 8) | - ((uint32_t)(p[2]) << 16) | - ((uint32_t)(p[3]) << 24)); -} diff --git a/crypto/ed25519-donna/ed25519-keccak.h b/crypto/ed25519-donna/ed25519-keccak.h deleted file mode 100644 index 962f0412b46..00000000000 --- a/crypto/ed25519-donna/ed25519-keccak.h +++ /dev/null @@ -1,27 +0,0 @@ -#include "../options.h" - -#if USE_KECCAK - -#ifndef ED25519_KECCAK_H -#define ED25519_KECCAK_H - -#include "ed25519.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -void ed25519_publickey_keccak(const ed25519_secret_key sk, ed25519_public_key pk); - -int ed25519_sign_open_keccak(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign_keccak(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); - -int ed25519_scalarmult_keccak(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_KECCAK_H - -#endif // USE_KECCAK \ No newline at end of file diff --git a/crypto/ed25519-donna/ed25519-sha3.h b/crypto/ed25519-donna/ed25519-sha3.h deleted file mode 100644 index 51b764b032e..00000000000 --- a/crypto/ed25519-donna/ed25519-sha3.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ED25519_SHA3_H -#define ED25519_SHA3_H - -#include "ed25519.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -void ed25519_publickey_sha3(const ed25519_secret_key sk, ed25519_public_key pk); - -int ed25519_sign_open_sha3(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign_sha3(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); - -int ed25519_scalarmult_sha3(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_SHA3_H diff --git a/crypto/ed25519-donna/ed25519.c b/crypto/ed25519-donna/ed25519.c deleted file mode 100644 index ec68143f405..00000000000 --- a/crypto/ed25519-donna/ed25519.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - Public domain by Andrew M. - - Ed25519 reference implementation using Ed25519-donna -*/ - - -/* define ED25519_SUFFIX to have it appended to the end of each public function */ -#ifdef ED25519_SUFFIX -#define ED25519_FN3(fn,suffix) fn##suffix -#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix) -#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX) -#else -#define ED25519_FN(fn) fn -#endif - -#include "ed25519-donna.h" -#include "ed25519.h" - -#include "ed25519-hash-custom.h" -#include "../rand.h" -#include "../memzero.h" - -/* - Generates a (extsk[0..31]) and aExt (extsk[32..63]) -*/ -DONNA_INLINE static void -ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { - ed25519_hash(extsk, sk, 32); - extsk[0] &= 248; - extsk[31] &= 127; - extsk[31] |= 64; -} - -static void -ed25519_hram(hash_512bits hram, const ed25519_public_key R, const ed25519_public_key pk, const unsigned char *m, size_t mlen) { - ed25519_hash_context ctx; - ed25519_hash_init(&ctx); - ed25519_hash_update(&ctx, R, 32); - ed25519_hash_update(&ctx, pk, 32); - ed25519_hash_update(&ctx, m, mlen); - ed25519_hash_final(&ctx, hram); -} - -void -ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) { - hash_512bits extsk = {0}; - ed25519_extsk(extsk, sk); - ed25519_publickey_ext(extsk, pk); - memzero(&extsk, sizeof(extsk)); -} - -void -ED25519_FN(ed25519_cosi_commit) (ed25519_secret_key nonce, ed25519_public_key commitment) { - bignum256modm r = {0}; - ge25519 ALIGN(16) R; - unsigned char extnonce[64] = {0}; - - /* r = random512 mod L */ - random_buffer(extnonce, sizeof(extnonce)); - expand256_modm(r, extnonce, sizeof(extnonce)); - memzero(&extnonce, sizeof(extnonce)); - contract256_modm(nonce, r); - - /* R = rB */ - ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); - memzero(&r, sizeof(r)); - ge25519_pack(commitment, &R); -} - -int -ED25519_FN(ed25519_cosi_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) { - bignum256modm r = {0}, S = {0}, a = {0}; - hash_512bits extsk = {0}, hram = {0}; - - ed25519_extsk(extsk, sk); - - /* r */ - expand_raw256_modm(r, nonce); - if (!is_reduced256_modm(r)) - return -1; - - /* S = H(R,A,m).. */ - ed25519_hram(hram, R, pk, m, mlen); - expand256_modm(S, hram, 64); - - /* S = H(R,A,m)a */ - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - mul256_modm(S, S, a); - memzero(&a, sizeof(a)); - - /* S = (r + H(R,A,m)a) */ - add256_modm(S, S, r); - memzero(&r, sizeof(r)); - - /* S = (r + H(R,A,m)a) mod L */ - contract256_modm(sig, S); - - return 0; -} - -void -ED25519_FN(ed25519_sign_ext) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_signature RS) { - ed25519_hash_context ctx; - bignum256modm r = {0}, S = {0}, a = {0}; - ge25519 ALIGN(16) R = {0}; - ge25519 ALIGN(16) A = {0}; - ed25519_public_key pk = {0}; - hash_512bits extsk = {0}, hashr = {0}, hram = {0}; - - /* we don't stretch the key through hashing first since its already 64 bytes */ - - memcpy(extsk, sk, 32); - memcpy(extsk+32, skext, 32); - - - /* r = H(aExt[32..64], m) */ - ed25519_hash_init(&ctx); - ed25519_hash_update(&ctx, extsk + 32, 32); - ed25519_hash_update(&ctx, m, mlen); - ed25519_hash_final(&ctx, hashr); - expand256_modm(r, hashr, 64); - memzero(&hashr, sizeof(hashr)); - - /* R = rB */ - ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); - ge25519_pack(RS, &R); - - /* a = aExt[0..31] */ - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - - /* A = aB */ - ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); - ge25519_pack(pk, &A); - - /* S = H(R,A,m).. */ - ed25519_hram(hram, RS, pk, m, mlen); - expand256_modm(S, hram, 64); - - /* S = H(R,A,m)a */ - mul256_modm(S, S, a); - memzero(&a, sizeof(a)); - - /* S = (r + H(R,A,m)a) */ - add256_modm(S, S, r); - memzero(&r, sizeof(r)); - - /* S = (r + H(R,A,m)a) mod L */ - contract256_modm(RS + 32, S); -} - -void -ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS) { - hash_512bits extsk = {0}; - ed25519_extsk(extsk, sk); - ED25519_FN(ed25519_sign_ext)(m, mlen, extsk, extsk + 32, RS); - memzero(&extsk, sizeof(extsk)); -} - -int -ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { - ge25519 ALIGN(16) R = {0}, A = {0}; - hash_512bits hash = {0}; - bignum256modm hram = {0}, S = {0}; - unsigned char checkR[32] = {0}; - - if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) - return -1; - - /* hram = H(R,A,m) */ - ed25519_hram(hash, RS, pk, m, mlen); - expand256_modm(hram, hash, 64); - - /* S */ - expand_raw256_modm(S, RS + 32); - if (!is_reduced256_modm(S)) - return -1; - - /* SB - H(R,A,m)A */ - ge25519_double_scalarmult_vartime(&R, &A, hram, S); - ge25519_pack(checkR, &R); - - /* check that R = SB - H(R,A,m)A */ - return ed25519_verify(RS, checkR, 32) ? 0 : -1; -} - -int -ED25519_FN(ed25519_scalarmult) (ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk) { - bignum256modm a = {0}; - ge25519 ALIGN(16) A = {0}, P = {0}; - hash_512bits extsk = {0}; - - ed25519_extsk(extsk, sk); - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - - if (!ge25519_unpack_negative_vartime(&P, pk)) { - return -1; - } - - ge25519_scalarmult(&A, &P, a); - memzero(&a, sizeof(a)); - curve25519_neg(A.x, A.x); - ge25519_pack(res, &A); - return 0; -} - - -#ifndef ED25519_SUFFIX - -#include "curve25519-donna-scalarmult-base.h" - -void -ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk) { - bignum256modm a = {0}; - ge25519 ALIGN(16) A = {0}; - - expand256_modm(a, extsk, 32); - - /* A = aB */ - ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); - memzero(&a, sizeof(a)); - ge25519_pack(pk, &A); -} - -int -ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) { - size_t i = 0; - ge25519 P = {0}; - ge25519_pniels sump = {0}; - ge25519_p1p1 sump1 = {0}; - - if (n == 1) { - memcpy(res, pks, sizeof(ed25519_public_key)); - return 0; - } - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_full_to_pniels(&sump, &P); - while (i < n - 1) { - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_pnielsadd(&sump, &P, &sump); - } - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0); - ge25519_p1p1_to_partial(&P, &sump1); - curve25519_neg(P.x, P.x); - ge25519_pack(res, &P); - return 0; -} - -void -ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) { - bignum256modm s = {0}, t = {0}; - size_t i = 0; - - expand256_modm(s, sigs[i++], 32); - while (i < n) { - expand256_modm(t, sigs[i++], 32); - add256_modm(s, s, t); - } - memcpy(res, R, 32); - contract256_modm(res + 32, s); -} - -/* - Fast Curve25519 basepoint scalar multiplication -*/ -void -curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) { - curve25519_key ec = {0}; - bignum256modm s = {0}; - bignum25519 ALIGN(16) yplusz = {0}, zminusy = {0}; - ge25519 ALIGN(16) p = {0}; - size_t i = 0; - - /* clamp */ - for (i = 0; i < 32; i++) ec[i] = e[i]; - ec[0] &= 248; - ec[31] &= 127; - ec[31] |= 64; - - expand_raw256_modm(s, ec); - memzero(&ec, sizeof(ec)); - - /* scalar * basepoint */ - ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); - memzero(&s, sizeof(s)); - - /* u = (y + z) / (z - y) */ - curve25519_add(yplusz, p.y, p.z); - curve25519_sub(zminusy, p.z, p.y); - curve25519_recip(zminusy, zminusy); - curve25519_mul(yplusz, yplusz, zminusy); - curve25519_contract(pk, yplusz); -} - -void -curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint) { - curve25519_key e = {0}; - size_t i = 0; - - for (i = 0;i < 32;++i) e[i] = secret[i]; - e[0] &= 0xf8; - e[31] &= 0x7f; - e[31] |= 0x40; - curve25519_scalarmult_donna(mypublic, e, basepoint); - memzero(&e, sizeof(e)); -} - -#endif // ED25519_SUFFIX diff --git a/crypto/ed25519-donna/ed25519.h b/crypto/ed25519-donna/ed25519.h deleted file mode 100644 index 322294a7f5c..00000000000 --- a/crypto/ed25519-donna/ed25519.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef ED25519_H -#define ED25519_H - -#include "../options.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -typedef unsigned char ed25519_signature[64]; -typedef unsigned char ed25519_public_key[32]; -typedef unsigned char ed25519_secret_key[32]; - -typedef unsigned char curve25519_key[32]; - -typedef unsigned char ed25519_cosi_signature[32]; - -void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); -void ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk); - -int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); -void ed25519_sign_ext(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_signature RS); - -int ed25519_scalarmult(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -void curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint); -void curve25519_scalarmult_basepoint(curve25519_key mypublic, const curve25519_key secret); - -#if !defined(__GNUC__) || __GNUC__ > 4 -#define CONST const -#else -#define CONST -#endif - -int ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n); -void ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n); -void ed25519_cosi_commit(ed25519_secret_key nonce, ed25519_public_key commitment); -int ed25519_cosi_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key key, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_H diff --git a/crypto/ed25519-donna/modm-donna-32bit.c b/crypto/ed25519-donna/modm-donna-32bit.c deleted file mode 100644 index 4ff735f3f0e..00000000000 --- a/crypto/ed25519-donna/modm-donna-32bit.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - Public domain by Andrew M. -*/ - -#include "ed25519-donna.h" - -/* - Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 - - k = 32 - b = 1 << 8 = 256 - m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed - mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b -*/ - -static const bignum256modm modm_m = { - 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8, - 0x00000014, 0x00000000, 0x00000000, 0x00000000, - 0x00001000 -}; - -static const bignum256modm modm_mu = { - 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742, - 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff, - 0x000fffff -}; - -static bignum256modm_element_t -lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { - return (a - b) >> 31; -} - -/* see HAC, Alg. 14.42 Step 4 */ -void reduce256_modm(bignum256modm r) { - bignum256modm t = {0}; - bignum256modm_element_t b = 0, pb = 0, mask = 0; - - /* t = r - m */ - pb = 0; - pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b; - pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b; - pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b; - pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b; - pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b; - pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b; - pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b; - pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b; - pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16)); - - /* keep r if r was smaller than m */ - mask = b - 1; - r[0] ^= mask & (r[0] ^ t[0]); - r[1] ^= mask & (r[1] ^ t[1]); - r[2] ^= mask & (r[2] ^ t[2]); - r[3] ^= mask & (r[3] ^ t[3]); - r[4] ^= mask & (r[4] ^ t[4]); - r[5] ^= mask & (r[5] ^ t[5]); - r[6] ^= mask & (r[6] ^ t[6]); - r[7] ^= mask & (r[7] ^ t[7]); - r[8] ^= mask & (r[8] ^ t[8]); -} - -/* - Barrett reduction, see HAC, Alg. 14.42 - - Instead of passing in x, pre-process in to q1 and r1 for efficiency -*/ -void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { - bignum256modm q3 = {0}, r2 = {0}; - uint64_t c = 0; - bignum256modm_element_t f = 0, b = 0, pb = 0; - - /* q1 = x >> 248 = 264 bits = 9 30 bit elements - q2 = mu * q1 - q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ - c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); - c >>= 30; - c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]); - f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); - f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]); - f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); - f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]); - f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); - f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]); - f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); - f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[8], q1[8]); - f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24); - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(32+1) = x & ((1 << 264) - 1) - r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */ - c = mul32x32_64(modm_m[0], q3[0]); - r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); - r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]); - r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); - r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]); - r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); - r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]); - r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); - r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]); - r2[8] = (bignum256modm_element_t)(c & 0xffffff); - - /* r = r1 - r2 - if (r < 0) r += (1 << 264) */ - pb = 0; - pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b; - pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b; - pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b; - pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b; - pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b; - pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b; - pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b; - pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b; - pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24)); - - reduce256_modm(r); - reduce256_modm(r); -} - -/* addition modulo m */ -void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm_element_t c = 0; - - c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30; - c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30; - c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30; - c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30; - c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30; - c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30; - c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30; - c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30; - c += x[8] + y[8]; r[8] = c; - - reduce256_modm(r); -} - -/* -x modulo m */ -void neg256_modm(bignum256modm r, const bignum256modm x) { - bignum256modm_element_t b = 0, pb = 0; - - /* r = m - x */ - pb = 0; - pb += x[0]; b = lt_modm(modm_m[0], pb); r[0] = (modm_m[0] - pb + (b << 30)); pb = b; - pb += x[1]; b = lt_modm(modm_m[1], pb); r[1] = (modm_m[1] - pb + (b << 30)); pb = b; - pb += x[2]; b = lt_modm(modm_m[2], pb); r[2] = (modm_m[2] - pb + (b << 30)); pb = b; - pb += x[3]; b = lt_modm(modm_m[3], pb); r[3] = (modm_m[3] - pb + (b << 30)); pb = b; - pb += x[4]; b = lt_modm(modm_m[4], pb); r[4] = (modm_m[4] - pb + (b << 30)); pb = b; - pb += x[5]; b = lt_modm(modm_m[5], pb); r[5] = (modm_m[5] - pb + (b << 30)); pb = b; - pb += x[6]; b = lt_modm(modm_m[6], pb); r[6] = (modm_m[6] - pb + (b << 30)); pb = b; - pb += x[7]; b = lt_modm(modm_m[7], pb); r[7] = (modm_m[7] - pb + (b << 30)); pb = b; - pb += x[8]; b = lt_modm(modm_m[8], pb); r[8] = (modm_m[8] - pb + (b << 16)); - - // if x==0, reduction is required - reduce256_modm(r); -} - -/* consts for subtraction, > p */ -/* Emilia Kasper trick, https://www.imperialviolet.org/2010/12/04/ecc.html */ -static const uint32_t twoP[] = { - 0x5cf5d3ed, 0x60498c68, 0x6f79cd64, 0x77be77a7, 0x40000013, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xfff}; - -/* subtraction x-y % m */ -void sub256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm_element_t c = 0; - c = twoP[0] + x[0] - y[0]; r[0] = c & 0x3fffffff; c >>= 30; - c += twoP[1] + x[1] - y[1]; r[1] = c & 0x3fffffff; c >>= 30; - c += twoP[2] + x[2] - y[2]; r[2] = c & 0x3fffffff; c >>= 30; - c += twoP[3] + x[3] - y[3]; r[3] = c & 0x3fffffff; c >>= 30; - c += twoP[4] + x[4] - y[4]; r[4] = c & 0x3fffffff; c >>= 30; - c += twoP[5] + x[5] - y[5]; r[5] = c & 0x3fffffff; c >>= 30; - c += twoP[6] + x[6] - y[6]; r[6] = c & 0x3fffffff; c >>= 30; - c += twoP[7] + x[7] - y[7]; r[7] = c & 0x3fffffff; c >>= 30; - c += twoP[8] + x[8] - y[8]; r[8] = c; - reduce256_modm(r); -} - -/* multiplication modulo m */ -void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm r1 = {0}, q1 = {0}; - uint64_t c = 0; - bignum256modm_element_t f = 0; - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) - q1 = x >> 248 = 264 bits = 9 30 bit elements */ - c = mul32x32_64(x[0], y[0]); - f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); - f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); - f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]); - f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); - f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); - f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]); - f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); - f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); - f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); - f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]); - f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); - f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); - f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]); - f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); - f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); - f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[8], y[8]); - f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff; - - barrett_reduce256_modm(r, q1, r1); -} - -void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { - unsigned char work[64] = {0}; - bignum256modm_element_t x[16] = {0}; - bignum256modm q1 = {0}; - - memcpy(work, in, len); - x[0] = U8TO32_LE(work + 0); - x[1] = U8TO32_LE(work + 4); - x[2] = U8TO32_LE(work + 8); - x[3] = U8TO32_LE(work + 12); - x[4] = U8TO32_LE(work + 16); - x[5] = U8TO32_LE(work + 20); - x[6] = U8TO32_LE(work + 24); - x[7] = U8TO32_LE(work + 28); - x[8] = U8TO32_LE(work + 32); - x[9] = U8TO32_LE(work + 36); - x[10] = U8TO32_LE(work + 40); - x[11] = U8TO32_LE(work + 44); - x[12] = U8TO32_LE(work + 48); - x[13] = U8TO32_LE(work + 52); - x[14] = U8TO32_LE(work + 56); - x[15] = U8TO32_LE(work + 60); - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ - out[0] = ( x[0]) & 0x3fffffff; - out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; - out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; - out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; - out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; - out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; - out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; - out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; - out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff; - - /* 8*31 = 248 bits, no need to reduce */ - if (len < 32) - return; - - /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ - q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff; - q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff; - q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff; - q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; - q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; - q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; - q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; - q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; - q1[8] = ((x[15] >> 8) ); - - barrett_reduce256_modm(out, q1, out); -} - -void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { - bignum256modm_element_t x[8] = {0}; - - x[0] = U8TO32_LE(in + 0); - x[1] = U8TO32_LE(in + 4); - x[2] = U8TO32_LE(in + 8); - x[3] = U8TO32_LE(in + 12); - x[4] = U8TO32_LE(in + 16); - x[5] = U8TO32_LE(in + 20); - x[6] = U8TO32_LE(in + 24); - x[7] = U8TO32_LE(in + 28); - - out[0] = ( x[0]) & 0x3fffffff; - out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; - out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; - out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; - out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; - out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; - out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; - out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; - out[8] = ((x[ 7] >> 16) ) & 0x0000ffff; -} - -int is_reduced256_modm(const bignum256modm in) -{ - int i = 0; - uint32_t res1 = 0; - uint32_t res2 = 0; - for (i = 8; i >= 0; i--) { - res1 = (res1 << 1) | (in[i] < modm_m[i]); - res2 = (res2 << 1) | (in[i] > modm_m[i]); - } - return res1 > res2; -} - -void contract256_modm(unsigned char out[32], const bignum256modm in) { - U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30)); - U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); - U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); - U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); - U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); - U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); - U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); - U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); -} - -void contract256_window4_modm(signed char r[64], const bignum256modm in) { - char carry = 0; - signed char *quads = r; - bignum256modm_element_t i = 0, j = 0, v = 0; - - for (i = 0; i < 8; i += 2) { - v = in[i]; - for (j = 0; j < 7; j++) { - *quads++ = (v & 15); - v >>= 4; - } - v |= (in[i+1] << 2); - for (j = 0; j < 8; j++) { - *quads++ = (v & 15); - v >>= 4; - } - } - v = in[8]; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - - /* making it signed */ - carry = 0; - for(i = 0; i < 63; i++) { - r[i] += carry; - r[i+1] += (r[i] >> 4); - r[i] &= 15; - carry = (r[i] >> 3); - r[i] -= (carry << 4); - } - r[63] += carry; -} - -void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { - int i = 0, j = 0, k = 0, b = 0; - int m = (1 << (windowsize - 1)) - 1, soplen = 256; - signed char *bits = r; - bignum256modm_element_t v = 0; - - /* first put the binary expansion into r */ - for (i = 0; i < 8; i++) { - v = s[i]; - for (j = 0; j < 30; j++, v >>= 1) - *bits++ = (v & 1); - } - v = s[8]; - for (j = 0; j < 16; j++, v >>= 1) - *bits++ = (v & 1); - - /* Making it sliding window */ - for (j = 0; j < soplen; j++) { - if (!r[j]) - continue; - - for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { - if ((r[j] + (r[j + b] << b)) <= m) { - r[j] += r[j + b] << b; - r[j + b] = 0; - } else if ((r[j] - (r[j + b] << b)) >= -m) { - r[j] -= r[j + b] << b; - for (k = j + b; k < soplen; k++) { - if (!r[k]) { - r[k] = 1; - break; - } - r[k] = 0; - } - } else if (r[j + b]) { - break; - } - } - } -} - -void set256_modm(bignum256modm r, uint64_t v) { - r[0] = (bignum256modm_element_t) (v & 0x3fffffff); v >>= 30; - r[1] = (bignum256modm_element_t) (v & 0x3fffffff); v >>= 30; - r[2] = (bignum256modm_element_t) (v & 0x3fffffff); - r[3] = 0; - r[4] = 0; - r[5] = 0; - r[6] = 0; - r[7] = 0; - r[8] = 0; -} - -int get256_modm(uint64_t * v, const bignum256modm r){ - *v = 0; - int con1 = 0; - -#define NONZ(x) ((((((int64_t)(x)) - 1) >> 32) + 1) & 1) - bignum256modm_element_t c = 0; - c = r[0]; *v += (uint64_t)c & 0x3fffffff; c >>= 30; // 30 - c += r[1]; *v += ((uint64_t)c & 0x3fffffff) << 30; c >>= 30; // 60 - c += r[2]; *v += ((uint64_t)c & 0xf) << 60; con1 |= NONZ(c>>4); c >>= 30; // 64 bits - c += r[3]; con1 |= NONZ(c); c >>= 30; - c += r[4]; con1 |= NONZ(c); c >>= 30; - c += r[5]; con1 |= NONZ(c); c >>= 30; - c += r[6]; con1 |= NONZ(c); c >>= 30; - c += r[7]; con1 |= NONZ(c); c >>= 30; - c += r[8]; con1 |= NONZ(c); c >>= 30; - con1 |= NONZ(c); -#undef NONZ - - return con1 ^ 1; -} - -int eq256_modm(const bignum256modm x, const bignum256modm y){ - size_t differentbits = 0; - int len = bignum256modm_limb_size; - while (len--) { - differentbits |= (*x++ ^ *y++); - } - return (int) (1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); -} - -int cmp256_modm(const bignum256modm x, const bignum256modm y){ - int len = 2*bignum256modm_limb_size; - uint32_t a_gt = 0; - uint32_t b_gt = 0; - - // 16B chunks - while (len--) { - const uint32_t ln = (const uint32_t) len; - const uint32_t a = (x[ln>>1] >> 16*(ln & 1)) & 0xffff; - const uint32_t b = (y[ln>>1] >> 16*(ln & 1)) & 0xffff; - - const uint32_t limb_a_gt = ((b - a) >> 16) & 1; - const uint32_t limb_b_gt = ((a - b) >> 16) & 1; - a_gt |= limb_a_gt & ~b_gt; - b_gt |= limb_b_gt & ~a_gt; - } - - return a_gt - b_gt; -} - -int iszero256_modm(const bignum256modm x){ - size_t differentbits = 0; - int len = bignum256modm_limb_size; - while (len--) { - differentbits |= (*x++); - } - return (int) (1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); -} - -void copy256_modm(bignum256modm r, const bignum256modm x){ - r[0] = x[0]; - r[1] = x[1]; - r[2] = x[2]; - r[3] = x[3]; - r[4] = x[4]; - r[5] = x[5]; - r[6] = x[6]; - r[7] = x[7]; - r[8] = x[8]; -} - -int check256_modm(const bignum256modm x){ - int ok = 1; - bignum256modm t={0}, z={0}; - - ok &= iszero256_modm(x) ^ 1; - barrett_reduce256_modm(t, z, x); - ok &= eq256_modm(t, x); - return ok; -} - -void mulsub256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c){ - //(cc - aa * bb) % l - bignum256modm t={0}; - mul256_modm(t, a, b); - sub256_modm(r, c, t); -} - -void muladd256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c){ - //(cc + aa * bb) % l - bignum256modm t={0}; - mul256_modm(t, a, b); - add256_modm(r, c, t); -} diff --git a/crypto/ed25519-donna/README.md b/crypto/ed25519_donna/README.md similarity index 93% rename from crypto/ed25519-donna/README.md rename to crypto/ed25519_donna/README.md index db40438ec0d..323f5334a75 100644 --- a/crypto/ed25519-donna/README.md +++ b/crypto/ed25519_donna/README.md @@ -27,12 +27,12 @@ are made. - + - + - - + +
ImplementationSigngcciccclangVerifygcciccclang
ed25519-donna 64bit 100k110k137k327k (144k) 342k (163k) 422k (194k)
ed25519_donna 64bit 100k110k137k327k (144k) 342k (163k) 422k (194k)
amd64-64-24k 102k 355k (158k)
ed25519-donna-sse2 64bit108k111k116k353k (155k) 345k (154k) 360k (161k)
ed25519_donna-sse2 64bit108k111k116k353k (155k) 345k (154k) 360k (161k)
amd64-51-32k 116k 380k (175k)
ed25519-donna-sse2 32bit147k147k156k380k (178k) 381k (173k) 430k (192k)
ed25519-donna 32bit 597k335k380k1693k (720k)1052k (453k)1141k (493k)
ed25519_donna-sse2 32bit147k147k156k380k (178k) 381k (173k) 430k (192k)
ed25519_donna 32bit 597k335k380k1693k (720k)1052k (453k)1141k (493k)
@@ -42,11 +42,11 @@ are made. ImplementationSigngcciccclangVerifygcciccclang amd64-64-24k 68k 225k (104k) -ed25519-donna 64bit 71k 75k 90k226k (105k) 226k (112k) 277k (125k) +ed25519_donna 64bit 71k 75k 90k226k (105k) 226k (112k) 277k (125k) amd64-51-32k 72k 218k (107k) -ed25519-donna-sse2 64bit 79k 82k 92k252k (122k) 259k (124k) 282k (131k) -ed25519-donna-sse2 32bit 94k 95k103k296k (146k) 294k (137k) 306k (147k) -ed25519-donna 32bit 525k299k316k1502k (645k)959k (418k) 954k (416k) +ed25519_donna-sse2 64bit 79k 82k 92k252k (122k) 259k (124k) 282k (131k) +ed25519_donna-sse2 32bit 94k 95k103k296k (146k) 294k (137k) 306k (147k) +ed25519_donna 32bit 525k299k316k1502k (645k)959k (418k) 954k (416k) diff --git a/crypto/ed25519_donna/curve25519_donna_32bit.c b/crypto/ed25519_donna/curve25519_donna_32bit.c new file mode 100644 index 00000000000..603abeb240c --- /dev/null +++ b/crypto/ed25519_donna/curve25519_donna_32bit.c @@ -0,0 +1,953 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + 32 bit integer curve25519 implementation +*/ + +#include "ed25519_donna.h" + +static const uint32_t reduce_mask_25 = (1 << 25) - 1; +static const uint32_t reduce_mask_26 = (1 << 26) - 1; + +/* out = in */ +void curve25519_copy(bignum25519 out, const bignum25519 in) { + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + out[4] = in[4]; + out[5] = in[5]; + out[6] = in[6]; + out[7] = in[7]; + out[8] = in[8]; + out[9] = in[9]; +} + +/* out = a + b */ +void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + out[9] = a[9] + b[9]; +} + +void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c = 0; + out[0] = a[0] + b[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c = 0; + out[0] = a[0] + b[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = a[1] + b[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = a[2] + b[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = a[3] + b[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = a[4] + b[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = a[5] + b[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = a[6] + b[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = a[7] + b[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = a[8] + b[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = a[9] + b[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* multiples of p */ +static const uint32_t twoP0 = 0x07ffffda; +static const uint32_t twoP13579 = 0x03fffffe; +static const uint32_t twoP2468 = 0x07fffffe; +static const uint32_t fourP0 = 0x0fffffb4; +static const uint32_t fourP13579 = 0x07fffffc; +static const uint32_t fourP2468 = 0x0ffffffc; + +/* out = a - b */ +void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c = 0; + out[0] = twoP0 + a[0] - b[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = twoP13579 + a[1] - b[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = twoP2468 + a[2] - b[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = twoP13579 + a[3] - b[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = twoP2468 + a[4] - b[4] + c; + out[5] = twoP13579 + a[5] - b[5]; + out[6] = twoP2468 + a[6] - b[6]; + out[7] = twoP13579 + a[7] - b[7]; + out[8] = twoP2468 + a[8] - b[8]; + out[9] = twoP13579 + a[9] - b[9]; +} + +/* out = in * scalar */ +void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) { + uint64_t a = 0; + uint32_t c = 0; + a = mul32x32_64(in[0], scalar); + out[0] = (uint32_t)a & reduce_mask_26; + c = (uint32_t)(a >> 26); + a = mul32x32_64(in[1], scalar) + c; + out[1] = (uint32_t)a & reduce_mask_25; + c = (uint32_t)(a >> 25); + a = mul32x32_64(in[2], scalar) + c; + out[2] = (uint32_t)a & reduce_mask_26; + c = (uint32_t)(a >> 26); + a = mul32x32_64(in[3], scalar) + c; + out[3] = (uint32_t)a & reduce_mask_25; + c = (uint32_t)(a >> 25); + a = mul32x32_64(in[4], scalar) + c; + out[4] = (uint32_t)a & reduce_mask_26; + c = (uint32_t)(a >> 26); + a = mul32x32_64(in[5], scalar) + c; + out[5] = (uint32_t)a & reduce_mask_25; + c = (uint32_t)(a >> 25); + a = mul32x32_64(in[6], scalar) + c; + out[6] = (uint32_t)a & reduce_mask_26; + c = (uint32_t)(a >> 26); + a = mul32x32_64(in[7], scalar) + c; + out[7] = (uint32_t)a & reduce_mask_25; + c = (uint32_t)(a >> 25); + a = mul32x32_64(in[8], scalar) + c; + out[8] = (uint32_t)a & reduce_mask_26; + c = (uint32_t)(a >> 26); + a = mul32x32_64(in[9], scalar) + c; + out[9] = (uint32_t)a & reduce_mask_25; + c = (uint32_t)(a >> 25); + out[0] += c * 19; +} + +/* out = a - b, where a is the result of a basic op (add,sub) */ +void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c = 0; + out[0] = fourP0 + a[0] - b[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t c = 0; + out[0] = fourP0 + a[0] - b[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = fourP13579 + a[1] - b[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = fourP2468 + a[2] - b[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = fourP13579 + a[3] - b[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = fourP2468 + a[4] - b[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = fourP13579 + a[5] - b[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = fourP2468 + a[6] - b[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = fourP13579 + a[7] - b[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = fourP2468 + a[8] - b[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = fourP13579 + a[9] - b[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = -a */ +void curve25519_neg(bignum25519 out, const bignum25519 a) { + uint32_t c = 0; + out[0] = twoP0 - a[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = twoP13579 - a[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = twoP2468 - a[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = twoP13579 - a[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = twoP2468 - a[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = twoP13579 - a[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = twoP2468 - a[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = twoP13579 - a[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = twoP2468 - a[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = twoP13579 - a[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +/* out = a * b */ +#define curve25519_mul_noinline curve25519_mul +void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { + uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; + uint32_t s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0, s6 = 0, s7 = 0, s8 = 0, s9 = 0; + uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; + uint32_t p = 0; + + r0 = b[0]; + r1 = b[1]; + r2 = b[2]; + r3 = b[3]; + r4 = b[4]; + r5 = b[5]; + r6 = b[6]; + r7 = b[7]; + r8 = b[8]; + r9 = b[9]; + + s0 = a[0]; + s1 = a[1]; + s2 = a[2]; + s3 = a[3]; + s4 = a[4]; + s5 = a[5]; + s6 = a[6]; + s7 = a[7]; + s8 = a[8]; + s9 = a[9]; + + m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); + m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); + m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); + m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); + m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); + + r1 *= 2; + r3 *= 2; + r5 *= 2; + r7 *= 2; + + m0 = mul32x32_64(r0, s0); + m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); + m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + + mul32x32_64(r4, s0); + m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); + m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + + mul32x32_64(r8, s0); + + r1 *= 19; + r2 *= 19; + r3 = (r3 / 2) * 19; + r4 *= 19; + r5 = (r5 / 2) * 19; + r6 *= 19; + r7 = (r7 / 2) * 19; + r8 *= 19; + r9 *= 19; + + m1 += + (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); + m3 += + (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); + m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); + m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); + + r3 *= 2; + r5 *= 2; + r7 *= 2; + r9 *= 2; + + m0 += + (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + + mul32x32_64(r1, s9)); + m2 += + (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); + m4 += + (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + + mul32x32_64(r5, s9)); + m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); + m8 += (mul32x32_64(r9, s9)); + + r0 = (uint32_t)m0 & reduce_mask_26; + c = (m0 >> 26); + m1 += c; + r1 = (uint32_t)m1 & reduce_mask_25; + c = (m1 >> 25); + m2 += c; + r2 = (uint32_t)m2 & reduce_mask_26; + c = (m2 >> 26); + m3 += c; + r3 = (uint32_t)m3 & reduce_mask_25; + c = (m3 >> 25); + m4 += c; + r4 = (uint32_t)m4 & reduce_mask_26; + c = (m4 >> 26); + m5 += c; + r5 = (uint32_t)m5 & reduce_mask_25; + c = (m5 >> 25); + m6 += c; + r6 = (uint32_t)m6 & reduce_mask_26; + c = (m6 >> 26); + m7 += c; + r7 = (uint32_t)m7 & reduce_mask_25; + c = (m7 >> 25); + m8 += c; + r8 = (uint32_t)m8 & reduce_mask_26; + c = (m8 >> 26); + m9 += c; + r9 = (uint32_t)m9 & reduce_mask_25; + p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p, 19); + r0 = (uint32_t)m0 & reduce_mask_26; + p = (uint32_t)(m0 >> 26); + r1 += p; + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* out = in * in */ +void curve25519_square(bignum25519 out, const bignum25519 in) { + uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; + uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; + uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; + uint32_t p = 0; + + r0 = in[0]; + r1 = in[1]; + r2 = in[2]; + r3 = in[3]; + r4 = in[4]; + r5 = in[5]; + r6 = in[6]; + r7 = in[7]; + r8 = in[8]; + r9 = in[9]; + + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6) + + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += + (mul32x32_64(d9, r1) + mul32x32_64(d8, r2) + mul32x32_64(d7, r3) + + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += + (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3) + mul32x32_64(d7, r4) + + mul32x32_64(d6, r5 * 2)); + m2 += + (mul32x32_64(d9, r3) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + + mul32x32_64(d6, r6)); + m3 += (mul32x32_64(d9, r4) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6)); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7)); + m5 += (mul32x32_64(d9, r6) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8)); + m7 += (mul32x32_64(d9, r8)); + m8 += (mul32x32_64(d9, r9)); + + r0 = (uint32_t)m0 & reduce_mask_26; + c = (m0 >> 26); + m1 += c; + r1 = (uint32_t)m1 & reduce_mask_25; + c = (m1 >> 25); + m2 += c; + r2 = (uint32_t)m2 & reduce_mask_26; + c = (m2 >> 26); + m3 += c; + r3 = (uint32_t)m3 & reduce_mask_25; + c = (m3 >> 25); + m4 += c; + r4 = (uint32_t)m4 & reduce_mask_26; + c = (m4 >> 26); + m5 += c; + r5 = (uint32_t)m5 & reduce_mask_25; + c = (m5 >> 25); + m6 += c; + r6 = (uint32_t)m6 & reduce_mask_26; + c = (m6 >> 26); + m7 += c; + r7 = (uint32_t)m7 & reduce_mask_25; + c = (m7 >> 25); + m8 += c; + r8 = (uint32_t)m8 & reduce_mask_26; + c = (m8 >> 26); + m9 += c; + r9 = (uint32_t)m9 & reduce_mask_25; + p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p, 19); + r0 = (uint32_t)m0 & reduce_mask_26; + p = (uint32_t)(m0 >> 26); + r1 += p; + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* out = in ^ (2 * count) */ +void curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { + uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; + uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; + uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; + uint32_t p = 0; + + r0 = in[0]; + r1 = in[1]; + r2 = in[2]; + r3 = in[3]; + r4 = in[4]; + r5 = in[5]; + r6 = in[6]; + r7 = in[7]; + r8 = in[8]; + r9 = in[9]; + + do { + m0 = mul32x32_64(r0, r0); + r0 *= 2; + m1 = mul32x32_64(r0, r1); + m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); + r1 *= 2; + m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2); + m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); + r2 *= 2; + m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4) + mul32x32_64(r2, r3); + m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + + mul32x32_64(r3, r3 * 2); + r3 *= 2; + m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4); + m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4); + m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8) + mul32x32_64(r2, r7) + + mul32x32_64(r3, r6) + mul32x32_64(r4, r5 * 2); + + d6 = r6 * 19; + d7 = r7 * 2 * 19; + d8 = r8 * 19; + d9 = r9 * 2 * 19; + + m0 += + (mul32x32_64(d9, r1) + mul32x32_64(d8, r2) + mul32x32_64(d7, r3) + + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); + m1 += + (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3) + mul32x32_64(d7, r4) + + mul32x32_64(d6, r5 * 2)); + m2 += + (mul32x32_64(d9, r3) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + + mul32x32_64(d6, r6)); + m3 += (mul32x32_64(d9, r4) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6)); + m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7)); + m5 += (mul32x32_64(d9, r6) + mul32x32_64(d8, r7 * 2)); + m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8)); + m7 += (mul32x32_64(d9, r8)); + m8 += (mul32x32_64(d9, r9)); + + r0 = (uint32_t)m0 & reduce_mask_26; + c = (m0 >> 26); + m1 += c; + r1 = (uint32_t)m1 & reduce_mask_25; + c = (m1 >> 25); + m2 += c; + r2 = (uint32_t)m2 & reduce_mask_26; + c = (m2 >> 26); + m3 += c; + r3 = (uint32_t)m3 & reduce_mask_25; + c = (m3 >> 25); + m4 += c; + r4 = (uint32_t)m4 & reduce_mask_26; + c = (m4 >> 26); + m5 += c; + r5 = (uint32_t)m5 & reduce_mask_25; + c = (m5 >> 25); + m6 += c; + r6 = (uint32_t)m6 & reduce_mask_26; + c = (m6 >> 26); + m7 += c; + r7 = (uint32_t)m7 & reduce_mask_25; + c = (m7 >> 25); + m8 += c; + r8 = (uint32_t)m8 & reduce_mask_26; + c = (m8 >> 26); + m9 += c; + r9 = (uint32_t)m9 & reduce_mask_25; + p = (uint32_t)(m9 >> 25); + m0 = r0 + mul32x32_64(p, 19); + r0 = (uint32_t)m0 & reduce_mask_26; + p = (uint32_t)(m0 >> 26); + r1 += p; + } while(--count); + + out[0] = r0; + out[1] = r1; + out[2] = r2; + out[3] = r3; + out[4] = r4; + out[5] = r5; + out[6] = r6; + out[7] = r7; + out[8] = r8; + out[9] = r9; +} + +/* Take a little-endian, 32-byte number and expand it into polynomial form */ +void curve25519_expand(bignum25519 out, const unsigned char in[32]) { + uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; +#define F(s) \ + ((((uint32_t)in[s + 0])) | (((uint32_t)in[s + 1]) << 8) | (((uint32_t)in[s + 2]) << 16) | \ + (((uint32_t)in[s + 3]) << 24)) + x0 = F(0); + x1 = F(4); + x2 = F(8); + x3 = F(12); + x4 = F(16); + x5 = F(20); + x6 = F(24); + x7 = F(28); +#undef F + + out[0] = (x0)&reduce_mask_26; + out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; + out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; + out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; + out[4] = ((x3) >> 6) & reduce_mask_26; + out[5] = (x4)&reduce_mask_25; + out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; + out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; + out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; + out[9] = ((x7) >> 6) & reduce_mask_25; /* ignore the top bit */ +} + +/* Take a fully reduced polynomial form number and contract it into a + * little-endian, 32-byte array + */ +void curve25519_contract(unsigned char out[32], const bignum25519 in) { + bignum25519 f = {0}; + curve25519_copy(f, in); + +#define carry_pass() \ + f[1] += f[0] >> 26; \ + f[0] &= reduce_mask_26; \ + f[2] += f[1] >> 25; \ + f[1] &= reduce_mask_25; \ + f[3] += f[2] >> 26; \ + f[2] &= reduce_mask_26; \ + f[4] += f[3] >> 25; \ + f[3] &= reduce_mask_25; \ + f[5] += f[4] >> 26; \ + f[4] &= reduce_mask_26; \ + f[6] += f[5] >> 25; \ + f[5] &= reduce_mask_25; \ + f[7] += f[6] >> 26; \ + f[6] &= reduce_mask_26; \ + f[8] += f[7] >> 25; \ + f[7] &= reduce_mask_25; \ + f[9] += f[8] >> 26; \ + f[8] &= reduce_mask_26; + +#define carry_pass_full() \ + carry_pass() f[0] += 19 * (f[9] >> 25); \ + f[9] &= reduce_mask_25; + +#define carry_pass_final() carry_pass() f[9] &= reduce_mask_25; + + carry_pass_full() carry_pass_full() + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + f[0] += 19; + carry_pass_full() + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + f[0] += (reduce_mask_26 + 1) - 19; + f[1] += (reduce_mask_25 + 1) - 1; + f[2] += (reduce_mask_26 + 1) - 1; + f[3] += (reduce_mask_25 + 1) - 1; + f[4] += (reduce_mask_26 + 1) - 1; + f[5] += (reduce_mask_25 + 1) - 1; + f[6] += (reduce_mask_26 + 1) - 1; + f[7] += (reduce_mask_25 + 1) - 1; + f[8] += (reduce_mask_26 + 1) - 1; + f[9] += (reduce_mask_25 + 1) - 1; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + carry_pass_final() + +#undef carry_pass +#undef carry_full +#undef carry_final + + f[1] <<= 2; + f[2] <<= 3; + f[3] <<= 5; + f[4] <<= 6; + f[6] <<= 1; + f[7] <<= 3; + f[8] <<= 4; + f[9] <<= 6; + +#define F(i, s) \ + out[s + 0] |= (unsigned char)(f[i] & 0xff); \ + out[s + 1] = (unsigned char)((f[i] >> 8) & 0xff); \ + out[s + 2] = (unsigned char)((f[i] >> 16) & 0xff); \ + out[s + 3] = (unsigned char)((f[i] >> 24) & 0xff); + + out[0] = 0; + out[16] = 0; + F(0, 0); + F(1, 3); + F(2, 6); + F(3, 9); + F(4, 12); + F(5, 16); + F(6, 19); + F(7, 22); + F(8, 25); + F(9, 28); +#undef F +} + +/* if (iswap) swap(a, b) */ +void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) { + const uint32_t swap = (uint32_t)(-(int32_t)iswap); + uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0; + + x0 = swap & (a[0] ^ b[0]); + a[0] ^= x0; + b[0] ^= x0; + x1 = swap & (a[1] ^ b[1]); + a[1] ^= x1; + b[1] ^= x1; + x2 = swap & (a[2] ^ b[2]); + a[2] ^= x2; + b[2] ^= x2; + x3 = swap & (a[3] ^ b[3]); + a[3] ^= x3; + b[3] ^= x3; + x4 = swap & (a[4] ^ b[4]); + a[4] ^= x4; + b[4] ^= x4; + x5 = swap & (a[5] ^ b[5]); + a[5] ^= x5; + b[5] ^= x5; + x6 = swap & (a[6] ^ b[6]); + a[6] ^= x6; + b[6] ^= x6; + x7 = swap & (a[7] ^ b[7]); + a[7] ^= x7; + b[7] ^= x7; + x8 = swap & (a[8] ^ b[8]); + a[8] ^= x8; + b[8] ^= x8; + x9 = swap & (a[9] ^ b[9]); + a[9] ^= x9; + b[9] ^= x9; +} + +void curve25519_set(bignum25519 r, uint32_t x) { + r[0] = x & reduce_mask_26; + x >>= 26; + r[1] = x & reduce_mask_25; + r[2] = 0; + r[3] = 0; + r[4] = 0; + r[5] = 0; + r[6] = 0; + r[7] = 0; + r[8] = 0; + r[9] = 0; +} + +void curve25519_set_d(bignum25519 r) { + curve25519_copy(r, ge25519_ecd); +} + +void curve25519_set_2d(bignum25519 r) { + curve25519_copy(r, ge25519_ec2d); +} + +void curve25519_set_sqrtneg1(bignum25519 r) { + curve25519_copy(r, ge25519_sqrtneg1); +} + +int curve25519_isnegative(const bignum25519 f) { + unsigned char s[32] = {0}; + curve25519_contract(s, f); + return s[0] & 1; +} + +int curve25519_isnonzero(const bignum25519 f) { + unsigned char s[32] = {0}; + curve25519_contract(s, f); + return ((((int)(s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | s[27] | s[28] | s[29] | s[30] | s[31]) - + 1) >> + 8) + + 1) & + 0x1; +} + +void curve25519_reduce(bignum25519 out, const bignum25519 in) { + uint32_t c = 0; + out[0] = in[0]; + c = (out[0] >> 26); + out[0] &= reduce_mask_26; + out[1] = in[1] + c; + c = (out[1] >> 25); + out[1] &= reduce_mask_25; + out[2] = in[2] + c; + c = (out[2] >> 26); + out[2] &= reduce_mask_26; + out[3] = in[3] + c; + c = (out[3] >> 25); + out[3] &= reduce_mask_25; + out[4] = in[4] + c; + c = (out[4] >> 26); + out[4] &= reduce_mask_26; + out[5] = in[5] + c; + c = (out[5] >> 25); + out[5] &= reduce_mask_25; + out[6] = in[6] + c; + c = (out[6] >> 26); + out[6] &= reduce_mask_26; + out[7] = in[7] + c; + c = (out[7] >> 25); + out[7] &= reduce_mask_25; + out[8] = in[8] + c; + c = (out[8] >> 26); + out[8] &= reduce_mask_26; + out[9] = in[9] + c; + c = (out[9] >> 25); + out[9] &= reduce_mask_25; + out[0] += 19 * c; +} + +void curve25519_divpowm1(bignum25519 r, const bignum25519 u, const bignum25519 v) { + bignum25519 v3 = {0}, uv7 = {0}, t0 = {0}, t1 = {0}, t2 = {0}; + int i = 0; + + curve25519_square(v3, v); + curve25519_mul(v3, v3, v); /* v3 = v^3 */ + curve25519_square(uv7, v3); + curve25519_mul(uv7, uv7, v); + curve25519_mul(uv7, uv7, u); /* uv7 = uv^7 */ + + /*fe_pow22523(uv7, uv7);*/ + /* From fe_pow22523.c */ + + curve25519_square(t0, uv7); + curve25519_square(t1, t0); + curve25519_square(t1, t1); + curve25519_mul(t1, uv7, t1); + curve25519_mul(t0, t0, t1); + curve25519_square(t0, t0); + curve25519_mul(t0, t1, t0); + curve25519_square(t1, t0); + for(i = 0; i < 4; ++i) { + curve25519_square(t1, t1); + } + curve25519_mul(t0, t1, t0); + curve25519_square(t1, t0); + for(i = 0; i < 9; ++i) { + curve25519_square(t1, t1); + } + curve25519_mul(t1, t1, t0); + curve25519_square(t2, t1); + for(i = 0; i < 19; ++i) { + curve25519_square(t2, t2); + } + curve25519_mul(t1, t2, t1); + for(i = 0; i < 10; ++i) { + curve25519_square(t1, t1); + } + curve25519_mul(t0, t1, t0); + curve25519_square(t1, t0); + for(i = 0; i < 49; ++i) { + curve25519_square(t1, t1); + } + curve25519_mul(t1, t1, t0); + curve25519_square(t2, t1); + for(i = 0; i < 99; ++i) { + curve25519_square(t2, t2); + } + curve25519_mul(t1, t2, t1); + for(i = 0; i < 50; ++i) { + curve25519_square(t1, t1); + } + curve25519_mul(t0, t1, t0); + curve25519_square(t0, t0); + curve25519_square(t0, t0); + curve25519_mul(t0, t0, uv7); + + /* End fe_pow22523.c */ + /* t0 = (uv^7)^((q-5)/8) */ + curve25519_mul(t0, t0, v3); + curve25519_mul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ +} + +void curve25519_expand_reduce(bignum25519 out, const unsigned char in[32]) { + uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; +#define F(s) \ + ((((uint32_t)in[s + 0])) | (((uint32_t)in[s + 1]) << 8) | (((uint32_t)in[s + 2]) << 16) | \ + (((uint32_t)in[s + 3]) << 24)) + x0 = F(0); + x1 = F(4); + x2 = F(8); + x3 = F(12); + x4 = F(16); + x5 = F(20); + x6 = F(24); + x7 = F(28); +#undef F + + out[0] = (x0)&reduce_mask_26; + out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; + out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; + out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; + out[4] = ((x3) >> 6) & reduce_mask_26; + out[5] = (x4)&reduce_mask_25; + out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; + out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; + out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; + out[9] = ((x7) >> 6); // & reduce_mask_25; /* ignore the top bit */ + out[0] += 19 * (out[9] >> 25); + out[9] &= reduce_mask_25; +} diff --git a/crypto/ed25519-donna/curve25519-donna-32bit.h b/crypto/ed25519_donna/curve25519_donna_32bit.h similarity index 100% rename from crypto/ed25519-donna/curve25519-donna-32bit.h rename to crypto/ed25519_donna/curve25519_donna_32bit.h diff --git a/crypto/ed25519_donna/curve25519_donna_helpers.c b/crypto/ed25519_donna/curve25519_donna_helpers.c new file mode 100644 index 00000000000..22a7b025489 --- /dev/null +++ b/crypto/ed25519_donna/curve25519_donna_helpers.c @@ -0,0 +1,66 @@ +/* + Public domain by Andrew M. + See: https://github.com/floodyberry/curve25519-donna + + Curve25519 implementation agnostic helpers +*/ + +#include "ed25519_donna.h" + +/* + * In: b = 2^5 - 2^0 + * Out: b = 2^250 - 2^0 + */ +void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { + bignum25519 ALIGN(16) t0 = {0}, c = {0}; + + /* 2^5 - 2^0 */ /* b */ + /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); + /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); + /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); + /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); + /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); + /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); + /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); + /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); + /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); + /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); + /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); +} + +/* + * z^(p - 2) = z(2^255 - 21) + */ +void curve25519_recip(bignum25519 out, const bignum25519 z) { + bignum25519 ALIGN(16) a = {0}, t0 = {0}, b = {0}; + + /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ + /* 8 */ curve25519_square_times(t0, a, 2); + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ + /* 22 */ curve25519_square_times(t0, a, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); + /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); +} + +/* + * z^((p-5)/8) = z^(2^252 - 3) + */ +void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { + bignum25519 ALIGN(16) b, c, t0; + + /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ + /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ + /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ + /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ + /* 22 */ curve25519_square_times(t0, c, 1); + /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); + /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); + /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); + /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); +} diff --git a/crypto/ed25519-donna/curve25519-donna-helpers.h b/crypto/ed25519_donna/curve25519_donna_helpers.h similarity index 100% rename from crypto/ed25519-donna/curve25519-donna-helpers.h rename to crypto/ed25519_donna/curve25519_donna_helpers.h diff --git a/crypto/ed25519_donna/curve25519_donna_scalarmult_base.c b/crypto/ed25519_donna/curve25519_donna_scalarmult_base.c new file mode 100644 index 00000000000..ff162869aaf --- /dev/null +++ b/crypto/ed25519_donna/curve25519_donna_scalarmult_base.c @@ -0,0 +1,70 @@ +#include "ed25519_donna.h" +#include "ed25519.h" + +/* Calculates nQ where Q is the x-coordinate of a point on the curve + * + * mypublic: the packed little endian x coordinate of the resulting curve point + * n: a little endian, 32-byte number + * basepoint: a packed little endian point of the curve + */ + +void curve25519_scalarmult_donna( + curve25519_key mypublic, + const curve25519_key n, + const curve25519_key basepoint) { + bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx = {0}; + bignum25519 q = {0}, qx = {0}, qpqx = {0}, qqx = {0}, zzz = {0}, zmone = {0}; + size_t bit = 0, lastbit = 0; + int32_t i = 0; + + curve25519_expand(q, basepoint); + curve25519_copy(nqx, q); + + /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and + start pre-swapped on bit 254 */ + lastbit = 1; + + /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ + for(i = 253; i >= 2; i--) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_add(qpqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_mul(nqpqx, qpqx, nqz); + curve25519_mul(nqpqz, qx, nqpqz); + curve25519_add(qqx, nqpqx, nqpqz); + curve25519_sub(nqpqz, nqpqx, nqpqz); + curve25519_square(nqpqz, nqpqz); + curve25519_square(nqpqx, qqx); + curve25519_mul(nqpqz, nqpqz, q); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + + bit = (n[i / 8] >> (i & 7)) & 1; + curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit); + curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit); + lastbit = bit; + } + + /* the final 3 bits are always zero, so we only need to double */ + for(i = 0; i < 3; i++) { + curve25519_add(qx, nqx, nqz); + curve25519_sub(nqz, nqx, nqz); + curve25519_square(qx, qx); + curve25519_square(nqz, nqz); + curve25519_mul(nqx, qx, nqz); + curve25519_sub(nqz, qx, nqz); + curve25519_scalar_product(zzz, nqz, 121665); + curve25519_add(zzz, zzz, qx); + curve25519_mul(nqz, nqz, zzz); + } + + curve25519_recip(zmone, nqz); + curve25519_mul(nqz, nqx, zmone); + curve25519_contract(mypublic, nqz); +} diff --git a/crypto/ed25519-donna/curve25519-donna-scalarmult-base.h b/crypto/ed25519_donna/curve25519_donna_scalarmult_base.h similarity index 66% rename from crypto/ed25519-donna/curve25519-donna-scalarmult-base.h rename to crypto/ed25519_donna/curve25519_donna_scalarmult_base.h index 9f3d7989568..c6f18ed60fd 100644 --- a/crypto/ed25519-donna/curve25519-donna-scalarmult-base.h +++ b/crypto/ed25519_donna/curve25519_donna_scalarmult_base.h @@ -5,4 +5,7 @@ * basepoint: a packed little endian point of the curve */ -void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint); +void curve25519_scalarmult_donna( + curve25519_key mypublic, + const curve25519_key n, + const curve25519_key basepoint); diff --git a/crypto/ed25519_donna/ed25519.c b/crypto/ed25519_donna/ed25519.c new file mode 100644 index 00000000000..486ddcbb15c --- /dev/null +++ b/crypto/ed25519_donna/ed25519.c @@ -0,0 +1,336 @@ +/* + Public domain by Andrew M. + + Ed25519 reference implementation using ed25519_donna +*/ + +/* define ED25519_SUFFIX to have it appended to the end of each public function */ +#ifdef ED25519_SUFFIX +#define ED25519_FN3(fn, suffix) fn##suffix +#define ED25519_FN2(fn, suffix) ED25519_FN3(fn, suffix) +#define ED25519_FN(fn) ED25519_FN2(fn, ED25519_SUFFIX) +#else +#define ED25519_FN(fn) fn +#endif + +#include "ed25519_donna.h" +#include "ed25519.h" + +#include "ed25519_hash_custom.h" +#include "../rand.h" +#include "../memzero.h" + +/* + Generates a (extsk[0..31]) and aExt (extsk[32..63]) +*/ +DONNA_INLINE static void ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { + ed25519_hash(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; +} + +static void ed25519_hram( + hash_512bits hram, + const ed25519_public_key R, + const ed25519_public_key pk, + const unsigned char* m, + size_t mlen) { + ed25519_hash_context ctx; + ed25519_hash_init(&ctx); + ed25519_hash_update(&ctx, R, 32); + ed25519_hash_update(&ctx, pk, 32); + ed25519_hash_update(&ctx, m, mlen); + ed25519_hash_final(&ctx, hram); +} + +void ED25519_FN(ed25519_publickey)(const ed25519_secret_key sk, ed25519_public_key pk) { + hash_512bits extsk = {0}; + ed25519_extsk(extsk, sk); + ed25519_publickey_ext(extsk, pk); + memzero(&extsk, sizeof(extsk)); +} + +void ED25519_FN(ed25519_cosi_commit)(ed25519_secret_key nonce, ed25519_public_key commitment) { + bignum256modm r = {0}; + ge25519 ALIGN(16) R; + unsigned char extnonce[64] = {0}; + + /* r = random512 mod L */ + random_buffer(extnonce, sizeof(extnonce)); + expand256_modm(r, extnonce, sizeof(extnonce)); + memzero(&extnonce, sizeof(extnonce)); + contract256_modm(nonce, r); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + memzero(&r, sizeof(r)); + ge25519_pack(commitment, &R); +} + +int ED25519_FN(ed25519_cosi_sign)( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + const ed25519_secret_key nonce, + const ed25519_public_key R, + const ed25519_public_key pk, + ed25519_cosi_signature sig) { + bignum256modm r = {0}, S = {0}, a = {0}; + hash_512bits extsk = {0}, hram = {0}; + + ed25519_extsk(extsk, sk); + + /* r */ + expand_raw256_modm(r, nonce); + if(!is_reduced256_modm(r)) return -1; + + /* S = H(R,A,m).. */ + ed25519_hram(hram, R, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + expand256_modm(a, extsk, 32); + memzero(&extsk, sizeof(extsk)); + mul256_modm(S, S, a); + memzero(&a, sizeof(a)); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + memzero(&r, sizeof(r)); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(sig, S); + + return 0; +} + +void ED25519_FN(ed25519_sign_ext)( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + const ed25519_secret_key skext, + ed25519_signature RS) { + ed25519_hash_context ctx; + bignum256modm r = {0}, S = {0}, a = {0}; + ge25519 ALIGN(16) R = {0}; + ge25519 ALIGN(16) A = {0}; + ed25519_public_key pk = {0}; + hash_512bits extsk = {0}, hashr = {0}, hram = {0}; + + /* we don't stretch the key through hashing first since its already 64 bytes */ + + memcpy(extsk, sk, 32); + memcpy(extsk + 32, skext, 32); + + /* r = H(aExt[32..64], m) */ + ed25519_hash_init(&ctx); + ed25519_hash_update(&ctx, extsk + 32, 32); + ed25519_hash_update(&ctx, m, mlen); + ed25519_hash_final(&ctx, hashr); + expand256_modm(r, hashr, 64); + memzero(&hashr, sizeof(hashr)); + + /* R = rB */ + ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); + ge25519_pack(RS, &R); + + /* a = aExt[0..31] */ + expand256_modm(a, extsk, 32); + memzero(&extsk, sizeof(extsk)); + + /* A = aB */ + ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); + ge25519_pack(pk, &A); + + /* S = H(R,A,m).. */ + ed25519_hram(hram, RS, pk, m, mlen); + expand256_modm(S, hram, 64); + + /* S = H(R,A,m)a */ + mul256_modm(S, S, a); + memzero(&a, sizeof(a)); + + /* S = (r + H(R,A,m)a) */ + add256_modm(S, S, r); + memzero(&r, sizeof(r)); + + /* S = (r + H(R,A,m)a) mod L */ + contract256_modm(RS + 32, S); +} + +void ED25519_FN(ed25519_sign)( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + ed25519_signature RS) { + hash_512bits extsk = {0}; + ed25519_extsk(extsk, sk); + ED25519_FN(ed25519_sign_ext)(m, mlen, extsk, extsk + 32, RS); + memzero(&extsk, sizeof(extsk)); +} + +int ED25519_FN(ed25519_sign_open)( + const unsigned char* m, + size_t mlen, + const ed25519_public_key pk, + const ed25519_signature RS) { + ge25519 ALIGN(16) R = {0}, A = {0}; + hash_512bits hash = {0}; + bignum256modm hram = {0}, S = {0}; + unsigned char checkR[32] = {0}; + + if((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) return -1; + + /* hram = H(R,A,m) */ + ed25519_hram(hash, RS, pk, m, mlen); + expand256_modm(hram, hash, 64); + + /* S */ + expand_raw256_modm(S, RS + 32); + if(!is_reduced256_modm(S)) return -1; + + /* SB - H(R,A,m)A */ + ge25519_double_scalarmult_vartime(&R, &A, hram, S); + ge25519_pack(checkR, &R); + + /* check that R = SB - H(R,A,m)A */ + return ed25519_verify(RS, checkR, 32) ? 0 : -1; +} + +int ED25519_FN(ed25519_scalarmult)( + ed25519_public_key res, + const ed25519_secret_key sk, + const ed25519_public_key pk) { + bignum256modm a = {0}; + ge25519 ALIGN(16) A = {0}, P = {0}; + hash_512bits extsk = {0}; + + ed25519_extsk(extsk, sk); + expand256_modm(a, extsk, 32); + memzero(&extsk, sizeof(extsk)); + + if(!ge25519_unpack_negative_vartime(&P, pk)) { + return -1; + } + + ge25519_scalarmult(&A, &P, a); + memzero(&a, sizeof(a)); + curve25519_neg(A.x, A.x); + ge25519_pack(res, &A); + return 0; +} + +#ifndef ED25519_SUFFIX + +#include "curve25519_donna_scalarmult_base.h" + +void ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk) { + bignum256modm a = {0}; + ge25519 ALIGN(16) A = {0}; + + expand256_modm(a, extsk, 32); + + /* A = aB */ + ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); + memzero(&a, sizeof(a)); + ge25519_pack(pk, &A); +} + +int ed25519_cosi_combine_publickeys( + ed25519_public_key res, + CONST ed25519_public_key* pks, + size_t n) { + size_t i = 0; + ge25519 P = {0}; + ge25519_pniels sump = {0}; + ge25519_p1p1 sump1 = {0}; + + if(n == 1) { + memcpy(res, pks, sizeof(ed25519_public_key)); + return 0; + } + if(!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_full_to_pniels(&sump, &P); + while(i < n - 1) { + if(!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_pnielsadd(&sump, &P, &sump); + } + if(!ge25519_unpack_negative_vartime(&P, pks[i++])) { + return -1; + } + ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0); + ge25519_p1p1_to_partial(&P, &sump1); + curve25519_neg(P.x, P.x); + ge25519_pack(res, &P); + return 0; +} + +void ed25519_cosi_combine_signatures( + ed25519_signature res, + const ed25519_public_key R, + CONST ed25519_cosi_signature* sigs, + size_t n) { + bignum256modm s = {0}, t = {0}; + size_t i = 0; + + expand256_modm(s, sigs[i++], 32); + while(i < n) { + expand256_modm(t, sigs[i++], 32); + add256_modm(s, s, t); + } + memcpy(res, R, 32); + contract256_modm(res + 32, s); +} + +/* + Fast Curve25519 basepoint scalar multiplication +*/ +void curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) { + curve25519_key ec = {0}; + bignum256modm s = {0}; + bignum25519 ALIGN(16) yplusz = {0}, zminusy = {0}; + ge25519 ALIGN(16) p = {0}; + size_t i = 0; + + /* clamp */ + for(i = 0; i < 32; i++) ec[i] = e[i]; + ec[0] &= 248; + ec[31] &= 127; + ec[31] |= 64; + + expand_raw256_modm(s, ec); + memzero(&ec, sizeof(ec)); + + /* scalar * basepoint */ + ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); + memzero(&s, sizeof(s)); + + /* u = (y + z) / (z - y) */ + curve25519_add(yplusz, p.y, p.z); + curve25519_sub(zminusy, p.z, p.y); + curve25519_recip(zminusy, zminusy); + curve25519_mul(yplusz, yplusz, zminusy); + curve25519_contract(pk, yplusz); +} + +void curve25519_scalarmult( + curve25519_key mypublic, + const curve25519_key secret, + const curve25519_key basepoint) { + curve25519_key e = {0}; + size_t i = 0; + + for(i = 0; i < 32; ++i) e[i] = secret[i]; + e[0] &= 0xf8; + e[31] &= 0x7f; + e[31] |= 0x40; + curve25519_scalarmult_donna(mypublic, e, basepoint); + memzero(&e, sizeof(e)); +} + +#endif // ED25519_SUFFIX diff --git a/crypto/ed25519_donna/ed25519.h b/crypto/ed25519_donna/ed25519.h new file mode 100644 index 00000000000..f2f0017b633 --- /dev/null +++ b/crypto/ed25519_donna/ed25519.h @@ -0,0 +1,78 @@ +#ifndef ED25519_H +#define ED25519_H + +#include "../options.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef unsigned char ed25519_signature[64]; +typedef unsigned char ed25519_public_key[32]; +typedef unsigned char ed25519_secret_key[32]; + +typedef unsigned char curve25519_key[32]; + +typedef unsigned char ed25519_cosi_signature[32]; + +void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); +void ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk); + +int ed25519_sign_open( + const unsigned char* m, + size_t mlen, + const ed25519_public_key pk, + const ed25519_signature RS); +void ed25519_sign( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + ed25519_signature RS); +void ed25519_sign_ext( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + const ed25519_secret_key skext, + ed25519_signature RS); + +int ed25519_scalarmult( + ed25519_public_key res, + const ed25519_secret_key sk, + const ed25519_public_key pk); + +void curve25519_scalarmult( + curve25519_key mypublic, + const curve25519_key secret, + const curve25519_key basepoint); +void curve25519_scalarmult_basepoint(curve25519_key mypublic, const curve25519_key secret); + +#if !defined(__GNUC__) || __GNUC__ > 4 +#define CONST const +#else +#define CONST +#endif + +int ed25519_cosi_combine_publickeys( + ed25519_public_key res, + CONST ed25519_public_key* pks, + size_t n); +void ed25519_cosi_combine_signatures( + ed25519_signature res, + const ed25519_public_key R, + CONST ed25519_cosi_signature* sigs, + size_t n); +void ed25519_cosi_commit(ed25519_secret_key nonce, ed25519_public_key commitment); +int ed25519_cosi_sign( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key key, + const ed25519_secret_key nonce, + const ed25519_public_key R, + const ed25519_public_key pk, + ed25519_cosi_signature sig); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_H diff --git a/crypto/ed25519-donna/ed25519-donna.h b/crypto/ed25519_donna/ed25519_donna.h similarity index 68% rename from crypto/ed25519-donna/ed25519-donna.h rename to crypto/ed25519_donna/ed25519_donna.h index d3c34022700..00746ab8d9d 100644 --- a/crypto/ed25519-donna/ed25519-donna.h +++ b/crypto/ed25519_donna/ed25519_donna.h @@ -11,13 +11,13 @@ #ifndef ED25519_DONNA_H #define ED25519_DONNA_H -#include "ed25519-donna-portable.h" +#include "ed25519_donna_portable.h" -#include "curve25519-donna-32bit.h" +#include "curve25519_donna_32bit.h" -#include "curve25519-donna-helpers.h" +#include "curve25519_donna_helpers.h" -#include "modm-donna-32bit.h" +#include "modm_donna_32bit.h" typedef unsigned char hash_512bits[64]; @@ -28,25 +28,25 @@ typedef unsigned char hash_512bits[64]; */ typedef struct ge25519_t { - bignum25519 x, y, z, t; + bignum25519 x, y, z, t; } ge25519; typedef struct ge25519_p1p1_t { - bignum25519 x, y, z, t; + bignum25519 x, y, z, t; } ge25519_p1p1; typedef struct ge25519_niels_t { - bignum25519 ysubx, xaddy, t2d; + bignum25519 ysubx, xaddy, t2d; } ge25519_niels; typedef struct ge25519_pniels_t { - bignum25519 ysubx, xaddy, z, t2d; + bignum25519 ysubx, xaddy, z, t2d; } ge25519_pniels; -#include "ed25519-donna-basepoint-table.h" +#include "ed25519_donna_basepoint_table.h" -#include "ed25519-donna-32bit-tables.h" +#include "ed25519_donna_32bit_tables.h" -#include "ed25519-donna-impl-base.h" +#include "ed25519_donna_impl_base.h" #endif diff --git a/crypto/ed25519_donna/ed25519_donna_32bit_tables.c b/crypto/ed25519_donna/ed25519_donna_32bit_tables.c new file mode 100644 index 00000000000..4b932dd0fe7 --- /dev/null +++ b/crypto/ed25519_donna/ed25519_donna_32bit_tables.c @@ -0,0 +1,1049 @@ +#include "ed25519_donna.h" + +const ge25519 ALIGN(16) ge25519_basepoint = { + {0x0325d51a, + 0x018b5823, + 0x00f6592a, + 0x0104a92d, + 0x01a4b31d, + 0x01d6dc5c, + 0x027118fe, + 0x007fd814, + 0x013cd6e5, + 0x0085a4db}, + {0x02666658, + 0x01999999, + 0x00cccccc, + 0x01333333, + 0x01999999, + 0x00666666, + 0x03333333, + 0x00cccccc, + 0x02666666, + 0x01999999}, + {0x00000001, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000}, + {0x01b7dda3, + 0x01a2ace9, + 0x025eadbb, + 0x0003ba8a, + 0x0083c27e, + 0x00abe37d, + 0x01274732, + 0x00ccacdd, + 0x00fd78b7, + 0x019e1d7c}}; + +/* + d +*/ + +const bignum25519 ALIGN(16) ge25519_ecd = { + 0x035978a3, + 0x00d37284, + 0x03156ebd, + 0x006a0a0e, + 0x0001c029, + 0x0179e898, + 0x03a03cbb, + 0x01ce7198, + 0x02e2b6ff, + 0x01480db3}; + +const bignum25519 ALIGN(16) ge25519_ec2d = { + 0x02b2f159, + 0x01a6e509, + 0x022add7a, + 0x00d4141d, + 0x00038052, + 0x00f3d130, + 0x03407977, + 0x019ce331, + 0x01c56dff, + 0x00901b67}; + +/* + sqrt(-1) +*/ + +const bignum25519 ALIGN(16) ge25519_sqrtneg1 = { + 0x020ea0b0, + 0x0186c9d2, + 0x008f189d, + 0x0035697f, + 0x00bd0c60, + 0x01fbd7a7, + 0x02804c9e, + 0x01e16569, + 0x0004fc1d, + 0x00ae0c92}; + +const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = { + {{0x0340913e, + 0x000e4175, + 0x03d673a2, + 0x002e8a05, + 0x03f4e67c, + 0x008f8a09, + 0x00c21a34, + 0x004cf4b8, + 0x01298f81, + 0x0113f4be}, + {0x018c3b85, + 0x0124f1bd, + 0x01c325f7, + 0x0037dc60, + 0x033e4cb7, + 0x003d42c2, + 0x01a44c32, + 0x014ca4e1, + 0x03a33d4b, + 0x001f3e74}, + {0x037aaa68, + 0x00448161, + 0x0093d579, + 0x011e6556, + 0x009b67a0, + 0x0143598c, + 0x01bee5ee, + 0x00b50b43, + 0x0289f0c6, + 0x01bc45ed}}, + {{0x00fcd265, + 0x0047fa29, + 0x034faacc, + 0x01ef2e0d, + 0x00ef4d4f, + 0x014bd6bd, + 0x00f98d10, + 0x014c5026, + 0x007555bd, + 0x00aae456}, + {0x00ee9730, + 0x016c2a13, + 0x017155e4, + 0x01874432, + 0x00096a10, + 0x01016732, + 0x01a8014f, + 0x011e9823, + 0x01b9a80f, + 0x01e85938}, + {0x01d0d889, + 0x01a4cfc3, + 0x034c4295, + 0x0110e1ae, + 0x0162508c, + 0x00f2db4c, + 0x0072a2c6, + 0x0098da2e, + 0x02f12b9b, + 0x0168a09a}}, + {{0x0047d6ba, + 0x0060b0e9, + 0x0136eff2, + 0x008a5939, + 0x03540053, + 0x0064a087, + 0x02788e5c, + 0x00be7c67, + 0x033eb1b5, + 0x005529f9}, + {0x00a5bb33, + 0x00af1102, + 0x01a05442, + 0x001e3af7, + 0x02354123, + 0x00bfec44, + 0x01f5862d, + 0x00dd7ba3, + 0x03146e20, + 0x00a51733}, + {0x012a8285, + 0x00f6fc60, + 0x023f9797, + 0x003e85ee, + 0x009c3820, + 0x01bda72d, + 0x01b3858d, + 0x00d35683, + 0x0296b3bb, + 0x010eaaf9}}, + {{0x023221b1, + 0x01cb26aa, + 0x0074f74d, + 0x0099ddd1, + 0x01b28085, + 0x00192c3a, + 0x013b27c9, + 0x00fc13bd, + 0x01d2e531, + 0x0075bb75}, + {0x004ea3bf, + 0x00973425, + 0x001a4d63, + 0x01d59cee, + 0x01d1c0d4, + 0x00542e49, + 0x01294114, + 0x004fce36, + 0x029283c9, + 0x01186fa9}, + {0x01b8b3a2, + 0x00db7200, + 0x00935e30, + 0x003829f5, + 0x02cc0d7d, + 0x0077adf3, + 0x0220dd2c, + 0x0014ea53, + 0x01c6a0f9, + 0x01ea7eec}}, + {{0x039d8064, + 0x01885f80, + 0x00337e6d, + 0x01b7a902, + 0x02628206, + 0x015eb044, + 0x01e30473, + 0x0191f2d9, + 0x011fadc9, + 0x01270169}, + {0x02a8632f, + 0x0199e2a9, + 0x00d8b365, + 0x017a8de2, + 0x02994279, + 0x0086f5b5, + 0x0119e4e3, + 0x01eb39d6, + 0x0338add7, + 0x00d2e7b4}, + {0x0045af1b, + 0x013a2fe4, + 0x0245e0d6, + 0x014538ce, + 0x038bfe0f, + 0x01d4cf16, + 0x037e14c9, + 0x0160d55e, + 0x0021b008, + 0x01cf05c8}}, + {{0x01864348, + 0x01d6c092, + 0x0070262b, + 0x014bb844, + 0x00fb5acd, + 0x008deb95, + 0x003aaab5, + 0x00eff474, + 0x00029d5c, + 0x0062ad66}, + {0x02802ade, + 0x01c02122, + 0x01c4e5f7, + 0x00781181, + 0x039767fb, + 0x01703406, + 0x0342388b, + 0x01f5e227, + 0x022546d8, + 0x0109d6ab}, + {0x016089e9, + 0x00cb317f, + 0x00949b05, + 0x01099417, + 0x000c7ad2, + 0x011a8622, + 0x0088ccda, + 0x01290886, + 0x022b53df, + 0x00f71954}}, + {{0x027fbf93, + 0x01c04ecc, + 0x01ed6a0d, + 0x004cdbbb, + 0x02bbf3af, + 0x00ad5968, + 0x01591955, + 0x0094f3a2, + 0x02d17602, + 0x00099e20}, + {0x02007f6d, + 0x003088a8, + 0x03db77ee, + 0x00d5ade6, + 0x02fe12ce, + 0x0107ba07, + 0x0107097d, + 0x00482a6f, + 0x02ec346f, + 0x008d3f5f}, + {0x032ea378, + 0x0028465c, + 0x028e2a6c, + 0x018efc6e, + 0x0090df9a, + 0x01a7e533, + 0x039bfc48, + 0x010c745d, + 0x03daa097, + 0x0125ee9b}}, + {{0x028ccf0b, + 0x00f36191, + 0x021ac081, + 0x012154c8, + 0x034e0a6e, + 0x01b25192, + 0x00180403, + 0x01d7eea1, + 0x00218d05, + 0x010ed735}, + {0x03cfeaa0, + 0x01b300c4, + 0x008da499, + 0x0068c4e1, + 0x0219230a, + 0x01f2d4d0, + 0x02defd60, + 0x00e565b7, + 0x017f12de, + 0x018788a4}, + {0x03d0b516, + 0x009d8be6, + 0x03ddcbb3, + 0x0071b9fe, + 0x03ace2bd, + 0x01d64270, + 0x032d3ec9, + 0x01084065, + 0x0210ae4d, + 0x01447584}}, + {{0x0020de87, + 0x00e19211, + 0x01b68102, + 0x00b5ac97, + 0x022873c0, + 0x01942d25, + 0x01271394, + 0x0102073f, + 0x02fe2482, + 0x01c69ff9}, + {0x010e9d81, + 0x019dbbe5, + 0x0089f258, + 0x006e06b8, + 0x02951883, + 0x018f1248, + 0x019b3237, + 0x00bc7553, + 0x024ddb85, + 0x01b4c964}, + {0x01c8c854, + 0x0060ae29, + 0x01406d8e, + 0x01cff2f9, + 0x00cff451, + 0x01778d0c, + 0x03ac8c41, + 0x01552e59, + 0x036559ee, + 0x011d1b12}}, + {{0x00741147, + 0x0151b219, + 0x01092690, + 0x00e877e6, + 0x01f4d6bb, + 0x0072a332, + 0x01cd3b03, + 0x00dadff2, + 0x0097db5e, + 0x0086598d}, + {0x01c69a2b, + 0x01decf1b, + 0x02c2fa6e, + 0x013b7c4f, + 0x037beac8, + 0x013a16b5, + 0x028e7bda, + 0x01f6e8ac, + 0x01e34fe9, + 0x01726947}, + {0x01f10e67, + 0x003c73de, + 0x022b7ea2, + 0x010f32c2, + 0x03ff776a, + 0x00142277, + 0x01d38b88, + 0x00776138, + 0x03c60822, + 0x01201140}}, + {{0x0236d175, + 0x0008748e, + 0x03c6476d, + 0x013f4cdc, + 0x02eed02a, + 0x00838a47, + 0x032e7210, + 0x018bcbb3, + 0x00858de4, + 0x01dc7826}, + {0x00a37fc7, + 0x0127b40b, + 0x01957884, + 0x011d30ad, + 0x02816683, + 0x016e0e23, + 0x00b76be4, + 0x012db115, + 0x02516506, + 0x0154ce62}, + {0x00451edf, + 0x00bd749e, + 0x03997342, + 0x01cc2c4c, + 0x00eb6975, + 0x01a59508, + 0x03a516cf, + 0x00c228ef, + 0x0168ff5a, + 0x01697b47}}, + {{0x00527359, + 0x01783156, + 0x03afd75c, + 0x00ce56dc, + 0x00e4b970, + 0x001cabe9, + 0x029e0f6d, + 0x0188850c, + 0x0135fefd, + 0x00066d80}, + {0x02150e83, + 0x01448abf, + 0x02bb0232, + 0x012bf259, + 0x033c8268, + 0x00711e20, + 0x03fc148f, + 0x005e0e70, + 0x017d8bf9, + 0x0112b2e2}, + {0x02134b83, + 0x001a0517, + 0x0182c3cc, + 0x00792182, + 0x0313d799, + 0x001a3ed7, + 0x0344547e, + 0x01f24a0d, + 0x03de6ad2, + 0x00543127}}, + {{0x00dca868, + 0x00618f27, + 0x015a1709, + 0x00ddc38a, + 0x0320fd13, + 0x0036168d, + 0x0371ab06, + 0x01783fc7, + 0x0391e05f, + 0x01e29b5d}, + {0x01471138, + 0x00fca542, + 0x00ca31cf, + 0x01ca7bad, + 0x0175bfbc, + 0x01a708ad, + 0x03bce212, + 0x01244215, + 0x0075bb99, + 0x01acad68}, + {0x03a0b976, + 0x01dc12d1, + 0x011aab17, + 0x00aba0ba, + 0x029806cd, + 0x0142f590, + 0x018fd8ea, + 0x01a01545, + 0x03c4ad55, + 0x01c971ff}}, + {{0x00d098c0, + 0x000afdc7, + 0x006cd230, + 0x01276af3, + 0x03f905b2, + 0x0102994c, + 0x002eb8a4, + 0x015cfbeb, + 0x025f855f, + 0x01335518}, + {0x01cf99b2, + 0x0099c574, + 0x01a69c88, + 0x00881510, + 0x01cd4b54, + 0x0112109f, + 0x008abdc5, + 0x0074647a, + 0x0277cb1f, + 0x01e53324}, + {0x02ac5053, + 0x01b109b0, + 0x024b095e, + 0x016997b3, + 0x02f26bb6, + 0x00311021, + 0x00197885, + 0x01d0a55a, + 0x03b6fcc8, + 0x01c020d5}}, + {{0x02584a34, + 0x00e7eee0, + 0x03257a03, + 0x011e95a3, + 0x011ead91, + 0x00536202, + 0x00b1ce24, + 0x008516c6, + 0x03669d6d, + 0x004ea4a8}, + {0x00773f01, + 0x0019c9ce, + 0x019f6171, + 0x01d4afde, + 0x02e33323, + 0x01ad29b6, + 0x02ead1dc, + 0x01ed51a5, + 0x01851ad0, + 0x001bbdfa}, + {0x00577de5, + 0x00ddc730, + 0x038b9952, + 0x00f281ae, + 0x01d50390, + 0x0002e071, + 0x000780ec, + 0x010d448d, + 0x01f8a2af, + 0x00f0a5b7}}, + {{0x031f2541, + 0x00d34bae, + 0x0323ff9d, + 0x003a056d, + 0x02e25443, + 0x00a1ad05, + 0x00d1bee8, + 0x002f7f8e, + 0x03007477, + 0x002a24b1}, + {0x0114a713, + 0x01457e76, + 0x032255d5, + 0x01cc647f, + 0x02a4bdef, + 0x0153d730, + 0x00118bcf, + 0x00f755ff, + 0x013490c7, + 0x01ea674e}, + {0x02bda3e8, + 0x00bb490d, + 0x00f291ea, + 0x000abf40, + 0x01dea321, + 0x002f9ce0, + 0x00b2b193, + 0x00fa54b5, + 0x0128302f, + 0x00a19d8b}}, + {{0x022ef5bd, + 0x01638af3, + 0x038c6f8a, + 0x01a33a3d, + 0x039261b2, + 0x01bb89b8, + 0x010bcf9d, + 0x00cf42a9, + 0x023d6f17, + 0x01da1bca}, + {0x00e35b25, + 0x000d824f, + 0x0152e9cf, + 0x00ed935d, + 0x020b8460, + 0x01c7b83f, + 0x00c969e5, + 0x01a74198, + 0x0046a9d9, + 0x00cbc768}, + {0x01597c6a, + 0x0144a99b, + 0x00a57551, + 0x0018269c, + 0x023c464c, + 0x0009b022, + 0x00ee39e1, + 0x0114c7f2, + 0x038a9ad2, + 0x01584c17}}, + {{0x03b0c0d5, + 0x00b30a39, + 0x038a6ce4, + 0x01ded83a, + 0x01c277a6, + 0x01010a61, + 0x0346d3eb, + 0x018d995e, + 0x02f2c57c, + 0x000c286b}, + {0x0092aed1, + 0x0125e37b, + 0x027ca201, + 0x001a6b6b, + 0x03290f55, + 0x0047ba48, + 0x018d916c, + 0x01a59062, + 0x013e35d4, + 0x0002abb1}, + {0x003ad2aa, + 0x007ddcc0, + 0x00c10f76, + 0x0001590b, + 0x002cfca6, + 0x000ed23e, + 0x00ee4329, + 0x00900f04, + 0x01c24065, + 0x0082fa70}}, + {{0x02025e60, + 0x003912b8, + 0x0327041c, + 0x017e5ee5, + 0x02c0ecec, + 0x015a0d1c, + 0x02b1ce7c, + 0x0062220b, + 0x0145067e, + 0x01a5d931}, + {0x009673a6, + 0x00e1f609, + 0x00927c2a, + 0x016faa37, + 0x01650ef0, + 0x016f63b5, + 0x03cd40e1, + 0x003bc38f, + 0x0361f0ac, + 0x01d42acc}, + {0x02f81037, + 0x008ca0e8, + 0x017e23d1, + 0x011debfe, + 0x01bcbb68, + 0x002e2563, + 0x03e8add6, + 0x000816e5, + 0x03fb7075, + 0x0153e5ac}}, + {{0x02b11ecd, + 0x016bf185, + 0x008f22ef, + 0x00e7d2bb, + 0x0225d92e, + 0x00ece785, + 0x00508873, + 0x017e16f5, + 0x01fbe85d, + 0x01e39a0e}, + {0x01669279, + 0x017c810a, + 0x024941f5, + 0x0023ebeb, + 0x00eb7688, + 0x005760f1, + 0x02ca4146, + 0x0073cde7, + 0x0052bb75, + 0x00f5ffa7}, + {0x03b8856b, + 0x00cb7dcd, + 0x02f14e06, + 0x001820d0, + 0x01d74175, + 0x00e59e22, + 0x03fba550, + 0x00484641, + 0x03350088, + 0x01c3c9a3}}, + {{0x00dcf355, + 0x0104481c, + 0x0022e464, + 0x01f73fe7, + 0x00e03325, + 0x0152b698, + 0x02ef769a, + 0x00973663, + 0x00039b8c, + 0x0101395b}, + {0x01805f47, + 0x019160ec, + 0x03832cd0, + 0x008b06eb, + 0x03d4d717, + 0x004cb006, + 0x03a75b8f, + 0x013b3d30, + 0x01cfad88, + 0x01f034d1}, + {0x0078338a, + 0x01c7d2e3, + 0x02bc2b23, + 0x018b3f05, + 0x0280d9aa, + 0x005f3d44, + 0x0220a95a, + 0x00eeeb97, + 0x0362aaec, + 0x00835d51}}, + {{0x01b9f543, + 0x013fac4d, + 0x02ad93ae, + 0x018ef464, + 0x0212cdf7, + 0x01138ba9, + 0x011583ab, + 0x019c3d26, + 0x028790b4, + 0x00e2e2b6}, + {0x033bb758, + 0x01f0dbf1, + 0x03734bd1, + 0x0129b1e5, + 0x02b3950e, + 0x003bc922, + 0x01a53ec8, + 0x018c5532, + 0x006f3cee, + 0x00ae3c79}, + {0x0351f95d, + 0x0012a737, + 0x03d596b8, + 0x017658fe, + 0x00ace54a, + 0x008b66da, + 0x0036c599, + 0x012a63a2, + 0x032ceba1, + 0x00126bac}}, + {{0x03dcfe7e, + 0x019f4f18, + 0x01c81aee, + 0x0044bc2b, + 0x00827165, + 0x014f7c13, + 0x03b430f0, + 0x00bf96cc, + 0x020c8d62, + 0x01471997}, + {0x01fc7931, + 0x001f42dd, + 0x00ba754a, + 0x005bd339, + 0x003fbe49, + 0x016b3930, + 0x012a159c, + 0x009f83b0, + 0x03530f67, + 0x01e57b85}, + {0x02ecbd81, + 0x0096c294, + 0x01fce4a9, + 0x017701a5, + 0x0175047d, + 0x00ee4a31, + 0x012686e5, + 0x008efcd4, + 0x0349dc54, + 0x01b3466f}}, + {{0x02179ca3, + 0x01d86414, + 0x03f0afd0, + 0x00305964, + 0x015c7428, + 0x0099711e, + 0x015d5442, + 0x00c71014, + 0x01b40b2e, + 0x01d483cf}, + {0x01afc386, + 0x01984859, + 0x036203ff, + 0x0045c6a8, + 0x0020a8aa, + 0x00990baa, + 0x03313f10, + 0x007ceede, + 0x027429e4, + 0x017806ce}, + {0x039357a1, + 0x0142f8f4, + 0x0294a7b6, + 0x00eaccf4, + 0x0259edb3, + 0x01311e6e, + 0x004d326f, + 0x0130c346, + 0x01ccef3c, + 0x01c424b2}}, + {{0x0364918c, + 0x00148fc0, + 0x01638a7b, + 0x01a1fd5b, + 0x028ad013, + 0x0081e5a4, + 0x01a54f33, + 0x0174e101, + 0x003d0257, + 0x003a856c}, + {0x00051dcf, + 0x00f62b1d, + 0x0143d0ad, + 0x0042adbd, + 0x000fda90, + 0x01743ceb, + 0x0173e5e4, + 0x017bc749, + 0x03b7137a, + 0x0105ce96}, + {0x00f9218a, + 0x015b8c7c, + 0x00e102f8, + 0x0158d7e2, + 0x0169a5b8, + 0x00b2f176, + 0x018b347a, + 0x014cfef2, + 0x0214a4e3, + 0x017f1595}}, + {{0x006d7ae5, + 0x0195c371, + 0x0391e26d, + 0x0062a7c6, + 0x003f42ab, + 0x010dad86, + 0x024f8198, + 0x01542b2a, + 0x0014c454, + 0x0189c471}, + {0x0390988e, + 0x00b8799d, + 0x02e44912, + 0x0078e2e6, + 0x00075654, + 0x01923eed, + 0x0040cd72, + 0x00a37c76, + 0x0009d466, + 0x00c8531d}, + {0x02651770, + 0x00609d01, + 0x0286c265, + 0x0134513c, + 0x00ee9281, + 0x005d223c, + 0x035c760c, + 0x00679b36, + 0x0073ecb8, + 0x016faa50}}, + {{0x02c89be4, + 0x016fc244, + 0x02f38c83, + 0x018beb72, + 0x02b3ce2c, + 0x0097b065, + 0x034f017b, + 0x01dd957f, + 0x00148f61, + 0x00eab357}, + {0x0343d2f8, + 0x003398fc, + 0x011e368e, + 0x00782a1f, + 0x00019eea, + 0x00117b6f, + 0x0128d0d1, + 0x01a5e6bb, + 0x01944f1b, + 0x012b41e1}, + {0x03318301, + 0x018ecd30, + 0x0104d0b1, + 0x0038398b, + 0x03726701, + 0x019da88c, + 0x002d9769, + 0x00a7a681, + 0x031d9028, + 0x00ebfc32}}, + {{0x0220405e, + 0x0171face, + 0x02d930f8, + 0x017f6d6a, + 0x023b8c47, + 0x0129d5f9, + 0x02972456, + 0x00a3a524, + 0x006f4cd2, + 0x004439fa}, + {0x00c53505, + 0x0190c2fd, + 0x00507244, + 0x009930f9, + 0x01a39270, + 0x01d327c6, + 0x0399bc47, + 0x01cfe13d, + 0x0332bd99, + 0x00b33e7d}, + {0x0203f5e4, + 0x003627b5, + 0x00018af8, + 0x01478581, + 0x004a2218, + 0x002e3bb7, + 0x039384d0, + 0x0146ea62, + 0x020b9693, + 0x0017155f}}, + {{0x03c97e6f, + 0x00738c47, + 0x03b5db1f, + 0x01808fcf, + 0x01e8fc98, + 0x01ed25dd, + 0x01bf5045, + 0x00eb5c2b, + 0x0178fe98, + 0x01b85530}, + {0x01c20eb0, + 0x01aeec22, + 0x030b9eee, + 0x01b7d07e, + 0x0187e16f, + 0x014421fb, + 0x009fa731, + 0x0040b6d7, + 0x00841861, + 0x00a27fbc}, + {0x02d69abf, + 0x0058cdbf, + 0x0129f9ec, + 0x013c19ae, + 0x026c5b93, + 0x013a7fe7, + 0x004bb2ba, + 0x0063226f, + 0x002a95ca, + 0x01abefd9}}, + {{0x02f5d2c1, + 0x00378318, + 0x03734fb5, + 0x01258073, + 0x0263f0f6, + 0x01ad70e0, + 0x01b56d06, + 0x01188fbd, + 0x011b9503, + 0x0036d2e1}, + {0x0113a8cc, + 0x01541c3e, + 0x02ac2bbc, + 0x01d95867, + 0x01f47459, + 0x00ead489, + 0x00ab5b48, + 0x01db3b45, + 0x00edb801, + 0x004b024f}, + {0x00b8190f, + 0x011fe4c2, + 0x00621f82, + 0x010508d7, + 0x001a5a76, + 0x00c7d7fd, + 0x03aab96d, + 0x019cd9dc, + 0x019c6635, + 0x00ceaa1e}}, + {{0x01085cf2, + 0x01fd47af, + 0x03e3f5e1, + 0x004b3e99, + 0x01e3d46a, + 0x0060033c, + 0x015ff0a8, + 0x0150cdd8, + 0x029e8e21, + 0x008cf1bc}, + {0x00156cb1, + 0x003d623f, + 0x01a4f069, + 0x00d8d053, + 0x01b68aea, + 0x01ca5ab6, + 0x0316ae43, + 0x0134dc44, + 0x001c8d58, + 0x0084b343}, + {0x0318c781, + 0x0135441f, + 0x03a51a5e, + 0x019293f4, + 0x0048bb37, + 0x013d3341, + 0x0143151e, + 0x019c74e1, + 0x00911914, + 0x0076ddde}}, + {{0x006bc26f, + 0x00d48e5f, + 0x00227bbe, + 0x00629ea8, + 0x01ea5f8b, + 0x0179a330, + 0x027a1d5f, + 0x01bf8f8e, + 0x02d26e2a, + 0x00c6b65e}, + {0x01701ab6, + 0x0051da77, + 0x01b4b667, + 0x00a0ce7c, + 0x038ae37b, + 0x012ac852, + 0x03a0b0fe, + 0x0097c2bb, + 0x00a017d2, + 0x01eb8b2a}, + {0x0120b962, + 0x0005fb42, + 0x0353b6fd, + 0x0061f8ce, + 0x007a1463, + 0x01560a64, + 0x00e0a792, + 0x01907c92, + 0x013a6622, + 0x007b47f1}}}; diff --git a/crypto/ed25519-donna/ed25519-donna-32bit-tables.h b/crypto/ed25519_donna/ed25519_donna_32bit_tables.h similarity index 100% rename from crypto/ed25519-donna/ed25519-donna-32bit-tables.h rename to crypto/ed25519_donna/ed25519_donna_32bit_tables.h diff --git a/crypto/ed25519_donna/ed25519_donna_basepoint_table.c b/crypto/ed25519_donna/ed25519_donna_basepoint_table.c new file mode 100644 index 00000000000..29d81467587 --- /dev/null +++ b/crypto/ed25519_donna/ed25519_donna_basepoint_table.c @@ -0,0 +1,1796 @@ +#include "ed25519_donna.h" + +/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ +const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = { + {0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, + 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, + 0x92, 0x2f, 0xfd, 0x44, 0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, + 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, + 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07, 0x59, 0xbb, 0x6f, 0x4b, 0x67, 0x15, + 0xbd, 0xdb, 0xea, 0xa5, 0xa2, 0xee, 0x00, 0x3f, 0xe1, 0x41, 0xfa, 0xc6, 0x57, 0xc9, + 0x1c, 0x9d, 0xd4, 0xcd, 0xca, 0xec, 0x16, 0xaf, 0x1f, 0xbe, 0x0e, 0x4f}, + {0xa8, 0xd5, 0xb4, 0x42, 0x60, 0xa5, 0x99, 0x8a, 0xf6, 0xac, 0x60, 0x4e, 0x0c, 0x81, + 0x2b, 0x8f, 0xaa, 0x37, 0x6e, 0xb1, 0x6b, 0x23, 0x9e, 0xe0, 0x55, 0x25, 0xc9, 0x69, + 0xa6, 0x95, 0xb5, 0x6b, 0xd7, 0x71, 0x3c, 0x93, 0xfc, 0xe7, 0x24, 0x92, 0xb5, 0xf5, + 0x0f, 0x7a, 0x96, 0x9d, 0x46, 0x9f, 0x02, 0x07, 0xd6, 0xe1, 0x65, 0x9a, 0xa6, 0x5a, + 0x2e, 0x2e, 0x7d, 0xa8, 0x3f, 0x06, 0x0c, 0x59, 0x02, 0x68, 0xd3, 0xda, 0xaa, 0x7e, + 0x34, 0x6e, 0x05, 0x48, 0xee, 0x83, 0x93, 0x59, 0xf3, 0xba, 0x26, 0x68, 0x07, 0xe6, + 0x10, 0xbe, 0xca, 0x3b, 0xb8, 0xd1, 0x5e, 0x16, 0x0a, 0x4f, 0x31, 0x49}, + {0x65, 0xd2, 0xfc, 0xa4, 0xe8, 0x1f, 0x61, 0x56, 0x7d, 0xba, 0xc1, 0xe5, 0xfd, 0x53, + 0xd3, 0x3b, 0xbd, 0xd6, 0x4b, 0x21, 0x1a, 0xf3, 0x31, 0x81, 0x62, 0xda, 0x5b, 0x55, + 0x87, 0x15, 0xb9, 0x2a, 0x30, 0x97, 0xee, 0x4c, 0xa8, 0xb0, 0x25, 0xaf, 0x8a, 0x4b, + 0x86, 0xe8, 0x30, 0x84, 0x5a, 0x02, 0x32, 0x67, 0x01, 0x9f, 0x02, 0x50, 0x1b, 0xc1, + 0xf4, 0xf8, 0x80, 0x9a, 0x1b, 0x4e, 0x16, 0x7a, 0x34, 0x48, 0x67, 0xf1, 0xf4, 0x11, + 0xf2, 0x9b, 0x95, 0xf8, 0x2d, 0xf6, 0x17, 0x6b, 0x4e, 0xb8, 0x4e, 0x2a, 0x72, 0x5b, + 0x07, 0x6f, 0xde, 0xd7, 0x21, 0x2a, 0xbb, 0x63, 0xb9, 0x04, 0x9a, 0x54}, + {0xbf, 0x18, 0x68, 0x05, 0x0a, 0x05, 0xfe, 0x95, 0xa9, 0xfa, 0x60, 0x56, 0x71, 0x89, + 0x7e, 0x32, 0x73, 0x50, 0xa0, 0x06, 0xcd, 0xe3, 0xe8, 0xc3, 0x9a, 0xa4, 0x45, 0x74, + 0x4c, 0x3f, 0x93, 0x27, 0x9f, 0x09, 0xfc, 0x8e, 0xb9, 0x51, 0x73, 0x28, 0x38, 0x25, + 0xfd, 0x7d, 0xf4, 0xc6, 0x65, 0x67, 0x65, 0x92, 0x0a, 0xfb, 0x3d, 0x8d, 0x34, 0xca, + 0x27, 0x87, 0xe5, 0x21, 0x03, 0x91, 0x0e, 0x68, 0xb0, 0x26, 0x14, 0xe5, 0xec, 0x45, + 0x1e, 0xbf, 0x94, 0x0f, 0xba, 0x6d, 0x3d, 0xc6, 0x2b, 0xe3, 0xc0, 0x52, 0xf8, 0x8c, + 0xd5, 0x74, 0x29, 0xe4, 0x18, 0x4c, 0xe6, 0xb0, 0xb1, 0x79, 0xf0, 0x44}, + {0xba, 0xd6, 0x47, 0xa4, 0xc3, 0x82, 0x91, 0x7f, 0xb7, 0x29, 0x27, 0x4b, 0xd1, 0x14, + 0x00, 0xd5, 0x87, 0xa0, 0x64, 0xb8, 0x1c, 0xf1, 0x3c, 0xe3, 0xf3, 0x55, 0x1b, 0xeb, + 0x73, 0x7e, 0x4a, 0x15, 0x33, 0xbb, 0xa5, 0x08, 0x44, 0xbc, 0x12, 0xa2, 0x02, 0xed, + 0x5e, 0xc7, 0xc3, 0x48, 0x50, 0x8d, 0x44, 0xec, 0xbf, 0x5a, 0x0c, 0xeb, 0x1b, 0xdd, + 0xeb, 0x06, 0xe2, 0x46, 0xf1, 0xcc, 0x45, 0x29, 0xb3, 0x03, 0xd0, 0xe7, 0x79, 0xa1, + 0x32, 0xc8, 0x7e, 0x4d, 0x12, 0x00, 0x0a, 0x9d, 0x72, 0x5f, 0xf3, 0x8f, 0x6d, 0x0e, + 0xa1, 0xd4, 0xc1, 0x62, 0x98, 0x7a, 0xb2, 0x38, 0x59, 0xac, 0xb8, 0x68}, + {0xa4, 0x8c, 0x7d, 0x7b, 0xb6, 0x06, 0x98, 0x49, 0x39, 0x27, 0xd2, 0x27, 0x84, 0xe2, + 0x5b, 0x57, 0xb9, 0x53, 0x45, 0x20, 0xe7, 0x5c, 0x08, 0xbb, 0x84, 0x78, 0x41, 0xae, + 0x41, 0x4c, 0xb6, 0x38, 0x31, 0x71, 0x15, 0x77, 0xeb, 0xee, 0x0c, 0x3a, 0x88, 0xaf, + 0xc8, 0x00, 0x89, 0x15, 0x27, 0x9b, 0x36, 0xa7, 0x59, 0xda, 0x68, 0xb6, 0x65, 0x80, + 0xbd, 0x38, 0xcc, 0xa2, 0xb6, 0x7b, 0xe5, 0x51, 0xa4, 0xe3, 0x9d, 0x68, 0x91, 0xad, + 0x9d, 0x8f, 0x37, 0x91, 0xfb, 0xf8, 0x28, 0x24, 0x5f, 0x17, 0x88, 0xb9, 0xcf, 0x9f, + 0x32, 0xb5, 0x0a, 0x05, 0x9f, 0xc0, 0x54, 0x13, 0xa2, 0xdf, 0x65, 0x78}, + {0xb1, 0x21, 0x32, 0xaa, 0x9a, 0x2c, 0x6f, 0xba, 0xa7, 0x23, 0xba, 0x3b, 0x53, 0x21, + 0xa0, 0x6c, 0x3a, 0x2c, 0x19, 0x92, 0x4f, 0x76, 0xea, 0x9d, 0xe0, 0x17, 0x53, 0x2e, + 0x5d, 0xdd, 0x6e, 0x1d, 0xbf, 0xa3, 0x4e, 0x94, 0xd0, 0x5c, 0x1a, 0x6b, 0xd2, 0xc0, + 0x9d, 0xb3, 0x3a, 0x35, 0x70, 0x74, 0x49, 0x2e, 0x54, 0x28, 0x82, 0x52, 0xb2, 0x71, + 0x7e, 0x92, 0x3c, 0x28, 0x69, 0xea, 0x1b, 0x46, 0x36, 0xda, 0x0f, 0xab, 0xac, 0x8a, + 0x7a, 0x21, 0xc8, 0x49, 0x35, 0x3d, 0x54, 0xc6, 0x28, 0xa5, 0x68, 0x75, 0xab, 0x13, + 0x8b, 0x5b, 0xd0, 0x37, 0x37, 0xbc, 0x2c, 0x3a, 0x62, 0xef, 0x3c, 0x23}, + {0xd9, 0x34, 0x92, 0xf3, 0xed, 0x5d, 0xa7, 0xe2, 0xf9, 0x58, 0xb5, 0xe1, 0x80, 0x76, + 0x3d, 0x96, 0xfb, 0x23, 0x3c, 0x6e, 0xac, 0x41, 0x27, 0x2c, 0xc3, 0x01, 0x0e, 0x32, + 0xa1, 0x24, 0x90, 0x3a, 0x8f, 0x3e, 0xdd, 0x04, 0x66, 0x59, 0xb7, 0x59, 0x2c, 0x70, + 0x88, 0xe2, 0x77, 0x03, 0xb3, 0x6c, 0x23, 0xc3, 0xd9, 0x5e, 0x66, 0x9c, 0x33, 0xb1, + 0x2f, 0xe5, 0xbc, 0x61, 0x60, 0xe7, 0x15, 0x09, 0x7e, 0xa3, 0x34, 0xa8, 0x35, 0xe8, + 0x7d, 0xdf, 0xea, 0x57, 0x98, 0x68, 0xda, 0x9c, 0xe1, 0x8b, 0x26, 0xb3, 0x67, 0x71, + 0x36, 0x85, 0x11, 0x2c, 0xc2, 0xd5, 0xef, 0xdb, 0xd9, 0xb3, 0x9e, 0x58}, + {0x5e, 0x51, 0xaa, 0x49, 0x54, 0x63, 0x5b, 0xed, 0x3a, 0x82, 0xc6, 0x0b, 0x9f, 0xc4, + 0x65, 0xa8, 0xc4, 0xd1, 0x42, 0x5b, 0xe9, 0x1f, 0x0c, 0x85, 0xb9, 0x15, 0xd3, 0x03, + 0x6f, 0x6d, 0xd7, 0x30, 0x1d, 0x9c, 0x2f, 0x63, 0x0e, 0xdd, 0xcc, 0x2e, 0x15, 0x31, + 0x89, 0x76, 0x96, 0xb6, 0xd0, 0x51, 0x58, 0x7a, 0x63, 0xa8, 0x6b, 0xb7, 0xdf, 0x52, + 0x39, 0xef, 0x0e, 0xa0, 0x49, 0x7d, 0xd3, 0x6d, 0xc7, 0xe4, 0x06, 0x21, 0x17, 0x44, + 0x44, 0x6c, 0x69, 0x7f, 0x8d, 0x92, 0x80, 0xd6, 0x53, 0xfb, 0x26, 0x3f, 0x4d, 0x69, + 0xa4, 0x9e, 0x73, 0xb4, 0xb0, 0x4b, 0x86, 0x2e, 0x11, 0x97, 0xc6, 0x10}, + {0xde, 0x5f, 0xbe, 0x7d, 0x27, 0xc4, 0x93, 0x64, 0xa2, 0x7e, 0xad, 0x19, 0xad, 0x4f, + 0x5d, 0x26, 0x90, 0x45, 0x30, 0x46, 0xc8, 0xdf, 0x00, 0x0e, 0x09, 0xfe, 0x66, 0xed, + 0xab, 0x1c, 0xe6, 0x25, 0x05, 0xc8, 0x58, 0x83, 0xa0, 0x2a, 0xa6, 0x0c, 0x47, 0x42, + 0x20, 0x7a, 0xe3, 0x4a, 0x3d, 0x6a, 0xdc, 0xed, 0x11, 0x3b, 0xa6, 0xd3, 0x64, 0x74, + 0xef, 0x06, 0x08, 0x55, 0xaf, 0x9b, 0xbf, 0x03, 0x04, 0x66, 0x58, 0xcc, 0x28, 0xe1, + 0x13, 0x3f, 0x7e, 0x74, 0x59, 0xb4, 0xec, 0x73, 0x58, 0x6f, 0xf5, 0x68, 0x12, 0xcc, + 0xed, 0x3d, 0xb6, 0xa0, 0x2c, 0xe2, 0x86, 0x45, 0x63, 0x78, 0x6d, 0x56}, + {0x34, 0x08, 0xc1, 0x9c, 0x9f, 0xa4, 0x37, 0x16, 0x51, 0xc4, 0x9b, 0xa8, 0xd5, 0x56, + 0x8e, 0xbc, 0xdb, 0xd2, 0x7f, 0x7f, 0x0f, 0xec, 0xb5, 0x1c, 0xd9, 0x35, 0xcc, 0x5e, + 0xca, 0x5b, 0x97, 0x33, 0xd0, 0x2f, 0x5a, 0xc6, 0x85, 0x42, 0x05, 0xa1, 0xc3, 0x67, + 0x16, 0xf3, 0x2a, 0x11, 0x64, 0x6c, 0x58, 0xee, 0x1a, 0x73, 0x40, 0xe2, 0x0a, 0x68, + 0x2a, 0xb2, 0x93, 0x47, 0xf3, 0xa5, 0xfb, 0x14, 0xd4, 0xf7, 0x85, 0x69, 0x16, 0x46, + 0xd7, 0x3c, 0x57, 0x00, 0xc8, 0xc9, 0x84, 0x5e, 0x3e, 0x59, 0x1e, 0x13, 0x61, 0x7b, + 0xb6, 0xf2, 0xc3, 0x2f, 0x6c, 0x52, 0xfc, 0x83, 0xea, 0x9c, 0x82, 0x14}, + {0xc2, 0x95, 0xdd, 0x97, 0x84, 0x7b, 0x43, 0xff, 0xa7, 0xb5, 0x4e, 0xaa, 0x30, 0x4e, + 0x74, 0x6c, 0x8b, 0xe8, 0x85, 0x3c, 0x61, 0x5d, 0x0c, 0x9e, 0x73, 0x81, 0x75, 0x5f, + 0x1e, 0xc7, 0xd9, 0x2f, 0xb8, 0xec, 0x71, 0x4e, 0x2f, 0x0b, 0xe7, 0x21, 0xe3, 0x77, + 0xa4, 0x40, 0xb9, 0xdd, 0x56, 0xe6, 0x80, 0x4f, 0x1d, 0xce, 0xce, 0x56, 0x65, 0xbf, + 0x7e, 0x7b, 0x5d, 0x53, 0xc4, 0x3b, 0xfc, 0x05, 0xdd, 0xde, 0xaf, 0x52, 0xae, 0xb3, + 0xb8, 0x24, 0xcf, 0x30, 0x3b, 0xed, 0x8c, 0x63, 0x95, 0x34, 0x95, 0x81, 0xbe, 0xa9, + 0x83, 0xbc, 0xa4, 0x33, 0x04, 0x1f, 0x65, 0x5c, 0x47, 0x67, 0x37, 0x37}, + {0xd9, 0xad, 0xd1, 0x40, 0xfd, 0x99, 0xba, 0x2f, 0x27, 0xd0, 0xf4, 0x96, 0x6f, 0x16, + 0x07, 0xb3, 0xae, 0x3b, 0xf0, 0x15, 0x52, 0xf0, 0x63, 0x43, 0x99, 0xf9, 0x18, 0x3b, + 0x6c, 0xa5, 0xbe, 0x1f, 0x90, 0x65, 0x24, 0x14, 0xcb, 0x95, 0x40, 0x63, 0x35, 0x55, + 0xc1, 0x16, 0x40, 0x14, 0x12, 0xef, 0x60, 0xbc, 0x10, 0x89, 0x0c, 0x14, 0x38, 0x9e, + 0x8c, 0x7c, 0x90, 0x30, 0x57, 0x90, 0xf5, 0x6b, 0x8a, 0x5b, 0x41, 0xe1, 0xf1, 0x78, + 0xa7, 0x0f, 0x7e, 0xa7, 0xc3, 0xba, 0xf7, 0x9f, 0x40, 0x06, 0x50, 0x9a, 0xa2, 0x9a, + 0xb8, 0xd7, 0x52, 0x6f, 0x56, 0x5a, 0x63, 0x7a, 0xf6, 0x1c, 0x52, 0x02}, + {0x94, 0x52, 0x9d, 0x0a, 0x0b, 0xee, 0x3f, 0x51, 0x66, 0x5a, 0xdf, 0x0f, 0x5c, 0xe7, + 0x98, 0x8f, 0xce, 0x07, 0xe1, 0xbf, 0x88, 0x86, 0x61, 0xd4, 0xed, 0x2c, 0x38, 0x71, + 0x7e, 0x0a, 0xa0, 0x3f, 0xe4, 0x5e, 0x2f, 0x77, 0x20, 0x67, 0x14, 0xb1, 0xce, 0x9a, + 0x07, 0x96, 0xb1, 0x94, 0xf8, 0xe8, 0x4a, 0x82, 0xac, 0x00, 0x4d, 0x22, 0xf8, 0x4a, + 0xc4, 0x6c, 0xcd, 0xf7, 0xd9, 0x53, 0x17, 0x00, 0x34, 0xdb, 0x3d, 0x96, 0x2d, 0x23, + 0x69, 0x3c, 0x58, 0x38, 0x97, 0xb4, 0xda, 0x87, 0xde, 0x1d, 0x85, 0xf2, 0x91, 0xa0, + 0xf9, 0xd1, 0xd7, 0xaa, 0xb6, 0xed, 0x48, 0xa0, 0x2f, 0xfe, 0xb5, 0x12}, + {0x4d, 0xe3, 0xfc, 0x96, 0xc4, 0xfb, 0xf0, 0x71, 0xed, 0x5b, 0xf3, 0xad, 0x6b, 0x82, + 0xb9, 0x73, 0x61, 0xc5, 0x28, 0xff, 0x61, 0x72, 0x04, 0xd2, 0x6f, 0x20, 0xb1, 0x6f, + 0xf9, 0x76, 0x9b, 0x74, 0x92, 0x1e, 0x6f, 0xad, 0x26, 0x7c, 0x2b, 0xdf, 0x13, 0x89, + 0x4b, 0x50, 0x23, 0xd3, 0x66, 0x4b, 0xc3, 0x8b, 0x1c, 0x75, 0xc0, 0x9d, 0x40, 0x8c, + 0xb8, 0xc7, 0x96, 0x07, 0xc2, 0x93, 0x7e, 0x6f, 0x05, 0xae, 0xa6, 0xae, 0x04, 0xf6, + 0x5a, 0x1f, 0x99, 0x9c, 0xe4, 0xbe, 0xf1, 0x51, 0x23, 0xc1, 0x66, 0x6b, 0xff, 0xee, + 0xb5, 0x08, 0xa8, 0x61, 0x51, 0x21, 0xe0, 0x01, 0x0f, 0xc1, 0xce, 0x0f}, + {0x44, 0x1e, 0xfe, 0x49, 0xa6, 0x58, 0x4d, 0x64, 0x7e, 0x77, 0xad, 0x31, 0xa2, 0xae, + 0xfc, 0x21, 0xd2, 0xd0, 0x7f, 0x88, 0x5a, 0x1c, 0x44, 0x02, 0xf3, 0x11, 0xc5, 0x83, + 0x71, 0xaa, 0x01, 0x49, 0x45, 0x4e, 0x24, 0xc4, 0x9d, 0xd2, 0xf2, 0x3d, 0x0a, 0xde, + 0xd8, 0x93, 0x74, 0x0e, 0x02, 0x2b, 0x4d, 0x21, 0x0c, 0x82, 0x7e, 0x06, 0xc8, 0x6c, + 0x0a, 0xb9, 0xea, 0x6f, 0x16, 0x79, 0x37, 0x41, 0xf0, 0xf8, 0x1a, 0x8c, 0x54, 0xb7, + 0xb1, 0x08, 0xb4, 0x99, 0x62, 0x24, 0x7c, 0x7a, 0x0f, 0xce, 0x39, 0xd9, 0x06, 0x1e, + 0xf9, 0xb0, 0x60, 0xf7, 0x13, 0x12, 0x6d, 0x72, 0x7b, 0x88, 0xbb, 0x41}, + {0xbe, 0x46, 0x43, 0x74, 0x44, 0x7d, 0xe8, 0x40, 0x25, 0x2b, 0xb5, 0x15, 0xd4, 0xda, + 0x48, 0x1d, 0x3e, 0x60, 0x3b, 0xa1, 0x18, 0x8a, 0x3a, 0x7c, 0xf7, 0xbd, 0xcd, 0x2f, + 0xc1, 0x28, 0xb7, 0x4e, 0xae, 0x91, 0x66, 0x7c, 0x59, 0x4c, 0x23, 0x7e, 0xc8, 0xb4, + 0x85, 0x0a, 0x3d, 0x9d, 0x88, 0x64, 0xe7, 0xfa, 0x4a, 0x35, 0x0c, 0xc9, 0xe2, 0xda, + 0x1d, 0x9e, 0x6a, 0x0c, 0x07, 0x1e, 0x87, 0x0a, 0x89, 0x89, 0xbc, 0x4b, 0x99, 0xb5, + 0x01, 0x33, 0x60, 0x42, 0xdd, 0x5b, 0x3a, 0xae, 0x6b, 0x73, 0x3c, 0x9e, 0xd5, 0x19, + 0xe2, 0xad, 0x61, 0x0d, 0x64, 0xd4, 0x85, 0x26, 0x0f, 0x30, 0xe7, 0x3e}, + {0xb7, 0xd6, 0x7d, 0x9e, 0xe4, 0x55, 0xd2, 0xf5, 0xac, 0x1e, 0x0b, 0x61, 0x5c, 0x11, + 0x16, 0x80, 0xca, 0x87, 0xe1, 0x92, 0x5d, 0x97, 0x99, 0x3c, 0xc2, 0x25, 0x91, 0x97, + 0x62, 0x57, 0x81, 0x13, 0x18, 0x75, 0x1e, 0x84, 0x47, 0x79, 0xfa, 0x43, 0xd7, 0x46, + 0x9c, 0x63, 0x59, 0xfa, 0xc6, 0xe5, 0x74, 0x2b, 0x05, 0xe3, 0x1d, 0x5e, 0x06, 0xa1, + 0x30, 0x90, 0xb8, 0xcf, 0xa2, 0xc6, 0x47, 0x7d, 0xe0, 0xd6, 0xf0, 0x8e, 0x14, 0xd0, + 0xda, 0x3f, 0x3c, 0x6f, 0x54, 0x91, 0x9a, 0x74, 0x3e, 0x9d, 0x57, 0x81, 0xbb, 0x26, + 0x10, 0x62, 0xec, 0x71, 0x80, 0xec, 0xc9, 0x34, 0x8d, 0xf5, 0x8c, 0x14}, + {0x27, 0xf0, 0x34, 0x79, 0xf6, 0x92, 0xa4, 0x46, 0xa9, 0x0a, 0x84, 0xf6, 0xbe, 0x84, + 0x99, 0x46, 0x54, 0x18, 0x61, 0x89, 0x2a, 0xbc, 0xa1, 0x5c, 0xd4, 0xbb, 0x5d, 0xbd, + 0x1e, 0xfa, 0xf2, 0x3f, 0x6d, 0x75, 0xe4, 0x9a, 0x7d, 0x2f, 0x57, 0xe2, 0x7f, 0x48, + 0xf3, 0x88, 0xbb, 0x45, 0xc3, 0x56, 0x8d, 0xa8, 0x60, 0x69, 0x6d, 0x0b, 0xd1, 0x9f, + 0xb9, 0xa1, 0xae, 0x4e, 0xad, 0xeb, 0x8f, 0x27, 0x66, 0x39, 0x93, 0x8c, 0x1f, 0x68, + 0xaa, 0xb1, 0x98, 0x0c, 0x29, 0x20, 0x9c, 0x94, 0x21, 0x8c, 0x52, 0x3c, 0x9d, 0x21, + 0x91, 0x52, 0x11, 0x39, 0x7b, 0x67, 0x9c, 0xfe, 0x02, 0xdd, 0x04, 0x41}, + {0x2a, 0x42, 0x24, 0x11, 0x5e, 0xbf, 0xb2, 0x72, 0xb5, 0x3a, 0xa3, 0x98, 0x33, 0x0c, + 0xfa, 0xa1, 0x66, 0xb6, 0x52, 0xfa, 0x01, 0x61, 0xcb, 0x94, 0xd5, 0x53, 0xaf, 0xaf, + 0x00, 0x3b, 0x86, 0x2c, 0xb8, 0x6a, 0x09, 0xdb, 0x06, 0x4e, 0x21, 0x81, 0x35, 0x4f, + 0xe4, 0x0c, 0xc9, 0xb6, 0xa8, 0x21, 0xf5, 0x2a, 0x9e, 0x40, 0x2a, 0xc1, 0x24, 0x65, + 0x81, 0xa4, 0xfc, 0x8e, 0xa4, 0xb5, 0x65, 0x01, 0x76, 0x6a, 0x84, 0xa0, 0x74, 0xa4, + 0x90, 0xf1, 0xc0, 0x7c, 0x2f, 0xcd, 0x84, 0xf9, 0xef, 0x12, 0x8f, 0x2b, 0xaa, 0x58, + 0x06, 0x29, 0x5e, 0x69, 0xb8, 0xc8, 0xfe, 0xbf, 0xd9, 0x67, 0x1b, 0x59}, + {0xfa, 0x9b, 0xb4, 0x80, 0x1c, 0x0d, 0x2f, 0x31, 0x8a, 0xec, 0xf3, 0xab, 0x5e, 0x51, + 0x79, 0x59, 0x88, 0x1c, 0xf0, 0x9e, 0xc0, 0x33, 0x70, 0x72, 0xcb, 0x7b, 0x8f, 0xca, + 0xc7, 0x2e, 0xe0, 0x3d, 0x5d, 0xb5, 0x18, 0x9f, 0x71, 0xb3, 0xb9, 0x99, 0x1e, 0x64, + 0x8c, 0xa1, 0xfa, 0xe5, 0x65, 0xe4, 0xed, 0x05, 0x9f, 0xc2, 0x36, 0x11, 0x08, 0x61, + 0x8b, 0x12, 0x30, 0x70, 0x86, 0x4f, 0x9b, 0x48, 0xef, 0x92, 0xeb, 0x3a, 0x2d, 0x10, + 0x32, 0xd2, 0x61, 0xa8, 0x16, 0x61, 0xb4, 0x53, 0x62, 0xe1, 0x24, 0xaa, 0x0b, 0x19, + 0xe7, 0xab, 0x7e, 0x3d, 0xbf, 0xbe, 0x6c, 0x49, 0xba, 0xfb, 0xf5, 0x49}, + {0xd4, 0xcf, 0x5b, 0x8a, 0x10, 0x9a, 0x94, 0x30, 0xeb, 0x73, 0x64, 0xbc, 0x70, 0xdd, + 0x40, 0xdc, 0x1c, 0x0d, 0x7c, 0x30, 0xc1, 0x94, 0xc2, 0x92, 0x74, 0x6e, 0xfa, 0xcb, + 0x6d, 0xa8, 0x04, 0x56, 0x2e, 0x57, 0x9c, 0x1e, 0x8c, 0x62, 0x5d, 0x15, 0x41, 0x47, + 0x88, 0xc5, 0xac, 0x86, 0x4d, 0x8a, 0xeb, 0x63, 0x57, 0x51, 0xf6, 0x52, 0xa3, 0x91, + 0x5b, 0x51, 0x67, 0x88, 0xc2, 0xa6, 0xa1, 0x06, 0xb6, 0x64, 0x17, 0x7c, 0xd4, 0xd1, + 0x88, 0x72, 0x51, 0x8b, 0x41, 0xe0, 0x40, 0x11, 0x54, 0x72, 0xd1, 0xf6, 0xac, 0x18, + 0x60, 0x1a, 0x03, 0x9f, 0xc6, 0x42, 0x27, 0xfe, 0x89, 0x9e, 0x98, 0x20}, + {0x7f, 0xcc, 0x2d, 0x3a, 0xfd, 0x77, 0x97, 0x49, 0x92, 0xd8, 0x4f, 0xa5, 0x2c, 0x7c, + 0x85, 0x32, 0xa0, 0xe3, 0x07, 0xd2, 0x64, 0xd8, 0x79, 0xa2, 0x29, 0x7e, 0xa6, 0x0c, + 0x1d, 0xed, 0x03, 0x04, 0x2e, 0xec, 0xea, 0x85, 0x8b, 0x27, 0x74, 0x16, 0xdf, 0x2b, + 0xcb, 0x7a, 0x07, 0xdc, 0x21, 0x56, 0x5a, 0xf4, 0xcb, 0x61, 0x16, 0x4c, 0x0a, 0x64, + 0xd3, 0x95, 0x05, 0xf7, 0x50, 0x99, 0x0b, 0x73, 0x52, 0xc5, 0x4e, 0x87, 0x35, 0x2d, + 0x4b, 0xc9, 0x8d, 0x6f, 0x24, 0x98, 0xcf, 0xc8, 0xe6, 0xc5, 0xce, 0x35, 0xc0, 0x16, + 0xfa, 0x46, 0xcb, 0xf7, 0xcc, 0x3d, 0x30, 0x08, 0x43, 0x45, 0xd7, 0x5b}, + {0xc2, 0x4c, 0xb2, 0x28, 0x95, 0xd1, 0x9a, 0x7f, 0x81, 0xc1, 0x35, 0x63, 0x65, 0x54, + 0x6b, 0x7f, 0x36, 0x72, 0xc0, 0x4f, 0x6e, 0xb6, 0xb8, 0x66, 0x83, 0xad, 0x80, 0x73, + 0x00, 0x78, 0x3a, 0x13, 0x2a, 0x79, 0xe7, 0x15, 0x21, 0x93, 0xc4, 0x85, 0xc9, 0xdd, + 0xcd, 0xbd, 0xa2, 0x89, 0x4c, 0xc6, 0x62, 0xd7, 0xa3, 0xad, 0xa8, 0x3d, 0x1e, 0x9d, + 0x2c, 0xf8, 0x67, 0x30, 0x12, 0xdb, 0xb7, 0x5b, 0xbe, 0x62, 0xca, 0xc6, 0x67, 0xf4, + 0x61, 0x09, 0xee, 0x52, 0x19, 0x21, 0xd6, 0x21, 0xec, 0x04, 0x70, 0x47, 0xd5, 0x9b, + 0x77, 0x60, 0x23, 0x18, 0xd2, 0xe0, 0xf0, 0x58, 0x6d, 0xca, 0x0d, 0x74}, + {0x4e, 0xce, 0xcf, 0x52, 0x07, 0xee, 0x48, 0xdf, 0xb7, 0x08, 0xec, 0x06, 0xf3, 0xfa, + 0xff, 0xc3, 0xc4, 0x59, 0x54, 0xb9, 0x2a, 0x0b, 0x71, 0x05, 0x8d, 0xa3, 0x3e, 0x96, + 0xfa, 0x25, 0x1d, 0x16, 0x3c, 0x43, 0x78, 0x04, 0x57, 0x8c, 0x1a, 0x23, 0x9d, 0x43, + 0x81, 0xc2, 0x0e, 0x27, 0xb5, 0xb7, 0x9f, 0x07, 0xd9, 0xe3, 0xea, 0x99, 0xaa, 0xdb, + 0xd9, 0x03, 0x2b, 0x6c, 0x25, 0xf5, 0x03, 0x2c, 0x7d, 0xa4, 0x53, 0x7b, 0x75, 0x18, + 0x0f, 0x79, 0x79, 0x58, 0x0c, 0xcf, 0x30, 0x01, 0x7b, 0x30, 0xf9, 0xf7, 0x7e, 0x25, + 0x77, 0x3d, 0x90, 0x31, 0xaf, 0xbb, 0x96, 0xbd, 0xbd, 0x68, 0x94, 0x69}, + {0xcf, 0xfe, 0xda, 0xf4, 0x46, 0x2f, 0x1f, 0xbd, 0xf7, 0xd6, 0x7f, 0xa4, 0x14, 0x01, + 0xef, 0x7c, 0x7f, 0xb3, 0x47, 0x4a, 0xda, 0xfd, 0x1f, 0xd3, 0x85, 0x57, 0x90, 0x73, + 0xa4, 0x19, 0x52, 0x52, 0x48, 0x19, 0xa9, 0x6a, 0xe6, 0x3d, 0xdd, 0xd8, 0xcc, 0xd2, + 0xc0, 0x2f, 0xc2, 0x64, 0x50, 0x48, 0x2f, 0xea, 0xfd, 0x34, 0x66, 0x24, 0x48, 0x9b, + 0x3a, 0x2e, 0x4a, 0x6c, 0x4e, 0x1c, 0x3e, 0x29, 0xe1, 0x12, 0x51, 0x92, 0x4b, 0x13, + 0x6e, 0x37, 0xa0, 0x5d, 0xa1, 0xdc, 0xb5, 0x78, 0x37, 0x70, 0x11, 0x31, 0x1c, 0x46, + 0xaf, 0x89, 0x45, 0xb0, 0x23, 0x28, 0x03, 0x7f, 0x44, 0x5c, 0x60, 0x5b}, + {0x89, 0x7c, 0xc4, 0x20, 0x59, 0x80, 0x65, 0xb9, 0xcc, 0x8f, 0x3b, 0x92, 0x0c, 0x10, + 0xf0, 0xe7, 0x77, 0xef, 0xe2, 0x02, 0x65, 0x25, 0x01, 0x00, 0xee, 0xb3, 0xae, 0xa8, + 0xce, 0x6d, 0xa7, 0x24, 0x4c, 0xf0, 0xe7, 0xf0, 0xc6, 0xfe, 0xe9, 0x3b, 0x62, 0x49, + 0xe3, 0x75, 0x9e, 0x57, 0x6a, 0x86, 0x1a, 0xe6, 0x1d, 0x1e, 0x16, 0xef, 0x42, 0x55, + 0xd5, 0xbd, 0x5a, 0xcc, 0xf4, 0xfe, 0x12, 0x2f, 0x40, 0xc7, 0xc0, 0xdf, 0xb2, 0x22, + 0x45, 0x0a, 0x07, 0xa4, 0xc9, 0x40, 0x7f, 0x6e, 0xd0, 0x10, 0x68, 0xf6, 0xcf, 0x78, + 0x41, 0x14, 0xcf, 0xc6, 0x90, 0x37, 0xa4, 0x18, 0x25, 0x7b, 0x60, 0x5e}, + {0x18, 0x18, 0xdf, 0x6c, 0x8f, 0x1d, 0xb3, 0x58, 0xa2, 0x58, 0x62, 0xc3, 0x4f, 0xa7, + 0xcf, 0x35, 0x6e, 0x1d, 0xe6, 0x66, 0x4f, 0xff, 0xb3, 0xe1, 0xf7, 0xd5, 0xcd, 0x6c, + 0xab, 0xac, 0x67, 0x50, 0x14, 0xcf, 0x96, 0xa5, 0x1c, 0x43, 0x2c, 0xa0, 0x00, 0xe4, + 0xd3, 0xae, 0x40, 0x2d, 0xc4, 0xe3, 0xdb, 0x26, 0x0f, 0x2e, 0x80, 0x26, 0x45, 0xd2, + 0x68, 0x70, 0x45, 0x9e, 0x13, 0x33, 0x1f, 0x20, 0x51, 0x9d, 0x03, 0x08, 0x6b, 0x7f, + 0x52, 0xfd, 0x06, 0x00, 0x7c, 0x01, 0x64, 0x49, 0xb1, 0x18, 0xa8, 0xa4, 0x25, 0x2e, + 0xb0, 0x0e, 0x22, 0xd5, 0x75, 0x03, 0x46, 0x62, 0x88, 0xba, 0x7c, 0x39}, + {0xb2, 0x59, 0x59, 0xf0, 0x93, 0x30, 0xc1, 0x30, 0x76, 0x79, 0xa9, 0xe9, 0x8d, 0xa1, + 0x3a, 0xe2, 0x26, 0x5e, 0x1d, 0x72, 0x91, 0xd4, 0x2f, 0x22, 0x3a, 0x6c, 0x6e, 0x76, + 0x20, 0xd3, 0x39, 0x23, 0xe7, 0x79, 0x13, 0xc8, 0xfb, 0xc3, 0x15, 0x78, 0xf1, 0x2a, + 0xe1, 0xdd, 0x20, 0x94, 0x61, 0xa6, 0xd5, 0xfd, 0xa8, 0x85, 0xf8, 0xc0, 0xa9, 0xff, + 0x52, 0xc2, 0xe1, 0xc1, 0x22, 0x40, 0x1b, 0x77, 0xa7, 0x2f, 0x3a, 0x51, 0x86, 0xd9, + 0x7d, 0xd8, 0x08, 0xcf, 0xd4, 0xf9, 0x71, 0x9b, 0xac, 0xf5, 0xb3, 0x83, 0xa2, 0x1e, + 0x1b, 0xc3, 0x6b, 0xd0, 0x76, 0x1a, 0x97, 0x19, 0x92, 0x18, 0x1a, 0x33}, + {0xc6, 0x80, 0x4f, 0xfb, 0x45, 0x6f, 0x16, 0xf5, 0xcf, 0x75, 0xc7, 0x61, 0xde, 0xc7, + 0x36, 0x9c, 0x1c, 0xd9, 0x41, 0x90, 0x1b, 0xe8, 0xd4, 0xe3, 0x21, 0xfe, 0xbd, 0x83, + 0x6b, 0x7c, 0x16, 0x31, 0xaf, 0x72, 0x75, 0x9d, 0x3a, 0x2f, 0x51, 0x26, 0x9e, 0x4a, + 0x07, 0x68, 0x88, 0xe2, 0xcb, 0x5b, 0xc4, 0xf7, 0x80, 0x11, 0xc1, 0xc1, 0xed, 0x84, + 0x7b, 0xa6, 0x49, 0xf6, 0x9f, 0x61, 0xc9, 0x1a, 0x68, 0x10, 0x4b, 0x52, 0x42, 0x38, + 0x2b, 0xf2, 0x87, 0xe9, 0x9c, 0xee, 0x3b, 0x34, 0x68, 0x50, 0xc8, 0x50, 0x62, 0x4a, + 0x84, 0x71, 0x9d, 0xfc, 0x11, 0xb1, 0x08, 0x1f, 0x34, 0x36, 0x24, 0x61}, + {0x8d, 0x89, 0x4e, 0x87, 0xdb, 0x41, 0x9d, 0xd9, 0x20, 0xdc, 0x07, 0x6c, 0xf1, 0xa5, + 0xfe, 0x09, 0xbc, 0x9b, 0x0f, 0xd0, 0x67, 0x2c, 0x3d, 0x79, 0x40, 0xff, 0x5e, 0x9e, + 0x30, 0xe2, 0xeb, 0x46, 0x38, 0x26, 0x2d, 0x1a, 0xe3, 0x49, 0x63, 0x8b, 0x35, 0xfd, + 0xd3, 0x9b, 0x00, 0xb7, 0xdf, 0x9d, 0xa4, 0x6b, 0xa0, 0xa3, 0xb8, 0xf1, 0x8b, 0x7f, + 0x45, 0x04, 0xd9, 0x78, 0x31, 0xaa, 0x22, 0x15, 0x38, 0x49, 0x61, 0x69, 0x53, 0x2f, + 0x38, 0x2c, 0x10, 0x6d, 0x2d, 0xb7, 0x9a, 0x40, 0xfe, 0xda, 0x27, 0xf2, 0x46, 0xb6, + 0x91, 0x33, 0xc8, 0xe8, 0x6c, 0x30, 0x24, 0x05, 0xf5, 0x70, 0xfe, 0x45}, + {0x8c, 0x0b, 0x0c, 0x96, 0xa6, 0x75, 0x48, 0xda, 0x20, 0x2f, 0x0e, 0xef, 0x76, 0xd0, + 0x68, 0x5b, 0xd4, 0x8f, 0x0b, 0x3d, 0xcf, 0x51, 0xfb, 0x07, 0xd4, 0x92, 0xe3, 0xa0, + 0x23, 0x16, 0x8d, 0x42, 0x91, 0x14, 0x95, 0xc8, 0x20, 0x49, 0xf2, 0x62, 0xa2, 0x0c, + 0x63, 0x3f, 0xc8, 0x07, 0xf0, 0x05, 0xb8, 0xd4, 0xc9, 0xf5, 0xd2, 0x45, 0xbb, 0x6f, + 0x45, 0x22, 0x7a, 0xb5, 0x6d, 0x9f, 0x61, 0x16, 0xfd, 0x08, 0xa3, 0x01, 0x44, 0x4a, + 0x4f, 0x08, 0xac, 0xca, 0xa5, 0x76, 0xc3, 0x19, 0x22, 0xa8, 0x7d, 0xbc, 0xd1, 0x43, + 0x46, 0xde, 0xb8, 0xde, 0xc6, 0x38, 0xbd, 0x60, 0x2d, 0x59, 0x81, 0x1d}, + {0x5f, 0xac, 0x0d, 0xa6, 0x56, 0x87, 0x36, 0x61, 0x57, 0xdc, 0xab, 0xeb, 0x6a, 0x2f, + 0xe0, 0x17, 0x7d, 0x0f, 0xce, 0x4c, 0x2d, 0x3f, 0x19, 0x7f, 0xf0, 0xdc, 0xec, 0x89, + 0x77, 0x4a, 0x23, 0x20, 0xe8, 0xc5, 0x85, 0x7b, 0x9f, 0xb6, 0x65, 0x87, 0xb2, 0xba, + 0x68, 0xd1, 0x8b, 0x67, 0xf0, 0x6f, 0x9b, 0x0f, 0x33, 0x1d, 0x7c, 0xe7, 0x70, 0x3a, + 0x7c, 0x8e, 0xaf, 0xb0, 0x51, 0x6d, 0x5f, 0x3a, 0x52, 0xb2, 0x78, 0x71, 0xb6, 0x0d, + 0xd2, 0x76, 0x60, 0xd1, 0x1e, 0xd5, 0xf9, 0x34, 0x1c, 0x07, 0x70, 0x11, 0xe4, 0xb3, + 0x20, 0x4a, 0x2a, 0xf6, 0x66, 0xe3, 0xff, 0x3c, 0x35, 0x82, 0xd6, 0x7c}, + {0xb6, 0xfa, 0x87, 0xd8, 0x5b, 0xa4, 0xe1, 0x0b, 0x6e, 0x3b, 0x40, 0xba, 0x32, 0x6a, + 0x84, 0x2a, 0x00, 0x60, 0x6e, 0xe9, 0x12, 0x10, 0x92, 0xd9, 0x43, 0x09, 0xdc, 0x3b, + 0x86, 0xc8, 0x38, 0x28, 0xf3, 0xf4, 0xac, 0x68, 0x60, 0xcd, 0x65, 0xa6, 0xd3, 0xe3, + 0xd7, 0x3c, 0x18, 0x2d, 0xd9, 0x42, 0xd9, 0x25, 0x60, 0x33, 0x9d, 0x38, 0x59, 0x57, + 0xff, 0xd8, 0x2c, 0x2b, 0x3b, 0x25, 0xf0, 0x3e, 0x30, 0x50, 0x46, 0x4a, 0xcf, 0xb0, + 0x6b, 0xd1, 0xab, 0x77, 0xc5, 0x15, 0x41, 0x6b, 0x49, 0xfa, 0x9d, 0x41, 0xab, 0xf4, + 0x8a, 0xae, 0xcf, 0x82, 0x12, 0x28, 0xa8, 0x06, 0xa6, 0xb8, 0xdc, 0x21}, + {0xc8, 0x9f, 0x9d, 0x8c, 0x46, 0x04, 0x60, 0x5c, 0xcb, 0xa3, 0x2a, 0xd4, 0x6e, 0x09, + 0x40, 0x25, 0x9c, 0x2f, 0xee, 0x12, 0x4c, 0x4d, 0x5b, 0x12, 0xab, 0x1d, 0xa3, 0x94, + 0x81, 0xd0, 0xc3, 0x0b, 0xba, 0x31, 0x77, 0xbe, 0xfa, 0x00, 0x8d, 0x9a, 0x89, 0x18, + 0x9e, 0x62, 0x7e, 0x60, 0x03, 0x82, 0x7f, 0xd9, 0xf3, 0x43, 0x37, 0x02, 0xcc, 0xb2, + 0x8b, 0x67, 0x6f, 0x6c, 0xbf, 0x0d, 0x84, 0x5d, 0x8b, 0xe1, 0x9f, 0x30, 0x0d, 0x38, + 0x6e, 0x70, 0xc7, 0x65, 0xe1, 0xb9, 0xa6, 0x2d, 0xb0, 0x6e, 0xab, 0x20, 0xae, 0x7d, + 0x99, 0xba, 0xbb, 0x57, 0xdd, 0x96, 0xc1, 0x2a, 0x23, 0x76, 0x42, 0x3a}, + {0xfa, 0x84, 0x70, 0x8a, 0x2c, 0x43, 0x42, 0x4b, 0x45, 0xe5, 0xb9, 0xdf, 0xe3, 0x19, + 0x8a, 0x89, 0x5d, 0xe4, 0x58, 0x9c, 0x21, 0x00, 0x9f, 0xbe, 0xd1, 0xeb, 0x6d, 0xa1, + 0xce, 0x77, 0xf1, 0x1f, 0xcb, 0x7e, 0x44, 0xdb, 0x72, 0xc1, 0xf8, 0x3b, 0xbd, 0x2d, + 0x28, 0xc6, 0x1f, 0xc4, 0xcf, 0x5f, 0xfe, 0x15, 0xaa, 0x75, 0xc0, 0xff, 0xac, 0x80, + 0xf9, 0xa9, 0xe1, 0x24, 0xe8, 0xc9, 0x70, 0x07, 0xfd, 0xb5, 0xb5, 0x45, 0x9a, 0xd9, + 0x61, 0xcf, 0x24, 0x79, 0x3a, 0x1b, 0xe9, 0x84, 0x09, 0x86, 0x89, 0x3e, 0x3e, 0x30, + 0x19, 0x09, 0x30, 0xe7, 0x1e, 0x0b, 0x50, 0x41, 0xfd, 0x64, 0xf2, 0x39}, + {0x9c, 0xe2, 0xe7, 0xdb, 0x17, 0x34, 0xad, 0xa7, 0x9c, 0x13, 0x9c, 0x2b, 0x6a, 0x37, + 0x94, 0xbd, 0xa9, 0x7b, 0x59, 0x93, 0x8e, 0x1b, 0xe9, 0xa0, 0x40, 0x98, 0x88, 0x68, + 0x34, 0xd7, 0x12, 0x17, 0xe1, 0x7b, 0x09, 0xfe, 0xab, 0x4a, 0x9b, 0xd1, 0x29, 0x19, + 0xe0, 0xdf, 0xe1, 0xfc, 0x6d, 0xa4, 0xff, 0xf1, 0xa6, 0x2c, 0x94, 0x08, 0xc9, 0xc3, + 0x4e, 0xf1, 0x35, 0x2c, 0x27, 0x21, 0xc6, 0x65, 0xdd, 0x93, 0x31, 0xce, 0xf8, 0x89, + 0x2b, 0xe7, 0xbb, 0xc0, 0x25, 0xa1, 0x56, 0x33, 0x10, 0x4d, 0x83, 0xfe, 0x1c, 0x2e, + 0x3d, 0xa9, 0x19, 0x04, 0x72, 0xe2, 0x9c, 0xb1, 0x0a, 0x80, 0xf9, 0x22}, + {0xcb, 0xf8, 0x9e, 0x3e, 0x8a, 0x36, 0x5a, 0x60, 0x15, 0x47, 0x50, 0xa5, 0x22, 0xc0, + 0xe9, 0xe3, 0x8f, 0x24, 0x24, 0x5f, 0xb0, 0x48, 0x3d, 0x55, 0xe5, 0x26, 0x76, 0x64, + 0xcd, 0x16, 0xf4, 0x13, 0xac, 0xfd, 0x6e, 0x9a, 0xdd, 0x9f, 0x02, 0x42, 0x41, 0x49, + 0xa5, 0x34, 0xbe, 0xce, 0x12, 0xb9, 0x7b, 0xf3, 0xbd, 0x87, 0xb9, 0x64, 0x0f, 0x64, + 0xb4, 0xca, 0x98, 0x85, 0xd3, 0xa4, 0x71, 0x41, 0x8c, 0x4c, 0xc9, 0x99, 0xaa, 0x58, + 0x27, 0xfa, 0x07, 0xb8, 0x00, 0xb0, 0x6f, 0x6f, 0x00, 0x23, 0x92, 0x53, 0xda, 0xad, + 0xdd, 0x91, 0xd2, 0xfb, 0xab, 0xd1, 0x4b, 0x57, 0xfa, 0x14, 0x82, 0x50}, + {0x4b, 0xfe, 0xd6, 0x3e, 0x15, 0x69, 0x02, 0xc2, 0xc4, 0x77, 0x1d, 0x51, 0x39, 0x67, + 0x5a, 0xa6, 0x94, 0xaf, 0x14, 0x2c, 0x46, 0x26, 0xde, 0xcb, 0x4b, 0xa7, 0xab, 0x6f, + 0xec, 0x60, 0xf9, 0x22, 0xd6, 0x03, 0xd0, 0x53, 0xbb, 0x15, 0x1a, 0x46, 0x65, 0xc9, + 0xf3, 0xbc, 0x88, 0x28, 0x10, 0xb2, 0x5a, 0x3a, 0x68, 0x6c, 0x75, 0x76, 0xc5, 0x27, + 0x47, 0xb4, 0x6c, 0xc8, 0xa4, 0x58, 0x77, 0x3a, 0x76, 0x50, 0xae, 0x93, 0xf6, 0x11, + 0x81, 0x54, 0xa6, 0x54, 0xfd, 0x1d, 0xdf, 0x21, 0xae, 0x1d, 0x65, 0x5e, 0x11, 0xf3, + 0x90, 0x8c, 0x24, 0x12, 0x94, 0xf4, 0xe7, 0x8d, 0x5f, 0xd1, 0x9f, 0x5d}, + {0x7f, 0x72, 0x63, 0x6d, 0xd3, 0x08, 0x14, 0x03, 0x33, 0xb5, 0xc7, 0xd7, 0xef, 0x9a, + 0x37, 0x6a, 0x4b, 0xe2, 0xae, 0xcc, 0xc5, 0x8f, 0xe1, 0xa9, 0xd3, 0xbe, 0x8f, 0x4f, + 0x91, 0x35, 0x2f, 0x33, 0x1e, 0x52, 0xd7, 0xee, 0x2a, 0x4d, 0x24, 0x3f, 0x15, 0x96, + 0x2e, 0x43, 0x28, 0x90, 0x3a, 0x8e, 0xd4, 0x16, 0x9c, 0x2e, 0x77, 0xba, 0x64, 0xe1, + 0xd8, 0x98, 0xeb, 0x47, 0xfa, 0x87, 0xc1, 0x3b, 0x0c, 0xc2, 0x86, 0xea, 0x15, 0x01, + 0x47, 0x6d, 0x25, 0xd1, 0x46, 0x6c, 0xcb, 0xb7, 0x8a, 0x99, 0x88, 0x01, 0x66, 0x3a, + 0xb5, 0x32, 0x78, 0xd7, 0x03, 0xba, 0x6f, 0x90, 0xce, 0x81, 0x0d, 0x45}, + {0x75, 0x52, 0x20, 0xa6, 0xa1, 0xb6, 0x7b, 0x6e, 0x83, 0x8e, 0x3c, 0x41, 0xd7, 0x21, + 0x4f, 0xaa, 0xb2, 0x5c, 0x8f, 0xe8, 0x55, 0xd1, 0x56, 0x6f, 0xe1, 0x5b, 0x34, 0xa6, + 0x4b, 0x5d, 0xe2, 0x2d, 0x3f, 0x74, 0xae, 0x1c, 0x96, 0xd8, 0x74, 0xd0, 0xed, 0x63, + 0x1c, 0xee, 0xf5, 0x18, 0x6d, 0xf8, 0x29, 0xed, 0xf4, 0xe7, 0x5b, 0xc5, 0xbd, 0x97, + 0x08, 0xb1, 0x3a, 0x66, 0x79, 0xd2, 0xba, 0x4c, 0xcd, 0x1f, 0xd7, 0xa0, 0x24, 0x90, + 0xd1, 0x80, 0xf8, 0x8a, 0x28, 0xfb, 0x0a, 0xc2, 0x25, 0xc5, 0x19, 0x64, 0x3a, 0x5f, + 0x4b, 0x97, 0xa3, 0xb1, 0x33, 0x72, 0x00, 0xe2, 0xef, 0xbc, 0x7f, 0x7d}, + {0x01, 0x28, 0x6b, 0x26, 0x6a, 0x1e, 0xef, 0xfa, 0x16, 0x9f, 0x73, 0xd5, 0xc4, 0x68, + 0x6c, 0x86, 0x2c, 0x76, 0x03, 0x1b, 0xbc, 0x2f, 0x8a, 0xf6, 0x8d, 0x5a, 0xb7, 0x87, + 0x5e, 0x43, 0x75, 0x59, 0x94, 0x90, 0xc2, 0xf3, 0xc5, 0x5d, 0x7c, 0xcd, 0xab, 0x05, + 0x91, 0x2a, 0x9a, 0xa2, 0x81, 0xc7, 0x58, 0x30, 0x1c, 0x42, 0x36, 0x1d, 0xc6, 0x80, + 0xd7, 0xd4, 0xd8, 0xdc, 0x96, 0xd1, 0x9c, 0x4f, 0x68, 0x37, 0x7b, 0x6a, 0xd8, 0x97, + 0x92, 0x19, 0x63, 0x7a, 0xd1, 0x1a, 0x24, 0x58, 0xd0, 0xd0, 0x17, 0x0c, 0x1c, 0x5c, + 0xad, 0x9c, 0x02, 0xba, 0x07, 0x03, 0x7a, 0x38, 0x84, 0xd0, 0xcd, 0x7c}, + {0x17, 0x04, 0x26, 0x6d, 0x2c, 0x42, 0xa6, 0xdc, 0xbd, 0x40, 0x82, 0x94, 0x50, 0x3d, + 0x15, 0xae, 0x77, 0xc6, 0x68, 0xfb, 0xb4, 0xc1, 0xc0, 0xa9, 0x53, 0xcf, 0xd0, 0x61, + 0xed, 0xd0, 0x8b, 0x42, 0x93, 0xcc, 0x60, 0x67, 0x18, 0x84, 0x0c, 0x9b, 0x99, 0x2a, + 0xb3, 0x1a, 0x7a, 0x00, 0xae, 0xcd, 0x18, 0xda, 0x0b, 0x62, 0x86, 0xec, 0x8d, 0xa8, + 0x44, 0xca, 0x90, 0x81, 0x84, 0xca, 0x93, 0x35, 0xa7, 0x9a, 0x84, 0x5e, 0x9a, 0x18, + 0x13, 0x92, 0xcd, 0xfa, 0xd8, 0x65, 0x35, 0xc3, 0xd8, 0xd4, 0xd1, 0xbb, 0xfd, 0x53, + 0x5b, 0x54, 0x52, 0x8c, 0xe6, 0x63, 0x2d, 0xda, 0x08, 0x83, 0x39, 0x27}, + {0x13, 0xd4, 0x5e, 0x43, 0x28, 0x8d, 0xc3, 0x42, 0xc9, 0xcc, 0x78, 0x32, 0x60, 0xf3, + 0x50, 0xbd, 0xef, 0x03, 0xda, 0x79, 0x1a, 0xab, 0x07, 0xbb, 0x55, 0x33, 0x8c, 0xbe, + 0xae, 0x97, 0x95, 0x26, 0x53, 0x24, 0x70, 0x0a, 0x4c, 0x0e, 0xa1, 0xb9, 0xde, 0x1b, + 0x7d, 0xd5, 0x66, 0x58, 0xa2, 0x0f, 0xf7, 0xda, 0x27, 0xcd, 0xb5, 0xd9, 0xb9, 0xff, + 0xfd, 0x33, 0x2c, 0x49, 0x45, 0x29, 0x2c, 0x57, 0xbe, 0x30, 0xcd, 0xd6, 0x45, 0xc7, + 0x7f, 0xc7, 0xfb, 0xae, 0xba, 0xe3, 0xd3, 0xe8, 0xdf, 0xe4, 0x0c, 0xda, 0x5d, 0xaa, + 0x30, 0x88, 0x2c, 0xa2, 0x80, 0xca, 0x5b, 0xc0, 0x98, 0x54, 0x98, 0x7f}, + {0x17, 0xe1, 0x0b, 0x9f, 0x88, 0xce, 0x49, 0x38, 0x88, 0xa2, 0x54, 0x7b, 0x1b, 0xad, + 0x05, 0x80, 0x1c, 0x92, 0xfc, 0x23, 0x9f, 0xc3, 0xa3, 0x3d, 0x04, 0xf3, 0x31, 0x0a, + 0x47, 0xec, 0xc2, 0x76, 0x63, 0x63, 0xbf, 0x0f, 0x52, 0x15, 0x56, 0xd3, 0xa6, 0xfb, + 0x4d, 0xcf, 0x45, 0x5a, 0x04, 0x08, 0xc2, 0xa0, 0x3f, 0x87, 0xbc, 0x4f, 0xc2, 0xee, + 0xe7, 0x12, 0x9b, 0xd6, 0x3c, 0x65, 0xf2, 0x30, 0x85, 0x0c, 0xc1, 0xaa, 0x38, 0xc9, + 0x08, 0x8a, 0xcb, 0x6b, 0x27, 0xdb, 0x60, 0x9b, 0x17, 0x46, 0x70, 0xac, 0x6f, 0x0e, + 0x1e, 0xc0, 0x20, 0xa9, 0xda, 0x73, 0x64, 0x59, 0xf1, 0x73, 0x12, 0x2f}, + {0x11, 0x1e, 0xe0, 0x8a, 0x7c, 0xfc, 0x39, 0x47, 0x9f, 0xab, 0x6a, 0x4a, 0x90, 0x74, + 0x52, 0xfd, 0x2e, 0x8f, 0x72, 0x87, 0x82, 0x8a, 0xd9, 0x41, 0xf2, 0x69, 0x5b, 0xd8, + 0x2a, 0x57, 0x9e, 0x5d, 0xc0, 0x0b, 0xa7, 0x55, 0xd7, 0x8b, 0x48, 0x30, 0xe7, 0x42, + 0xd4, 0xf1, 0xa4, 0xb5, 0xd6, 0x06, 0x62, 0x61, 0x59, 0xbc, 0x9e, 0xa6, 0xd1, 0xea, + 0x84, 0xf7, 0xc5, 0xed, 0x97, 0x19, 0xac, 0x38, 0x3b, 0xb1, 0x51, 0xa7, 0x17, 0xb5, + 0x66, 0x06, 0x8c, 0x85, 0x9b, 0x7e, 0x86, 0x06, 0x7d, 0x74, 0x49, 0xde, 0x4d, 0x45, + 0x11, 0xc0, 0xac, 0xac, 0x9c, 0xe6, 0xe9, 0xbf, 0x9c, 0xcd, 0xdf, 0x22}, + {0xd9, 0x0c, 0x0d, 0xc3, 0xe0, 0xd2, 0xdb, 0x8d, 0x33, 0x43, 0xbb, 0xac, 0x5f, 0x66, + 0x8e, 0xad, 0x1f, 0x96, 0x2a, 0x32, 0x8c, 0x25, 0x6b, 0x8f, 0xc7, 0xc1, 0x48, 0x54, + 0xc0, 0x16, 0x29, 0x6b, 0xa1, 0xe0, 0x3b, 0x10, 0xb4, 0x59, 0xec, 0x56, 0x69, 0xf9, + 0x59, 0xd2, 0xec, 0xba, 0xe3, 0x2e, 0x32, 0xcd, 0xf5, 0x13, 0x94, 0xb2, 0x7c, 0x79, + 0x72, 0xe4, 0xcd, 0x24, 0x78, 0x87, 0xe9, 0x0f, 0x3b, 0x91, 0xba, 0x0a, 0xd1, 0x34, + 0xdb, 0x7e, 0x0e, 0xac, 0x6d, 0x2e, 0x82, 0xcd, 0xa3, 0x4e, 0x15, 0xf8, 0x78, 0x65, + 0xff, 0x3d, 0x08, 0x66, 0x17, 0x0a, 0xf0, 0x7f, 0x30, 0x3f, 0x30, 0x4c}, + {0x85, 0x8c, 0xb2, 0x17, 0xd6, 0x3b, 0x0a, 0xd3, 0xea, 0x3b, 0x77, 0x39, 0xb7, 0x77, + 0xd3, 0xc5, 0xbf, 0x5c, 0x6a, 0x1e, 0x8c, 0xe7, 0xc6, 0xc6, 0xc4, 0xb7, 0x2a, 0x8b, + 0xf7, 0xb8, 0x61, 0x0d, 0x00, 0x45, 0xd9, 0x0d, 0x58, 0x03, 0xfc, 0x29, 0x93, 0xec, + 0xbb, 0x6f, 0xa4, 0x7a, 0xd2, 0xec, 0xf8, 0xa7, 0xe2, 0xc2, 0x5f, 0x15, 0x0a, 0x13, + 0xd5, 0xa1, 0x06, 0xb7, 0x1a, 0x15, 0x6b, 0x41, 0xb0, 0x36, 0xc1, 0xe9, 0xef, 0xd7, + 0xa8, 0x56, 0x20, 0x4b, 0xe4, 0x58, 0xcd, 0xe5, 0x07, 0xbd, 0xab, 0xe0, 0x57, 0x1b, + 0xda, 0x2f, 0xe6, 0xaf, 0xd2, 0xe8, 0x77, 0x42, 0xf7, 0x2a, 0x1a, 0x19}, + {0x31, 0x14, 0x3c, 0xc5, 0x4b, 0xf7, 0x16, 0xce, 0xde, 0xed, 0x72, 0x20, 0xce, 0x25, + 0x97, 0x2b, 0xe7, 0x3e, 0xb2, 0xb5, 0x6f, 0xc3, 0xb9, 0xb8, 0x08, 0xc9, 0x5c, 0x0b, + 0x45, 0x0e, 0x2e, 0x7e, 0xfb, 0x0e, 0x46, 0x4f, 0x43, 0x2b, 0xe6, 0x9f, 0xd6, 0x07, + 0x36, 0xa6, 0xd4, 0x03, 0xd3, 0xde, 0x24, 0xda, 0xa0, 0xb7, 0x0e, 0x21, 0x52, 0xf0, + 0x93, 0x5b, 0x54, 0x00, 0xbe, 0x7d, 0x7e, 0x23, 0x30, 0xb4, 0x01, 0x67, 0xed, 0x75, + 0x35, 0x01, 0x10, 0xfd, 0x0b, 0x9f, 0xe6, 0x94, 0x10, 0x23, 0x22, 0x7f, 0xe4, 0x83, + 0x15, 0x0f, 0x32, 0x75, 0xe3, 0x55, 0x11, 0xb1, 0x99, 0xa6, 0xaf, 0x71}, + {0x1d, 0xb6, 0x53, 0x39, 0x9b, 0x6f, 0xce, 0x65, 0xe6, 0x41, 0xa1, 0xaf, 0xea, 0x39, + 0x58, 0xc6, 0xfe, 0x59, 0xf7, 0xa9, 0xfd, 0x5f, 0x43, 0x0f, 0x8e, 0xc2, 0xb1, 0xc2, + 0xe9, 0x42, 0x11, 0x02, 0xd6, 0x50, 0x3b, 0x47, 0x1c, 0x3c, 0x42, 0xea, 0x10, 0xef, + 0x38, 0x3b, 0x1f, 0x7a, 0xe8, 0x51, 0x95, 0xbe, 0xc9, 0xb2, 0x5f, 0xbf, 0x84, 0x9b, + 0x1c, 0x9a, 0xf8, 0x78, 0xbc, 0x1f, 0x73, 0x00, 0x80, 0x18, 0xf8, 0x48, 0x18, 0xc7, + 0x30, 0xe4, 0x19, 0xc1, 0xce, 0x5e, 0x22, 0x0c, 0x96, 0xbf, 0xe3, 0x15, 0xba, 0x6b, + 0x83, 0xe0, 0xda, 0xb6, 0x08, 0x58, 0xe1, 0x47, 0x33, 0x6f, 0x4d, 0x4c}, + {0xc9, 0x1f, 0x7d, 0xc1, 0xcf, 0xec, 0xf7, 0x18, 0x14, 0x3c, 0x40, 0x51, 0xa6, 0xf5, + 0x75, 0x6c, 0xdf, 0x0c, 0xee, 0xf7, 0x2b, 0x71, 0xde, 0xdb, 0x22, 0x7a, 0xe4, 0xa7, + 0xaa, 0xdd, 0x3f, 0x19, 0x70, 0x19, 0x8f, 0x98, 0xfc, 0xdd, 0x0c, 0x2f, 0x1b, 0xf5, + 0xb9, 0xb0, 0x27, 0x62, 0x91, 0x6b, 0xbe, 0x76, 0x91, 0x77, 0xc4, 0xb6, 0xc7, 0x6e, + 0xa8, 0x9f, 0x8f, 0xa8, 0x00, 0x95, 0xbf, 0x38, 0x6f, 0x87, 0xe8, 0x37, 0x3c, 0xc9, + 0xd2, 0x1f, 0x2c, 0x46, 0xd1, 0x18, 0x5a, 0x1e, 0xf6, 0xa2, 0x76, 0x12, 0x24, 0x39, + 0x82, 0xf5, 0x80, 0x50, 0x69, 0x49, 0x0d, 0xbf, 0x9e, 0xb9, 0x6f, 0x6a}, + {0xeb, 0x55, 0x08, 0x56, 0xbb, 0xc1, 0x46, 0x6a, 0x9d, 0xf0, 0x93, 0xf8, 0x38, 0xbb, + 0x16, 0x24, 0xc1, 0xac, 0x71, 0x8f, 0x37, 0x11, 0x1d, 0xd7, 0xea, 0x96, 0x18, 0xa3, + 0x14, 0x69, 0xf7, 0x75, 0xc6, 0x23, 0xe4, 0xb6, 0xb5, 0x22, 0xb1, 0xee, 0x8e, 0xff, + 0x86, 0xf2, 0x10, 0x70, 0x9d, 0x93, 0x8c, 0x5d, 0xcf, 0x1d, 0x83, 0x2a, 0xa9, 0x90, + 0x10, 0xeb, 0xc5, 0x42, 0x9f, 0xda, 0x6f, 0x13, 0xd1, 0xbd, 0x05, 0xa3, 0xb1, 0xdf, + 0x4c, 0xf9, 0x08, 0x2c, 0xf8, 0x9f, 0x9d, 0x4b, 0x36, 0x0f, 0x8a, 0x58, 0xbb, 0xc3, + 0xa5, 0xd8, 0x87, 0x2a, 0xba, 0xdc, 0xe8, 0x0b, 0x51, 0x83, 0x21, 0x02}, + {0x14, 0x2d, 0xad, 0x5e, 0x38, 0x66, 0xf7, 0x4a, 0x30, 0x58, 0x7c, 0xca, 0x80, 0xd8, + 0x8e, 0xa0, 0x3d, 0x1e, 0x21, 0x10, 0xe6, 0xa6, 0x13, 0x0d, 0x03, 0x6c, 0x80, 0x7b, + 0xe1, 0x1c, 0x07, 0x6a, 0x7f, 0x7a, 0x30, 0x43, 0x01, 0x71, 0x5a, 0x9d, 0x5f, 0xa4, + 0x7d, 0xc4, 0x9e, 0xde, 0x63, 0xb0, 0xd3, 0x7a, 0x92, 0xbe, 0x52, 0xfe, 0xbb, 0x22, + 0x6c, 0x42, 0x40, 0xfd, 0x41, 0xc4, 0x87, 0x13, 0xf8, 0x8a, 0x97, 0x87, 0xd1, 0xc3, + 0xd3, 0xb5, 0x13, 0x44, 0x0e, 0x7f, 0x3d, 0x5a, 0x2b, 0x72, 0xa0, 0x7c, 0x47, 0xbb, + 0x48, 0x48, 0x7b, 0x0d, 0x92, 0xdc, 0x1e, 0xaf, 0x6a, 0xb2, 0x71, 0x31}, + {0xa8, 0x4c, 0x56, 0x97, 0x90, 0x31, 0x2f, 0xa9, 0x19, 0xe1, 0x75, 0x22, 0x4c, 0xb8, + 0x7b, 0xff, 0x50, 0x51, 0x87, 0xa4, 0x37, 0xfe, 0x55, 0x4f, 0x5a, 0x83, 0xf0, 0x3c, + 0x87, 0xd4, 0x1f, 0x22, 0xd1, 0x47, 0x8a, 0xb2, 0xd8, 0xb7, 0x0d, 0xa6, 0xf1, 0xa4, + 0x70, 0x17, 0xd6, 0x14, 0xbf, 0xa6, 0x58, 0xbd, 0xdd, 0x53, 0x93, 0xf8, 0xa1, 0xd4, + 0xe9, 0x43, 0x42, 0x34, 0x63, 0x4a, 0x51, 0x6c, 0x41, 0x63, 0x15, 0x3a, 0x4f, 0x20, + 0x22, 0x23, 0x2d, 0x03, 0x0a, 0xba, 0xe9, 0xe0, 0x73, 0xfb, 0x0e, 0x03, 0x0f, 0x41, + 0x4c, 0xdd, 0xe0, 0xfc, 0xaa, 0x4a, 0x92, 0xfb, 0x96, 0xa5, 0xda, 0x48}, + {0xc7, 0x9c, 0xa5, 0x5c, 0x66, 0x8e, 0xca, 0x6e, 0xa0, 0xac, 0x38, 0x2e, 0x4b, 0x25, + 0x47, 0xa8, 0xce, 0x17, 0x1e, 0xd2, 0x08, 0xc7, 0xaf, 0x31, 0xf7, 0x4a, 0xd8, 0xca, + 0xfc, 0xd6, 0x6d, 0x67, 0x93, 0x97, 0x4c, 0xc8, 0x5d, 0x1d, 0xf6, 0x14, 0x06, 0x82, + 0x41, 0xef, 0xe3, 0xf9, 0x41, 0x99, 0xac, 0x77, 0x62, 0x34, 0x8f, 0xb8, 0xf5, 0xcd, + 0xa9, 0x79, 0x8a, 0x0e, 0xfa, 0x37, 0xc8, 0x58, 0x58, 0x90, 0xfc, 0x96, 0x85, 0x68, + 0xf9, 0x0c, 0x1b, 0xa0, 0x56, 0x7b, 0xf3, 0xbb, 0xdc, 0x1d, 0x6a, 0xd6, 0x35, 0x49, + 0x7d, 0xe7, 0xc2, 0xdc, 0x0a, 0x7f, 0xa5, 0xc6, 0xf2, 0x73, 0x4f, 0x1c}, + {0xbb, 0xa0, 0x5f, 0x30, 0xbd, 0x4f, 0x7a, 0x0e, 0xad, 0x63, 0xc6, 0x54, 0xe0, 0x4c, + 0x9d, 0x82, 0x48, 0x38, 0xe3, 0x2f, 0x83, 0xc3, 0x21, 0xf4, 0x42, 0x4c, 0xf6, 0x1b, + 0x0d, 0xc8, 0x5a, 0x79, 0x84, 0x34, 0x7c, 0xfc, 0x6e, 0x70, 0x6e, 0xb3, 0x61, 0xcf, + 0xc1, 0xc3, 0xb4, 0xc9, 0xdf, 0x73, 0xe5, 0xc7, 0x1c, 0x78, 0xc9, 0x79, 0x1d, 0xeb, + 0x5c, 0x67, 0xaf, 0x7d, 0xdb, 0x9a, 0x45, 0x70, 0xb3, 0x2b, 0xb4, 0x91, 0x49, 0xdb, + 0x91, 0x1b, 0xca, 0xdc, 0x02, 0x4b, 0x23, 0x96, 0x26, 0x57, 0xdc, 0x78, 0x8c, 0x1f, + 0xe5, 0x9e, 0xdf, 0x9f, 0xd3, 0x1f, 0xe2, 0x8c, 0x84, 0x62, 0xe1, 0x5f}, + {0x1a, 0x96, 0x94, 0xe1, 0x4f, 0x21, 0x59, 0x4e, 0x4f, 0xcd, 0x71, 0x0d, 0xc7, 0x7d, + 0xbe, 0x49, 0x2d, 0xf2, 0x50, 0x3b, 0xd2, 0xcf, 0x00, 0x93, 0x32, 0x72, 0x91, 0xfc, + 0x46, 0xd4, 0x89, 0x47, 0x08, 0xb2, 0x7c, 0x5d, 0x2d, 0x85, 0x79, 0x28, 0xe7, 0xf2, + 0x7d, 0x68, 0x70, 0xdd, 0xde, 0xb8, 0x91, 0x78, 0x68, 0x21, 0xab, 0xff, 0x0b, 0xdc, + 0x35, 0xaa, 0x7d, 0x67, 0x43, 0xc0, 0x44, 0x2b, 0x8e, 0xb7, 0x4e, 0x07, 0xab, 0x87, + 0x1c, 0x1a, 0x67, 0xf4, 0xda, 0x99, 0x8e, 0xd1, 0xc6, 0xfa, 0x67, 0x90, 0x4f, 0x48, + 0xcd, 0xbb, 0xac, 0x3e, 0xe4, 0xa4, 0xb9, 0x2b, 0xef, 0x2e, 0xc5, 0x60}, + {0xf1, 0x8b, 0xfd, 0x3b, 0xbc, 0x89, 0x5d, 0x0b, 0x1a, 0x55, 0xf3, 0xc9, 0x37, 0x92, + 0x6b, 0xb0, 0xf5, 0x28, 0x30, 0xd5, 0xb0, 0x16, 0x4c, 0x0e, 0xab, 0xca, 0xcf, 0x2c, + 0x31, 0x9c, 0xbc, 0x10, 0x11, 0x6d, 0xae, 0x7c, 0xc2, 0xc5, 0x2b, 0x70, 0xab, 0x8c, + 0xa4, 0x54, 0x9b, 0x69, 0xc7, 0x44, 0xb2, 0x2e, 0x49, 0xba, 0x56, 0x40, 0xbc, 0xef, + 0x6d, 0x67, 0xb6, 0xd9, 0x48, 0x72, 0xd7, 0x70, 0x5b, 0xa0, 0xc2, 0x3e, 0x4b, 0xe8, + 0x8a, 0xaa, 0xe0, 0x81, 0x17, 0xed, 0xf4, 0x9e, 0x69, 0x98, 0xd1, 0x85, 0x8e, 0x70, + 0xe4, 0x13, 0x45, 0x79, 0x13, 0xf4, 0x76, 0xa9, 0xd3, 0x5b, 0x75, 0x63}, + {0x53, 0x08, 0xd1, 0x2a, 0x3e, 0xa0, 0x5f, 0xb5, 0x69, 0x35, 0xe6, 0x9e, 0x90, 0x75, + 0x6f, 0x35, 0x90, 0xb8, 0x69, 0xbe, 0xfd, 0xf1, 0xf9, 0x9f, 0x84, 0x6f, 0xc1, 0x8b, + 0xc4, 0xc1, 0x8c, 0x0d, 0xb7, 0xac, 0xf1, 0x97, 0x18, 0x10, 0xc7, 0x3d, 0xd8, 0xbb, + 0x65, 0xc1, 0x5e, 0x7d, 0xda, 0x5d, 0x0f, 0x02, 0xa1, 0x0f, 0x9c, 0x5b, 0x8e, 0x50, + 0x56, 0x2a, 0xc5, 0x37, 0x17, 0x75, 0x63, 0x27, 0xa9, 0x19, 0xb4, 0x6e, 0xd3, 0x02, + 0x94, 0x02, 0xa5, 0x60, 0xb4, 0x77, 0x7e, 0x4e, 0xb4, 0xf0, 0x56, 0x49, 0x3c, 0xd4, + 0x30, 0x62, 0xa8, 0xcf, 0xe7, 0x66, 0xd1, 0x7a, 0x8a, 0xdd, 0xc2, 0x70}, + {0x0e, 0xec, 0x6f, 0x9f, 0x50, 0x94, 0x61, 0x65, 0x8d, 0x51, 0xc6, 0x46, 0xa9, 0x7e, + 0x2e, 0xee, 0x5c, 0x9b, 0xe0, 0x67, 0xf3, 0xc1, 0x33, 0x97, 0x95, 0x84, 0x94, 0x63, + 0x63, 0xac, 0x0f, 0x2e, 0x13, 0x7e, 0xed, 0xb8, 0x7d, 0x96, 0xd4, 0x91, 0x7a, 0x81, + 0x76, 0xd7, 0x0a, 0x2f, 0x25, 0x74, 0x64, 0x25, 0x85, 0x0d, 0xe0, 0x82, 0x09, 0xe4, + 0xe5, 0x3c, 0xa5, 0x16, 0x38, 0x61, 0xb8, 0x32, 0x64, 0xcd, 0x48, 0xe4, 0xbe, 0xf7, + 0xe7, 0x79, 0xd0, 0x86, 0x78, 0x08, 0x67, 0x3a, 0xc8, 0x6a, 0x2e, 0xdb, 0xe4, 0xa0, + 0xd9, 0xd4, 0x9f, 0xf8, 0x41, 0x4f, 0x5a, 0x73, 0x5c, 0x21, 0x79, 0x41}, + {0x2a, 0xed, 0xdc, 0xd7, 0xe7, 0x94, 0x70, 0x8c, 0x70, 0x9c, 0xd3, 0x47, 0xc3, 0x8a, + 0xfb, 0x97, 0x02, 0xd9, 0x06, 0xa9, 0x33, 0xe0, 0x3b, 0xe1, 0x76, 0x9d, 0xd9, 0x0c, + 0xa3, 0x44, 0x03, 0x70, 0x34, 0xcd, 0x6b, 0x28, 0xb9, 0x33, 0xae, 0xe4, 0xdc, 0xd6, + 0x9d, 0x55, 0xb6, 0x7e, 0xef, 0xb7, 0x1f, 0x8e, 0xd3, 0xb3, 0x1f, 0x14, 0x8b, 0x27, + 0x86, 0xc2, 0x41, 0x22, 0x66, 0x85, 0xfa, 0x31, 0xf4, 0x22, 0x36, 0x2e, 0x42, 0x6c, + 0x82, 0xaf, 0x2d, 0x50, 0x33, 0x98, 0x87, 0x29, 0x20, 0xc1, 0x23, 0x91, 0x38, 0x2b, + 0xe1, 0xb7, 0xc1, 0x9b, 0x89, 0x24, 0x95, 0xa9, 0x12, 0x23, 0xbb, 0x24}, + {0xc3, 0x67, 0xde, 0x32, 0x17, 0xed, 0xa8, 0xb1, 0x48, 0x49, 0x1b, 0x46, 0x18, 0x94, + 0xb4, 0x3c, 0xd2, 0xbc, 0xcf, 0x76, 0x43, 0x43, 0xbd, 0x8e, 0x08, 0x80, 0x18, 0x1e, + 0x87, 0x3e, 0xee, 0x0f, 0x6b, 0x5c, 0xf8, 0xf5, 0x2a, 0x0c, 0xf8, 0x41, 0x94, 0x67, + 0xfa, 0x04, 0xc3, 0x84, 0x72, 0x68, 0xad, 0x1b, 0xba, 0xa3, 0x99, 0xdf, 0x45, 0x89, + 0x16, 0x5d, 0xeb, 0xff, 0xf9, 0x2a, 0x1d, 0x0d, 0xdf, 0x1e, 0x62, 0x32, 0xa1, 0x8a, + 0xda, 0xa9, 0x79, 0x65, 0x22, 0x59, 0xa1, 0x22, 0xb8, 0x30, 0x93, 0xc1, 0x9a, 0xa7, + 0x7b, 0x19, 0x04, 0x40, 0x76, 0x1d, 0x53, 0x18, 0x97, 0xd7, 0xac, 0x16}, + {0x3d, 0x1d, 0x9b, 0x2d, 0xaf, 0x72, 0xdf, 0x72, 0x5a, 0x24, 0x32, 0xa4, 0x36, 0x2a, + 0x46, 0x63, 0x37, 0x96, 0xb3, 0x16, 0x79, 0xa0, 0xce, 0x3e, 0x09, 0x23, 0x30, 0xb9, + 0xf6, 0x0e, 0x3e, 0x12, 0xad, 0xb6, 0x87, 0x78, 0xc5, 0xc6, 0x59, 0xc9, 0xba, 0xfe, + 0x90, 0x5f, 0xad, 0x9e, 0xe1, 0x94, 0x04, 0xf5, 0x42, 0xa3, 0x62, 0x4e, 0xe2, 0x16, + 0x00, 0x17, 0x16, 0x18, 0x4b, 0xd3, 0x4e, 0x16, 0x9a, 0xe6, 0x2f, 0x19, 0x4c, 0xd9, + 0x7e, 0x48, 0x13, 0x15, 0x91, 0x3a, 0xea, 0x2c, 0xae, 0x61, 0x27, 0xde, 0xa4, 0xb9, + 0xd3, 0xf6, 0x7b, 0x87, 0xeb, 0xf3, 0x73, 0x10, 0xc6, 0x0f, 0xda, 0x78}, + {0x6a, 0xc6, 0x2b, 0xe5, 0x28, 0x5d, 0xf1, 0x5b, 0x8e, 0x1a, 0xf0, 0x70, 0x18, 0xe3, + 0x47, 0x2c, 0xdd, 0x8b, 0xc2, 0x06, 0xbc, 0xaf, 0x19, 0x24, 0x3a, 0x17, 0x6b, 0x25, + 0xeb, 0xde, 0x25, 0x2d, 0x94, 0x3a, 0x0c, 0x68, 0xf1, 0x80, 0x9f, 0xa2, 0xe6, 0xe7, + 0xe9, 0x1a, 0x15, 0x7e, 0xf7, 0x71, 0x73, 0x79, 0x01, 0x48, 0x58, 0xf1, 0x00, 0x11, + 0xdd, 0x8d, 0xb3, 0x16, 0xb3, 0xa4, 0x4a, 0x05, 0xb8, 0x7c, 0x26, 0x19, 0x8d, 0x46, + 0xc8, 0xdf, 0xaf, 0x4d, 0xe5, 0x66, 0x9c, 0x78, 0x28, 0x0b, 0x17, 0xec, 0x6e, 0x66, + 0x2a, 0x1d, 0xeb, 0x2a, 0x60, 0xa7, 0x7d, 0xab, 0xa6, 0x10, 0x46, 0x13}, + {0xfe, 0xb0, 0xf6, 0x8d, 0xc7, 0x8e, 0x13, 0x51, 0x1b, 0xf5, 0x75, 0xe5, 0x89, 0xda, + 0x97, 0x53, 0xb9, 0xf1, 0x7a, 0x71, 0x1d, 0x7a, 0x20, 0x09, 0x50, 0xd6, 0x20, 0x2b, + 0xba, 0xfd, 0x02, 0x21, 0x15, 0xf5, 0xd1, 0x77, 0xe7, 0x65, 0x2a, 0xcd, 0xf1, 0x60, + 0xaa, 0x8f, 0x87, 0x91, 0x89, 0x54, 0xe5, 0x06, 0xbc, 0xda, 0xbc, 0x3b, 0xb7, 0xb1, + 0xfb, 0xc9, 0x7c, 0xa9, 0xcb, 0x78, 0x48, 0x65, 0xa1, 0xe6, 0x5c, 0x05, 0x05, 0xe4, + 0x9e, 0x96, 0x29, 0xad, 0x51, 0x12, 0x68, 0xa7, 0xbc, 0x36, 0x15, 0xa4, 0x7d, 0xaa, + 0x17, 0xf5, 0x1a, 0x3a, 0xba, 0xb2, 0xec, 0x29, 0xdb, 0x25, 0xd7, 0x0a}, + {0x57, 0x24, 0x4e, 0x83, 0xb1, 0x67, 0x42, 0xdc, 0xc5, 0x1b, 0xce, 0x70, 0xb5, 0x44, + 0x75, 0xb6, 0xd7, 0x5e, 0xd1, 0xf7, 0x0b, 0x7a, 0xf0, 0x1a, 0x50, 0x36, 0xa0, 0x71, + 0xfb, 0xcf, 0xef, 0x4a, 0x85, 0x6f, 0x05, 0x9b, 0x0c, 0xbc, 0xc7, 0xfe, 0xd7, 0xff, + 0xf5, 0xe7, 0x68, 0x52, 0x7d, 0x53, 0xfa, 0xae, 0x12, 0x43, 0x62, 0xc6, 0xaf, 0x77, + 0xd9, 0x9f, 0x39, 0x02, 0x53, 0x5f, 0x67, 0x4f, 0x1e, 0x17, 0x15, 0x04, 0x36, 0x36, + 0x2d, 0xc3, 0x3b, 0x48, 0x98, 0x89, 0x11, 0xef, 0x2b, 0xcd, 0x10, 0x51, 0x94, 0xd0, + 0xad, 0x6e, 0x0a, 0x87, 0x61, 0x65, 0xa8, 0xa2, 0x72, 0xbb, 0xcc, 0x0b}, + {0xc8, 0xa9, 0xb1, 0xea, 0x2f, 0x96, 0x5e, 0x18, 0xcd, 0x7d, 0x14, 0x65, 0x35, 0xe6, + 0xe7, 0x86, 0xf2, 0x6d, 0x5b, 0xbb, 0x31, 0xe0, 0x92, 0xb0, 0x3e, 0xb7, 0xd6, 0x59, + 0xab, 0xf0, 0x24, 0x40, 0x96, 0x12, 0xfe, 0x50, 0x4c, 0x5e, 0x6d, 0x18, 0x7e, 0x9f, + 0xe8, 0xfe, 0x82, 0x7b, 0x39, 0xe0, 0xb0, 0x31, 0x70, 0x50, 0xc5, 0xf6, 0xc7, 0x3b, + 0xc2, 0x37, 0x8f, 0x10, 0x69, 0xfd, 0x78, 0x66, 0xc2, 0x63, 0x68, 0x63, 0x31, 0xfa, + 0x86, 0x15, 0xf2, 0x33, 0x2d, 0x57, 0x48, 0x8c, 0xf6, 0x07, 0xfc, 0xae, 0x9e, 0x78, + 0x9f, 0xcc, 0x73, 0x4f, 0x01, 0x47, 0xad, 0x8e, 0x10, 0xe2, 0x42, 0x2d}, + {0x9b, 0xd2, 0xdf, 0x94, 0x15, 0x13, 0xf5, 0x97, 0x6a, 0x4c, 0x3f, 0x31, 0x5d, 0x98, + 0x55, 0x61, 0x10, 0x50, 0x45, 0x08, 0x07, 0x3f, 0xa1, 0xeb, 0x22, 0xd3, 0xd2, 0xb8, + 0x08, 0x26, 0x6b, 0x67, 0x93, 0x75, 0x53, 0x0f, 0x0d, 0x7b, 0x71, 0x21, 0x4c, 0x06, + 0x1e, 0x13, 0x0b, 0x69, 0x4e, 0x91, 0x9f, 0xe0, 0x2a, 0x75, 0xae, 0x87, 0xb6, 0x1b, + 0x6e, 0x3c, 0x42, 0x9b, 0xa7, 0xf3, 0x0b, 0x42, 0x47, 0x2b, 0x5b, 0x1c, 0x65, 0xba, + 0x38, 0x81, 0x80, 0x1b, 0x1b, 0x31, 0xec, 0xb6, 0x71, 0x86, 0xb0, 0x35, 0x31, 0xbc, + 0xb1, 0x0c, 0xff, 0x7b, 0xe0, 0xf1, 0x0c, 0x9c, 0xfa, 0x2f, 0x5d, 0x74}, + {0xbd, 0xc8, 0xc9, 0x2b, 0x1e, 0x5a, 0x52, 0xbf, 0x81, 0x9d, 0x47, 0x26, 0x08, 0x26, + 0x5b, 0xea, 0xdb, 0x55, 0x01, 0xdf, 0x0e, 0xc7, 0x11, 0xd5, 0xd0, 0xf5, 0x0c, 0x96, + 0xeb, 0x3c, 0xe2, 0x1a, 0x6a, 0x4e, 0xd3, 0x21, 0x57, 0xdf, 0x36, 0x60, 0xd0, 0xb3, + 0x7b, 0x99, 0x27, 0x88, 0xdb, 0xb1, 0xfa, 0x6a, 0x75, 0xc8, 0xc3, 0x09, 0xc2, 0xd3, + 0x39, 0xc8, 0x1d, 0x4c, 0xe5, 0x5b, 0xe1, 0x06, 0x4a, 0x99, 0x32, 0x19, 0x87, 0x5d, + 0x72, 0x5b, 0xb0, 0xda, 0xb1, 0xce, 0xb5, 0x1c, 0x35, 0x32, 0x05, 0xca, 0xb7, 0xda, + 0x49, 0x15, 0xc4, 0x7d, 0xf7, 0xc1, 0x8e, 0x27, 0x61, 0xd8, 0xde, 0x58}, + {0x5c, 0xc5, 0x66, 0xf2, 0x93, 0x37, 0x17, 0xd8, 0x49, 0x4e, 0x45, 0xcc, 0xc5, 0x76, + 0xc9, 0xc8, 0xa8, 0xc3, 0x26, 0xbc, 0xf8, 0x82, 0xe3, 0x5c, 0xf9, 0xf6, 0x85, 0x54, + 0xe8, 0x9d, 0xf3, 0x2f, 0xa8, 0xc9, 0xc2, 0xb6, 0xa8, 0x5b, 0xfb, 0x2d, 0x8c, 0x59, + 0x2c, 0xf5, 0x8e, 0xef, 0xee, 0x48, 0x73, 0x15, 0x2d, 0xf1, 0x07, 0x91, 0x80, 0x33, + 0xd8, 0x5b, 0x1d, 0x53, 0x6b, 0x69, 0xba, 0x08, 0x7a, 0xc5, 0xef, 0xc3, 0xee, 0x3e, + 0xed, 0x77, 0x11, 0x48, 0xff, 0xd4, 0x17, 0x55, 0xe0, 0x04, 0xcb, 0x71, 0xa6, 0xf1, + 0x3f, 0x7a, 0x3d, 0xea, 0x54, 0xfe, 0x7c, 0x94, 0xb4, 0x33, 0x06, 0x12}, + {0x42, 0x00, 0x61, 0x91, 0x78, 0x98, 0x94, 0x0b, 0xe8, 0xfa, 0xeb, 0xec, 0x3c, 0xb1, + 0xe7, 0x4e, 0xc0, 0xa4, 0xf0, 0x94, 0x95, 0x73, 0xbe, 0x70, 0x85, 0x91, 0xd5, 0xb4, + 0x99, 0x0a, 0xd3, 0x35, 0x0a, 0x10, 0x12, 0x49, 0x47, 0x31, 0xbd, 0x82, 0x06, 0xbe, + 0x6f, 0x7e, 0x6d, 0x7b, 0x23, 0xde, 0xc6, 0x79, 0xea, 0x11, 0x19, 0x76, 0x1e, 0xe1, + 0xde, 0x3b, 0x39, 0xcb, 0xe3, 0x3b, 0x43, 0x07, 0xf4, 0x97, 0xe9, 0x5c, 0xc0, 0x44, + 0x79, 0xff, 0xa3, 0x51, 0x5c, 0xb0, 0xe4, 0x3d, 0x5d, 0x57, 0x7c, 0x84, 0x76, 0x5a, + 0xfd, 0x81, 0x33, 0x58, 0x9f, 0xda, 0xf6, 0x7a, 0xde, 0x3e, 0x87, 0x2d}, + {0x09, 0x34, 0x37, 0x43, 0x64, 0x31, 0x7a, 0x15, 0xd9, 0x81, 0xaa, 0xf4, 0xee, 0xb7, + 0xb8, 0xfa, 0x06, 0x48, 0xa6, 0xf5, 0xe6, 0xfe, 0x93, 0xb0, 0xb6, 0xa7, 0x7f, 0x70, + 0x54, 0x36, 0x77, 0x2e, 0x81, 0xf9, 0x5d, 0x4e, 0xe1, 0x02, 0x62, 0xaa, 0xf5, 0xe1, + 0x15, 0x50, 0x17, 0x59, 0x0d, 0xa2, 0x6c, 0x1d, 0xe2, 0xba, 0xd3, 0x75, 0xa2, 0x18, + 0x53, 0x02, 0x60, 0x01, 0x8a, 0x61, 0x43, 0x05, 0xc1, 0x23, 0x4c, 0x97, 0xf4, 0xbd, + 0xea, 0x0d, 0x93, 0x46, 0xce, 0x9d, 0x25, 0x0a, 0x6f, 0xaa, 0x2c, 0xba, 0x9a, 0xa2, + 0xb8, 0x2c, 0x20, 0x04, 0x0d, 0x96, 0x07, 0x2d, 0x36, 0x43, 0x14, 0x4b}, + {0x7a, 0x1f, 0x6e, 0xb6, 0xc7, 0xb7, 0xc4, 0xcc, 0x7e, 0x2f, 0x0c, 0xf5, 0x25, 0x7e, + 0x15, 0x44, 0x1c, 0xaf, 0x3e, 0x71, 0xfc, 0x6d, 0xf0, 0x3e, 0xf7, 0x63, 0xda, 0x52, + 0x67, 0x44, 0x2f, 0x58, 0xcb, 0x9c, 0x52, 0x1c, 0xe9, 0x54, 0x7c, 0x96, 0xfb, 0x35, + 0xc6, 0x64, 0x92, 0x26, 0xf6, 0x30, 0x65, 0x19, 0x12, 0x78, 0xf4, 0xaf, 0x47, 0x27, + 0x5c, 0x6f, 0xf6, 0xea, 0x18, 0x84, 0x03, 0x17, 0xe4, 0x4c, 0x32, 0x20, 0xd3, 0x7b, + 0x31, 0xc6, 0xc4, 0x8b, 0x48, 0xa4, 0xe8, 0x42, 0x10, 0xa8, 0x64, 0x13, 0x5a, 0x4e, + 0x8b, 0xf1, 0x1e, 0xb2, 0xc9, 0x8d, 0xa2, 0xcd, 0x4b, 0x1c, 0x2a, 0x0c}, + {0x47, 0x04, 0x1f, 0x6f, 0xd0, 0xc7, 0x4d, 0xd2, 0x59, 0xc0, 0x87, 0xdb, 0x3e, 0x9e, + 0x26, 0xb2, 0x8f, 0xd2, 0xb2, 0xfb, 0x72, 0x02, 0x5b, 0xd1, 0x77, 0x48, 0xf6, 0xc6, + 0xd1, 0x8b, 0x55, 0x7c, 0x45, 0x69, 0xbd, 0x69, 0x48, 0x81, 0xc4, 0xed, 0x22, 0x8d, + 0x1c, 0xbe, 0x7d, 0x90, 0x6d, 0x0d, 0xab, 0xc5, 0x5c, 0xd5, 0x12, 0xd2, 0x3b, 0xc6, + 0x83, 0xdc, 0x14, 0xa3, 0x30, 0x9b, 0x6a, 0x5a, 0x3d, 0x46, 0x96, 0xd3, 0x24, 0x15, + 0xec, 0xd0, 0xf0, 0x24, 0x5a, 0xc3, 0x8a, 0x62, 0xbb, 0x12, 0xa4, 0x5f, 0xbc, 0x1c, + 0x79, 0x3a, 0x0c, 0xa5, 0xc3, 0xaf, 0xfb, 0x0a, 0xca, 0xa5, 0x04, 0x04}, + {0xd6, 0x43, 0xa7, 0x0a, 0x07, 0x40, 0x1f, 0x8c, 0xe8, 0x5e, 0x26, 0x5b, 0xcb, 0xd0, + 0xba, 0xcc, 0xde, 0xd2, 0x8f, 0x66, 0x6b, 0x04, 0x4b, 0x57, 0x33, 0x96, 0xdd, 0xca, + 0xfd, 0x5b, 0x39, 0x46, 0xd1, 0x6f, 0x41, 0x2a, 0x1b, 0x9e, 0xbc, 0x62, 0x8b, 0x59, + 0x50, 0xe3, 0x28, 0xf7, 0xc6, 0xb5, 0x67, 0x69, 0x5d, 0x3d, 0xd8, 0x3f, 0x34, 0x04, + 0x98, 0xee, 0xf8, 0xe7, 0x16, 0x75, 0x52, 0x39, 0x9c, 0x9a, 0x5d, 0x1a, 0x2d, 0xdb, + 0x7f, 0x11, 0x2a, 0x5c, 0x00, 0xd1, 0xbc, 0x45, 0x77, 0x9c, 0xea, 0x6f, 0xd5, 0x54, + 0xf1, 0xbe, 0xd4, 0xef, 0x16, 0xd0, 0x22, 0xe8, 0x29, 0x9a, 0x57, 0x76}, + {0x17, 0x2a, 0xc0, 0x49, 0x7e, 0x8e, 0xb6, 0x45, 0x7f, 0xa3, 0xa9, 0xbc, 0xa2, 0x51, + 0xcd, 0x23, 0x1b, 0x4c, 0x22, 0xec, 0x11, 0x5f, 0xd6, 0x3e, 0xb1, 0xbd, 0x05, 0x9e, + 0xdc, 0x84, 0xa3, 0x43, 0xf2, 0x34, 0xb4, 0x52, 0x13, 0xb5, 0x3c, 0x33, 0xe1, 0x80, + 0xde, 0x93, 0x49, 0x28, 0x32, 0xd8, 0xce, 0x35, 0x0d, 0x75, 0x87, 0x28, 0x51, 0xb5, + 0xc1, 0x77, 0x27, 0x2a, 0xbb, 0x14, 0xc5, 0x02, 0x45, 0xb6, 0xf1, 0x8b, 0xda, 0xd5, + 0x4b, 0x68, 0x53, 0x4b, 0xb5, 0xf6, 0x7e, 0xd3, 0x8b, 0xfb, 0x53, 0xd2, 0xb0, 0xa9, + 0xd7, 0x16, 0x39, 0x31, 0x59, 0x80, 0x54, 0x61, 0x09, 0x92, 0x60, 0x11}, + {0xaa, 0xcf, 0xda, 0x29, 0x69, 0x16, 0x4d, 0xb4, 0x8f, 0x59, 0x13, 0x84, 0x4c, 0x9f, + 0x52, 0xda, 0x59, 0x55, 0x3d, 0x45, 0xca, 0x63, 0xef, 0xe9, 0x0b, 0x8e, 0x69, 0xc5, + 0x5b, 0x12, 0x1e, 0x35, 0xcd, 0x4d, 0x9b, 0x36, 0x16, 0x56, 0x38, 0x7a, 0x63, 0x35, + 0x5c, 0x65, 0xa7, 0x2c, 0xc0, 0x75, 0x21, 0x80, 0xf1, 0xd4, 0xf9, 0x1b, 0xc2, 0x7d, + 0x42, 0xe0, 0xe6, 0x91, 0x74, 0x7d, 0x63, 0x2f, 0xbe, 0x7b, 0xf6, 0x1a, 0x46, 0x9b, + 0xb4, 0xd4, 0x61, 0x89, 0xab, 0xc8, 0x7a, 0x03, 0x03, 0xd6, 0xfb, 0x99, 0xa6, 0xf9, + 0x9f, 0xe1, 0xde, 0x71, 0x9a, 0x2a, 0xce, 0xe7, 0x06, 0x2d, 0x18, 0x7f}, + {0xec, 0x68, 0x01, 0xab, 0x64, 0x8e, 0x7c, 0x7a, 0x43, 0xc5, 0xed, 0x15, 0x55, 0x4a, + 0x5a, 0xcb, 0xda, 0x0e, 0xcd, 0x47, 0xd3, 0x19, 0x55, 0x09, 0xb0, 0x93, 0x3e, 0x34, + 0x8c, 0xac, 0xd4, 0x67, 0x22, 0x75, 0x21, 0x8e, 0x72, 0x4b, 0x45, 0x09, 0xd8, 0xb8, + 0x84, 0xd4, 0xf4, 0xe8, 0x58, 0xaa, 0x3c, 0x90, 0x46, 0x7f, 0x4d, 0x25, 0x58, 0xd3, + 0x17, 0x52, 0x1c, 0x24, 0x43, 0xc0, 0xac, 0x44, 0x77, 0x57, 0x7a, 0x4f, 0xbb, 0x6b, + 0x7d, 0x1c, 0xe1, 0x13, 0x83, 0x91, 0xd4, 0xfe, 0x35, 0x8b, 0x84, 0x46, 0x6b, 0xc9, + 0xc6, 0xa1, 0xdc, 0x4a, 0xbd, 0x71, 0xad, 0x12, 0x83, 0x1c, 0x6d, 0x55}, + {0x82, 0x39, 0x8d, 0x0c, 0xe3, 0x40, 0xef, 0x17, 0x34, 0xfa, 0xa3, 0x15, 0x3e, 0x07, + 0xf7, 0x31, 0x6e, 0x64, 0x73, 0x07, 0xcb, 0xf3, 0x21, 0x4f, 0xff, 0x4e, 0x82, 0x1d, + 0x6d, 0x6c, 0x6c, 0x74, 0x21, 0xe8, 0x1b, 0xb1, 0x56, 0x67, 0xf0, 0x81, 0xdd, 0xf3, + 0xa3, 0x10, 0x23, 0xf8, 0xaf, 0x0f, 0x5d, 0x46, 0x99, 0x6a, 0x55, 0xd0, 0xb2, 0xf8, + 0x05, 0x7f, 0x8c, 0xcc, 0x38, 0xbe, 0x7a, 0x09, 0xa4, 0x2d, 0xa5, 0x7e, 0x87, 0xc9, + 0x49, 0x0c, 0x43, 0x1d, 0xdc, 0x9b, 0x55, 0x69, 0x43, 0x4c, 0xd2, 0xeb, 0xcc, 0xf7, + 0x09, 0x38, 0x2c, 0x02, 0xbd, 0x84, 0xee, 0x4b, 0xa3, 0x14, 0x7e, 0x57}, + {0x0a, 0x3b, 0xa7, 0x61, 0xac, 0x68, 0xe2, 0xf0, 0xf5, 0xa5, 0x91, 0x37, 0x10, 0xfa, + 0xfa, 0xf2, 0xe9, 0x00, 0x6d, 0x6b, 0x82, 0x3e, 0xe1, 0xc1, 0x42, 0x8f, 0xd7, 0x6f, + 0xe9, 0x7e, 0xfa, 0x60, 0x2b, 0xd7, 0x4d, 0xbd, 0xbe, 0xce, 0xfe, 0x94, 0x11, 0x22, + 0x0f, 0x06, 0xda, 0x4f, 0x6a, 0xf4, 0xff, 0xd1, 0xc8, 0xc0, 0x77, 0x59, 0x4a, 0x12, + 0x95, 0x92, 0x00, 0xfb, 0xb8, 0x04, 0x53, 0x70, 0xc6, 0x6e, 0x29, 0x4d, 0x35, 0x1d, + 0x3d, 0xb6, 0xd8, 0x31, 0xad, 0x5f, 0x3e, 0x05, 0xc3, 0xf3, 0xec, 0x42, 0xbd, 0xb4, + 0x8c, 0x95, 0x0b, 0x67, 0xfd, 0x53, 0x63, 0xa1, 0x0c, 0x8e, 0x39, 0x21}, + {0xf3, 0x33, 0x2b, 0x38, 0x8a, 0x05, 0xf5, 0x89, 0xb4, 0xc0, 0x48, 0xad, 0x0b, 0xba, + 0xe2, 0x5a, 0x6e, 0xb3, 0x3d, 0xa5, 0x03, 0xb5, 0x93, 0x8f, 0xe6, 0x32, 0xa2, 0x95, + 0x9d, 0xed, 0xa3, 0x5a, 0x01, 0x56, 0xb7, 0xb4, 0xf9, 0xaa, 0x98, 0x27, 0x72, 0xad, + 0x8d, 0x5c, 0x13, 0x72, 0xac, 0x5e, 0x23, 0xa0, 0xb7, 0x61, 0x61, 0xaa, 0xce, 0xd2, + 0x4e, 0x7d, 0x8f, 0xe9, 0x84, 0xb2, 0xbf, 0x1b, 0x61, 0x65, 0xd9, 0xc7, 0xe9, 0x77, + 0x67, 0x65, 0x36, 0x80, 0xc7, 0x72, 0x54, 0x12, 0x2b, 0xcb, 0xee, 0x6e, 0x50, 0xd9, + 0x99, 0x32, 0x05, 0x65, 0xcc, 0x57, 0x89, 0x5e, 0x4e, 0xe1, 0x07, 0x4a}, + {0x99, 0xf9, 0x0d, 0x98, 0xcb, 0x12, 0xe4, 0x4e, 0x71, 0xc7, 0x6e, 0x3c, 0x6f, 0xd7, + 0x15, 0xa3, 0xfd, 0x77, 0x5c, 0x92, 0xde, 0xed, 0xa5, 0xbb, 0x02, 0x34, 0x31, 0x1d, + 0x39, 0xac, 0x0b, 0x3f, 0x9b, 0xa4, 0x77, 0xc4, 0xcd, 0x58, 0x0b, 0x24, 0x17, 0xf0, + 0x47, 0x64, 0xde, 0xda, 0x38, 0xfd, 0xad, 0x6a, 0xc8, 0xa7, 0x32, 0x8d, 0x92, 0x19, + 0x81, 0xa0, 0xaf, 0x84, 0xed, 0x7a, 0xaf, 0x50, 0xe5, 0x5b, 0xf6, 0x15, 0x01, 0xde, + 0x4f, 0x6e, 0xb2, 0x09, 0x61, 0x21, 0x21, 0x26, 0x98, 0x29, 0xd9, 0xd6, 0xad, 0x0b, + 0x81, 0x05, 0x02, 0x78, 0x06, 0xd0, 0xeb, 0xba, 0x16, 0xa3, 0x21, 0x19}, + {0xfc, 0x70, 0xb8, 0xdf, 0x7e, 0x2f, 0x42, 0x89, 0xbd, 0xb3, 0x76, 0x4f, 0xeb, 0x6b, + 0x29, 0x2c, 0xf7, 0x4d, 0xc2, 0x36, 0xd4, 0xf1, 0x38, 0x07, 0xb0, 0xae, 0x73, 0xe2, + 0x41, 0xdf, 0x58, 0x64, 0x8b, 0xc1, 0xf3, 0xd9, 0x9a, 0xad, 0x5a, 0xd7, 0x9c, 0xc1, + 0xb1, 0x60, 0xef, 0x0e, 0x6a, 0x56, 0xd9, 0x0e, 0x5c, 0x25, 0xac, 0x0b, 0x9a, 0x3e, + 0xf5, 0xc7, 0x62, 0xa0, 0xec, 0x9d, 0x04, 0x7b, 0x83, 0x44, 0x44, 0x35, 0x7a, 0xe3, + 0xcb, 0xdc, 0x93, 0xbe, 0xed, 0x0f, 0x33, 0x79, 0x88, 0x75, 0x87, 0xdd, 0xc5, 0x12, + 0xc3, 0x04, 0x60, 0x78, 0x64, 0x0e, 0x95, 0xc2, 0xcb, 0xdc, 0x93, 0x60}, + {0x6d, 0x70, 0xe0, 0x85, 0x85, 0x9a, 0xf3, 0x1f, 0x33, 0x39, 0xe7, 0xb3, 0xd8, 0xa5, + 0xd0, 0x36, 0x3b, 0x45, 0x8f, 0x71, 0xe1, 0xf2, 0xb9, 0x43, 0x7c, 0xa9, 0x27, 0x48, + 0x08, 0xea, 0xd1, 0x57, 0x4b, 0x03, 0x84, 0x60, 0xbe, 0xee, 0xde, 0x6b, 0x54, 0xb8, + 0x0f, 0x78, 0xb6, 0xc2, 0x99, 0x31, 0x95, 0x06, 0x2d, 0xb6, 0xab, 0x76, 0x33, 0x97, + 0x90, 0x7d, 0x64, 0x8b, 0xc9, 0x80, 0x31, 0x6e, 0x71, 0xb0, 0x28, 0xa1, 0xe7, 0xb6, + 0x7a, 0xee, 0xaa, 0x8b, 0xa8, 0x93, 0x6d, 0x59, 0xc1, 0xa4, 0x30, 0x61, 0x21, 0xb2, + 0x82, 0xde, 0xb4, 0xf7, 0x18, 0xbd, 0x97, 0xdd, 0x9d, 0x99, 0x3e, 0x36}, + {0xc4, 0x1f, 0xee, 0x35, 0xc1, 0x43, 0xa8, 0x96, 0xcf, 0xc8, 0xe4, 0x08, 0x55, 0xb3, + 0x6e, 0x97, 0x30, 0xd3, 0x8c, 0xb5, 0x01, 0x68, 0x2f, 0xb4, 0x2b, 0x05, 0x3a, 0x69, + 0x78, 0x9b, 0xee, 0x48, 0xc6, 0xae, 0x4b, 0xe2, 0xdc, 0x48, 0x18, 0x2f, 0x60, 0xaf, + 0xbc, 0xba, 0x55, 0x72, 0x9b, 0x76, 0x31, 0xe9, 0xef, 0x3c, 0x6e, 0x3c, 0xcb, 0x90, + 0x55, 0xb3, 0xf9, 0xc6, 0x9b, 0x97, 0x1f, 0x23, 0xc6, 0xf3, 0x2a, 0xcc, 0x4b, 0xde, + 0x31, 0x5c, 0x1f, 0x8d, 0x20, 0xfe, 0x30, 0xb0, 0x4b, 0xb0, 0x66, 0xb4, 0x4f, 0xc1, + 0x09, 0x70, 0x8d, 0xb7, 0x13, 0x24, 0x79, 0x08, 0x9b, 0xfa, 0x9b, 0x07}, + {0xf4, 0x0d, 0x30, 0xda, 0x51, 0x3a, 0x90, 0xe3, 0xb0, 0x5a, 0xa9, 0x3d, 0x23, 0x64, + 0x39, 0x84, 0x80, 0x64, 0x35, 0x0b, 0x2d, 0xf1, 0x3c, 0xed, 0x94, 0x71, 0x81, 0x84, + 0xf6, 0x77, 0x8c, 0x03, 0x45, 0x42, 0xd5, 0xa2, 0x80, 0xed, 0xc9, 0xf3, 0x52, 0x39, + 0xf6, 0x77, 0x78, 0x8b, 0xa0, 0x0a, 0x75, 0x54, 0x08, 0xd1, 0x63, 0xac, 0x6d, 0xd7, + 0x6b, 0x63, 0x70, 0x94, 0x15, 0xfb, 0xf4, 0x1e, 0xec, 0x7b, 0x16, 0x5b, 0xe6, 0x5e, + 0x4e, 0x85, 0xc2, 0xcd, 0xd0, 0x96, 0x42, 0x0a, 0x59, 0x59, 0x99, 0x21, 0x10, 0x98, + 0x34, 0xdf, 0xb2, 0x72, 0x56, 0xff, 0x0b, 0x4a, 0x2a, 0xe9, 0x5e, 0x57}, + {0xcf, 0x2f, 0x18, 0x8a, 0x90, 0x80, 0xc0, 0xd4, 0xbd, 0x9d, 0x48, 0x99, 0xc2, 0x70, + 0xe1, 0x30, 0xde, 0x33, 0xf7, 0x52, 0x57, 0xbd, 0xba, 0x05, 0x00, 0xfd, 0xd3, 0x2c, + 0x11, 0xe7, 0xd4, 0x43, 0x01, 0xd8, 0xa4, 0x0a, 0x45, 0xbc, 0x46, 0x5d, 0xd8, 0xb9, + 0x33, 0xa5, 0x27, 0x12, 0xaf, 0xc3, 0xc2, 0x06, 0x89, 0x2b, 0x26, 0x3b, 0x9e, 0x38, + 0x1b, 0x58, 0x2f, 0x38, 0x7e, 0x1e, 0x0a, 0x20, 0xc5, 0x3a, 0xf9, 0xea, 0x67, 0xb9, + 0x8d, 0x51, 0xc0, 0x52, 0x66, 0x05, 0x9b, 0x98, 0xbc, 0x71, 0xf5, 0x97, 0x71, 0x56, + 0xd9, 0x85, 0x2b, 0xfe, 0x38, 0x4e, 0x1e, 0x65, 0x52, 0xca, 0x0e, 0x05}, + {0x9c, 0x0c, 0x3f, 0x45, 0xde, 0x1a, 0x43, 0xc3, 0x9b, 0x3b, 0x70, 0xff, 0x5e, 0x04, + 0xf5, 0xe9, 0x3d, 0x7b, 0x84, 0xed, 0xc9, 0x7a, 0xd9, 0xfc, 0xc6, 0xf4, 0x58, 0x1c, + 0xc2, 0xe6, 0x0e, 0x4b, 0xea, 0x68, 0xe6, 0x60, 0x76, 0x39, 0xac, 0x97, 0x97, 0xb4, + 0x3a, 0x15, 0xfe, 0xbb, 0x19, 0x9b, 0x9f, 0xa7, 0xec, 0x34, 0xb5, 0x79, 0xb1, 0x4c, + 0x57, 0xae, 0x31, 0xa1, 0x9f, 0xc0, 0x51, 0x61, 0x96, 0x5d, 0xf0, 0xfd, 0x0d, 0x5c, + 0xf5, 0x3a, 0x7a, 0xee, 0xb4, 0x2a, 0xe0, 0x2e, 0x26, 0xdd, 0x09, 0x17, 0x17, 0x12, + 0x87, 0xbb, 0xb2, 0x11, 0x0b, 0x03, 0x0f, 0x80, 0xfa, 0x24, 0xef, 0x1f}, + {0x96, 0x31, 0xa7, 0x1a, 0xfb, 0x53, 0xd6, 0x37, 0x18, 0x64, 0xd7, 0x3f, 0x30, 0x95, + 0x94, 0x0f, 0xb2, 0x17, 0x3a, 0xfb, 0x09, 0x0b, 0x20, 0xad, 0x3e, 0x61, 0xc8, 0x2f, + 0x29, 0x49, 0x4d, 0x54, 0x86, 0x6b, 0x97, 0x30, 0xf5, 0xaf, 0xd2, 0x22, 0x04, 0x46, + 0xd2, 0xc2, 0x06, 0xb8, 0x90, 0x8d, 0xe5, 0xba, 0xe5, 0x4d, 0x6c, 0x89, 0xa1, 0xdc, + 0x17, 0x0c, 0x34, 0xc8, 0xe6, 0x5f, 0x00, 0x28, 0x88, 0x86, 0x52, 0x34, 0x9f, 0xba, + 0xef, 0x6a, 0xa1, 0x7d, 0x10, 0x25, 0x94, 0xff, 0x1b, 0x5c, 0x36, 0x4b, 0xd9, 0x66, + 0xcd, 0xbb, 0x5b, 0xf7, 0xfa, 0x6d, 0x31, 0x0f, 0x93, 0x72, 0xe4, 0x72}, + {0x4f, 0x08, 0x81, 0x97, 0x8c, 0x20, 0x95, 0x26, 0xe1, 0x0e, 0x45, 0x23, 0x0b, 0x2a, + 0x50, 0xb1, 0x02, 0xde, 0xef, 0x03, 0xa6, 0xae, 0x9d, 0xfd, 0x4c, 0xa3, 0x33, 0x27, + 0x8c, 0x2e, 0x9d, 0x5a, 0x27, 0x76, 0x2a, 0xd3, 0x35, 0xf6, 0xf3, 0x07, 0xf0, 0x66, + 0x65, 0x5f, 0x86, 0x4d, 0xaa, 0x7a, 0x50, 0x44, 0xd0, 0x28, 0x97, 0xe7, 0x85, 0x3c, + 0x38, 0x64, 0xe0, 0x0f, 0x00, 0x7f, 0xee, 0x1f, 0xe5, 0xf7, 0xdb, 0x03, 0xda, 0x05, + 0x53, 0x76, 0xbd, 0xcd, 0x34, 0x14, 0x49, 0xf2, 0xda, 0xa4, 0xec, 0x88, 0x4a, 0xd2, + 0xcd, 0xd5, 0x4a, 0x7b, 0x43, 0x05, 0x04, 0xee, 0x51, 0x40, 0xf9, 0x00}, + {0xb2, 0x30, 0xd3, 0xc3, 0x23, 0x6b, 0x35, 0x8d, 0x06, 0x1b, 0x47, 0xb0, 0x9b, 0x8b, + 0x1c, 0xf2, 0x3c, 0xb8, 0x42, 0x6e, 0x6c, 0x31, 0x6c, 0xb3, 0x0d, 0xb1, 0xea, 0x8b, + 0x7e, 0x9c, 0xd7, 0x07, 0x53, 0x97, 0xaf, 0x07, 0xbb, 0x93, 0xef, 0xd7, 0xa7, 0x66, + 0xb7, 0x3d, 0xcf, 0xd0, 0x3e, 0x58, 0xc5, 0x1e, 0x0b, 0x6e, 0xbf, 0x98, 0x69, 0xce, + 0x52, 0x04, 0xd4, 0x5d, 0xd2, 0xff, 0xb7, 0x47, 0x12, 0xdd, 0x08, 0xbc, 0x9c, 0xfb, + 0xfb, 0x87, 0x9b, 0xc2, 0xee, 0xe1, 0x3a, 0x6b, 0x06, 0x8a, 0xbf, 0xc1, 0x1f, 0xdb, + 0x2b, 0x24, 0x57, 0x0d, 0xb6, 0x4b, 0xa6, 0x5e, 0xa3, 0x20, 0x35, 0x1c}, + {0x4a, 0xa3, 0xcb, 0xbc, 0xa6, 0x53, 0xd2, 0x80, 0x9b, 0x21, 0x38, 0x38, 0xa1, 0xc3, + 0x61, 0x3e, 0x96, 0xe3, 0x82, 0x98, 0x01, 0xb6, 0xc3, 0x90, 0x6f, 0xe6, 0x0e, 0x5d, + 0x77, 0x05, 0x3d, 0x1c, 0x59, 0xc0, 0x6b, 0x21, 0x40, 0x6f, 0xa8, 0xcd, 0x7e, 0xd8, + 0xbc, 0x12, 0x1d, 0x23, 0xbb, 0x1f, 0x90, 0x09, 0xc7, 0x17, 0x9e, 0x6a, 0x95, 0xb4, + 0x55, 0x2e, 0xd1, 0x66, 0x3b, 0x0c, 0x75, 0x38, 0x1a, 0xe5, 0x22, 0x94, 0x40, 0xf1, + 0x2e, 0x69, 0x71, 0xf6, 0x5d, 0x2b, 0x3c, 0xc7, 0xc0, 0xcb, 0x29, 0xe0, 0x4c, 0x74, + 0xe7, 0x4f, 0x01, 0x21, 0x7c, 0x48, 0x30, 0xd3, 0xc7, 0xe2, 0x21, 0x06}, + {0x8d, 0x83, 0x59, 0x82, 0xcc, 0x60, 0x98, 0xaf, 0xdc, 0x9a, 0x9f, 0xc6, 0xc1, 0x48, + 0xea, 0x90, 0x30, 0x1e, 0x58, 0x65, 0x37, 0x48, 0x26, 0x65, 0xbc, 0xa5, 0xd3, 0x7b, + 0x09, 0xd6, 0x07, 0x00, 0xf3, 0xf0, 0xdb, 0xb0, 0x96, 0x17, 0xae, 0xb7, 0x96, 0xe1, + 0x7c, 0xe1, 0xb9, 0xaf, 0xdf, 0x54, 0xb4, 0xa3, 0xaa, 0xe9, 0x71, 0x30, 0x92, 0x25, + 0x9d, 0x2e, 0x00, 0xa1, 0x9c, 0x58, 0x8e, 0x5d, 0x4b, 0xa9, 0x42, 0x08, 0x95, 0x1d, + 0xbf, 0xc0, 0x3e, 0x2e, 0x8f, 0x58, 0x63, 0xc3, 0xd3, 0xb2, 0xef, 0xe2, 0x51, 0xbb, + 0x38, 0x14, 0x96, 0x0a, 0x86, 0xbf, 0x1c, 0x3c, 0x78, 0xd7, 0x83, 0x15}, + {0xe1, 0x7a, 0xa2, 0x5d, 0xef, 0xa2, 0xee, 0xec, 0x74, 0x01, 0x67, 0x55, 0x14, 0x3a, + 0x7c, 0x59, 0x7a, 0x16, 0x09, 0x66, 0x12, 0x2a, 0xa6, 0xc9, 0x70, 0x8f, 0xed, 0x81, + 0x2e, 0x5f, 0x2a, 0x25, 0xc7, 0x28, 0x9d, 0xcc, 0x04, 0x47, 0x03, 0x90, 0x8f, 0xc5, + 0x2c, 0xf7, 0x9e, 0x67, 0x1b, 0x1d, 0x26, 0x87, 0x5b, 0xbe, 0x5f, 0x2b, 0xe1, 0x16, + 0x0a, 0x58, 0xc5, 0x83, 0x4e, 0x06, 0x58, 0x49, 0x0d, 0xe8, 0x66, 0x50, 0x26, 0x94, + 0x28, 0x0d, 0x6b, 0x8c, 0x7c, 0x30, 0x85, 0xf7, 0xc3, 0xfc, 0xfd, 0x12, 0x11, 0x0c, + 0x78, 0xda, 0x53, 0x1b, 0x88, 0xb3, 0x43, 0xd8, 0x0b, 0x17, 0x9c, 0x07}, + {0xff, 0x6f, 0xfa, 0x64, 0xe4, 0xec, 0x06, 0x05, 0x23, 0xe5, 0x05, 0x62, 0x1e, 0x43, + 0xe3, 0xbe, 0x42, 0xea, 0xb8, 0x51, 0x24, 0x42, 0x79, 0x35, 0x00, 0xfb, 0xc9, 0x4a, + 0xe3, 0x05, 0xec, 0x6d, 0x56, 0xd0, 0xd5, 0xc0, 0x50, 0xcd, 0xd6, 0xcd, 0x3b, 0x57, + 0x03, 0xbb, 0x6d, 0x68, 0xf7, 0x9a, 0x48, 0xef, 0xc3, 0xf3, 0x3f, 0x72, 0xa6, 0x3c, + 0xcc, 0x8a, 0x7b, 0x31, 0xd7, 0xc0, 0x68, 0x67, 0xb3, 0xc1, 0x55, 0xf1, 0xe5, 0x25, + 0xb6, 0x94, 0x91, 0x7b, 0x7b, 0x99, 0xa7, 0xf3, 0x7b, 0x41, 0x00, 0x26, 0x6b, 0x6d, + 0xdc, 0xbd, 0x2c, 0xc2, 0xf4, 0x52, 0xcd, 0xdd, 0x14, 0x5e, 0x44, 0x51}, + {0x51, 0x49, 0x14, 0x3b, 0x4b, 0x2b, 0x50, 0x57, 0xb3, 0xbc, 0x4b, 0x44, 0x6b, 0xff, + 0x67, 0x8e, 0xdb, 0x85, 0x63, 0x16, 0x27, 0x69, 0xbd, 0xb8, 0xc8, 0x95, 0x92, 0xe3, + 0x31, 0x6f, 0x18, 0x13, 0x55, 0xa4, 0xbe, 0x2b, 0xab, 0x47, 0x31, 0x89, 0x29, 0x91, + 0x07, 0x92, 0x4f, 0xa2, 0x53, 0x8c, 0xa7, 0xf7, 0x30, 0xbe, 0x48, 0xf9, 0x49, 0x4b, + 0x3d, 0xd4, 0x4f, 0x6e, 0x08, 0x90, 0xe9, 0x12, 0x2e, 0xbb, 0xdf, 0x7f, 0xb3, 0x96, + 0x0c, 0xf1, 0xf9, 0xea, 0x1c, 0x12, 0x5e, 0x93, 0x9a, 0x9f, 0x3f, 0x98, 0x5b, 0x3a, + 0xc4, 0x36, 0x11, 0xdf, 0xaf, 0x99, 0x3e, 0x5d, 0xf0, 0xe3, 0xb2, 0x77}, + {0xde, 0xc4, 0x2e, 0x9c, 0xc5, 0xa9, 0x6f, 0x29, 0xcb, 0xf3, 0x84, 0x4f, 0xbf, 0x61, + 0x8b, 0xbc, 0x08, 0xf9, 0xa8, 0x17, 0xd9, 0x06, 0x77, 0x1c, 0x5d, 0x25, 0xd3, 0x7a, + 0xfc, 0x95, 0xb7, 0x63, 0xa4, 0xb0, 0xdd, 0x12, 0x9c, 0x63, 0x98, 0xd5, 0x6b, 0x86, + 0x24, 0xc0, 0x30, 0x9f, 0xd1, 0xa5, 0x60, 0xe4, 0xfc, 0x58, 0x03, 0x2f, 0x7c, 0xd1, + 0x8a, 0x5e, 0x09, 0x2e, 0x15, 0x95, 0xa1, 0x07, 0xc8, 0x5f, 0x9e, 0x38, 0x02, 0x8f, + 0x36, 0xa8, 0x3b, 0xe4, 0x8d, 0xcf, 0x02, 0x3b, 0x43, 0x90, 0x43, 0x26, 0x41, 0xc5, + 0x5d, 0xfd, 0xa1, 0xaf, 0x37, 0x01, 0x2f, 0x03, 0x3d, 0xe8, 0x8f, 0x3e}, + {0x94, 0xa2, 0x70, 0x05, 0xb9, 0x15, 0x8b, 0x2f, 0x49, 0x45, 0x08, 0x67, 0x70, 0x42, + 0xf2, 0x94, 0x84, 0xfd, 0xbb, 0x61, 0xe1, 0x5a, 0x1c, 0xde, 0x07, 0x40, 0xac, 0x7f, + 0x79, 0x3b, 0xba, 0x75, 0x3c, 0xd1, 0xef, 0xe8, 0x8d, 0x4c, 0x70, 0x08, 0x31, 0x37, + 0xe0, 0x33, 0x8e, 0x1a, 0xc5, 0xdf, 0xe3, 0xcd, 0x60, 0x12, 0xa5, 0x5d, 0x9d, 0xa5, + 0x86, 0x8c, 0x25, 0xa6, 0x99, 0x08, 0xd6, 0x22, 0x96, 0xd1, 0xcd, 0x70, 0xc0, 0xdb, + 0x39, 0x62, 0x9a, 0x8a, 0x7d, 0x6c, 0x8b, 0x8a, 0xfe, 0x60, 0x60, 0x12, 0x40, 0xeb, + 0xbc, 0x47, 0x88, 0xb3, 0x5e, 0x9e, 0x77, 0x87, 0x7b, 0xd0, 0x04, 0x09}, + {0x9c, 0x91, 0xba, 0xdd, 0xd4, 0x1f, 0xce, 0xb4, 0xaa, 0x8d, 0x4c, 0xc7, 0x3e, 0xdb, + 0x31, 0xcf, 0x51, 0xcc, 0x86, 0xad, 0x63, 0xcc, 0x63, 0x2c, 0x07, 0xde, 0x1d, 0xbc, + 0x3f, 0x14, 0xe2, 0x43, 0xb9, 0x40, 0xf9, 0x48, 0x66, 0x2d, 0x32, 0xf4, 0x39, 0x0c, + 0x2d, 0xbd, 0x0c, 0x2f, 0x95, 0x06, 0x31, 0xf9, 0x81, 0xa0, 0xad, 0x97, 0x76, 0x16, + 0x6c, 0x2a, 0xf7, 0xba, 0xce, 0xaa, 0x40, 0x62, 0xa0, 0x95, 0xa2, 0x5b, 0x9c, 0x74, + 0x34, 0xf8, 0x5a, 0xd2, 0x37, 0xca, 0x5b, 0x7c, 0x94, 0xd6, 0x6a, 0x31, 0xc9, 0xe7, + 0xa7, 0x3b, 0xf1, 0x66, 0xac, 0x0c, 0xb4, 0x8d, 0x23, 0xaf, 0xbd, 0x56}, + {0xeb, 0x33, 0x35, 0xf5, 0xe3, 0xb9, 0x2a, 0x36, 0x40, 0x3d, 0xb9, 0x6e, 0xd5, 0x68, + 0x85, 0x33, 0x72, 0x55, 0x5a, 0x1d, 0x52, 0x14, 0x0e, 0x9e, 0x18, 0x13, 0x74, 0x83, + 0x6d, 0xa8, 0x24, 0x1d, 0xb2, 0x3b, 0x9d, 0xc1, 0x6c, 0xd3, 0x10, 0x13, 0xb9, 0x86, + 0x23, 0x62, 0xb7, 0x6b, 0x2a, 0x06, 0x5c, 0x4f, 0xa1, 0xd7, 0x91, 0x85, 0x9b, 0x7c, + 0x54, 0x57, 0x1e, 0x7e, 0x50, 0x31, 0xaa, 0x03, 0x1f, 0xce, 0xd4, 0xff, 0x48, 0x76, + 0xec, 0xf4, 0x1c, 0x8c, 0xac, 0x54, 0xf0, 0xea, 0x45, 0xe0, 0x7c, 0x35, 0x09, 0x1d, + 0x82, 0x25, 0xd2, 0x88, 0x59, 0x48, 0xeb, 0x9a, 0xdc, 0x61, 0xb2, 0x43}, + {0xbb, 0x79, 0xbb, 0x88, 0x19, 0x1e, 0x5b, 0xe5, 0x9d, 0x35, 0x7a, 0xc1, 0x7d, 0xd0, + 0x9e, 0xa0, 0x33, 0xea, 0x3d, 0x60, 0xe2, 0x2e, 0x2c, 0xb0, 0xc2, 0x6b, 0x27, 0x5b, + 0xcf, 0x55, 0x60, 0x32, 0x64, 0x13, 0x95, 0x6c, 0x8b, 0x3d, 0x51, 0x19, 0x7b, 0xf4, + 0x0b, 0x00, 0x26, 0x71, 0xfe, 0x94, 0x67, 0x95, 0x4f, 0xd5, 0xdd, 0x10, 0x8d, 0x02, + 0x64, 0x09, 0x94, 0x42, 0xe2, 0xd5, 0xb4, 0x02, 0xf2, 0x8d, 0xd1, 0x28, 0xcb, 0x55, + 0xa1, 0xb4, 0x08, 0xe5, 0x6c, 0x18, 0x46, 0x46, 0xcc, 0xea, 0x89, 0x43, 0x82, 0x6c, + 0x93, 0xf4, 0x9c, 0xc4, 0x10, 0x34, 0x5d, 0xae, 0x09, 0xc8, 0xa6, 0x27}, + {0x88, 0xb1, 0x0d, 0x1f, 0xcd, 0xeb, 0xa6, 0x8b, 0xe8, 0x5b, 0x5a, 0x67, 0x3a, 0xd7, + 0xd3, 0x37, 0x5a, 0x58, 0xf5, 0x15, 0xa3, 0xdf, 0x2e, 0xf2, 0x7e, 0xa1, 0x60, 0xff, + 0x74, 0x71, 0xb6, 0x2c, 0x54, 0x69, 0x3d, 0xc4, 0x0a, 0x27, 0x2c, 0xcd, 0xb2, 0xca, + 0x66, 0x6a, 0x57, 0x3e, 0x4a, 0xdd, 0x6c, 0x03, 0xd7, 0x69, 0x24, 0x59, 0xfa, 0x79, + 0x99, 0x25, 0x8c, 0x3d, 0x60, 0x03, 0x15, 0x22, 0xd0, 0xe1, 0x0b, 0x39, 0xf9, 0xcd, + 0xee, 0x59, 0xf1, 0xe3, 0x8c, 0x72, 0x44, 0x20, 0x42, 0xa9, 0xf4, 0xf0, 0x94, 0x7a, + 0x66, 0x1c, 0x89, 0x82, 0x36, 0xf4, 0x90, 0x38, 0xb7, 0xf4, 0x1d, 0x7b}, + {0x24, 0xa2, 0xb2, 0xb3, 0xe0, 0xf2, 0x92, 0xe4, 0x60, 0x11, 0x55, 0x2b, 0x06, 0x9e, + 0x6c, 0x7c, 0x0e, 0x7b, 0x7f, 0x0d, 0xe2, 0x8f, 0xeb, 0x15, 0x92, 0x59, 0xfc, 0x58, + 0x26, 0xef, 0xfc, 0x61, 0x8c, 0xf5, 0xf8, 0x07, 0x18, 0x22, 0x2e, 0x5f, 0xd4, 0x09, + 0x94, 0xd4, 0x9f, 0x5c, 0x55, 0xe3, 0x30, 0xa6, 0xb6, 0x1f, 0x8d, 0xa8, 0xaa, 0xb2, + 0x3d, 0xe0, 0x52, 0xd3, 0x45, 0x82, 0x69, 0x68, 0x7a, 0x18, 0x18, 0x2a, 0x85, 0x5d, + 0xb1, 0xdb, 0xd7, 0xac, 0xdd, 0x86, 0xd3, 0xaa, 0xe4, 0xf3, 0x82, 0xc4, 0xf6, 0x0f, + 0x81, 0xe2, 0xba, 0x44, 0xcf, 0x01, 0xaf, 0x3d, 0x47, 0x4c, 0xcf, 0x46}, + {0xf9, 0xe5, 0xc4, 0x9e, 0xed, 0x25, 0x65, 0x42, 0x03, 0x33, 0x90, 0x16, 0x01, 0xda, + 0x5e, 0x0e, 0xdc, 0xca, 0xe5, 0xcb, 0xf2, 0xa7, 0xb1, 0x72, 0x40, 0x5f, 0xeb, 0x14, + 0xcd, 0x7b, 0x38, 0x29, 0x40, 0x81, 0x49, 0xf1, 0xa7, 0x6e, 0x3c, 0x21, 0x54, 0x48, + 0x2b, 0x39, 0xf8, 0x7e, 0x1e, 0x7c, 0xba, 0xce, 0x29, 0x56, 0x8c, 0xc3, 0x88, 0x24, + 0xbb, 0xc5, 0x8c, 0x0d, 0xe5, 0xaa, 0x65, 0x10, 0x57, 0x0d, 0x20, 0xdf, 0x25, 0x45, + 0x2c, 0x1c, 0x4a, 0x67, 0xca, 0xbf, 0xd6, 0x2d, 0x3b, 0x5c, 0x30, 0x40, 0x83, 0xe1, + 0xb1, 0xe7, 0x07, 0x0a, 0x16, 0xe7, 0x1c, 0x4f, 0xe6, 0x98, 0xa1, 0x69}, + {0xbc, 0x78, 0x1a, 0xd9, 0xe0, 0xb2, 0x62, 0x90, 0x67, 0x96, 0x50, 0xc8, 0x9c, 0x88, + 0xc9, 0x47, 0xb8, 0x70, 0x50, 0x40, 0x66, 0x4a, 0xf5, 0x9d, 0xbf, 0xa1, 0x93, 0x24, + 0xa9, 0xe6, 0x69, 0x73, 0xed, 0xca, 0xc5, 0xdc, 0x34, 0x44, 0x01, 0xe1, 0x33, 0xfb, + 0x84, 0x3c, 0x96, 0x5d, 0xed, 0x47, 0xe7, 0xa0, 0x86, 0xed, 0x76, 0x95, 0x01, 0x70, + 0xe4, 0xf9, 0x67, 0xd2, 0x7b, 0x69, 0xb2, 0x25, 0x64, 0x68, 0x98, 0x13, 0xfb, 0x3f, + 0x67, 0x9d, 0xb8, 0xc7, 0x5d, 0x41, 0xd9, 0xfb, 0xa5, 0x3c, 0x5e, 0x3b, 0x27, 0xdf, + 0x3b, 0xcc, 0x4e, 0xe0, 0xd2, 0x4c, 0x4e, 0xb5, 0x3d, 0x68, 0x20, 0x14}, + {0x97, 0xd1, 0x9d, 0x24, 0x1e, 0xbd, 0x78, 0xb4, 0x02, 0xc1, 0x58, 0x5e, 0x00, 0x35, + 0x0c, 0x62, 0x5c, 0xac, 0xba, 0xcc, 0x2f, 0xd3, 0x02, 0xfb, 0x2d, 0xa7, 0x08, 0xf5, + 0xeb, 0x3b, 0xb6, 0x60, 0xd0, 0x5a, 0xcc, 0xc1, 0x6f, 0xbb, 0xee, 0x34, 0x8b, 0xac, + 0x46, 0x96, 0xe9, 0x0c, 0x1b, 0x6a, 0x53, 0xde, 0x6b, 0xa6, 0x49, 0xda, 0xb0, 0xd3, + 0xc1, 0x81, 0xd0, 0x61, 0x41, 0x3b, 0xe8, 0x31, 0x4f, 0x2b, 0x06, 0x9e, 0x12, 0xc7, + 0xe8, 0x97, 0xd8, 0x0a, 0x32, 0x29, 0x4f, 0x8f, 0xe4, 0x49, 0x3f, 0x68, 0x18, 0x6f, + 0x4b, 0xe1, 0xec, 0x5b, 0x17, 0x03, 0x55, 0x2d, 0xb6, 0x1e, 0xcf, 0x55}, + {0x58, 0x3d, 0xc2, 0x65, 0x10, 0x10, 0x79, 0x58, 0x9c, 0x81, 0x94, 0x50, 0x6d, 0x08, + 0x9d, 0x8b, 0xa7, 0x5f, 0xc5, 0x12, 0xa9, 0x2f, 0x40, 0xe2, 0xd4, 0x91, 0x08, 0x57, + 0x64, 0x65, 0x9a, 0x66, 0x52, 0x8c, 0xf5, 0x7d, 0xe3, 0xb5, 0x76, 0x30, 0x36, 0xcc, + 0x99, 0xe7, 0xdd, 0xb9, 0x3a, 0xd7, 0x20, 0xee, 0x13, 0x49, 0xe3, 0x1c, 0x83, 0xbd, + 0x33, 0x01, 0xba, 0x62, 0xaa, 0xfb, 0x56, 0x1a, 0xec, 0xc9, 0x9d, 0x5c, 0x50, 0x6b, + 0x3e, 0x94, 0x1a, 0x37, 0x7c, 0xa7, 0xbb, 0x57, 0x25, 0x30, 0x51, 0x76, 0x34, 0x41, + 0x56, 0xae, 0x73, 0x98, 0x5c, 0x8a, 0xc5, 0x99, 0x67, 0x83, 0xc4, 0x13}, + {0xb9, 0xe1, 0xb3, 0x5a, 0x46, 0x5d, 0x3a, 0x42, 0x61, 0x3f, 0xf1, 0xc7, 0x87, 0xc1, + 0x13, 0xfc, 0xb6, 0xb9, 0xb5, 0xec, 0x64, 0x36, 0xf8, 0x19, 0x07, 0xb6, 0x37, 0xa6, + 0x93, 0x0c, 0xf8, 0x66, 0x80, 0xd0, 0x8b, 0x5d, 0x6a, 0xfb, 0xdc, 0xc4, 0x42, 0x48, + 0x1a, 0x57, 0xec, 0xc4, 0xeb, 0xde, 0x65, 0x53, 0xe5, 0xb8, 0x83, 0xe8, 0xb2, 0xd4, + 0x27, 0xb8, 0xe5, 0xc8, 0x7d, 0xc8, 0xbd, 0x50, 0x11, 0xe1, 0xdf, 0x6e, 0x83, 0x37, + 0x6d, 0x60, 0xd9, 0xab, 0x11, 0xf0, 0x15, 0x3e, 0x35, 0x32, 0x96, 0x3b, 0xb7, 0x25, + 0xc3, 0x3a, 0xb0, 0x64, 0xae, 0xd5, 0x5f, 0x72, 0x44, 0x64, 0xd5, 0x1d}, + {0x7d, 0x12, 0x62, 0x33, 0xf8, 0x7f, 0xa4, 0x8f, 0x15, 0x7c, 0xcd, 0x71, 0xc4, 0x6a, + 0x9f, 0xbc, 0x8b, 0x0c, 0x22, 0x49, 0x43, 0x45, 0x71, 0x6e, 0x2e, 0x73, 0x9f, 0x21, + 0x12, 0x59, 0x64, 0x0e, 0x9a, 0xc8, 0xba, 0x08, 0x00, 0xe6, 0x97, 0xc2, 0xe0, 0xc3, + 0xe1, 0xea, 0x11, 0xea, 0x4c, 0x7d, 0x7c, 0x97, 0xe7, 0x9f, 0xe1, 0x8b, 0xe3, 0xf3, + 0xcd, 0x05, 0xa3, 0x63, 0x0f, 0x45, 0x3a, 0x3a, 0x27, 0x46, 0x39, 0xd8, 0x31, 0x2f, + 0x8f, 0x07, 0x10, 0xa5, 0x94, 0xde, 0x83, 0x31, 0x9d, 0x38, 0x80, 0x6f, 0x99, 0x17, + 0x6d, 0x6c, 0xe3, 0xd1, 0x7b, 0xa8, 0xa9, 0x93, 0x93, 0x8d, 0x8c, 0x31}, + {0x19, 0xfe, 0xff, 0x2a, 0x03, 0x5d, 0x74, 0xf2, 0x66, 0xdb, 0x24, 0x7f, 0x49, 0x3c, + 0x9f, 0x0c, 0xef, 0x98, 0x85, 0xba, 0xe3, 0xd3, 0x98, 0xbc, 0x14, 0x53, 0x1d, 0x9a, + 0x67, 0x7c, 0x4c, 0x22, 0x98, 0xd3, 0x1d, 0xab, 0x29, 0x9e, 0x66, 0x5d, 0x3b, 0x9e, + 0x2d, 0x34, 0x58, 0x16, 0x92, 0xfc, 0xcd, 0x73, 0x59, 0xf3, 0xfd, 0x1d, 0x85, 0x55, + 0xf6, 0x0a, 0x95, 0x25, 0xc3, 0x41, 0x9a, 0x50, 0xe9, 0x25, 0xf9, 0xa6, 0xdc, 0x6e, + 0xc0, 0xbd, 0x33, 0x1f, 0x1b, 0x64, 0xf4, 0xf3, 0x3e, 0x79, 0x89, 0x3e, 0x83, 0x9d, + 0x80, 0x12, 0xec, 0x82, 0x89, 0x13, 0xa1, 0x28, 0x23, 0xf0, 0xbf, 0x05}, + {0x0b, 0xe0, 0xca, 0x23, 0x70, 0x13, 0x32, 0x36, 0x59, 0xcf, 0xac, 0xd1, 0x0a, 0xcf, + 0x4a, 0x54, 0x88, 0x1c, 0x1a, 0xd2, 0x49, 0x10, 0x74, 0x96, 0xa7, 0x44, 0x2a, 0xfa, + 0xc3, 0x8c, 0x0b, 0x78, 0xe4, 0x12, 0xc5, 0x0d, 0xdd, 0xa0, 0x81, 0x68, 0xfe, 0xfa, + 0xa5, 0x44, 0xc8, 0x0d, 0xe7, 0x4f, 0x40, 0x52, 0x4a, 0x8f, 0x6b, 0x8e, 0x74, 0x1f, + 0xea, 0xa3, 0x01, 0xee, 0xcd, 0x77, 0x62, 0x57, 0x5f, 0x30, 0x4f, 0x23, 0xbc, 0x8a, + 0xf3, 0x1e, 0x08, 0xde, 0x05, 0x14, 0xbd, 0x7f, 0x57, 0x9a, 0x0d, 0x2a, 0xe6, 0x34, + 0x14, 0xa5, 0x82, 0x5e, 0xa1, 0xb7, 0x71, 0x62, 0x72, 0x18, 0xf4, 0x5f}, + {0x9d, 0xdb, 0x89, 0x17, 0x0c, 0x08, 0x8e, 0x39, 0xf5, 0x78, 0xe7, 0xf3, 0x25, 0x20, + 0x60, 0xa7, 0x5d, 0x03, 0xbd, 0x06, 0x4c, 0x89, 0x98, 0xfa, 0xbe, 0x66, 0xa9, 0x25, + 0xdc, 0x03, 0x6a, 0x10, 0x40, 0x95, 0xb6, 0x13, 0xe8, 0x47, 0xdb, 0xe5, 0xe1, 0x10, + 0x26, 0x43, 0x3b, 0x2a, 0x5d, 0xf3, 0x76, 0x12, 0x78, 0x38, 0xe9, 0x26, 0x1f, 0xac, + 0x69, 0xcb, 0xa0, 0xa0, 0x8c, 0xdb, 0xd4, 0x29, 0xd0, 0x53, 0x33, 0x33, 0xaf, 0x0a, + 0xad, 0xd9, 0xe5, 0x09, 0xd3, 0xac, 0xa5, 0x9d, 0x66, 0x38, 0xf0, 0xf7, 0x88, 0xc8, + 0x8a, 0x65, 0x57, 0x3c, 0xfa, 0xbe, 0x2c, 0x05, 0x51, 0x8a, 0xb3, 0x4a}, + {0x93, 0xd5, 0x68, 0x67, 0x25, 0x2b, 0x7c, 0xda, 0x13, 0xca, 0x22, 0x44, 0x57, 0xc0, + 0xc1, 0x98, 0x1d, 0xce, 0x0a, 0xca, 0xd5, 0x0b, 0xa8, 0xf1, 0x90, 0xa6, 0x88, 0xc0, + 0xad, 0xd1, 0xcd, 0x29, 0x9c, 0xc0, 0xdd, 0x5f, 0xef, 0xd1, 0xcf, 0xd6, 0xce, 0x5d, + 0x57, 0xf7, 0xfd, 0x3e, 0x2b, 0xe8, 0xc2, 0x34, 0x16, 0x20, 0x5d, 0x6b, 0xd5, 0x25, + 0x9b, 0x2b, 0xed, 0x04, 0xbb, 0xc6, 0x41, 0x30, 0x48, 0xe1, 0x56, 0xd9, 0xf9, 0xf2, + 0xf2, 0x0f, 0x2e, 0x6b, 0x35, 0x9f, 0x75, 0x97, 0xe7, 0xad, 0x5c, 0x02, 0x6c, 0x5f, + 0xbb, 0x98, 0x46, 0x1a, 0x7b, 0x9a, 0x04, 0x14, 0x68, 0xbd, 0x4b, 0x10}, + {0x67, 0xed, 0xf1, 0x68, 0x31, 0xfd, 0xf0, 0x51, 0xc2, 0x3b, 0x6f, 0xd8, 0xcd, 0x1d, + 0x81, 0x2c, 0xde, 0xf2, 0xd2, 0x04, 0x43, 0x5c, 0xdc, 0x44, 0x49, 0x71, 0x2a, 0x09, + 0x57, 0xcc, 0xe8, 0x5b, 0x63, 0xf1, 0x7f, 0xd6, 0x5f, 0x9a, 0x5d, 0xa9, 0x81, 0x56, + 0xc7, 0x4c, 0x9d, 0xe6, 0x2b, 0xe9, 0x57, 0xf2, 0x20, 0xde, 0x4c, 0x02, 0xf8, 0xb7, + 0xf5, 0x2d, 0x07, 0xfb, 0x20, 0x2a, 0x4f, 0x20, 0x79, 0xb0, 0xeb, 0x30, 0x3d, 0x3b, + 0x14, 0xc8, 0x30, 0x2e, 0x65, 0xbd, 0x5a, 0x15, 0x89, 0x75, 0x31, 0x5c, 0x6d, 0x8f, + 0x31, 0x3c, 0x3c, 0x65, 0x1f, 0x16, 0x79, 0xc2, 0x17, 0xfb, 0x70, 0x25}, + {0x75, 0x15, 0xb6, 0x2c, 0x7f, 0x36, 0xfa, 0x3e, 0x6c, 0x02, 0xd6, 0x1c, 0x76, 0x6f, + 0xf9, 0xf5, 0x62, 0x25, 0xb5, 0x65, 0x2a, 0x14, 0xc7, 0xe8, 0xcd, 0x0a, 0x03, 0x53, + 0xea, 0x65, 0xcb, 0x3d, 0x5a, 0x24, 0xb8, 0x0b, 0x55, 0xa9, 0x2e, 0x19, 0xd1, 0x50, + 0x90, 0x8f, 0xa8, 0xfb, 0xe6, 0xc8, 0x35, 0xc9, 0xa4, 0x88, 0x2d, 0xea, 0x86, 0x79, + 0x68, 0x86, 0x01, 0xde, 0x91, 0x5f, 0x1c, 0x24, 0xaa, 0x6c, 0xde, 0x40, 0x29, 0x17, + 0xd8, 0x28, 0x3a, 0x73, 0xd9, 0x22, 0xf0, 0x2c, 0xbf, 0x8f, 0xd1, 0x01, 0x5b, 0x23, + 0xdd, 0xfc, 0xd7, 0x16, 0xe5, 0xf0, 0xcd, 0x5f, 0xdd, 0x0e, 0x42, 0x08}, + {0x4a, 0xfa, 0x62, 0x83, 0xab, 0x20, 0xff, 0xcd, 0x6e, 0x3e, 0x1a, 0xe2, 0xd4, 0x18, + 0xe1, 0x57, 0x2b, 0xe6, 0x39, 0xfc, 0x17, 0x96, 0x17, 0xe3, 0xfd, 0x69, 0x17, 0xbc, + 0xef, 0x53, 0x9a, 0x0d, 0xce, 0x10, 0xf4, 0x04, 0x4e, 0xc3, 0x58, 0x03, 0x85, 0x06, + 0x6e, 0x27, 0x5a, 0x5b, 0x13, 0xb6, 0x21, 0x15, 0xb9, 0xeb, 0xc7, 0x70, 0x96, 0x5d, + 0x9c, 0x88, 0xdb, 0x21, 0xf3, 0x54, 0xd6, 0x04, 0xd5, 0xb5, 0xbd, 0xdd, 0x16, 0xc1, + 0x7d, 0x5e, 0x2d, 0xdd, 0xa5, 0x8d, 0xb6, 0xde, 0x54, 0x29, 0x92, 0xa2, 0x34, 0x33, + 0x17, 0x08, 0xb6, 0x1c, 0xd7, 0x1a, 0x99, 0x18, 0x26, 0x4f, 0x7a, 0x4a}, + {0x95, 0x5f, 0xb1, 0x5f, 0x02, 0x18, 0xa7, 0xf4, 0x8f, 0x1b, 0x5c, 0x6b, 0x34, 0x5f, + 0xf6, 0x3d, 0x12, 0x11, 0xe0, 0x00, 0x85, 0xf0, 0xfc, 0xcd, 0x48, 0x18, 0xd3, 0xdd, + 0x4c, 0x0c, 0xb5, 0x11, 0x4b, 0x2a, 0x37, 0xaf, 0x91, 0xb2, 0xc3, 0x24, 0xf2, 0x47, + 0x81, 0x71, 0x70, 0x82, 0xda, 0x93, 0xf2, 0x9e, 0x89, 0x86, 0x64, 0x85, 0x84, 0xdd, + 0x33, 0xee, 0xe0, 0x23, 0x42, 0x31, 0x96, 0x4a, 0xd6, 0xff, 0xa4, 0x08, 0x44, 0x27, + 0xe8, 0xa6, 0xd9, 0x76, 0x15, 0x9c, 0x7e, 0x17, 0x8e, 0x73, 0xf2, 0xb3, 0x02, 0x3d, + 0xb6, 0x48, 0x33, 0x77, 0x51, 0xcc, 0x6b, 0xce, 0x4d, 0xce, 0x4b, 0x4f}, + {0x84, 0x25, 0x24, 0xe2, 0x5a, 0xce, 0x1f, 0xa7, 0x9e, 0x8a, 0xf5, 0x92, 0x56, 0x72, + 0xea, 0x26, 0xf4, 0x3c, 0xea, 0x1c, 0xd7, 0x09, 0x1a, 0xd2, 0xe6, 0x01, 0x1c, 0xb7, + 0x14, 0xdd, 0xfc, 0x73, 0x6f, 0x0b, 0x9d, 0xc4, 0x6e, 0x61, 0xe2, 0x30, 0x17, 0x23, + 0xec, 0xca, 0x8f, 0x71, 0x56, 0xe4, 0xa6, 0x4f, 0x6b, 0xf2, 0x9b, 0x40, 0xeb, 0x48, + 0x37, 0x5f, 0x59, 0x61, 0xe5, 0xce, 0x42, 0x30, 0x41, 0xac, 0x9b, 0x44, 0x79, 0x70, + 0x7e, 0x42, 0x0a, 0x31, 0xe2, 0xbc, 0x6d, 0xe3, 0x5a, 0x85, 0x7c, 0x1a, 0x84, 0x5f, + 0x21, 0x76, 0xae, 0x4c, 0xd6, 0xe1, 0x9c, 0x9a, 0x0c, 0x74, 0x9e, 0x38}, + {0xce, 0xb9, 0xdc, 0x34, 0xae, 0xb3, 0xfc, 0x64, 0xad, 0xd0, 0x48, 0xe3, 0x23, 0x03, + 0x50, 0x97, 0x1b, 0x38, 0xc6, 0x62, 0x7d, 0xf0, 0xb3, 0x45, 0x88, 0x67, 0x5a, 0x46, + 0x79, 0x53, 0x54, 0x61, 0x28, 0xac, 0x0e, 0x57, 0xf6, 0x78, 0xbd, 0xc9, 0xe1, 0x9c, + 0x91, 0x27, 0x32, 0x0b, 0x5b, 0xe5, 0xed, 0x91, 0x9b, 0xa1, 0xab, 0x3e, 0xfc, 0x65, + 0x90, 0x36, 0x26, 0xd6, 0xe5, 0x25, 0xc4, 0x25, 0x6e, 0xde, 0xd7, 0xf1, 0xa6, 0x06, + 0x3e, 0x3f, 0x08, 0x23, 0x06, 0x8e, 0x27, 0x76, 0xf9, 0x3e, 0x77, 0x6c, 0x8a, 0x4e, + 0x26, 0xf6, 0x14, 0x8c, 0x59, 0x47, 0x48, 0x15, 0x89, 0xa0, 0x39, 0x65}, + {0x73, 0xf7, 0xd2, 0xc3, 0x74, 0x1f, 0xd2, 0xe9, 0x45, 0x68, 0xc4, 0x25, 0x41, 0x54, + 0x50, 0xc1, 0x33, 0x9e, 0xb9, 0xf9, 0xe8, 0x5c, 0x4e, 0x62, 0x6c, 0x18, 0xcd, 0xc5, + 0xaa, 0xe4, 0xc5, 0x11, 0x19, 0x4a, 0xbb, 0x14, 0xd4, 0xdb, 0xc4, 0xdd, 0x8e, 0x4f, + 0x42, 0x98, 0x3c, 0xbc, 0xb2, 0x19, 0x69, 0x71, 0xca, 0x36, 0xd7, 0x9f, 0xa8, 0x48, + 0x90, 0xbd, 0x19, 0xf0, 0x0e, 0x32, 0x65, 0x0f, 0xc6, 0xe0, 0xfd, 0xca, 0xb1, 0xd1, + 0x86, 0xd4, 0x81, 0x51, 0x3b, 0x16, 0xe3, 0xe6, 0x3f, 0x4f, 0x9a, 0x93, 0xf2, 0xfa, + 0x0d, 0xaf, 0xa8, 0x59, 0x2a, 0x07, 0x33, 0xec, 0xbd, 0xc7, 0xab, 0x4c}, + {0x2e, 0x0a, 0x9c, 0x08, 0x24, 0x96, 0x9e, 0x23, 0x38, 0x47, 0xfe, 0x3a, 0xc0, 0xc4, + 0x48, 0xc7, 0x2a, 0xa1, 0x4f, 0x76, 0x2a, 0xed, 0xdb, 0x17, 0x82, 0x85, 0x1c, 0x32, + 0xf0, 0x93, 0x9b, 0x63, 0x89, 0xd2, 0x78, 0x3f, 0x8f, 0x78, 0x8f, 0xc0, 0x9f, 0x4d, + 0x40, 0xa1, 0x2c, 0xa7, 0x30, 0xfe, 0x9d, 0xcc, 0x65, 0xcf, 0xfc, 0x8b, 0x77, 0xf2, + 0x21, 0x20, 0xcb, 0x5a, 0x16, 0x98, 0xe4, 0x7e, 0xc3, 0xa1, 0x11, 0x91, 0xe3, 0x08, + 0xd5, 0x7b, 0x89, 0x74, 0x90, 0x80, 0xd4, 0x90, 0x2b, 0x2b, 0x19, 0xfd, 0x72, 0xae, + 0xc2, 0xae, 0xd2, 0xe7, 0xa6, 0x02, 0xb6, 0x85, 0x3c, 0x49, 0xdf, 0x0e}, + {0x68, 0x5a, 0x9b, 0x59, 0x58, 0x81, 0xcc, 0xae, 0x0e, 0xe2, 0xad, 0xeb, 0x0f, 0x4f, + 0x57, 0xea, 0x07, 0x7f, 0xb6, 0x22, 0x74, 0x1d, 0xe4, 0x4f, 0xb4, 0x4f, 0x9d, 0x01, + 0xe3, 0x92, 0x3b, 0x40, 0x13, 0x41, 0x76, 0x84, 0xd2, 0xc4, 0x67, 0x67, 0x35, 0xf8, + 0xf5, 0xf7, 0x3f, 0x40, 0x90, 0xa0, 0xde, 0xbe, 0xe6, 0xca, 0xfa, 0xcf, 0x8f, 0x1c, + 0x69, 0xa3, 0xdf, 0xd1, 0x54, 0x0c, 0xc0, 0x04, 0xf8, 0x5c, 0x46, 0x8b, 0x81, 0x2f, + 0xc2, 0x4d, 0xf8, 0xef, 0x80, 0x14, 0x5a, 0xf3, 0xa0, 0x71, 0x57, 0xd6, 0xc7, 0x04, + 0xad, 0xbf, 0xe8, 0xae, 0xf4, 0x76, 0x61, 0xb2, 0x2a, 0xb1, 0x5b, 0x35}, + {0xf4, 0xbb, 0x93, 0x74, 0xcc, 0x64, 0x1e, 0xa7, 0xc3, 0xb0, 0xa3, 0xec, 0xd9, 0x84, + 0xbd, 0xe5, 0x85, 0xe7, 0x05, 0xfa, 0x0c, 0xc5, 0x6b, 0x0a, 0x12, 0xc3, 0x2e, 0x18, + 0x32, 0x81, 0x9b, 0x0f, 0x18, 0x73, 0x8c, 0x5a, 0xc7, 0xda, 0x01, 0xa3, 0x11, 0xaa, + 0xce, 0xb3, 0x9d, 0x03, 0x90, 0xed, 0x2d, 0x3f, 0xae, 0x3b, 0xbf, 0x7c, 0x07, 0x6f, + 0x8e, 0xad, 0x52, 0xe0, 0xf8, 0xea, 0x18, 0x75, 0x32, 0x6c, 0x7f, 0x1b, 0xc4, 0x59, + 0x88, 0xa4, 0x98, 0x32, 0x38, 0xf4, 0xbc, 0x60, 0x2d, 0x0f, 0xd9, 0xd1, 0xb1, 0xc9, + 0x29, 0xa9, 0x15, 0x18, 0xc4, 0x55, 0x17, 0xbb, 0x1b, 0x87, 0xc3, 0x47}, + {0x48, 0x4f, 0xec, 0x71, 0x97, 0x53, 0x44, 0x51, 0x6e, 0x5d, 0x8c, 0xc9, 0x7d, 0xb1, + 0x05, 0xf8, 0x6b, 0xc6, 0xc3, 0x47, 0x1a, 0xc1, 0x62, 0xf7, 0xdc, 0x99, 0x46, 0x76, + 0x85, 0x9b, 0xb8, 0x00, 0xb0, 0x66, 0x50, 0xc8, 0x50, 0x5d, 0xe6, 0xfb, 0xb0, 0x99, + 0xa2, 0xb3, 0xb0, 0xc4, 0xec, 0x62, 0xe0, 0xe8, 0x1a, 0x44, 0xea, 0x54, 0x37, 0xe5, + 0x5f, 0x8d, 0xd4, 0xe8, 0x2c, 0xa0, 0xfe, 0x08, 0xd0, 0xea, 0xde, 0x68, 0x76, 0xdd, + 0x4d, 0x82, 0x23, 0x5d, 0x68, 0x4b, 0x20, 0x45, 0x64, 0xc8, 0x65, 0xd6, 0x89, 0x5d, + 0xcd, 0xcf, 0x14, 0xb5, 0x37, 0xd5, 0x75, 0x4f, 0xa7, 0x29, 0x38, 0x47}, + {0x18, 0xc4, 0x79, 0x46, 0x75, 0xda, 0xd2, 0x82, 0xf0, 0x8d, 0x61, 0xb2, 0xd8, 0xd7, + 0x3b, 0xe6, 0x0a, 0xeb, 0x47, 0xac, 0x24, 0xef, 0x5e, 0x35, 0xb4, 0xc6, 0x33, 0x48, + 0x4c, 0x68, 0x78, 0x20, 0xc9, 0x02, 0x39, 0xad, 0x3a, 0x53, 0xd9, 0x23, 0x8f, 0x58, + 0x03, 0xef, 0xce, 0xdd, 0xc2, 0x64, 0xb4, 0x2f, 0xe1, 0xcf, 0x90, 0x73, 0x25, 0x15, + 0x90, 0xd3, 0xe4, 0x44, 0x4d, 0x8b, 0x66, 0x6c, 0x0c, 0x82, 0x78, 0x7a, 0x21, 0xcf, + 0x48, 0x3b, 0x97, 0x3e, 0x27, 0x81, 0xb2, 0x0a, 0x6a, 0xf7, 0x7b, 0xed, 0x8e, 0x8c, + 0xa7, 0x65, 0x6c, 0xa9, 0x3f, 0x43, 0x8a, 0x4f, 0x05, 0xa6, 0x11, 0x74}, + {0x6d, 0xc8, 0x9d, 0xb9, 0x32, 0x9d, 0x65, 0x4d, 0x15, 0xf1, 0x3a, 0x60, 0x75, 0xdc, + 0x4c, 0x04, 0x88, 0xe4, 0xc2, 0xdc, 0x2c, 0x71, 0x4c, 0xb3, 0xff, 0x34, 0x81, 0xfb, + 0x74, 0x65, 0x13, 0x7c, 0xb4, 0x75, 0xb1, 0x18, 0x3d, 0xe5, 0x9a, 0x57, 0x02, 0xa1, + 0x92, 0xf3, 0x59, 0x31, 0x71, 0x68, 0xf5, 0x35, 0xef, 0x1e, 0xba, 0xec, 0x55, 0x84, + 0x8f, 0x39, 0x8c, 0x45, 0x72, 0xa8, 0xc9, 0x1e, 0x9b, 0x50, 0xa2, 0x00, 0xd4, 0xa4, + 0xe6, 0xb8, 0xb4, 0x82, 0xc8, 0x0b, 0x02, 0xd7, 0x81, 0x9b, 0x61, 0x75, 0x95, 0xf1, + 0x9b, 0xcc, 0xe7, 0x57, 0x60, 0x64, 0xcd, 0xc7, 0xa5, 0x88, 0xdd, 0x3a}, + {0xf2, 0xdc, 0x35, 0xb6, 0x70, 0x57, 0x89, 0xab, 0xbc, 0x1f, 0x6c, 0xf6, 0x6c, 0xef, + 0xdf, 0x02, 0x87, 0xd1, 0xb6, 0xbe, 0x68, 0x02, 0x53, 0x85, 0x74, 0x9e, 0x87, 0xcc, + 0xfc, 0x29, 0x99, 0x24, 0x46, 0x30, 0x39, 0x59, 0xd4, 0x98, 0xc2, 0x85, 0xec, 0x59, + 0xf6, 0x5f, 0x98, 0x35, 0x7e, 0x8f, 0x3a, 0x6e, 0xf6, 0xf2, 0x2a, 0xa2, 0x2c, 0x1d, + 0x20, 0xa7, 0x06, 0xa4, 0x31, 0x11, 0xba, 0x61, 0x29, 0x90, 0x95, 0x16, 0xf1, 0xa0, + 0xd0, 0xa3, 0x89, 0xbd, 0x7e, 0xba, 0x6c, 0x6b, 0x3b, 0x02, 0x07, 0x33, 0x78, 0x26, + 0x3e, 0x5a, 0xf1, 0x7b, 0xe7, 0xec, 0xd8, 0xbb, 0x0c, 0x31, 0x20, 0x56}, + {0x43, 0xd6, 0x34, 0x49, 0x43, 0x93, 0x89, 0x52, 0xf5, 0x22, 0x12, 0xa5, 0x06, 0xf8, + 0xdb, 0xb9, 0x22, 0x1c, 0xf4, 0xc3, 0x8f, 0x87, 0x6d, 0x8f, 0x30, 0x97, 0x9d, 0x4d, + 0x2a, 0x6a, 0x67, 0x37, 0xd6, 0x85, 0xe2, 0x77, 0xf4, 0xb5, 0x46, 0x66, 0x93, 0x61, + 0x8f, 0x6c, 0x67, 0xff, 0xe8, 0x40, 0xdd, 0x94, 0xb5, 0xab, 0x11, 0x73, 0xec, 0xa6, + 0x4d, 0xec, 0x8c, 0x65, 0xf3, 0x46, 0xc8, 0x7e, 0xc7, 0x2e, 0xa2, 0x1d, 0x3f, 0x8f, + 0x5e, 0x9b, 0x13, 0xcd, 0x01, 0x6c, 0x77, 0x1d, 0x0f, 0x13, 0xb8, 0x9f, 0x98, 0xa2, + 0xcf, 0x8f, 0x4c, 0x21, 0xd5, 0x9d, 0x9b, 0x39, 0x23, 0xf7, 0xaa, 0x6d}, + {0x47, 0xbe, 0x3d, 0xeb, 0x62, 0x75, 0x3a, 0x5f, 0xb8, 0xa0, 0xbd, 0x8e, 0x54, 0x38, + 0xea, 0xf7, 0x99, 0x72, 0x74, 0x45, 0x31, 0xe5, 0xc3, 0x00, 0x51, 0xd5, 0x27, 0x16, + 0xe7, 0xe9, 0x04, 0x13, 0xa2, 0x8e, 0xad, 0xac, 0xbf, 0x04, 0x3b, 0x58, 0x84, 0xe8, + 0x8b, 0x14, 0xe8, 0x43, 0xb7, 0x29, 0xdb, 0xc5, 0x10, 0x08, 0x3b, 0x58, 0x1e, 0x2b, + 0xaa, 0xbb, 0xb3, 0x8e, 0xe5, 0x49, 0x54, 0x2b, 0xfe, 0x9c, 0xdc, 0x6a, 0xd2, 0x14, + 0x98, 0x78, 0x0b, 0xdd, 0x48, 0x8b, 0x3f, 0xab, 0x1b, 0x3c, 0x0a, 0xc6, 0x79, 0xf9, + 0xff, 0xe1, 0x0f, 0xda, 0x93, 0xd6, 0x2d, 0x7c, 0x2d, 0xde, 0x68, 0x44}, + {0x9e, 0x46, 0x19, 0x94, 0x5e, 0x35, 0xbb, 0x51, 0x54, 0xc7, 0xdd, 0x23, 0x4c, 0xdc, + 0xe6, 0x33, 0x62, 0x99, 0x7f, 0x44, 0xd6, 0xb6, 0xa5, 0x93, 0x63, 0xbd, 0x44, 0xfb, + 0x6f, 0x7c, 0xce, 0x6c, 0xce, 0x07, 0x63, 0xf8, 0xc6, 0xd8, 0x9a, 0x4b, 0x28, 0x0c, + 0x5d, 0x43, 0x31, 0x35, 0x11, 0x21, 0x2c, 0x77, 0x7a, 0x65, 0xc5, 0x66, 0xa8, 0xd4, + 0x52, 0x73, 0x24, 0x63, 0x7e, 0x42, 0xa6, 0x5d, 0xca, 0x22, 0xac, 0xde, 0x88, 0xc6, + 0x94, 0x1a, 0xf8, 0x1f, 0xae, 0xbb, 0xf7, 0x6e, 0x06, 0xb9, 0x0f, 0x58, 0x59, 0x8d, + 0x38, 0x8c, 0xad, 0x88, 0xa8, 0x2c, 0x9f, 0xe7, 0xbf, 0x9a, 0xf2, 0x58}, + {0x68, 0x3e, 0xe7, 0x8d, 0xab, 0xcf, 0x0e, 0xe9, 0xa5, 0x76, 0x7e, 0x37, 0x9f, 0x6f, + 0x03, 0x54, 0x82, 0x59, 0x01, 0xbe, 0x0b, 0x5b, 0x49, 0xf0, 0x36, 0x1e, 0xf4, 0xa7, + 0xc4, 0x29, 0x76, 0x57, 0xf6, 0xcd, 0x0e, 0x71, 0xbf, 0x64, 0x5a, 0x4b, 0x3c, 0x29, + 0x2c, 0x46, 0x38, 0xe5, 0x4c, 0xb1, 0xb9, 0x3a, 0x0b, 0xd5, 0x56, 0xd0, 0x43, 0x36, + 0x70, 0x48, 0x5b, 0x18, 0x24, 0x37, 0xf9, 0x6a, 0x88, 0xa8, 0xc6, 0x09, 0x45, 0x02, + 0x20, 0x32, 0x73, 0x89, 0x55, 0x4b, 0x13, 0x36, 0xe0, 0xd2, 0x9f, 0x28, 0x33, 0x3c, + 0x23, 0x36, 0xe2, 0x83, 0x8f, 0xc1, 0xae, 0x0c, 0xbb, 0x25, 0x1f, 0x70}, + {0xed, 0x6c, 0x61, 0xe4, 0xf8, 0xb0, 0xa8, 0xc3, 0x7d, 0xa8, 0x25, 0x9e, 0x0e, 0x66, + 0x00, 0xf7, 0x9c, 0xa5, 0xbc, 0xf4, 0x1f, 0x06, 0xe3, 0x61, 0xe9, 0x0b, 0xc4, 0xbd, + 0xbf, 0x92, 0x0c, 0x2e, 0x13, 0xc1, 0xbe, 0x7c, 0xd9, 0xf6, 0x18, 0x9d, 0xe4, 0xdb, + 0xbf, 0x74, 0xe6, 0x06, 0x4a, 0x84, 0xd6, 0x60, 0x4e, 0xac, 0x22, 0xb5, 0xf5, 0x20, + 0x51, 0x5e, 0x95, 0x50, 0xc0, 0x5b, 0x0a, 0x72, 0x35, 0x5a, 0x80, 0x9b, 0x43, 0x09, + 0x3f, 0x0c, 0xfc, 0xab, 0x42, 0x62, 0x37, 0x8b, 0x4e, 0xe8, 0x46, 0x93, 0x22, 0x5c, + 0xf3, 0x17, 0x14, 0x69, 0xec, 0xf0, 0x4e, 0x14, 0xbb, 0x9c, 0x9b, 0x0e}, + {0xad, 0x20, 0x57, 0xfb, 0x8f, 0xd4, 0xba, 0xfb, 0x0e, 0x0d, 0xf9, 0xdb, 0x6b, 0x91, + 0x81, 0xee, 0xbf, 0x43, 0x55, 0x63, 0x52, 0x31, 0x81, 0xd4, 0xd8, 0x7b, 0x33, 0x3f, + 0xeb, 0x04, 0x11, 0x22, 0xee, 0xbe, 0xb1, 0x5d, 0xd5, 0x9b, 0xee, 0x8d, 0xb9, 0x3f, + 0x72, 0x0a, 0x37, 0xab, 0xc3, 0xc9, 0x91, 0xd7, 0x68, 0x1c, 0xbf, 0xf1, 0xa8, 0x44, + 0xde, 0x3c, 0xfd, 0x1c, 0x19, 0x44, 0x6d, 0x36, 0x14, 0x8c, 0xbc, 0xf2, 0x43, 0x17, + 0x3c, 0x9e, 0x3b, 0x6c, 0x85, 0xb5, 0xfc, 0x26, 0xda, 0x2e, 0x97, 0xfb, 0xa7, 0x68, + 0x0e, 0x2f, 0xb8, 0xcc, 0x44, 0x32, 0x59, 0xbc, 0xe6, 0xa4, 0x67, 0x41}, + {0x00, 0x27, 0xf6, 0x76, 0x28, 0x9d, 0x3b, 0x64, 0xeb, 0x68, 0x76, 0x0e, 0x40, 0x9d, + 0x1d, 0x5d, 0x84, 0x06, 0xfc, 0x21, 0x03, 0x43, 0x4b, 0x1b, 0x6a, 0x24, 0x55, 0x22, + 0x7e, 0xbb, 0x38, 0x79, 0xee, 0x8f, 0xce, 0xf8, 0x65, 0x26, 0xbe, 0xc2, 0x2c, 0xd6, + 0x80, 0xe8, 0x14, 0xff, 0x67, 0xe9, 0xee, 0x4e, 0x36, 0x2f, 0x7e, 0x6e, 0x2e, 0xf1, + 0xf6, 0xd2, 0x7e, 0xcb, 0x70, 0x33, 0xb3, 0x34, 0xcc, 0xd6, 0x81, 0x86, 0xee, 0x91, + 0xc5, 0xcd, 0x53, 0xa7, 0x85, 0xed, 0x9c, 0x10, 0x02, 0xce, 0x83, 0x88, 0x80, 0x58, + 0xc1, 0x85, 0x74, 0xed, 0xe4, 0x65, 0xfe, 0x2d, 0x6e, 0xfc, 0x76, 0x11}, + {0x9b, 0x61, 0x9c, 0x5b, 0xd0, 0x6c, 0xaf, 0xb4, 0x80, 0x84, 0xa5, 0xb2, 0xf4, 0xc9, + 0xdf, 0x2d, 0xc4, 0x4d, 0xe9, 0xeb, 0x02, 0xa5, 0x4f, 0x3d, 0x34, 0x5f, 0x7d, 0x67, + 0x4c, 0x3a, 0xfc, 0x08, 0xb8, 0x0e, 0x77, 0x49, 0x89, 0xe2, 0x90, 0xdb, 0xa3, 0x40, + 0xf4, 0xac, 0x2a, 0xcc, 0xfb, 0x98, 0x9b, 0x87, 0xd7, 0xde, 0xfe, 0x4f, 0x35, 0x21, + 0xb6, 0x06, 0x69, 0xf2, 0x54, 0x3e, 0x6a, 0x1f, 0xea, 0x34, 0x07, 0xd3, 0x99, 0xc1, + 0xa4, 0x60, 0xd6, 0x5c, 0x16, 0x31, 0xb6, 0x85, 0xc0, 0x40, 0x95, 0x82, 0x59, 0xf7, + 0x23, 0x3e, 0x33, 0xe2, 0xd1, 0x00, 0xb9, 0x16, 0x01, 0xad, 0x2f, 0x4f}, + {0x54, 0x4e, 0xae, 0x94, 0x41, 0xb2, 0xbe, 0x44, 0x6c, 0xef, 0x57, 0x18, 0x51, 0x1c, + 0x54, 0x5f, 0x98, 0x04, 0x8d, 0x36, 0x2d, 0x6b, 0x1e, 0xa6, 0xab, 0xf7, 0x2e, 0x97, + 0xa4, 0x84, 0x54, 0x44, 0x38, 0xb6, 0x3b, 0xb7, 0x1d, 0xd9, 0x2c, 0x96, 0x08, 0x9c, + 0x12, 0xfc, 0xaa, 0x77, 0x05, 0xe6, 0x89, 0x16, 0xb6, 0xf3, 0x39, 0x9b, 0x61, 0x6f, + 0x81, 0xee, 0x44, 0x29, 0x5f, 0x99, 0x51, 0x34, 0x7c, 0x7d, 0xea, 0x9f, 0xd0, 0xfc, + 0x52, 0x91, 0xf6, 0x5c, 0x93, 0xb0, 0x94, 0x6c, 0x81, 0x4a, 0x40, 0x5c, 0x28, 0x47, + 0xaa, 0x9a, 0x8e, 0x25, 0xb7, 0x93, 0x28, 0x04, 0xa6, 0x9c, 0xb8, 0x10}, + {0x9c, 0x28, 0x18, 0x97, 0x49, 0x47, 0x59, 0x3d, 0x26, 0x3f, 0x53, 0x24, 0xc5, 0xf8, + 0xeb, 0x12, 0x15, 0xef, 0xc3, 0x14, 0xcb, 0xbf, 0x62, 0x02, 0x8e, 0x51, 0xb7, 0x77, + 0xd5, 0x78, 0xb8, 0x20, 0x6e, 0xf0, 0x45, 0x5a, 0xbe, 0x41, 0x39, 0x75, 0x65, 0x5f, + 0x9c, 0x6d, 0xed, 0xae, 0x7c, 0xd0, 0xb6, 0x51, 0xff, 0x72, 0x9c, 0x6b, 0x77, 0x11, + 0xa9, 0x4d, 0x0d, 0xef, 0xd9, 0xd1, 0xd2, 0x17, 0x6a, 0x3e, 0x3f, 0x07, 0x18, 0xaf, + 0xf2, 0x27, 0x69, 0x10, 0x52, 0xd7, 0x19, 0xe5, 0x3f, 0xfd, 0x22, 0x00, 0xa6, 0x3c, + 0x2c, 0xb7, 0xe3, 0x22, 0xa7, 0xc6, 0x65, 0xcc, 0x63, 0x4f, 0x21, 0x72}, + {0x93, 0xa6, 0x07, 0x53, 0x40, 0x7f, 0xe3, 0xb4, 0x95, 0x67, 0x33, 0x2f, 0xd7, 0x14, + 0xa7, 0xab, 0x99, 0x10, 0x76, 0x73, 0xa7, 0xd0, 0xfb, 0xd6, 0xc9, 0xcb, 0x71, 0x81, + 0xc5, 0x48, 0xdf, 0x5f, 0xc9, 0x29, 0x3b, 0xf4, 0xb9, 0xb7, 0x9d, 0x1d, 0x75, 0x8f, + 0x51, 0x4f, 0x4a, 0x82, 0x05, 0xd6, 0xc4, 0x9d, 0x2f, 0x31, 0xbd, 0x72, 0xc0, 0xf2, + 0xb0, 0x45, 0x15, 0x5a, 0x85, 0xac, 0x24, 0x1f, 0xaa, 0x05, 0x95, 0x8e, 0x32, 0x08, + 0xd6, 0x24, 0xee, 0x20, 0x14, 0x0c, 0xd1, 0xc1, 0x48, 0x47, 0xa2, 0x25, 0xfb, 0x06, + 0x5c, 0xe4, 0xff, 0xc7, 0xe6, 0x95, 0xe3, 0x2a, 0x9e, 0x73, 0xba, 0x00}, + {0xd6, 0x90, 0x87, 0x5c, 0xde, 0x98, 0x2e, 0x59, 0xdf, 0xa2, 0xc2, 0x45, 0xd3, 0xb7, + 0xbf, 0xe5, 0x22, 0x99, 0xb4, 0xf9, 0x60, 0x3b, 0x5a, 0x11, 0xf3, 0x78, 0xad, 0x67, + 0x3e, 0x3a, 0x28, 0x03, 0x26, 0xbb, 0x88, 0xea, 0xf5, 0x26, 0x44, 0xae, 0xfb, 0x3b, + 0x97, 0x84, 0xd9, 0x79, 0x06, 0x36, 0x50, 0x4e, 0x69, 0x26, 0x0c, 0x03, 0x9f, 0x5c, + 0x26, 0xd2, 0x18, 0xd5, 0xe7, 0x7d, 0x29, 0x72, 0x39, 0xb9, 0x0c, 0xbe, 0xc7, 0x1d, + 0x24, 0x48, 0x80, 0x30, 0x63, 0x8b, 0x4d, 0x9b, 0xf1, 0x32, 0x08, 0x93, 0x28, 0x02, + 0x0d, 0xc9, 0xdf, 0xd3, 0x45, 0x19, 0x27, 0x46, 0x68, 0x29, 0xe1, 0x05}, + {0x5a, 0x49, 0x9c, 0x2d, 0xb3, 0xee, 0x82, 0xba, 0x7c, 0xb9, 0x2b, 0xf1, 0xfc, 0xc8, + 0xef, 0xce, 0xe0, 0xd1, 0xb5, 0x93, 0xae, 0xab, 0x2d, 0xb0, 0x9b, 0x8d, 0x69, 0x13, + 0x9c, 0x0c, 0xc0, 0x39, 0x50, 0x45, 0x2c, 0x24, 0xc8, 0xbb, 0xbf, 0xad, 0xd9, 0x81, + 0x30, 0xd0, 0xec, 0x0c, 0xc8, 0xbc, 0x92, 0xdf, 0xc8, 0xf5, 0xa6, 0x66, 0x35, 0x84, + 0x4c, 0xce, 0x58, 0x82, 0xd3, 0x25, 0xcf, 0x78, 0x68, 0x9d, 0x48, 0x31, 0x8e, 0x6b, + 0xae, 0x15, 0x87, 0xf0, 0x2b, 0x9c, 0xab, 0x1c, 0x85, 0xaa, 0x05, 0xfa, 0x4e, 0xf0, + 0x97, 0x5a, 0xa7, 0xc9, 0x32, 0xf8, 0x3f, 0x6b, 0x07, 0x52, 0x6b, 0x00}, + {0x1c, 0x78, 0x95, 0x9d, 0xe1, 0xcf, 0xe0, 0x29, 0xe2, 0x10, 0x63, 0x96, 0x18, 0xdf, + 0x81, 0xb6, 0x39, 0x6b, 0x51, 0x70, 0xd3, 0x39, 0xdf, 0x57, 0x22, 0x61, 0xc7, 0x3b, + 0x44, 0xe3, 0x57, 0x4d, 0x2d, 0x08, 0xce, 0xb9, 0x16, 0x7e, 0xcb, 0xf5, 0x29, 0xbc, + 0x7a, 0x41, 0x4c, 0xf1, 0x07, 0x34, 0xab, 0xa7, 0xf4, 0x2b, 0xce, 0x6b, 0xb3, 0xd4, + 0xce, 0x75, 0x9f, 0x1a, 0x56, 0xe9, 0xe2, 0x7d, 0xcb, 0x5e, 0xa5, 0xb6, 0xf4, 0xd4, + 0x70, 0xde, 0x99, 0xdb, 0x85, 0x5d, 0x7f, 0x52, 0x01, 0x48, 0x81, 0x9a, 0xee, 0xd3, + 0x40, 0xc4, 0xc9, 0xdb, 0xed, 0x29, 0x60, 0x1a, 0xaf, 0x90, 0x2a, 0x6b}, + {0x97, 0x1e, 0xe6, 0x9a, 0xfc, 0xf4, 0x23, 0x69, 0xd1, 0x5f, 0x3f, 0xe0, 0x1d, 0x28, + 0x35, 0x57, 0x2d, 0xd1, 0xed, 0xe6, 0x43, 0xae, 0x64, 0xa7, 0x4a, 0x3e, 0x2d, 0xd1, + 0xe9, 0xf4, 0xd8, 0x5f, 0x0a, 0xd8, 0xb2, 0x5b, 0x24, 0xf3, 0xeb, 0x77, 0x9b, 0x07, + 0xb9, 0x2f, 0x47, 0x1b, 0x30, 0xd8, 0x33, 0x73, 0xee, 0x4c, 0xf2, 0xe6, 0x47, 0xc6, + 0x09, 0x21, 0x6c, 0x27, 0xc8, 0x12, 0x58, 0x46, 0xd9, 0x62, 0x10, 0x2a, 0xb2, 0xbe, + 0x43, 0x4d, 0x16, 0xdc, 0x31, 0x38, 0x75, 0xfb, 0x65, 0x70, 0xd7, 0x68, 0x29, 0xde, + 0x7b, 0x4a, 0x0d, 0x18, 0x90, 0x67, 0xb1, 0x1c, 0x2b, 0x2c, 0xb3, 0x05}, + {0xfd, 0xa8, 0x4d, 0xd2, 0xcc, 0x5e, 0xc0, 0xc8, 0x83, 0xef, 0xdf, 0x05, 0xac, 0x1a, + 0xcf, 0xa1, 0x61, 0xcd, 0xf9, 0x7d, 0xf2, 0xef, 0xbe, 0xdb, 0x99, 0x1e, 0x47, 0x7b, + 0xa3, 0x56, 0x55, 0x3b, 0x95, 0x81, 0xd5, 0x7a, 0x2c, 0xa4, 0xfc, 0xf7, 0xcc, 0xf3, + 0x33, 0x43, 0x6e, 0x28, 0x14, 0x32, 0x9d, 0x97, 0x0b, 0x34, 0x0d, 0x9d, 0xc2, 0xb6, + 0xe1, 0x07, 0x73, 0x56, 0x48, 0x1a, 0x77, 0x31, 0x82, 0xd4, 0x4d, 0xe1, 0x24, 0xc5, + 0xb0, 0x32, 0xb6, 0xa4, 0x2b, 0x1a, 0x54, 0x51, 0xb3, 0xed, 0xf3, 0x5a, 0x2b, 0x28, + 0x48, 0x60, 0xd1, 0xa3, 0xeb, 0x36, 0x73, 0x7a, 0xd2, 0x79, 0xc0, 0x4f}, + {0x7f, 0x2f, 0xbf, 0x89, 0xb0, 0x38, 0xc9, 0x51, 0xa7, 0xe9, 0xdf, 0x02, 0x65, 0xbd, + 0x97, 0x24, 0x53, 0xe4, 0x80, 0x78, 0x9c, 0xc0, 0xff, 0xff, 0x92, 0x8e, 0xf9, 0xca, + 0xce, 0x67, 0x45, 0x12, 0x0d, 0xc5, 0x86, 0x0c, 0x44, 0x8b, 0x34, 0xdc, 0x51, 0xe6, + 0x94, 0xcc, 0xc9, 0xcb, 0x37, 0x13, 0xb9, 0x3c, 0x3e, 0x64, 0x4d, 0xf7, 0x22, 0x64, + 0x08, 0xcd, 0xe3, 0xba, 0xc2, 0x70, 0x11, 0x24, 0xb4, 0x73, 0xc4, 0x0a, 0x86, 0xab, + 0xf9, 0x3f, 0x35, 0xe4, 0x13, 0x01, 0xee, 0x1d, 0x91, 0xf0, 0xaf, 0xc4, 0xc6, 0xeb, + 0x60, 0x50, 0xe7, 0x4a, 0x0d, 0x00, 0x87, 0x6c, 0x96, 0x12, 0x86, 0x3f}, + {0xde, 0x0d, 0x2a, 0x78, 0xc9, 0x0c, 0x9a, 0x55, 0x85, 0x83, 0x71, 0xea, 0xb2, 0xcd, + 0x1d, 0x55, 0x8c, 0x23, 0xef, 0x31, 0x5b, 0x86, 0x62, 0x7f, 0x3d, 0x61, 0x73, 0x79, + 0x76, 0xa7, 0x4a, 0x50, 0x13, 0x8d, 0x04, 0x36, 0xfa, 0xfc, 0x18, 0x9c, 0xdd, 0x9d, + 0x89, 0x73, 0xb3, 0x9d, 0x15, 0x29, 0xaa, 0xd0, 0x92, 0x9f, 0x0b, 0x35, 0x9f, 0xdc, + 0xd4, 0x19, 0x8a, 0x87, 0xee, 0x7e, 0xf5, 0x26, 0xb1, 0xef, 0x87, 0x56, 0xd5, 0x2c, + 0xab, 0x0c, 0x7b, 0xf1, 0x7a, 0x24, 0x62, 0xd1, 0x80, 0x51, 0x67, 0x24, 0x5a, 0x4f, + 0x34, 0x5a, 0xc1, 0x85, 0x69, 0x30, 0xba, 0x9d, 0x3d, 0x94, 0x41, 0x40}, + {0x96, 0xcc, 0xeb, 0x43, 0xba, 0xee, 0xc0, 0xc3, 0xaf, 0x9c, 0xea, 0x26, 0x9c, 0x9c, + 0x74, 0x8d, 0xc6, 0xcc, 0x77, 0x1c, 0xee, 0x95, 0xfa, 0xd9, 0x0f, 0x34, 0x84, 0x76, + 0xd9, 0xa1, 0x20, 0x14, 0xdd, 0xaa, 0x6c, 0xa2, 0x43, 0x77, 0x21, 0x4b, 0xce, 0xb7, + 0x8a, 0x64, 0x24, 0xb4, 0xa6, 0x47, 0xe3, 0xc9, 0xfb, 0x03, 0x7a, 0x4f, 0x1d, 0xcb, + 0x19, 0xd0, 0x00, 0x98, 0x42, 0x31, 0xd9, 0x12, 0x4f, 0x59, 0x37, 0xd3, 0x99, 0x77, + 0xc6, 0x00, 0x7b, 0xa4, 0x3a, 0xb2, 0x40, 0x51, 0x3c, 0x5e, 0x95, 0xf3, 0x5f, 0xe3, + 0x54, 0x28, 0x18, 0x44, 0x12, 0xa0, 0x59, 0x43, 0x31, 0x92, 0x4f, 0x1b}, + {0x51, 0x09, 0x15, 0x89, 0x9d, 0x10, 0x5c, 0x3e, 0x6a, 0x69, 0xe9, 0x2d, 0x91, 0xfa, + 0xce, 0x39, 0x20, 0x30, 0x5f, 0x97, 0x3f, 0xe4, 0xea, 0x20, 0xae, 0x2d, 0x13, 0x7f, + 0x2a, 0x57, 0x9b, 0x23, 0xb1, 0x66, 0x98, 0xa4, 0x30, 0x30, 0xcf, 0x33, 0x59, 0x48, + 0x5f, 0x21, 0xd2, 0x73, 0x1f, 0x25, 0xf6, 0xf4, 0xde, 0x51, 0x40, 0xaa, 0x82, 0xab, + 0xf6, 0x23, 0x9a, 0x6f, 0xd5, 0x91, 0xf1, 0x5f, 0x68, 0x90, 0x2d, 0xac, 0x33, 0xd4, + 0x9e, 0x81, 0x23, 0x85, 0xc9, 0x5f, 0x79, 0xab, 0x83, 0x28, 0x3d, 0xeb, 0x93, 0x55, + 0x80, 0x72, 0x45, 0xef, 0xcb, 0x36, 0x8f, 0x75, 0x6a, 0x52, 0x0c, 0x02}, + {0xbc, 0xdb, 0xd8, 0x9e, 0xf8, 0x34, 0x98, 0x77, 0x6c, 0xa4, 0x7c, 0xdc, 0xf9, 0xaa, + 0xf2, 0xc8, 0x74, 0xb0, 0xe1, 0xa3, 0xdc, 0x4c, 0x52, 0xa9, 0x77, 0x38, 0x31, 0x15, + 0x46, 0xcc, 0xaa, 0x02, 0x89, 0xcc, 0x42, 0xf0, 0x59, 0xef, 0x31, 0xe9, 0xb6, 0x4b, + 0x12, 0x8e, 0x9d, 0x9c, 0x58, 0x2c, 0x97, 0x59, 0xc7, 0xae, 0x8a, 0xe1, 0xc8, 0xad, + 0x0c, 0xc5, 0x02, 0x56, 0x0a, 0xfe, 0x2c, 0x45, 0xdf, 0x77, 0x78, 0x64, 0xa0, 0xf7, + 0xa0, 0x86, 0x9f, 0x7c, 0x60, 0x0e, 0x27, 0x64, 0xc4, 0xbb, 0xc9, 0x11, 0xfb, 0xf1, + 0x25, 0xea, 0x17, 0xab, 0x7b, 0x87, 0x4b, 0x30, 0x7b, 0x7d, 0xfb, 0x4c}, + {0xfe, 0x75, 0x9b, 0xb8, 0x6c, 0x3d, 0xb4, 0x72, 0x80, 0xdc, 0x6a, 0x9c, 0xd9, 0x94, + 0xc6, 0x54, 0x9f, 0x4c, 0xe3, 0x3e, 0x37, 0xaa, 0xc3, 0xb8, 0x64, 0x53, 0x07, 0x39, + 0x2b, 0x62, 0xb4, 0x14, 0x12, 0xef, 0x89, 0x97, 0xc2, 0x99, 0x86, 0xe2, 0x0d, 0x19, + 0x57, 0xdf, 0x71, 0xcd, 0x6e, 0x2b, 0xd0, 0x70, 0xc9, 0xec, 0x57, 0xc8, 0x43, 0xc3, + 0xc5, 0x3a, 0x4d, 0x43, 0xbc, 0x4c, 0x1d, 0x5b, 0x26, 0x9f, 0x0a, 0xcc, 0x15, 0x26, + 0xfb, 0xb6, 0xe5, 0xcc, 0x8d, 0xb8, 0x2b, 0x0e, 0x4f, 0x3a, 0x05, 0xa7, 0x69, 0x33, + 0x8b, 0x49, 0x01, 0x13, 0xd1, 0x2d, 0x59, 0x58, 0x12, 0xf7, 0x98, 0x2f}, + {0x56, 0x9e, 0x0f, 0xb5, 0x4c, 0xa7, 0x94, 0x0c, 0x20, 0x13, 0x8e, 0x8e, 0xa9, 0xf4, + 0x1f, 0x5b, 0x67, 0x0f, 0x30, 0x82, 0x21, 0xcc, 0x2a, 0x9a, 0xf9, 0xaa, 0x06, 0xd8, + 0x49, 0xe2, 0x6a, 0x3a, 0x01, 0xa7, 0x54, 0x4f, 0x44, 0xae, 0x12, 0x2e, 0xde, 0xd7, + 0xcb, 0xa9, 0xf0, 0x3e, 0xfe, 0xfc, 0xe0, 0x5d, 0x83, 0x75, 0x0d, 0x89, 0xbf, 0xce, + 0x54, 0x45, 0x61, 0xe7, 0xe9, 0x62, 0x80, 0x1d, 0x5a, 0x7c, 0x90, 0xa9, 0x85, 0xda, + 0x7a, 0x65, 0x62, 0x0f, 0xb9, 0x91, 0xb5, 0xa8, 0x0e, 0x1a, 0xe9, 0xb4, 0x34, 0xdf, + 0xfb, 0x1d, 0x0e, 0x8d, 0xf3, 0x5f, 0xf2, 0xae, 0xe8, 0x8c, 0x8b, 0x29}, + {0xb2, 0x0c, 0xf7, 0xef, 0x53, 0x79, 0x92, 0x2a, 0x76, 0x70, 0x15, 0x79, 0x2a, 0xc9, + 0x89, 0x4b, 0x6a, 0xcf, 0xa7, 0x30, 0x7a, 0x45, 0x18, 0x94, 0x85, 0xe4, 0x5c, 0x4d, + 0x40, 0xa8, 0xb8, 0x34, 0xde, 0x65, 0x21, 0x0a, 0xea, 0x72, 0x7a, 0x83, 0xf6, 0x79, + 0xcf, 0x0b, 0xb4, 0x07, 0xab, 0x3f, 0x70, 0xae, 0x38, 0x77, 0xc7, 0x36, 0x16, 0x52, + 0xdc, 0xd7, 0xa7, 0x03, 0x18, 0x27, 0xa6, 0x6b, 0x35, 0x33, 0x69, 0x83, 0xb5, 0xec, + 0x6e, 0xc2, 0xfd, 0xfe, 0xb5, 0x63, 0xdf, 0x13, 0xa8, 0xd5, 0x73, 0x25, 0xb2, 0xa4, + 0x9a, 0xaa, 0x93, 0xa2, 0x6a, 0x1c, 0x5e, 0x46, 0xdd, 0x2b, 0xd6, 0x71}, + {0x80, 0xdf, 0x78, 0xd3, 0x28, 0xcc, 0x33, 0x65, 0xb4, 0xa4, 0x0f, 0x0a, 0x79, 0x43, + 0xdb, 0xf6, 0x5a, 0xda, 0x01, 0xf7, 0xf9, 0x5f, 0x64, 0xe3, 0xa4, 0x2b, 0x17, 0xf3, + 0x17, 0xf3, 0xd5, 0x74, 0xf5, 0x5e, 0xf7, 0xb1, 0xda, 0xb5, 0x2d, 0xcd, 0xf5, 0x65, + 0xb0, 0x16, 0xcf, 0x95, 0x7f, 0xd7, 0x85, 0xf0, 0x49, 0x3f, 0xea, 0x1f, 0x57, 0x14, + 0x3d, 0x2b, 0x2b, 0x26, 0x21, 0x36, 0x33, 0x1c, 0x81, 0xca, 0xd9, 0x67, 0x54, 0xe5, + 0x6f, 0xa8, 0x37, 0x8c, 0x29, 0x2b, 0x75, 0x7c, 0x8b, 0x39, 0x3b, 0x62, 0xac, 0xe3, + 0x92, 0x08, 0x6d, 0xda, 0x8c, 0xd9, 0xe9, 0x47, 0x45, 0xcc, 0xeb, 0x4a}, + {0xc9, 0x01, 0x6d, 0x27, 0x1b, 0x07, 0xf0, 0x12, 0x70, 0x8c, 0xc4, 0x86, 0xc5, 0xba, + 0xb8, 0xe7, 0xa9, 0xfb, 0xd6, 0x71, 0x9b, 0x12, 0x08, 0x53, 0x92, 0xb7, 0x3d, 0x5a, + 0xf9, 0xfb, 0x88, 0x5d, 0x10, 0xb6, 0x54, 0x73, 0x9e, 0x8d, 0x40, 0x0b, 0x6e, 0x5b, + 0xa8, 0x5b, 0x53, 0x32, 0x6b, 0x80, 0x07, 0xa2, 0x58, 0x4a, 0x03, 0x3a, 0xe6, 0xdb, + 0x2c, 0xdf, 0xa1, 0xc9, 0xdd, 0xd9, 0x3b, 0x17, 0xdf, 0x72, 0x58, 0xfe, 0x1e, 0x0f, + 0x50, 0x2b, 0xc1, 0x18, 0x39, 0xd4, 0x2e, 0x58, 0xd6, 0x58, 0xe0, 0x3a, 0x67, 0xc9, + 0x8e, 0x27, 0xed, 0xe6, 0x19, 0xa3, 0x9e, 0xb1, 0x13, 0xcd, 0xe1, 0x06}, + {0x23, 0x6f, 0x16, 0x6f, 0x51, 0xad, 0xd0, 0x40, 0xbe, 0x6a, 0xab, 0x1f, 0x93, 0x32, + 0x8e, 0x11, 0x8e, 0x08, 0x4d, 0xa0, 0x14, 0x5e, 0xe3, 0x3f, 0x66, 0x62, 0xe1, 0x26, + 0x35, 0x60, 0x80, 0x30, 0x53, 0x03, 0x5b, 0x9e, 0x62, 0xaf, 0x2b, 0x47, 0x47, 0x04, + 0x8d, 0x27, 0x90, 0x0b, 0xaa, 0x3b, 0x27, 0xbf, 0x43, 0x96, 0x46, 0x5f, 0x78, 0x0c, + 0x13, 0x7b, 0x83, 0x8d, 0x1a, 0x6a, 0x3a, 0x7f, 0x0b, 0x80, 0x3d, 0x5d, 0x39, 0x44, + 0xe6, 0xf7, 0xf6, 0xed, 0x01, 0xc9, 0x55, 0xd5, 0xa8, 0x95, 0x39, 0x63, 0x2c, 0x59, + 0x30, 0x78, 0xcd, 0x68, 0x7e, 0x30, 0x51, 0x2e, 0xed, 0xfd, 0xd0, 0x30}, + {0xb3, 0x33, 0x12, 0xf2, 0x1a, 0x4d, 0x59, 0xe0, 0x9c, 0x4d, 0xcc, 0xf0, 0x8e, 0xe7, + 0xdb, 0x1b, 0x77, 0x9a, 0x49, 0x8f, 0x7f, 0x18, 0x65, 0x69, 0x68, 0x98, 0x09, 0x2c, + 0x20, 0x14, 0x92, 0x0a, 0x50, 0x47, 0xb8, 0x68, 0x1e, 0x97, 0xb4, 0x9c, 0xcf, 0xbb, + 0x64, 0x66, 0x29, 0x72, 0x95, 0xa0, 0x2b, 0x41, 0xfa, 0x72, 0x26, 0xe7, 0x8d, 0x5c, + 0xd9, 0x89, 0xc5, 0x51, 0x43, 0x08, 0x15, 0x46, 0x2e, 0xa0, 0xb9, 0xae, 0xc0, 0x19, + 0x90, 0xbc, 0xae, 0x4c, 0x03, 0x16, 0x0d, 0x11, 0xc7, 0x55, 0xec, 0x32, 0x99, 0x65, + 0x01, 0xf5, 0x6d, 0x0e, 0xfe, 0x5d, 0xca, 0x95, 0x28, 0x0d, 0xca, 0x3b}, + {0xa4, 0x62, 0x5d, 0x3c, 0xbc, 0x31, 0xf0, 0x40, 0x60, 0x7a, 0xf0, 0xcf, 0x3e, 0x8b, + 0xfc, 0x19, 0x45, 0xb5, 0x0f, 0x13, 0xa2, 0x3d, 0x18, 0x98, 0xcd, 0x13, 0x8f, 0xae, + 0xdd, 0xde, 0x31, 0x56, 0xbf, 0x01, 0xcc, 0x9e, 0xb6, 0x8e, 0x68, 0x9c, 0x6f, 0x89, + 0x44, 0xa6, 0xad, 0x83, 0xbc, 0xf0, 0xe2, 0x9f, 0x7a, 0x5f, 0x5f, 0x95, 0x2d, 0xca, + 0x41, 0x82, 0xf2, 0x8d, 0x03, 0xb4, 0xa8, 0x4e, 0x02, 0xd2, 0xca, 0xf1, 0x0a, 0x46, + 0xed, 0x2a, 0x83, 0xee, 0x8c, 0xa4, 0x05, 0x53, 0x30, 0x46, 0x5f, 0x1a, 0xf1, 0x49, + 0x45, 0x77, 0x21, 0x91, 0x63, 0xa4, 0x2c, 0x54, 0x30, 0x09, 0xce, 0x24}, + {0x06, 0xc1, 0x06, 0xfd, 0xf5, 0x90, 0xe8, 0x1f, 0xf2, 0x10, 0x88, 0x5d, 0x35, 0x68, + 0xc4, 0xb5, 0x3e, 0xaf, 0x8c, 0x6e, 0xfe, 0x08, 0x78, 0x82, 0x4b, 0xd7, 0x06, 0x8a, + 0xc2, 0xe3, 0xd4, 0x41, 0x85, 0x0b, 0xf3, 0xfd, 0x55, 0xa1, 0xcf, 0x3f, 0xa4, 0x2e, + 0x37, 0x36, 0x8e, 0x16, 0xf7, 0xd2, 0x44, 0xf8, 0x92, 0x64, 0xde, 0x64, 0xe0, 0xb2, + 0x80, 0x42, 0x4f, 0x32, 0xa7, 0x28, 0x99, 0x54, 0x2e, 0x1a, 0xee, 0x63, 0xa7, 0x32, + 0x6e, 0xf2, 0xea, 0xfd, 0x5f, 0xd2, 0xb7, 0xe4, 0x91, 0xae, 0x69, 0x4d, 0x7f, 0xd1, + 0x3b, 0xd3, 0x3b, 0xbc, 0x6a, 0xff, 0xdc, 0xc0, 0xde, 0x66, 0x1b, 0x49}, + {0xa7, 0x32, 0xea, 0xc7, 0x3d, 0xb1, 0xf5, 0x98, 0x98, 0xdb, 0x16, 0x7e, 0xcc, 0xf8, + 0xd5, 0xe3, 0x47, 0xd9, 0xf8, 0xcb, 0x52, 0xbf, 0x0a, 0xac, 0xac, 0xe4, 0x5e, 0xc8, + 0xd0, 0x38, 0xf3, 0x08, 0xa1, 0x64, 0xda, 0xd0, 0x8e, 0x4a, 0xf0, 0x75, 0x4b, 0x28, + 0xe2, 0x67, 0xaf, 0x2c, 0x22, 0xed, 0xa4, 0x7b, 0x7b, 0x1f, 0x79, 0xa3, 0x34, 0x82, + 0x67, 0x8b, 0x01, 0xb7, 0xb0, 0xb8, 0xf6, 0x4c, 0xbd, 0x73, 0x1a, 0x99, 0x21, 0xa8, + 0x83, 0xc3, 0x7a, 0x0c, 0x32, 0xdf, 0x01, 0xbc, 0x27, 0xab, 0x63, 0x70, 0x77, 0x84, + 0x1b, 0x33, 0x3d, 0xc1, 0x99, 0x8a, 0x07, 0xeb, 0x82, 0x4a, 0x0d, 0x53}, + {0x25, 0x48, 0xf9, 0xe1, 0x30, 0x36, 0x4c, 0x00, 0x5a, 0x53, 0xab, 0x8c, 0x26, 0x78, + 0x2d, 0x7e, 0x8b, 0xff, 0x84, 0xcc, 0x23, 0x23, 0x48, 0xc7, 0xb9, 0x70, 0x17, 0x10, + 0x3f, 0x75, 0xea, 0x65, 0x9e, 0xbf, 0x9a, 0x6c, 0x45, 0x73, 0x69, 0x6d, 0x80, 0xa8, + 0x00, 0x49, 0xfc, 0xb2, 0x7f, 0x25, 0x50, 0xb8, 0xcf, 0xc8, 0x12, 0xf4, 0xac, 0x2b, + 0x5b, 0xbd, 0xbf, 0x0c, 0xe0, 0xe7, 0xb3, 0x0d, 0x63, 0x63, 0x09, 0xe2, 0x3e, 0xfc, + 0x66, 0x3d, 0x6b, 0xcb, 0xb5, 0x61, 0x7f, 0x2c, 0xd6, 0x81, 0x1a, 0x3b, 0x44, 0x13, + 0x42, 0x04, 0xbe, 0x0f, 0xdb, 0xa1, 0xe1, 0x21, 0x19, 0xec, 0xa4, 0x02}, + {0xa2, 0xb8, 0x24, 0x3b, 0x9a, 0x25, 0xe6, 0x5c, 0xb8, 0xa0, 0xaf, 0x45, 0xcc, 0x7a, + 0x57, 0xb8, 0x37, 0x70, 0xa0, 0x8b, 0xe8, 0xe6, 0xcb, 0xcc, 0xbf, 0x09, 0x78, 0x12, + 0x51, 0x3c, 0x14, 0x3d, 0x5f, 0x79, 0xcf, 0xf1, 0x62, 0x61, 0xc8, 0xf5, 0xf2, 0x57, + 0xee, 0x26, 0x19, 0x86, 0x8c, 0x11, 0x78, 0x35, 0x06, 0x1c, 0x85, 0x24, 0x21, 0x17, + 0xcf, 0x7f, 0x06, 0xec, 0x5d, 0x2b, 0xd1, 0x36, 0x57, 0x45, 0x15, 0x79, 0x91, 0x27, + 0x6d, 0x12, 0x0a, 0x3a, 0x78, 0xfc, 0x5c, 0x8f, 0xe4, 0xd5, 0xac, 0x9b, 0x17, 0xdf, + 0xe8, 0xb6, 0xbd, 0x36, 0x59, 0x28, 0xa8, 0x5b, 0x88, 0x17, 0xf5, 0x2e}, + {0xdc, 0xae, 0x58, 0x8c, 0x4e, 0x97, 0x37, 0x46, 0xa4, 0x41, 0xf0, 0xab, 0xfb, 0x22, + 0xef, 0xb9, 0x8a, 0x71, 0x80, 0xe9, 0x56, 0xd9, 0x85, 0xe1, 0xa6, 0xa8, 0x43, 0xb1, + 0xfa, 0x78, 0x1b, 0x2f, 0x51, 0x2f, 0x5b, 0x30, 0xfb, 0xbf, 0xee, 0x96, 0xb8, 0x96, + 0x95, 0x88, 0xad, 0x38, 0xf9, 0xd3, 0x25, 0xdd, 0xd5, 0x46, 0xc7, 0x2d, 0xf5, 0xf0, + 0x95, 0x00, 0x3a, 0xbb, 0x90, 0x82, 0x96, 0x57, 0x01, 0xe1, 0x20, 0x0a, 0x43, 0xb8, + 0x1a, 0xf7, 0x47, 0xec, 0xf0, 0x24, 0x8d, 0x65, 0x93, 0xf3, 0xd1, 0xee, 0xe2, 0x6e, + 0xa8, 0x09, 0x75, 0xcf, 0xe1, 0xa3, 0x2a, 0xdc, 0x35, 0x3e, 0xc4, 0x7d}, + {0xc3, 0xd9, 0x7d, 0x88, 0x65, 0x66, 0x96, 0x85, 0x55, 0x53, 0xb0, 0x4b, 0x31, 0x9b, + 0x0f, 0xc9, 0xb1, 0x79, 0x20, 0xef, 0xf8, 0x8d, 0xe0, 0xc6, 0x2f, 0xc1, 0x8c, 0x75, + 0x16, 0x20, 0xf7, 0x7e, 0x18, 0x97, 0x3e, 0x27, 0x5c, 0x2a, 0x78, 0x5a, 0x94, 0xfd, + 0x4e, 0x5e, 0x99, 0xc6, 0x76, 0x35, 0x3e, 0x7d, 0x23, 0x1f, 0x05, 0xd8, 0x2e, 0x0f, + 0x99, 0x0a, 0xd5, 0x82, 0x1d, 0xb8, 0x4f, 0x04, 0xd9, 0xe3, 0x07, 0xa9, 0xc5, 0x18, + 0xdf, 0xc1, 0x59, 0x63, 0x4c, 0xce, 0x1d, 0x37, 0xb3, 0x57, 0x49, 0xbb, 0x01, 0xb2, + 0x34, 0x45, 0x70, 0xca, 0x2e, 0xdd, 0x30, 0x9c, 0x3f, 0x82, 0x79, 0x7f}, + {0xe8, 0x13, 0xb5, 0xa3, 0x39, 0xd2, 0x34, 0x83, 0xd8, 0xa8, 0x1f, 0xb9, 0xd4, 0x70, + 0x36, 0xc1, 0x33, 0xbd, 0x90, 0xf5, 0x36, 0x41, 0xb5, 0x12, 0xb4, 0xd9, 0x84, 0xd7, + 0x73, 0x03, 0x4e, 0x0a, 0xba, 0x87, 0xf5, 0x68, 0xf0, 0x1f, 0x9c, 0x6a, 0xde, 0xc8, + 0x50, 0x00, 0x4e, 0x89, 0x27, 0x08, 0xe7, 0x5b, 0xed, 0x7d, 0x55, 0x99, 0xbf, 0x3c, + 0xf0, 0xd6, 0x06, 0x1c, 0x43, 0xb0, 0xa9, 0x64, 0x19, 0x29, 0x7d, 0x5b, 0xa1, 0xd6, + 0xb3, 0x2e, 0x35, 0x82, 0x3a, 0xd5, 0xa0, 0xf6, 0xb4, 0xb0, 0x47, 0x5d, 0xa4, 0x89, + 0x43, 0xce, 0x56, 0x71, 0x6c, 0x34, 0x18, 0xce, 0x0a, 0x7d, 0x1a, 0x07}, + {0x0b, 0xba, 0x87, 0xc8, 0xaa, 0x2d, 0x07, 0xd3, 0xee, 0x62, 0xa5, 0xbf, 0x05, 0x29, + 0x26, 0x01, 0x8b, 0x76, 0xef, 0xc0, 0x02, 0x30, 0x54, 0xcf, 0x9c, 0x7e, 0xea, 0x46, + 0x71, 0xcc, 0x3b, 0x2c, 0x31, 0x44, 0xe1, 0x20, 0x52, 0x35, 0x0c, 0xcc, 0x41, 0x51, + 0xb1, 0x09, 0x07, 0x95, 0x65, 0x0d, 0x36, 0x5f, 0x9d, 0x20, 0x1b, 0x62, 0xf5, 0x9a, + 0xd3, 0x55, 0x77, 0x61, 0xf7, 0xbc, 0x69, 0x7c, 0x5f, 0x29, 0xe8, 0x04, 0xeb, 0xd7, + 0xf0, 0x07, 0x7d, 0xf3, 0x50, 0x2f, 0x25, 0x18, 0xdb, 0x10, 0xd7, 0x98, 0x17, 0x17, + 0xa3, 0xa9, 0x51, 0xe9, 0x1d, 0xa5, 0xac, 0x22, 0x73, 0x9a, 0x5a, 0x6f}, + {0xc5, 0xc6, 0x41, 0x2f, 0x0c, 0x00, 0xa1, 0x8b, 0x9b, 0xfb, 0xfe, 0x0c, 0xc1, 0x79, + 0x9f, 0xc4, 0x9f, 0x1c, 0xc5, 0x3c, 0x70, 0x47, 0xfa, 0x4e, 0xca, 0xaf, 0x47, 0xe1, + 0xa2, 0x21, 0x4e, 0x49, 0xbe, 0x44, 0xd9, 0xa3, 0xeb, 0xd4, 0x29, 0xe7, 0x9e, 0xaf, + 0x78, 0x80, 0x40, 0x09, 0x9e, 0x8d, 0x03, 0x9c, 0x86, 0x47, 0x7a, 0x56, 0x25, 0x45, + 0x24, 0x3b, 0x8d, 0xee, 0x80, 0x96, 0xab, 0x02, 0x9a, 0x0d, 0xe5, 0xdd, 0x85, 0x8a, + 0xa4, 0xef, 0x49, 0xa2, 0xb9, 0x0f, 0x4e, 0x22, 0x9a, 0x21, 0xd9, 0xf6, 0x1e, 0xd9, + 0x1d, 0x1f, 0x09, 0xfa, 0x34, 0xbb, 0x46, 0xea, 0xcb, 0x76, 0x5d, 0x6b}, + {0x94, 0xd9, 0x0c, 0xec, 0x6c, 0x55, 0x57, 0x88, 0xba, 0x1d, 0xd0, 0x5c, 0x6f, 0xdc, + 0x72, 0x64, 0x77, 0xb4, 0x42, 0x8f, 0x14, 0x69, 0x01, 0xaf, 0x54, 0x73, 0x27, 0x85, + 0xf6, 0x33, 0xe3, 0x0a, 0x22, 0x25, 0x78, 0x1e, 0x17, 0x41, 0xf9, 0xe0, 0xd3, 0x36, + 0x69, 0x03, 0x74, 0xae, 0xe6, 0xf1, 0x46, 0xc7, 0xfc, 0xd0, 0xa2, 0x3e, 0x8b, 0x40, + 0x3e, 0x31, 0xdd, 0x03, 0x9c, 0x86, 0xfb, 0x16, 0x62, 0x09, 0xb6, 0x33, 0x97, 0x19, + 0x8e, 0x28, 0x33, 0xe1, 0xab, 0xd8, 0xb4, 0x72, 0xfc, 0x24, 0x3e, 0xd0, 0x91, 0x09, + 0xed, 0xf7, 0x11, 0x48, 0x75, 0xd0, 0x70, 0x8f, 0x8b, 0xe3, 0x81, 0x3f}, + {0xfe, 0xaf, 0xd9, 0x7e, 0xcc, 0x0f, 0x91, 0x7f, 0x4b, 0x87, 0x65, 0x24, 0xa1, 0xb8, + 0x5c, 0x54, 0x04, 0x47, 0x0c, 0x4b, 0xd2, 0x7e, 0x39, 0xa8, 0x93, 0x09, 0xf5, 0x04, + 0xc1, 0x0f, 0x51, 0x50, 0x24, 0xc8, 0x17, 0x5f, 0x35, 0x7f, 0xdb, 0x0a, 0xa4, 0x99, + 0x42, 0xd7, 0xc3, 0x23, 0xb9, 0x74, 0xf7, 0xea, 0xf8, 0xcb, 0x8b, 0x3e, 0x7c, 0xd5, + 0x3d, 0xdc, 0xde, 0x4c, 0xd3, 0xe2, 0xd3, 0x0a, 0x9d, 0x24, 0x6e, 0x33, 0xc5, 0x0f, + 0x0c, 0x6f, 0xd9, 0xcf, 0x31, 0xc3, 0x19, 0xde, 0x5e, 0x74, 0x1c, 0xfe, 0xee, 0x09, + 0x00, 0xfd, 0xd6, 0xf2, 0xbe, 0x1e, 0xfa, 0xf0, 0x8b, 0x15, 0x7c, 0x12}, + {0xa2, 0x79, 0x98, 0x2e, 0x42, 0x7c, 0x19, 0xf6, 0x47, 0x36, 0xca, 0x52, 0xd4, 0xdd, + 0x4a, 0xa4, 0xcb, 0xac, 0x4e, 0x4b, 0xc1, 0x3f, 0x41, 0x9b, 0x68, 0x4f, 0xef, 0x07, + 0x7d, 0xf8, 0x4e, 0x35, 0x74, 0xb9, 0x51, 0xae, 0xc4, 0x8f, 0xa2, 0xde, 0x96, 0xfe, + 0x4d, 0x74, 0xd3, 0x73, 0x99, 0x1d, 0xa8, 0x48, 0x38, 0x87, 0x0b, 0x68, 0x40, 0x62, + 0x95, 0xdf, 0x67, 0xd1, 0x79, 0x24, 0xd8, 0x4e, 0x75, 0xd9, 0xc5, 0x60, 0x22, 0xb5, + 0xe3, 0xfe, 0xb8, 0xb0, 0x41, 0xeb, 0xfc, 0x2e, 0x35, 0x50, 0x3c, 0x65, 0xf6, 0xa9, + 0x30, 0xac, 0x08, 0x88, 0x6d, 0x23, 0x39, 0x05, 0xd2, 0x92, 0x2d, 0x30}, + {0x3d, 0x28, 0xa4, 0xbc, 0xa2, 0xc1, 0x13, 0x78, 0xd9, 0x3d, 0x86, 0xa1, 0x91, 0xf0, + 0x62, 0xed, 0x86, 0xfa, 0x68, 0xc2, 0xb8, 0xbc, 0xc7, 0xae, 0x4c, 0xae, 0x1c, 0x6f, + 0xb7, 0xd3, 0xe5, 0x10, 0x77, 0xf1, 0xe0, 0xe4, 0xb6, 0x6f, 0xbc, 0x2d, 0x93, 0x6a, + 0xbd, 0xa4, 0x29, 0xbf, 0xe1, 0x04, 0xe8, 0xf6, 0x7a, 0x78, 0xd4, 0x66, 0x19, 0x5e, + 0x60, 0xd0, 0x26, 0xb4, 0x5e, 0x5f, 0xdc, 0x0e, 0x67, 0x8e, 0xda, 0x53, 0xd6, 0xbf, + 0x53, 0x54, 0x41, 0xf6, 0xa9, 0x24, 0xec, 0x1e, 0xdc, 0xe9, 0x23, 0x8a, 0x57, 0x03, + 0x3b, 0x26, 0x87, 0xbf, 0x72, 0xba, 0x1c, 0x36, 0x51, 0x6c, 0xb4, 0x45}, + {0xa1, 0x7f, 0x4f, 0x31, 0xbf, 0x2a, 0x40, 0xa9, 0x50, 0xf4, 0x8c, 0x8e, 0xdc, 0xf1, + 0x57, 0xe2, 0x84, 0xbe, 0xa8, 0x23, 0x4b, 0xd5, 0xbb, 0x1d, 0x3b, 0x71, 0xcb, 0x6d, + 0xa3, 0xbf, 0x77, 0x21, 0xe4, 0xe3, 0x7f, 0x8a, 0xdd, 0x4d, 0x9d, 0xce, 0x30, 0x0e, + 0x62, 0x76, 0x56, 0x64, 0x13, 0xab, 0x58, 0x99, 0x0e, 0xb3, 0x7b, 0x4f, 0x59, 0x4b, + 0xdf, 0x29, 0x12, 0x32, 0xef, 0x0a, 0x1c, 0x5c, 0x8f, 0xdb, 0x79, 0xfa, 0xbc, 0x1b, + 0x08, 0x37, 0xb3, 0x59, 0x5f, 0xc2, 0x1e, 0x81, 0x48, 0x60, 0x87, 0x24, 0x83, 0x9c, + 0x65, 0x76, 0x7a, 0x08, 0xbb, 0xb5, 0x8a, 0x7d, 0x38, 0x19, 0xe6, 0x4a}, + {0x2e, 0xa3, 0x44, 0x53, 0xaa, 0xf6, 0xdb, 0x8d, 0x78, 0x40, 0x1b, 0xb4, 0xb4, 0xea, + 0x88, 0x7d, 0x60, 0x0d, 0x13, 0x4a, 0x97, 0xeb, 0xb0, 0x5e, 0x03, 0x3e, 0xbf, 0x17, + 0x1b, 0xd9, 0x00, 0x1a, 0x83, 0xfb, 0x5b, 0x98, 0x44, 0x7e, 0x11, 0x61, 0x36, 0x31, + 0x96, 0x71, 0x2a, 0x46, 0xe0, 0xfc, 0x4b, 0x90, 0x25, 0xd4, 0x48, 0x34, 0xac, 0x83, + 0x64, 0x3d, 0xa4, 0x5b, 0xbe, 0x5a, 0x68, 0x75, 0xb2, 0xf2, 0x61, 0xeb, 0x33, 0x09, + 0x96, 0x6e, 0x52, 0x49, 0xff, 0xc9, 0xa8, 0x0f, 0x3d, 0x54, 0x69, 0x65, 0xf6, 0x7a, + 0x10, 0x75, 0x72, 0xdf, 0xaa, 0xe6, 0xb0, 0x23, 0xb6, 0x29, 0x55, 0x13}, + {0x18, 0xd5, 0xd1, 0xad, 0xd7, 0xdb, 0xf0, 0x18, 0x11, 0x1f, 0xc1, 0xcf, 0x88, 0x78, + 0x9f, 0x97, 0x9b, 0x75, 0x14, 0x71, 0xf0, 0xe1, 0x32, 0x87, 0x01, 0x3a, 0xca, 0x65, + 0x1a, 0xb8, 0xb5, 0x79, 0xfe, 0x83, 0x2e, 0xe2, 0xbc, 0x16, 0xc7, 0xf5, 0xc1, 0x85, + 0x09, 0xe8, 0x19, 0xeb, 0x2b, 0xb4, 0xae, 0x4a, 0x25, 0x14, 0x37, 0xa6, 0x9d, 0xec, + 0x13, 0xa6, 0x90, 0x15, 0x05, 0xea, 0x72, 0x59, 0x11, 0x78, 0x8f, 0xdc, 0x20, 0xac, + 0xd4, 0x0f, 0xa8, 0x4f, 0x4d, 0xac, 0x94, 0xd2, 0x9a, 0x9a, 0x34, 0x04, 0x36, 0xb3, + 0x64, 0x2d, 0x1b, 0xc0, 0xdb, 0x3b, 0x5f, 0x90, 0x95, 0x9c, 0x7e, 0x4f}, + {0x2e, 0x30, 0x81, 0x57, 0xbc, 0x4b, 0x67, 0x62, 0x0f, 0xdc, 0xad, 0x89, 0x39, 0x0f, + 0x52, 0xd8, 0xc6, 0xd9, 0xfb, 0x53, 0xae, 0x99, 0x29, 0x8c, 0x4c, 0x8e, 0x63, 0x2e, + 0xd9, 0x3a, 0x99, 0x31, 0xfe, 0x99, 0x52, 0x35, 0x3d, 0x44, 0xc8, 0x71, 0xd7, 0xea, + 0xeb, 0xdb, 0x1c, 0x3b, 0xcd, 0x8b, 0x66, 0x94, 0xa4, 0xf1, 0x9e, 0x49, 0x92, 0x80, + 0xc8, 0xad, 0x44, 0xa1, 0xc4, 0xee, 0x42, 0x19, 0x92, 0x49, 0x23, 0xae, 0x19, 0x53, + 0xac, 0x7d, 0x92, 0x3e, 0xea, 0x0c, 0x91, 0x3d, 0x1b, 0x2c, 0x22, 0x11, 0x3c, 0x25, + 0x94, 0xe4, 0x3c, 0x55, 0x75, 0xca, 0xf9, 0x4e, 0x31, 0x65, 0x0a, 0x2a}, + {0xc2, 0x27, 0xf9, 0xf7, 0x7f, 0x93, 0xb7, 0x2d, 0x35, 0xa6, 0xd0, 0x17, 0x06, 0x1f, + 0x74, 0xdb, 0x76, 0xaf, 0x55, 0x11, 0xa2, 0xf3, 0x82, 0x59, 0xed, 0x2d, 0x7c, 0x64, + 0x18, 0xe2, 0xf6, 0x4c, 0x3a, 0x79, 0x1c, 0x3c, 0xcd, 0x1a, 0x36, 0xcf, 0x3b, 0xbc, + 0x35, 0x5a, 0xac, 0xbc, 0x9e, 0x2f, 0xab, 0xa6, 0xcd, 0xa8, 0xe9, 0x60, 0xe8, 0x60, + 0x13, 0x1a, 0xea, 0x6d, 0x9b, 0xc3, 0x5d, 0x05, 0xb6, 0x5b, 0x8d, 0xc2, 0x7c, 0x22, + 0x19, 0xb1, 0xab, 0xff, 0x4d, 0x77, 0xbc, 0x4e, 0xe2, 0x07, 0x89, 0x2c, 0xa3, 0xe4, + 0xce, 0x78, 0x3c, 0xa8, 0xb6, 0x24, 0xaa, 0x10, 0x77, 0x30, 0x1a, 0x12}, + {0x97, 0x4a, 0x03, 0x9f, 0x5e, 0x5d, 0xdb, 0xe4, 0x2d, 0xbc, 0x34, 0x30, 0x09, 0xfc, + 0x53, 0xe1, 0xb1, 0xd3, 0x51, 0x95, 0x91, 0x46, 0x05, 0x46, 0x2d, 0xe5, 0x40, 0x7a, + 0x6c, 0xc7, 0x3f, 0x33, 0xc9, 0x83, 0x74, 0xc7, 0x3e, 0x71, 0x59, 0xd6, 0xaf, 0x96, + 0x2b, 0xb8, 0x77, 0xe0, 0xbf, 0x88, 0xd3, 0xbc, 0x97, 0x10, 0x23, 0x28, 0x9e, 0x28, + 0x9b, 0x3a, 0xed, 0x6c, 0x4a, 0xb9, 0x7b, 0x52, 0x2e, 0x48, 0x5b, 0x99, 0x2a, 0x99, + 0x3d, 0x56, 0x01, 0x38, 0x38, 0x6e, 0x7c, 0xd0, 0x05, 0x34, 0xe5, 0xd8, 0x64, 0x2f, + 0xde, 0x35, 0x50, 0x48, 0xf7, 0xa9, 0xa7, 0x20, 0x9b, 0x06, 0x89, 0x6b}, + {0x0d, 0x22, 0x70, 0x62, 0x41, 0xa0, 0x2a, 0x81, 0x4e, 0x5b, 0x24, 0xf9, 0xfa, 0x89, + 0x5a, 0x99, 0x05, 0xef, 0x72, 0x50, 0xce, 0xc4, 0xad, 0xff, 0x73, 0xeb, 0x73, 0xaa, + 0x03, 0x21, 0xbc, 0x23, 0x77, 0xdb, 0xc7, 0xb5, 0x8c, 0xfa, 0x82, 0x40, 0x55, 0xc1, + 0x34, 0xc7, 0xf8, 0x86, 0x86, 0x06, 0x7e, 0xa5, 0xe7, 0xf6, 0xd9, 0xc8, 0xe6, 0x29, + 0xcf, 0x9b, 0x63, 0xa7, 0x08, 0xd3, 0x73, 0x04, 0x05, 0x9e, 0x58, 0x03, 0x26, 0x79, + 0xee, 0xca, 0x92, 0xc4, 0xdc, 0x46, 0x12, 0x42, 0x4b, 0x2b, 0x4f, 0xa9, 0x01, 0xe6, + 0x74, 0xef, 0xa1, 0x02, 0x1a, 0x34, 0x04, 0xde, 0xbf, 0x73, 0x2f, 0x10}, + {0xc6, 0x45, 0x57, 0x7f, 0xab, 0xb9, 0x18, 0xeb, 0x90, 0xc6, 0x87, 0x57, 0xee, 0x8a, + 0x3a, 0x02, 0xa9, 0xaf, 0xf7, 0x2d, 0xda, 0x12, 0x27, 0xb7, 0x3d, 0x01, 0x5c, 0xea, + 0x25, 0x7d, 0x59, 0x36, 0x9a, 0x1c, 0x51, 0xb5, 0xe0, 0xda, 0xb4, 0xa2, 0x06, 0xff, + 0xff, 0x2b, 0x29, 0x60, 0xc8, 0x7a, 0x34, 0x42, 0x50, 0xf5, 0x5d, 0x37, 0x1f, 0x98, + 0x2d, 0xa1, 0x4e, 0xda, 0x25, 0xd7, 0x6b, 0x3f, 0xac, 0x58, 0x60, 0x10, 0x7b, 0x8d, + 0x4d, 0x73, 0x5f, 0x90, 0xc6, 0x6f, 0x9e, 0x57, 0x40, 0xd9, 0x2d, 0x93, 0x02, 0x92, + 0xf9, 0xf8, 0x66, 0x64, 0xd0, 0xd6, 0x60, 0xda, 0x19, 0xcc, 0x7e, 0x7b}, + {0x0d, 0x69, 0x5c, 0x69, 0x3c, 0x37, 0xc2, 0x78, 0x6e, 0x90, 0x42, 0x06, 0x66, 0x2e, + 0x25, 0xdd, 0xd2, 0x2b, 0xe1, 0x4a, 0x44, 0x44, 0x1d, 0x95, 0x56, 0x39, 0x74, 0x01, + 0x76, 0xad, 0x35, 0x42, 0x9b, 0xfa, 0x7c, 0xa7, 0x51, 0x4a, 0xae, 0x6d, 0x50, 0x86, + 0xa3, 0xe7, 0x54, 0x36, 0x26, 0x82, 0xdb, 0x82, 0x2d, 0x8f, 0xcd, 0xff, 0xbb, 0x09, + 0xba, 0xca, 0xf5, 0x1b, 0x66, 0xdc, 0xbe, 0x03, 0xf5, 0x75, 0x89, 0x07, 0x0d, 0xcb, + 0x58, 0x62, 0x98, 0xf2, 0x89, 0x91, 0x54, 0x42, 0x29, 0x49, 0xe4, 0x6e, 0xe3, 0xe2, + 0x23, 0xb4, 0xca, 0xa0, 0xa1, 0x66, 0xf0, 0xcd, 0xb0, 0xe2, 0x7c, 0x0e}, + {0xa3, 0x85, 0x8c, 0xc4, 0x3a, 0x64, 0x94, 0xc4, 0xad, 0x39, 0x61, 0x3c, 0xf4, 0x1d, + 0x36, 0xfd, 0x48, 0x4d, 0xe9, 0x3a, 0xdd, 0x17, 0xdb, 0x09, 0x4a, 0x67, 0xb4, 0x8f, + 0x5d, 0x0a, 0x6e, 0x66, 0xf9, 0x70, 0x4b, 0xd9, 0xdf, 0xfe, 0xa6, 0xfe, 0x2d, 0xba, + 0xfc, 0xc1, 0x51, 0xc0, 0x30, 0xf1, 0x89, 0xab, 0x2f, 0x7f, 0x7e, 0xd4, 0x82, 0x48, + 0xb5, 0xee, 0xec, 0x8a, 0x13, 0x56, 0x52, 0x61, 0x0d, 0xcb, 0x70, 0x48, 0x4e, 0xf6, + 0xbb, 0x2a, 0x6b, 0x8b, 0x45, 0xaa, 0xf0, 0xbc, 0x65, 0xcd, 0x5d, 0x98, 0xe8, 0x75, + 0xba, 0x4e, 0xbe, 0x9a, 0xe4, 0xde, 0x14, 0xd5, 0x10, 0xc8, 0x0b, 0x7f}, + {0x6f, 0x13, 0xf4, 0x26, 0xa4, 0x6b, 0x00, 0xb9, 0x35, 0x30, 0xe0, 0x57, 0x9e, 0x36, + 0x67, 0x8d, 0x28, 0x3c, 0x46, 0x4f, 0xd9, 0xdf, 0xc8, 0xcb, 0xf5, 0xdb, 0xee, 0xf8, + 0xbc, 0x8d, 0x1f, 0x0d, 0xa0, 0x13, 0x72, 0x73, 0xad, 0x9d, 0xac, 0x83, 0x98, 0x2e, + 0xf7, 0x2e, 0xba, 0xf8, 0xf6, 0x9f, 0x57, 0x69, 0xec, 0x43, 0xdd, 0x2e, 0x1e, 0x31, + 0x75, 0xab, 0xc5, 0xde, 0x7d, 0x90, 0x3a, 0x1d, 0xdc, 0x81, 0xd0, 0x3e, 0x31, 0x93, + 0x16, 0xba, 0x80, 0x34, 0x1b, 0x85, 0xad, 0x9f, 0x32, 0x29, 0xcb, 0x21, 0x03, 0x03, + 0x3c, 0x01, 0x28, 0x01, 0xe3, 0xfd, 0x1b, 0xa3, 0x44, 0x1b, 0x01, 0x00}, + {0x0c, 0x6c, 0xc6, 0x3f, 0x6c, 0xa0, 0xdf, 0x3f, 0xd2, 0x0d, 0xd6, 0x4d, 0x8e, 0xe3, + 0x40, 0x5d, 0x71, 0x4d, 0x8e, 0x26, 0x38, 0x8b, 0xe3, 0x7a, 0xe1, 0x57, 0x83, 0x6e, + 0x91, 0x8d, 0xc4, 0x3a, 0x5c, 0xa7, 0x0a, 0x6a, 0x69, 0x1f, 0x56, 0x16, 0x6a, 0xbd, + 0x52, 0x58, 0x5c, 0x72, 0xbf, 0xc1, 0xad, 0x66, 0x79, 0x9a, 0x7f, 0xdd, 0xa8, 0x11, + 0x26, 0x10, 0x85, 0xd2, 0xa2, 0x88, 0xd9, 0x63, 0x2e, 0x23, 0xbd, 0xaf, 0x53, 0x07, + 0x12, 0x00, 0x83, 0xf6, 0xd8, 0xfd, 0xb8, 0xce, 0x2b, 0xe9, 0x91, 0x2b, 0xe7, 0x84, + 0xb3, 0x69, 0x16, 0xf8, 0x66, 0xa0, 0x68, 0x23, 0x2b, 0xd5, 0xfa, 0x33}, + {0x16, 0x1e, 0xe4, 0xc5, 0xc6, 0x49, 0x06, 0x54, 0x35, 0x77, 0x3f, 0x33, 0x30, 0x64, + 0xf8, 0x0a, 0x46, 0xe7, 0x05, 0xf3, 0xd2, 0xfc, 0xac, 0xb2, 0xa7, 0xdc, 0x56, 0xa2, + 0x29, 0xf4, 0xc0, 0x16, 0xe8, 0xcf, 0x22, 0xc4, 0xd0, 0xc8, 0x2c, 0x8d, 0xcb, 0x3a, + 0xa1, 0x05, 0x7b, 0x4f, 0x2b, 0x07, 0x6f, 0xa5, 0xf6, 0xec, 0xe6, 0xb6, 0xfe, 0xa3, + 0xe2, 0x71, 0x0a, 0xb9, 0xcc, 0x55, 0xc3, 0x3c, 0x31, 0x91, 0x3e, 0x90, 0x43, 0x94, + 0xb6, 0xe9, 0xce, 0x37, 0x56, 0x7a, 0xcb, 0x94, 0xa4, 0xb8, 0x44, 0x92, 0xba, 0xba, + 0xa4, 0xd1, 0x7c, 0xc8, 0x68, 0x75, 0xae, 0x6b, 0x42, 0xaf, 0x1e, 0x63}, + {0x9f, 0xfe, 0x66, 0xda, 0x10, 0x04, 0xe9, 0xb3, 0xa6, 0xe5, 0x16, 0x6c, 0x52, 0x4b, + 0xdd, 0x85, 0x83, 0xbf, 0xf9, 0x1e, 0x61, 0x97, 0x3d, 0xbc, 0xb5, 0x19, 0xa9, 0x1e, + 0x8b, 0x64, 0x99, 0x55, 0xe8, 0x0d, 0x70, 0xa3, 0xb9, 0x75, 0xd9, 0x47, 0x52, 0x05, + 0xf8, 0xe2, 0xfb, 0xc5, 0x80, 0x72, 0xe1, 0x5d, 0xe4, 0x32, 0x27, 0x8f, 0x65, 0x53, + 0xb5, 0x80, 0x5f, 0x66, 0x7f, 0x2c, 0x1f, 0x43, 0x19, 0x7b, 0x8f, 0x85, 0x44, 0x63, + 0x02, 0xd6, 0x4a, 0x51, 0xea, 0xa1, 0x2f, 0x35, 0xab, 0x14, 0xd7, 0xa9, 0x90, 0x20, + 0x1a, 0x44, 0x00, 0x89, 0x26, 0x3b, 0x25, 0x91, 0x5f, 0x71, 0x04, 0x7b}, + {0x43, 0xae, 0xf6, 0xac, 0x28, 0xbd, 0xed, 0x83, 0xb4, 0x7a, 0x5c, 0x7d, 0x8b, 0x7c, + 0x35, 0x86, 0x44, 0x2c, 0xeb, 0xb7, 0x69, 0x47, 0x40, 0xc0, 0x3f, 0x58, 0xf6, 0xc2, + 0xf5, 0x7b, 0xb3, 0x59, 0xc6, 0xba, 0xe6, 0xc4, 0x80, 0xc2, 0x76, 0xb3, 0x0b, 0x9b, + 0x1d, 0x6d, 0xdd, 0xd3, 0x0e, 0x97, 0x44, 0xf9, 0x0b, 0x45, 0x58, 0x95, 0x9a, 0xb0, + 0x23, 0xe2, 0xcd, 0x57, 0xfa, 0xac, 0xd0, 0x48, 0x71, 0xe6, 0xab, 0x7d, 0xe4, 0x26, + 0x0f, 0xb6, 0x37, 0x3a, 0x2f, 0x62, 0x97, 0xa1, 0xd1, 0xf1, 0x94, 0x03, 0x96, 0xe9, + 0x7e, 0xce, 0x08, 0x42, 0xdb, 0x3b, 0x6d, 0x33, 0x91, 0x41, 0x23, 0x16}, + {0xf6, 0x7f, 0x26, 0xf6, 0xde, 0x99, 0xe4, 0xb9, 0x43, 0x08, 0x2c, 0x74, 0x7b, 0xca, + 0x72, 0x77, 0xb1, 0xf2, 0xa4, 0xe9, 0x3f, 0x15, 0xa0, 0x23, 0x06, 0x50, 0xd0, 0xd5, + 0xec, 0xdf, 0xdf, 0x2c, 0x40, 0x86, 0xf3, 0x1f, 0xd6, 0x9c, 0x49, 0xdd, 0xa0, 0x25, + 0x36, 0x06, 0xc3, 0x9b, 0xcd, 0x29, 0xc3, 0x3d, 0xd7, 0x3d, 0x02, 0xd8, 0xe2, 0x51, + 0x31, 0x92, 0x3b, 0x20, 0x7a, 0x70, 0x25, 0x4a, 0x6a, 0xed, 0xf6, 0x53, 0x8a, 0x66, + 0xb7, 0x2a, 0xa1, 0x70, 0xd1, 0x1d, 0x58, 0x42, 0x42, 0x30, 0x61, 0x01, 0xe2, 0x3a, + 0x4c, 0x14, 0x00, 0x40, 0xfc, 0x49, 0x8e, 0x24, 0x6d, 0x89, 0x21, 0x57}, + {0xae, 0x1b, 0x18, 0xfd, 0x17, 0x55, 0x6e, 0x0b, 0xb4, 0x63, 0xb9, 0x2b, 0x9f, 0x62, + 0x22, 0x90, 0x25, 0x46, 0x06, 0x32, 0xe9, 0xbc, 0x09, 0x55, 0xda, 0x13, 0x3c, 0xf6, + 0x74, 0xdd, 0x8e, 0x57, 0x4e, 0xda, 0xd0, 0xa1, 0x91, 0x50, 0x5d, 0x28, 0x08, 0x3e, + 0xfe, 0xb5, 0xa7, 0x6f, 0xaa, 0x4b, 0xb3, 0x93, 0x93, 0xe1, 0x7c, 0x17, 0xe5, 0x63, + 0xfd, 0x30, 0xb0, 0xc4, 0xaf, 0x35, 0xc9, 0x03, 0x3d, 0x0c, 0x2b, 0x49, 0xc6, 0x76, + 0x72, 0x99, 0xfc, 0x05, 0xe2, 0xdf, 0xc4, 0xc2, 0xcc, 0x47, 0x3c, 0x3a, 0x62, 0xdd, + 0x84, 0x9b, 0xd2, 0xdc, 0xa2, 0xc7, 0x88, 0x02, 0x59, 0xab, 0xc2, 0x3e}, + {0xb9, 0x7b, 0xd8, 0xe4, 0x7b, 0xd2, 0xa0, 0xa1, 0xed, 0x1a, 0x39, 0x61, 0xeb, 0x4d, + 0x8b, 0xa9, 0x83, 0x9b, 0xcb, 0x73, 0xd0, 0xdd, 0xa0, 0x99, 0xce, 0xca, 0x0f, 0x20, + 0x5a, 0xc2, 0xd5, 0x2d, 0xcb, 0xd1, 0x32, 0xae, 0x09, 0x3a, 0x21, 0xa7, 0xd5, 0xc2, + 0xf5, 0x40, 0xdf, 0x87, 0x2b, 0x0f, 0x29, 0xab, 0x1e, 0xe8, 0xc6, 0xa4, 0xae, 0x0b, + 0x5e, 0xac, 0xdb, 0x6a, 0x6c, 0xf6, 0x1b, 0x0e, 0x7e, 0x88, 0x2c, 0x79, 0xe9, 0xd5, + 0xab, 0xe2, 0x5d, 0x6d, 0x92, 0xcb, 0x18, 0x00, 0x02, 0x1a, 0x1e, 0x5f, 0xae, 0xba, + 0xcd, 0x69, 0xba, 0xbf, 0x5f, 0x8f, 0xe8, 0x5a, 0xb3, 0x48, 0x05, 0x73}, + {0xee, 0xb8, 0xa8, 0xcb, 0xa3, 0x51, 0x35, 0xc4, 0x16, 0x5f, 0x11, 0xb2, 0x1d, 0x6f, + 0xa2, 0x65, 0x50, 0x38, 0x8c, 0xab, 0x52, 0x4f, 0x0f, 0x76, 0xca, 0xb8, 0x1d, 0x41, + 0x3b, 0x44, 0x43, 0x30, 0x34, 0xe3, 0xd6, 0xa1, 0x4b, 0x09, 0x5b, 0x80, 0x19, 0x3f, + 0x35, 0x09, 0x77, 0xf1, 0x3e, 0xbf, 0x2b, 0x70, 0x22, 0x06, 0xcb, 0x06, 0x3f, 0x42, + 0xdd, 0x45, 0x78, 0xd8, 0x77, 0x22, 0x5a, 0x58, 0x62, 0x89, 0xd4, 0x33, 0x82, 0x5f, + 0x8a, 0xa1, 0x7f, 0x25, 0x78, 0xec, 0xb5, 0xc4, 0x98, 0x66, 0xff, 0x41, 0x3e, 0x37, + 0xa5, 0x6f, 0x8e, 0xa7, 0x1f, 0x98, 0xef, 0x50, 0x89, 0x27, 0x56, 0x76}, + {0xc0, 0xc8, 0x1f, 0xd5, 0x59, 0xcf, 0xc3, 0x38, 0xf2, 0xb6, 0x06, 0x05, 0xfd, 0xd2, + 0xed, 0x9b, 0x8f, 0x0e, 0x57, 0xab, 0x9f, 0x10, 0xbf, 0x26, 0xa6, 0x46, 0xb8, 0xc1, + 0xa8, 0x60, 0x41, 0x3f, 0x9d, 0xcf, 0x86, 0xea, 0xa3, 0x73, 0x70, 0xe1, 0xdc, 0x5f, + 0x15, 0x07, 0xb7, 0xfb, 0x8c, 0x3a, 0x8e, 0x8a, 0x83, 0x31, 0xfc, 0xe7, 0x53, 0x48, + 0x16, 0xf6, 0x13, 0xb6, 0x84, 0xf4, 0xbb, 0x28, 0x7c, 0x6c, 0x13, 0x6f, 0x5c, 0x2f, + 0x61, 0xf2, 0xbe, 0x11, 0xdd, 0xf6, 0x07, 0xd1, 0xea, 0xaf, 0x33, 0x6f, 0xde, 0x13, + 0xd2, 0x9a, 0x7e, 0x52, 0x5d, 0xf7, 0x88, 0x81, 0x35, 0xcb, 0x79, 0x1e}, + {0xf1, 0xe3, 0xf7, 0xee, 0xc3, 0x36, 0x34, 0x01, 0xf8, 0x10, 0x9e, 0xfe, 0x7f, 0x6a, + 0x8b, 0x82, 0xfc, 0xde, 0xf9, 0xbc, 0xe5, 0x08, 0xf9, 0x7f, 0x31, 0x38, 0x3b, 0x3a, + 0x1b, 0x95, 0xd7, 0x65, 0x81, 0x81, 0xe0, 0xf5, 0xd8, 0x53, 0xe9, 0x77, 0xd9, 0xde, + 0x9d, 0x29, 0x44, 0x0c, 0xa5, 0x84, 0xe5, 0x25, 0x45, 0x86, 0x0c, 0x2d, 0x6c, 0xdc, + 0xf4, 0xf2, 0xd1, 0x39, 0x2d, 0xb5, 0x8a, 0x47, 0x59, 0xd1, 0x52, 0x92, 0xd3, 0xa4, + 0xa6, 0x66, 0x07, 0xc8, 0x1a, 0x87, 0xbc, 0xe1, 0xdd, 0xe5, 0x6f, 0xc9, 0xc1, 0xa6, + 0x40, 0x6b, 0x2c, 0xb8, 0x14, 0x22, 0x21, 0x1a, 0x41, 0x7a, 0xd8, 0x16}, + {0x15, 0x62, 0x06, 0x42, 0x5a, 0x7e, 0xbd, 0xb3, 0xc1, 0x24, 0x5a, 0x0c, 0xcd, 0xe3, + 0x9b, 0x87, 0xb7, 0x94, 0xf9, 0xd6, 0xb1, 0x5d, 0xc0, 0x57, 0xa6, 0x8c, 0xf3, 0x65, + 0x81, 0x7c, 0xf8, 0x28, 0x83, 0x05, 0x4e, 0xd5, 0xe2, 0xd5, 0xa4, 0xfb, 0xfa, 0x99, + 0xbd, 0x2e, 0xd7, 0xaf, 0x1f, 0xe2, 0x8f, 0x77, 0xe9, 0x6e, 0x73, 0xc2, 0x7a, 0x49, + 0xde, 0x6d, 0x5a, 0x7a, 0x57, 0x0b, 0x99, 0x1f, 0xd6, 0xf7, 0xe8, 0x1b, 0xad, 0x4e, + 0x34, 0xa3, 0x8f, 0x79, 0xea, 0xac, 0xeb, 0x50, 0x1e, 0x7d, 0x52, 0xe0, 0x0d, 0x52, + 0x9e, 0x56, 0xc6, 0x77, 0x3e, 0x6d, 0x4d, 0x53, 0xe1, 0x2f, 0x88, 0x45}, + {0xd6, 0x83, 0x79, 0x75, 0x5d, 0x34, 0x69, 0x66, 0xa6, 0x11, 0xaa, 0x17, 0x11, 0xed, + 0xb6, 0x62, 0x8f, 0x12, 0x5e, 0x98, 0x57, 0x18, 0xdd, 0x7d, 0xdd, 0xf6, 0x26, 0xf6, + 0xb8, 0xe5, 0x8f, 0x68, 0xe4, 0x6f, 0x3c, 0x94, 0x29, 0x99, 0xac, 0xd8, 0xa2, 0x92, + 0x83, 0xa3, 0x61, 0xf1, 0xf9, 0xb5, 0xf3, 0x9a, 0xc8, 0xbe, 0x13, 0xdb, 0x99, 0x26, + 0x74, 0xf0, 0x05, 0xe4, 0x3c, 0x84, 0xcf, 0x7d, 0xc0, 0x32, 0x47, 0x4a, 0x48, 0xd6, + 0x90, 0x6c, 0x99, 0x32, 0x56, 0xca, 0xfd, 0x43, 0x21, 0xd5, 0xe1, 0xc6, 0x5d, 0x91, + 0xc3, 0x28, 0xbe, 0xb3, 0x1b, 0x19, 0x27, 0x73, 0x7e, 0x68, 0x39, 0x67}, + {0xa6, 0x75, 0x56, 0x38, 0x14, 0x20, 0x78, 0xef, 0xe8, 0xa9, 0xfd, 0xaa, 0x30, 0x9f, + 0x64, 0xa2, 0xcb, 0xa8, 0xdf, 0x5c, 0x50, 0xeb, 0xd1, 0x4c, 0xb3, 0xc0, 0x4d, 0x1d, + 0xba, 0x5a, 0x11, 0x46, 0xc0, 0x1a, 0x0c, 0xc8, 0x9d, 0xcc, 0x6d, 0xa6, 0x36, 0xa4, + 0x38, 0x1b, 0xf4, 0x5c, 0xa0, 0x97, 0xc6, 0xd7, 0xdb, 0x95, 0xbe, 0xf3, 0xeb, 0xa7, + 0xab, 0x7d, 0x7e, 0x8d, 0xf6, 0xb8, 0xa0, 0x7d, 0x76, 0xda, 0xb5, 0xc3, 0x53, 0x19, + 0x0f, 0xd4, 0x9b, 0x9e, 0x11, 0x21, 0x73, 0x6f, 0xac, 0x1d, 0x60, 0x59, 0xb2, 0xfe, + 0x21, 0x60, 0xcc, 0x03, 0x4b, 0x4b, 0x67, 0x83, 0x7e, 0x88, 0x5f, 0x5a}, + {0x11, 0x3d, 0xa1, 0x70, 0xcf, 0x01, 0x63, 0x8f, 0xc4, 0xd0, 0x0d, 0x35, 0x15, 0xb8, + 0xce, 0xcf, 0x7e, 0xa4, 0xbc, 0xa4, 0xd4, 0x97, 0x02, 0xf7, 0x34, 0x14, 0x4d, 0xe4, + 0x56, 0xb6, 0x69, 0x36, 0xb9, 0x43, 0xa6, 0xa0, 0xd3, 0x28, 0x96, 0x9e, 0x64, 0x20, + 0xc3, 0xe6, 0x00, 0xcb, 0xc3, 0xb5, 0x32, 0xec, 0x2d, 0x7c, 0x89, 0x02, 0x53, 0x9b, + 0x0c, 0xc7, 0xd1, 0xd5, 0xe2, 0x7a, 0xe3, 0x43, 0x33, 0xe1, 0xa6, 0xed, 0x06, 0x3f, + 0x7e, 0x38, 0xc0, 0x3a, 0xa1, 0x99, 0x51, 0x1d, 0x30, 0x67, 0x11, 0x38, 0x26, 0x36, + 0xf8, 0xd8, 0x5a, 0xbd, 0xbe, 0xe9, 0xd5, 0x4f, 0xcd, 0xe6, 0x21, 0x6a}, + {0x5f, 0xe6, 0x46, 0x30, 0x0a, 0x17, 0xc6, 0xf1, 0x24, 0x35, 0xd2, 0x00, 0x2a, 0x2a, + 0x71, 0x58, 0x55, 0xb7, 0x82, 0x8c, 0x3c, 0xbd, 0xdb, 0x69, 0x57, 0xff, 0x95, 0xa1, + 0xf1, 0xf9, 0x6b, 0x58, 0xe3, 0xb2, 0x99, 0x66, 0x12, 0x29, 0x41, 0xef, 0x01, 0x13, + 0x8d, 0x70, 0x47, 0x08, 0xd3, 0x71, 0xbd, 0xb0, 0x82, 0x11, 0xd0, 0x32, 0x54, 0x32, + 0x36, 0x8b, 0x1e, 0x00, 0x07, 0x1b, 0x37, 0x45, 0x0b, 0x79, 0xf8, 0x5e, 0x8d, 0x08, + 0xdb, 0xa6, 0xe5, 0x37, 0x09, 0x61, 0xdc, 0xf0, 0x78, 0x52, 0xb8, 0x6e, 0xa1, 0x61, + 0xd2, 0x49, 0x03, 0xac, 0x79, 0x21, 0xe5, 0x90, 0x37, 0xb0, 0xaf, 0x0e}, + {0x2f, 0x04, 0x48, 0x37, 0xc1, 0x55, 0x05, 0x96, 0x11, 0xaa, 0x0b, 0x82, 0xe6, 0x41, + 0x9a, 0x21, 0x0c, 0x6d, 0x48, 0x73, 0x38, 0xf7, 0x81, 0x1c, 0x61, 0xc6, 0x02, 0x5a, + 0x67, 0xcc, 0x9a, 0x30, 0x1d, 0xae, 0x75, 0x0f, 0x5e, 0x80, 0x40, 0x51, 0x30, 0xcc, + 0x62, 0x26, 0xe3, 0xfb, 0x02, 0xec, 0x6d, 0x39, 0x92, 0xea, 0x1e, 0xdf, 0xeb, 0x2c, + 0xb3, 0x5b, 0x43, 0xc5, 0x44, 0x33, 0xae, 0x44, 0xee, 0x43, 0xa5, 0xbb, 0xb9, 0x89, + 0xf2, 0x9c, 0x42, 0x71, 0xc9, 0x5a, 0x9d, 0x0e, 0x76, 0xf3, 0xaa, 0x60, 0x93, 0x4f, + 0xc6, 0xe5, 0x82, 0x1d, 0x8f, 0x67, 0x94, 0x7f, 0x1b, 0x22, 0xd5, 0x62}, + {0x6d, 0x93, 0xd0, 0x18, 0x9c, 0x29, 0x4c, 0x52, 0x0c, 0x1a, 0x0c, 0x8a, 0x6c, 0xb5, + 0x6b, 0xc8, 0x31, 0x86, 0x4a, 0xdb, 0x2e, 0x05, 0x75, 0xa3, 0x62, 0x45, 0x75, 0xbc, + 0xe4, 0xfd, 0x0e, 0x5c, 0x3c, 0x7a, 0xf7, 0x3a, 0x26, 0xd4, 0x85, 0x75, 0x4d, 0x14, + 0xe9, 0xfe, 0x11, 0x7b, 0xae, 0xdf, 0x3d, 0x19, 0xf7, 0x59, 0x80, 0x70, 0x06, 0xa5, + 0x37, 0x20, 0x92, 0x83, 0x53, 0x9a, 0xf2, 0x14, 0xf5, 0xd7, 0xb2, 0x25, 0xdc, 0x7e, + 0x71, 0xdf, 0x40, 0x30, 0xb5, 0x99, 0xdb, 0x70, 0xf9, 0x21, 0x62, 0x4c, 0xed, 0xc3, + 0xb7, 0x34, 0x92, 0xda, 0x3e, 0x09, 0xee, 0x7b, 0x5c, 0x36, 0x72, 0x5e}, + {0x7f, 0x21, 0x71, 0x45, 0x07, 0xfc, 0x5b, 0x57, 0x5b, 0xd9, 0x94, 0x06, 0x5d, 0x67, + 0x79, 0x37, 0x33, 0x1e, 0x19, 0xf4, 0xbb, 0x37, 0x0a, 0x9a, 0xbc, 0xea, 0xb4, 0x47, + 0x4c, 0x10, 0xf1, 0x77, 0x3e, 0xb3, 0x08, 0x2f, 0x06, 0x39, 0x93, 0x7d, 0xbe, 0x32, + 0x9f, 0xdf, 0xe5, 0x59, 0x96, 0x5b, 0xfd, 0xbd, 0x9e, 0x1f, 0xad, 0x3d, 0xff, 0xac, + 0xb7, 0x49, 0x73, 0xcb, 0x55, 0x05, 0xb2, 0x70, 0x4c, 0x2c, 0x11, 0x55, 0xc5, 0x13, + 0x51, 0xbe, 0xcd, 0x1f, 0x88, 0x9a, 0x3a, 0x42, 0x88, 0x66, 0x47, 0x3b, 0x50, 0x5e, + 0x85, 0x77, 0x66, 0x44, 0x4a, 0x40, 0x06, 0x4a, 0x8f, 0x39, 0x34, 0x0e}, + {0xe8, 0xbd, 0xce, 0x3e, 0xd9, 0x22, 0x7d, 0xb6, 0x07, 0x2f, 0x82, 0x27, 0x41, 0xe8, + 0xb3, 0x09, 0x8d, 0x6d, 0x5b, 0xb0, 0x1f, 0xa6, 0x3f, 0x74, 0x72, 0x23, 0x36, 0x8a, + 0x36, 0x05, 0x54, 0x5e, 0x28, 0x19, 0x4b, 0x3e, 0x09, 0x0b, 0x93, 0x18, 0x40, 0xf6, + 0xf3, 0x73, 0x0e, 0xe1, 0xe3, 0x7d, 0x6f, 0x5d, 0x39, 0x73, 0xda, 0x17, 0x32, 0xf4, + 0x3e, 0x9c, 0x37, 0xca, 0xd6, 0xde, 0x8a, 0x6f, 0x9a, 0xb2, 0xb7, 0xfd, 0x3d, 0x12, + 0x40, 0xe3, 0x91, 0xb2, 0x1a, 0xa2, 0xe1, 0x97, 0x7b, 0x48, 0x9e, 0x94, 0xe6, 0xfd, + 0x02, 0x7d, 0x96, 0xf9, 0x97, 0xde, 0xd3, 0xc8, 0x2e, 0xe7, 0x0d, 0x78}, + {0xbc, 0xe7, 0x9a, 0x08, 0x45, 0x85, 0xe2, 0x0a, 0x06, 0x4d, 0x7f, 0x1c, 0xcf, 0xde, + 0x8d, 0x38, 0xb8, 0x11, 0x48, 0x0a, 0x51, 0x15, 0xac, 0x38, 0xe4, 0x8c, 0x92, 0x71, + 0xf6, 0x8b, 0xb2, 0x0e, 0x72, 0x27, 0xf4, 0x00, 0xf3, 0xea, 0x1f, 0x67, 0xaa, 0x41, + 0x8c, 0x2a, 0x2a, 0xeb, 0x72, 0x8f, 0x92, 0x32, 0x37, 0x97, 0xd7, 0x7f, 0xa1, 0x29, + 0xa6, 0x87, 0xb5, 0x32, 0xad, 0xc6, 0xef, 0x1d, 0xa7, 0x95, 0x51, 0xef, 0x1a, 0xbe, + 0x5b, 0xaf, 0xed, 0x15, 0x7b, 0x91, 0x77, 0x12, 0x8c, 0x14, 0x2e, 0xda, 0xe5, 0x7a, + 0xfb, 0xf7, 0x91, 0x29, 0x67, 0x28, 0xdd, 0xf8, 0x1b, 0x20, 0x7d, 0x46}, + {0xad, 0x4f, 0xef, 0x74, 0x9a, 0x91, 0xfe, 0x95, 0xa2, 0x08, 0xa3, 0xf6, 0xec, 0x7b, + 0x82, 0x3a, 0x01, 0x7b, 0xa4, 0x09, 0xd3, 0x01, 0x4e, 0x96, 0x97, 0xc7, 0xa3, 0x5b, + 0x4f, 0x3c, 0xc4, 0x71, 0xa9, 0xe7, 0x7a, 0x56, 0xbd, 0xf4, 0x1e, 0xbc, 0xbd, 0x98, + 0x44, 0xd6, 0xb2, 0x4c, 0x62, 0x3f, 0xc8, 0x4e, 0x1f, 0x2c, 0xd2, 0x64, 0x10, 0xe4, + 0x01, 0x40, 0x38, 0xba, 0xa5, 0xc5, 0xf9, 0x2e, 0xcd, 0x74, 0x9e, 0xfa, 0xf6, 0x6d, + 0xfd, 0xb6, 0x7a, 0x26, 0xaf, 0xe4, 0xbc, 0x78, 0x82, 0xf1, 0x0e, 0x99, 0xef, 0xf1, + 0xd0, 0xb3, 0x55, 0x82, 0x93, 0xf2, 0xc5, 0x90, 0xa3, 0x8c, 0x75, 0x5a}, + {0x95, 0x24, 0x46, 0xd9, 0x10, 0x27, 0xb7, 0xa2, 0x03, 0x50, 0x7d, 0xd5, 0xd2, 0xc6, + 0xa8, 0x3a, 0xca, 0x87, 0xb4, 0xa0, 0xbf, 0x00, 0xd4, 0xe3, 0xec, 0x72, 0xeb, 0xb3, + 0x44, 0xe2, 0xba, 0x2d, 0x94, 0xdc, 0x61, 0x1d, 0x8b, 0x91, 0xe0, 0x8c, 0x66, 0x30, + 0x81, 0x9a, 0x46, 0x36, 0xed, 0x8d, 0xd3, 0xaa, 0xe8, 0xaf, 0x29, 0xa8, 0xe6, 0xd4, + 0x3f, 0xd4, 0x39, 0xf6, 0x27, 0x80, 0x73, 0x0a, 0xcc, 0xe1, 0xff, 0x57, 0x2f, 0x4a, + 0x0f, 0x98, 0x43, 0x98, 0x83, 0xe1, 0x0d, 0x0d, 0x67, 0x00, 0xfd, 0x15, 0xfb, 0x49, + 0x4a, 0x3f, 0x5c, 0x10, 0x9c, 0xa6, 0x26, 0x51, 0x63, 0xca, 0x98, 0x26}, + {0x78, 0xba, 0xb0, 0x32, 0x88, 0x31, 0x65, 0xe7, 0x8b, 0xff, 0x5c, 0x92, 0xf7, 0x31, + 0x18, 0x38, 0xcc, 0x1f, 0x29, 0xa0, 0x91, 0x1b, 0xa8, 0x08, 0x07, 0xeb, 0xca, 0x49, + 0xcc, 0x3d, 0xb4, 0x1f, 0x0e, 0xd9, 0x3d, 0x5e, 0x2f, 0x70, 0x3d, 0x2e, 0x86, 0x53, + 0xd2, 0xe4, 0x18, 0x09, 0x3f, 0x9e, 0x6a, 0xa9, 0x4d, 0x02, 0xf6, 0x3e, 0x77, 0x5e, + 0x32, 0x33, 0xfa, 0x4a, 0x0c, 0x4b, 0x00, 0x3c, 0x2b, 0xb8, 0xf4, 0x06, 0xac, 0x46, + 0xa9, 0x9a, 0xf3, 0xc4, 0x06, 0xa8, 0xa5, 0x84, 0xa2, 0x1c, 0x87, 0x47, 0xcd, 0xc6, + 0x5f, 0x26, 0xd3, 0x3e, 0x17, 0xd2, 0x1f, 0xcd, 0x01, 0xfd, 0x43, 0x6b}, + {0x44, 0xc5, 0x97, 0x46, 0x4b, 0x5d, 0xa7, 0xc7, 0xbf, 0xff, 0x0f, 0xdf, 0x48, 0xf8, + 0xfd, 0x15, 0x5a, 0x78, 0x46, 0xaa, 0xeb, 0xb9, 0x68, 0x28, 0x14, 0xf7, 0x52, 0x5b, + 0x10, 0xd7, 0x68, 0x5a, 0xf3, 0x0e, 0x76, 0x3e, 0x58, 0x42, 0xc7, 0xb5, 0x90, 0xb9, + 0x0a, 0xee, 0xb9, 0x52, 0xdc, 0x75, 0x3f, 0x92, 0x2b, 0x07, 0xc2, 0x27, 0x14, 0xbf, + 0xf0, 0xd9, 0xf0, 0x6f, 0x2d, 0x0b, 0x42, 0x73, 0x06, 0x1e, 0x85, 0x9e, 0xcb, 0xf6, + 0x2c, 0xaf, 0xc4, 0x38, 0x22, 0xc6, 0x13, 0x39, 0x59, 0x8f, 0x73, 0xf3, 0xfb, 0x99, + 0x96, 0xb8, 0x8a, 0xda, 0x9e, 0xbc, 0x34, 0xea, 0x2f, 0x63, 0xb5, 0x3d}, + {0xd8, 0xd9, 0x5d, 0xf7, 0x2b, 0xee, 0x6e, 0xf4, 0xa5, 0x59, 0x67, 0x39, 0xf6, 0xb1, + 0x17, 0x0d, 0x73, 0x72, 0x9e, 0x49, 0x31, 0xd1, 0xf2, 0x1b, 0x13, 0x5f, 0xd7, 0x49, + 0xdf, 0x1a, 0x32, 0x04, 0xd5, 0x25, 0x98, 0x82, 0xb1, 0x90, 0x49, 0x2e, 0x91, 0x89, + 0x9a, 0x3e, 0x87, 0xeb, 0xea, 0xed, 0xf8, 0x4a, 0x70, 0x4c, 0x39, 0x3d, 0xf0, 0xee, + 0x0e, 0x2b, 0xdf, 0x95, 0xa4, 0x7e, 0x19, 0x59, 0xae, 0x5a, 0xe5, 0xe4, 0x19, 0x60, + 0xe1, 0x04, 0xe9, 0x92, 0x2f, 0x7e, 0x7a, 0x43, 0x7b, 0xe7, 0xa4, 0x9a, 0x15, 0x6f, + 0xc1, 0x2d, 0xce, 0xc7, 0xc0, 0x0c, 0xd7, 0xf4, 0xc1, 0xfd, 0xea, 0x45}, + {0x2b, 0xd7, 0x45, 0x80, 0x85, 0x01, 0x84, 0x69, 0x51, 0x06, 0x2f, 0xcf, 0xa2, 0xfa, + 0x22, 0x4c, 0xc6, 0x2d, 0x22, 0x6b, 0x65, 0x36, 0x1a, 0x94, 0xde, 0xda, 0x62, 0x03, + 0xc8, 0xeb, 0x5e, 0x5a, 0xed, 0xb1, 0xcc, 0xcf, 0x24, 0x46, 0x0e, 0xb6, 0x95, 0x03, + 0x5c, 0xbd, 0x92, 0xc2, 0xdb, 0x59, 0xc9, 0x81, 0x04, 0xdc, 0x1d, 0x9d, 0xa0, 0x31, + 0x40, 0xd9, 0x56, 0x5d, 0xea, 0xce, 0x73, 0x3f, 0xc6, 0x8d, 0x4e, 0x0a, 0xd1, 0xbf, + 0xa7, 0xb7, 0x39, 0xb3, 0xc9, 0x44, 0x7e, 0x00, 0x57, 0xbe, 0xfa, 0xae, 0x57, 0x15, + 0x7f, 0x20, 0xc1, 0x60, 0xdb, 0x18, 0x62, 0x26, 0x91, 0x88, 0x05, 0x26}, + {0x04, 0xff, 0x60, 0x83, 0xa6, 0x04, 0xf7, 0x59, 0xf4, 0xe6, 0x61, 0x76, 0xde, 0x3f, + 0xd9, 0xc3, 0x51, 0x35, 0x87, 0x12, 0x73, 0x2a, 0x1b, 0x83, 0x57, 0x5d, 0x61, 0x4e, + 0x2e, 0x0c, 0xad, 0x54, 0x42, 0xe5, 0x76, 0xc6, 0x3c, 0x8e, 0x81, 0x4c, 0xad, 0xcc, + 0xce, 0x03, 0x93, 0x2c, 0x42, 0x5e, 0x08, 0x9f, 0x12, 0xb4, 0xca, 0xcc, 0x07, 0xec, + 0xb8, 0x43, 0x44, 0xb2, 0x10, 0xfa, 0xed, 0x0d, 0x2a, 0x52, 0x2b, 0xb8, 0xd5, 0x67, + 0x3b, 0xee, 0xeb, 0xc1, 0xa5, 0x9f, 0x46, 0x63, 0xf1, 0x36, 0xd3, 0x9f, 0xc1, 0x6e, + 0xf2, 0xd2, 0xb4, 0xa5, 0x08, 0x94, 0x7a, 0xa7, 0xba, 0xb2, 0xec, 0x62}, + {0x3d, 0x2b, 0x15, 0x61, 0x52, 0x79, 0xed, 0xe5, 0xd1, 0xd7, 0xdd, 0x0e, 0x7d, 0x35, + 0x62, 0x49, 0x71, 0x4c, 0x6b, 0xb9, 0xd0, 0xc8, 0x82, 0x74, 0xbe, 0xd8, 0x66, 0xa9, + 0x19, 0xf9, 0x59, 0x2e, 0x74, 0x28, 0xb6, 0xaf, 0x36, 0x28, 0x07, 0x92, 0xa5, 0x04, + 0xe1, 0x79, 0x85, 0x5e, 0xcd, 0x5f, 0x4a, 0xa1, 0x30, 0xc6, 0xad, 0x01, 0xad, 0x5a, + 0x98, 0x3f, 0x66, 0x75, 0x50, 0x3d, 0x91, 0x61, 0xda, 0x31, 0x32, 0x1a, 0x36, 0x2d, + 0xc6, 0x0d, 0x70, 0x02, 0x20, 0x94, 0x32, 0x58, 0x47, 0xfa, 0xce, 0x94, 0x95, 0x3f, + 0x51, 0x01, 0xd8, 0x02, 0x5c, 0x5d, 0xc0, 0x31, 0xa1, 0xc2, 0xdb, 0x3d}, + {0x4b, 0xc5, 0x5e, 0xce, 0xf9, 0x0f, 0xdc, 0x9a, 0x0d, 0x13, 0x2f, 0x8c, 0x6b, 0x2a, + 0x9c, 0x03, 0x15, 0x95, 0xf8, 0xf0, 0xc7, 0x07, 0x80, 0x02, 0x6b, 0xb3, 0x04, 0xac, + 0x14, 0x83, 0x96, 0x78, 0x14, 0xbb, 0x96, 0x27, 0xa2, 0x57, 0xaa, 0xf3, 0x21, 0xda, + 0x07, 0x9b, 0xb7, 0xba, 0x3a, 0x88, 0x1c, 0x39, 0xa0, 0x31, 0x18, 0xe2, 0x4b, 0xe5, + 0xf9, 0x05, 0x32, 0xd8, 0x38, 0xfb, 0xe7, 0x5e, 0x8e, 0x6a, 0x44, 0x41, 0xcb, 0xfd, + 0x8d, 0x53, 0xf9, 0x37, 0x49, 0x43, 0xa9, 0xfd, 0xac, 0xa5, 0x78, 0x8c, 0x3c, 0x26, + 0x8d, 0x90, 0xaf, 0x46, 0x09, 0x0d, 0xca, 0x9b, 0x3c, 0x63, 0xd0, 0x61}, + {0x66, 0x25, 0xdb, 0xff, 0x35, 0x49, 0x74, 0x63, 0xbb, 0x68, 0x0b, 0x78, 0x89, 0x6b, + 0xbd, 0xc5, 0x03, 0xec, 0x3e, 0x55, 0x80, 0x32, 0x1b, 0x6f, 0xf5, 0xd7, 0xae, 0x47, + 0xd8, 0x5f, 0x96, 0x6e, 0xdf, 0x73, 0xfc, 0xf8, 0xbc, 0x28, 0xa3, 0xad, 0xfc, 0x37, + 0xf0, 0xa6, 0x5d, 0x69, 0x84, 0xee, 0x09, 0xa9, 0xc2, 0x38, 0xdb, 0xb4, 0x7f, 0x63, + 0xdc, 0x7b, 0x06, 0xf8, 0x2d, 0xac, 0x23, 0x5b, 0x7b, 0x52, 0x80, 0xee, 0x53, 0xb9, + 0xd2, 0x9a, 0x8d, 0x6d, 0xde, 0xfa, 0xaa, 0x19, 0x8f, 0xe8, 0xcf, 0x82, 0x0e, 0x15, + 0x04, 0x17, 0x71, 0x0e, 0xdc, 0xde, 0x95, 0xdd, 0xb9, 0xbb, 0xb9, 0x79}, + {0xc2, 0x26, 0x31, 0x6a, 0x40, 0x55, 0xb3, 0xeb, 0x93, 0xc3, 0xc8, 0x68, 0xa8, 0x83, + 0x63, 0xd2, 0x82, 0x7a, 0xb9, 0xe5, 0x29, 0x64, 0x0c, 0x6c, 0x47, 0x21, 0xfd, 0xc9, + 0x58, 0xf1, 0x65, 0x50, 0x74, 0x73, 0x9f, 0x8e, 0xae, 0x7d, 0x99, 0xd1, 0x16, 0x08, + 0xbb, 0xcf, 0xf8, 0xa2, 0x32, 0xa0, 0x0a, 0x5f, 0x44, 0x6d, 0x12, 0xba, 0x6c, 0xcd, + 0x34, 0xb8, 0xcc, 0x0a, 0x46, 0x11, 0xa8, 0x1b, 0x54, 0x99, 0x42, 0x0c, 0xfb, 0x69, + 0x81, 0x70, 0x67, 0xcf, 0x6e, 0xd7, 0xac, 0x00, 0x46, 0xe1, 0xba, 0x45, 0xe6, 0x70, + 0x8a, 0xb9, 0xaa, 0x2e, 0xf2, 0xfa, 0xa4, 0x58, 0x9e, 0xf3, 0x81, 0x39}, + {0x93, 0x0a, 0x23, 0x59, 0x75, 0x8a, 0xfb, 0x18, 0x5d, 0xf4, 0xe6, 0x60, 0x69, 0x8f, + 0x16, 0x1d, 0xb5, 0x3c, 0xa9, 0x14, 0x45, 0xa9, 0x85, 0x3a, 0xfd, 0xd0, 0xac, 0x05, + 0x37, 0x08, 0xdc, 0x38, 0xde, 0x6f, 0xe6, 0x6d, 0xa5, 0xdf, 0x45, 0xc8, 0x3a, 0x48, + 0x40, 0x2c, 0x00, 0xa5, 0x52, 0xe1, 0x32, 0xf6, 0xb4, 0xc7, 0x63, 0xe1, 0xd2, 0xe9, + 0x65, 0x1b, 0xbc, 0xdc, 0x2e, 0x45, 0xf4, 0x30, 0x40, 0x97, 0x75, 0xc5, 0x82, 0x27, + 0x6d, 0x85, 0xcc, 0xbe, 0x9c, 0xf9, 0x69, 0x45, 0x13, 0xfa, 0x71, 0x4e, 0xea, 0xc0, + 0x73, 0xfc, 0x44, 0x88, 0x69, 0x24, 0x3f, 0x59, 0x1a, 0x9a, 0x2d, 0x63}, + {0xa6, 0xcb, 0x07, 0xb8, 0x15, 0x6b, 0xbb, 0xf6, 0xd7, 0xf0, 0x54, 0xbc, 0xdf, 0xc7, + 0x23, 0x18, 0x0b, 0x67, 0x29, 0x6e, 0x03, 0x97, 0x1d, 0xbb, 0x57, 0x4a, 0xed, 0x47, + 0x88, 0xf4, 0x24, 0x0b, 0xa7, 0x84, 0x0c, 0xed, 0x11, 0xfd, 0x09, 0xbf, 0x3a, 0x69, + 0x9f, 0x0d, 0x81, 0x71, 0xf0, 0x63, 0x79, 0x87, 0xcf, 0x57, 0x2d, 0x8c, 0x90, 0x21, + 0xa2, 0x4b, 0xf6, 0x8a, 0xf2, 0x7d, 0x5a, 0x3a, 0xc7, 0xea, 0x1b, 0x51, 0xbe, 0xd4, + 0xda, 0xdc, 0xf2, 0xcc, 0x26, 0xed, 0x75, 0x80, 0x53, 0xa4, 0x65, 0x9a, 0x5f, 0x00, + 0x9f, 0xff, 0x9c, 0xe1, 0x63, 0x1f, 0x48, 0x75, 0x44, 0xf7, 0xfc, 0x34}, + {0xca, 0x67, 0x97, 0x78, 0x4c, 0xe0, 0x97, 0xc1, 0x7d, 0x46, 0xd9, 0x38, 0xcb, 0x4d, + 0x71, 0xb8, 0xa8, 0x5f, 0xf9, 0x83, 0x82, 0x88, 0xde, 0x55, 0xf7, 0x63, 0xfa, 0x4d, + 0x16, 0xdc, 0x3b, 0x3d, 0x98, 0xaa, 0xcf, 0x78, 0xab, 0x1d, 0xbb, 0xa5, 0xf2, 0x72, + 0x0b, 0x19, 0x67, 0xa2, 0xed, 0x5c, 0x8e, 0x60, 0x92, 0x0a, 0x11, 0xc9, 0x09, 0x93, + 0xb0, 0x74, 0xb3, 0x2f, 0x04, 0xa3, 0x19, 0x01, 0x7d, 0x17, 0xc2, 0xe8, 0x9c, 0xd8, + 0xa2, 0x67, 0xc1, 0xd0, 0x95, 0x68, 0xf6, 0xa5, 0x9d, 0x66, 0xb0, 0xa2, 0x82, 0xb2, + 0xe5, 0x98, 0x65, 0xf5, 0x73, 0x0a, 0xe2, 0xed, 0xf1, 0x88, 0xc0, 0x56}, + {0x17, 0x6e, 0xa8, 0x10, 0x11, 0x3d, 0x6d, 0x33, 0xfa, 0xb2, 0x75, 0x0b, 0x32, 0x88, + 0xf3, 0xd7, 0x88, 0x29, 0x07, 0x25, 0x76, 0x33, 0x15, 0xf9, 0x87, 0x8b, 0x10, 0x99, + 0x6b, 0x4c, 0x67, 0x09, 0x02, 0x8f, 0xf3, 0x24, 0xac, 0x5f, 0x1b, 0x58, 0xbd, 0x0c, + 0xe3, 0xba, 0xfe, 0xe9, 0x0b, 0xa9, 0xf0, 0x92, 0xcf, 0x8a, 0x02, 0x69, 0x21, 0x9a, + 0x8f, 0x03, 0x59, 0x83, 0xa4, 0x7e, 0x8b, 0x03, 0xf8, 0x6f, 0x31, 0x99, 0x21, 0xf8, + 0x4e, 0x9f, 0x4f, 0x8d, 0xa7, 0xea, 0x82, 0xd2, 0x49, 0x2f, 0x74, 0x31, 0xef, 0x5a, + 0xab, 0xa5, 0x71, 0x09, 0x65, 0xeb, 0x69, 0x59, 0x02, 0x31, 0x5e, 0x6e}, + {0xfb, 0x93, 0xe5, 0x87, 0xf5, 0x62, 0x6c, 0xb1, 0x71, 0x3e, 0x5d, 0xca, 0xde, 0xed, + 0x99, 0x49, 0x6d, 0x3e, 0xcc, 0x14, 0xe0, 0xc1, 0x91, 0xb4, 0xa8, 0xdb, 0xa8, 0x89, + 0x47, 0x11, 0xf5, 0x08, 0x22, 0x62, 0x06, 0x63, 0x0e, 0xfb, 0x04, 0x33, 0x3f, 0xba, + 0xac, 0x87, 0x89, 0x06, 0x35, 0xfb, 0xa3, 0x61, 0x10, 0x8c, 0x77, 0x24, 0x19, 0xbd, + 0x20, 0x86, 0x83, 0xd1, 0x43, 0xad, 0x58, 0x30, 0xd0, 0x63, 0x76, 0xe5, 0xfd, 0x0f, + 0x3c, 0x32, 0x10, 0xa6, 0x2e, 0xa2, 0x38, 0xdf, 0xc3, 0x05, 0x9a, 0x4f, 0x99, 0xac, + 0xbd, 0x8a, 0xc7, 0xbd, 0x99, 0xdc, 0xe3, 0xef, 0xa4, 0x9f, 0x54, 0x26}, + {0xd6, 0xf9, 0x6b, 0x1e, 0x46, 0x5a, 0x1d, 0x74, 0x81, 0xa5, 0x77, 0x77, 0xfc, 0xb3, + 0x05, 0x23, 0xd9, 0xd3, 0x74, 0x64, 0xa2, 0x74, 0x55, 0xd4, 0xff, 0xe0, 0x01, 0x64, + 0xdc, 0xe1, 0x26, 0x19, 0x6e, 0x66, 0x3f, 0xaf, 0x49, 0x85, 0x46, 0xdb, 0xa5, 0x0e, + 0x4a, 0xf1, 0x04, 0xcf, 0x7f, 0xd7, 0x47, 0x0c, 0xba, 0xa4, 0xf7, 0x3f, 0xf2, 0x3d, + 0x85, 0x3c, 0xce, 0x32, 0xe1, 0xdf, 0x10, 0x3a, 0xa0, 0xce, 0x17, 0xea, 0x8a, 0x4e, + 0x7f, 0xe0, 0xfd, 0xc1, 0x1f, 0x3a, 0x46, 0x15, 0xd5, 0x2f, 0xf1, 0xc0, 0xf2, 0x31, + 0xfd, 0x22, 0x53, 0x17, 0x15, 0x5d, 0x1e, 0x86, 0x1d, 0xd0, 0xa1, 0x1f}, + {0x32, 0x98, 0x59, 0x7d, 0x94, 0x55, 0x80, 0xcc, 0x20, 0x55, 0xf1, 0x37, 0xda, 0x56, + 0x46, 0x1e, 0x20, 0x93, 0x05, 0x4e, 0x74, 0xf7, 0xf6, 0x99, 0x33, 0xcf, 0x75, 0x6a, + 0xbc, 0x63, 0x35, 0x77, 0xab, 0x94, 0xdf, 0xd1, 0x00, 0xac, 0xdc, 0x38, 0xe9, 0x0d, + 0x08, 0xd1, 0xdd, 0x2b, 0x71, 0x2e, 0x62, 0xe2, 0xd5, 0xfd, 0x3e, 0xe9, 0x13, 0x7f, + 0xe5, 0x01, 0x9a, 0xee, 0x18, 0xed, 0xfc, 0x73, 0xb3, 0x9c, 0x13, 0x63, 0x08, 0xe9, + 0xb1, 0x06, 0xcd, 0x3e, 0xa0, 0xc5, 0x67, 0xda, 0x93, 0xa4, 0x32, 0x89, 0x63, 0xad, + 0xc8, 0xce, 0x77, 0x8d, 0x44, 0x4f, 0x86, 0x1b, 0x70, 0x6b, 0x42, 0x1f}, + {0x01, 0x1c, 0x91, 0x41, 0x4c, 0x26, 0xc9, 0xef, 0x25, 0x2c, 0xa2, 0x17, 0xb8, 0xb7, + 0xa3, 0xf1, 0x47, 0x14, 0x0f, 0xf3, 0x6b, 0xda, 0x75, 0x58, 0x90, 0xb0, 0x31, 0x1d, + 0x27, 0xf5, 0x1a, 0x4e, 0x52, 0x25, 0xa1, 0x91, 0xc8, 0x35, 0x7e, 0xf1, 0x76, 0x9c, + 0x5e, 0x57, 0x53, 0x81, 0x6b, 0xb7, 0x3e, 0x72, 0x9b, 0x0d, 0x6f, 0x40, 0x83, 0xfa, + 0x38, 0xe4, 0xa7, 0x3f, 0x1b, 0xbb, 0x76, 0x0b, 0x9b, 0x93, 0x92, 0x7f, 0xf9, 0xc1, + 0xb8, 0x08, 0x6e, 0xab, 0x44, 0xd4, 0xcb, 0x71, 0x67, 0xbe, 0x17, 0x80, 0xbb, 0x99, + 0x63, 0x64, 0xe5, 0x22, 0x55, 0xa9, 0x72, 0xb7, 0x1e, 0xd6, 0x6d, 0x7b}, + {0x92, 0x3d, 0xf3, 0x50, 0xe8, 0xc1, 0xad, 0xb7, 0xcf, 0xd5, 0x8c, 0x60, 0x4f, 0xfa, + 0x98, 0x79, 0xdb, 0x5b, 0xfc, 0x8d, 0xbd, 0x2d, 0x96, 0xad, 0x4f, 0x2f, 0x1d, 0xaf, + 0xce, 0x9b, 0x3e, 0x70, 0xc7, 0xd2, 0x01, 0xab, 0xf9, 0xab, 0x30, 0x57, 0x18, 0x3b, + 0x14, 0x40, 0xdc, 0x76, 0xfb, 0x16, 0x81, 0xb2, 0xcb, 0xa0, 0x65, 0xbe, 0x6c, 0x86, + 0xfe, 0x6a, 0xff, 0x9b, 0x65, 0x9b, 0xfa, 0x53, 0x55, 0x54, 0x88, 0x94, 0xe9, 0xc8, + 0x14, 0x6c, 0xe5, 0xd4, 0xae, 0x65, 0x66, 0x5d, 0x3a, 0x84, 0xf1, 0x5a, 0xd6, 0xbc, + 0x3e, 0xb7, 0x1b, 0x18, 0x50, 0x1f, 0xc6, 0xc4, 0xe5, 0x93, 0x8d, 0x39}, + {0xf3, 0x48, 0xe2, 0x33, 0x67, 0xd1, 0x4b, 0x1c, 0x5f, 0x0a, 0xbf, 0x15, 0x87, 0x12, + 0x9e, 0xbd, 0x76, 0x03, 0x0b, 0xa1, 0xf0, 0x8c, 0x3f, 0xd4, 0x13, 0x1b, 0x19, 0xdf, + 0x5d, 0x9b, 0xb0, 0x53, 0xf2, 0xe3, 0xe7, 0xd2, 0x60, 0x7c, 0x87, 0xc3, 0xb1, 0x8b, + 0x82, 0x30, 0xa0, 0xaa, 0x34, 0x3b, 0x38, 0xf1, 0x9e, 0x73, 0xe7, 0x26, 0x3e, 0x28, + 0x77, 0x05, 0xc3, 0x02, 0x90, 0x9c, 0x9c, 0x69, 0xcc, 0xf1, 0x46, 0x59, 0x23, 0xa7, + 0x06, 0xf3, 0x7d, 0xd9, 0xe5, 0xcc, 0xb5, 0x18, 0x17, 0x92, 0x75, 0xe9, 0xb4, 0x81, + 0x47, 0xd2, 0xcd, 0x28, 0x07, 0xd9, 0xcd, 0x6f, 0x0c, 0xf3, 0xca, 0x51}, + {0x0a, 0xe0, 0x74, 0x76, 0x42, 0xa7, 0x0b, 0xa6, 0xf3, 0x7b, 0x7a, 0xa1, 0x70, 0x85, + 0x0e, 0x63, 0xcc, 0x24, 0x33, 0xcf, 0x3d, 0x56, 0x58, 0x37, 0xaa, 0xfd, 0x83, 0x23, + 0x29, 0xaa, 0x04, 0x55, 0xc7, 0x54, 0xac, 0x18, 0x9a, 0xf9, 0x7a, 0x73, 0x0f, 0xb3, + 0x1c, 0xc5, 0xdc, 0x78, 0x33, 0x90, 0xc7, 0x0c, 0xe1, 0x4c, 0x33, 0xbc, 0x89, 0x2b, + 0x9a, 0xe9, 0xf8, 0x89, 0xc1, 0x29, 0xae, 0x12, 0xcf, 0x01, 0x0d, 0x1f, 0xcb, 0xc0, + 0x9e, 0xa9, 0xae, 0xf7, 0x34, 0x3a, 0xcc, 0xef, 0xd1, 0x0d, 0x22, 0x4e, 0x9c, 0xd0, + 0x21, 0x75, 0xca, 0x55, 0xea, 0xa5, 0xeb, 0x58, 0xe9, 0x4f, 0xd1, 0x5f}, + {0x2c, 0xab, 0x45, 0x28, 0xdf, 0x2d, 0xdc, 0xb5, 0x93, 0xe9, 0x7f, 0x0a, 0xb1, 0x91, + 0x94, 0x06, 0x46, 0xe3, 0x02, 0x40, 0xd6, 0xf3, 0xaa, 0x4d, 0xd1, 0x74, 0x64, 0x58, + 0x6e, 0xf2, 0x3f, 0x09, 0x8e, 0xcb, 0x93, 0xbf, 0x5e, 0xfe, 0x42, 0x3c, 0x5f, 0x56, + 0xd4, 0x36, 0x51, 0xa8, 0xdf, 0xbe, 0xe8, 0x20, 0x42, 0x88, 0x9e, 0x85, 0xf0, 0xe0, + 0x28, 0xd1, 0x25, 0x07, 0x96, 0x3f, 0xd7, 0x7d, 0x29, 0x98, 0x05, 0x68, 0xfe, 0x24, + 0x0d, 0xb1, 0xe5, 0x23, 0xaf, 0xdb, 0x72, 0x06, 0x73, 0x75, 0x29, 0xac, 0x57, 0xb4, + 0x3a, 0x25, 0x67, 0x13, 0xa4, 0x70, 0xb4, 0x86, 0xbc, 0xbc, 0x59, 0x2f}, + {0x5f, 0x13, 0x17, 0x99, 0x42, 0x7d, 0x84, 0x83, 0xd7, 0x03, 0x7d, 0x56, 0x1f, 0x91, + 0x1b, 0xad, 0xd1, 0xaa, 0x77, 0xbe, 0xd9, 0x48, 0x77, 0x7e, 0x4a, 0xaf, 0x51, 0x2e, + 0x2e, 0xb4, 0x58, 0x54, 0x01, 0xc3, 0x91, 0xb6, 0x60, 0xd5, 0x41, 0x70, 0x1e, 0xe7, + 0xd7, 0xad, 0x3f, 0x1b, 0x20, 0x85, 0x85, 0x55, 0x33, 0x11, 0x63, 0xe1, 0xc2, 0x16, + 0xb1, 0x28, 0x08, 0x01, 0x3d, 0x5e, 0xa5, 0x2a, 0x4f, 0x44, 0x07, 0x0c, 0xe6, 0x92, + 0x51, 0xed, 0x10, 0x1d, 0x42, 0x74, 0x2d, 0x4e, 0xc5, 0x42, 0x64, 0xc8, 0xb5, 0xfd, + 0x82, 0x4c, 0x2b, 0x35, 0x64, 0x86, 0x76, 0x8a, 0x4a, 0x00, 0xe9, 0x13}, + {0xdb, 0xce, 0x2f, 0x83, 0x45, 0x88, 0x9d, 0x73, 0x63, 0xf8, 0x6b, 0xae, 0xc9, 0xd6, + 0x38, 0xfa, 0xf7, 0xfe, 0x4f, 0xb7, 0xca, 0x0d, 0xbc, 0x32, 0x5e, 0xe4, 0xbc, 0x14, + 0x88, 0x7e, 0x93, 0x73, 0x7f, 0x87, 0x3b, 0x19, 0xc9, 0x00, 0x2e, 0xbb, 0x6b, 0x50, + 0xdc, 0xe0, 0x90, 0xa8, 0xe3, 0xec, 0x9f, 0x64, 0xde, 0x36, 0xc0, 0xb7, 0xf3, 0xec, + 0x1a, 0x9e, 0xde, 0x98, 0x08, 0x04, 0x46, 0x5f, 0x8d, 0xf4, 0x7b, 0x29, 0x16, 0x71, + 0x03, 0xb9, 0x34, 0x68, 0xf0, 0xd4, 0x22, 0x3b, 0xd1, 0xa9, 0xc6, 0xbd, 0x96, 0x46, + 0x57, 0x15, 0x97, 0xe1, 0x35, 0xe8, 0xd5, 0x91, 0xe8, 0xa4, 0xf8, 0x2c}, + {0x67, 0x0f, 0x11, 0x07, 0x87, 0xfd, 0x93, 0x6d, 0x49, 0xb5, 0x38, 0x7c, 0xd3, 0x09, + 0x4c, 0xdd, 0x86, 0x6a, 0x73, 0xc2, 0x4c, 0x6a, 0xb1, 0x7c, 0x09, 0x2a, 0x25, 0x58, + 0x6e, 0xbd, 0x49, 0x20, 0xa2, 0x6b, 0xd0, 0x17, 0x7e, 0x48, 0xb5, 0x2c, 0x6b, 0x19, + 0x50, 0x39, 0x1c, 0x38, 0xd2, 0x24, 0x30, 0x8a, 0x97, 0x85, 0x81, 0x9c, 0x65, 0xd7, + 0xf6, 0xa4, 0xd6, 0x91, 0x28, 0x7f, 0x6f, 0x7a, 0x49, 0xef, 0x9a, 0x6a, 0x8d, 0xfd, + 0x09, 0x7d, 0x0b, 0xb9, 0x3d, 0x5b, 0xbe, 0x60, 0xee, 0xf0, 0xd4, 0xbf, 0x9e, 0x51, + 0x2c, 0xb5, 0x21, 0x4c, 0x1d, 0x94, 0x45, 0xc5, 0xdf, 0xaa, 0x11, 0x60}, + {0x3c, 0xf8, 0x95, 0xcf, 0x6d, 0x92, 0x67, 0x5f, 0x71, 0x90, 0x28, 0x71, 0x61, 0x85, + 0x7e, 0x7c, 0x5b, 0x7a, 0x8f, 0x99, 0xf3, 0xe7, 0xa1, 0xd6, 0xe0, 0xf9, 0x62, 0x0b, + 0x1b, 0xcc, 0xc5, 0x6f, 0x90, 0xf8, 0xcb, 0x02, 0xc8, 0xd0, 0xde, 0x63, 0xaa, 0x6a, + 0xff, 0x0d, 0xca, 0x98, 0xd0, 0xfb, 0x99, 0xed, 0xb6, 0xb9, 0xfd, 0x0a, 0x4d, 0x62, + 0x1e, 0x0b, 0x34, 0x79, 0xb7, 0x18, 0xce, 0x69, 0xcb, 0x79, 0x98, 0xb2, 0x28, 0x55, + 0xef, 0xd1, 0x92, 0x90, 0x7e, 0xd4, 0x3c, 0xae, 0x1a, 0xdd, 0x52, 0x23, 0x9f, 0x18, + 0x42, 0x04, 0x7e, 0x12, 0xf1, 0x01, 0x71, 0xe5, 0x3a, 0x6b, 0x59, 0x15}, + {0xa2, 0x79, 0x91, 0x3f, 0xd2, 0x39, 0x27, 0x46, 0xcf, 0xdd, 0xd6, 0x97, 0x31, 0x12, + 0x83, 0xff, 0x8a, 0x14, 0xf2, 0x53, 0xb5, 0xde, 0x07, 0x13, 0xda, 0x4d, 0x5f, 0x7b, + 0x68, 0x37, 0x22, 0x0d, 0xca, 0x24, 0x51, 0x7e, 0x16, 0x31, 0xff, 0x09, 0xdf, 0x45, + 0xc7, 0xd9, 0x8b, 0x15, 0xe4, 0x0b, 0xe5, 0x56, 0xf5, 0x7e, 0x22, 0x7d, 0x2b, 0x29, + 0x38, 0xd1, 0xb6, 0xaf, 0x41, 0xe2, 0xa4, 0x3a, 0xf5, 0x05, 0x33, 0x2a, 0xbf, 0x38, + 0xc1, 0x2c, 0xc3, 0x26, 0xe9, 0xa2, 0x8f, 0x3f, 0x58, 0x48, 0xeb, 0xd2, 0x49, 0x55, + 0xa2, 0xb1, 0x3a, 0x08, 0x6c, 0xa3, 0x87, 0x46, 0x6e, 0xaa, 0xfc, 0x32}, + {0xf5, 0x9a, 0x7d, 0xc5, 0x8d, 0x6e, 0xc5, 0x7b, 0xf2, 0xbd, 0xf0, 0x9d, 0xed, 0xd2, + 0x0b, 0x3e, 0xa3, 0xe4, 0xef, 0x22, 0xde, 0x14, 0xc0, 0xaa, 0x5c, 0x6a, 0xbd, 0xfe, + 0xce, 0xe9, 0x27, 0x46, 0xdf, 0xcc, 0x87, 0x27, 0x73, 0xa4, 0x07, 0x32, 0xf8, 0xe3, + 0x13, 0xf2, 0x08, 0x19, 0xe3, 0x17, 0x4e, 0x96, 0x0d, 0xf6, 0xd7, 0xec, 0xb2, 0xd5, + 0xe9, 0x0b, 0x60, 0xc2, 0x36, 0x63, 0x6f, 0x74, 0x1c, 0x97, 0x6c, 0xab, 0x45, 0xf3, + 0x4a, 0x3f, 0x1f, 0x73, 0x43, 0x99, 0x72, 0xeb, 0x88, 0xe2, 0x6d, 0x18, 0x44, 0x03, + 0x8a, 0x6a, 0x59, 0x33, 0x93, 0x62, 0xd6, 0x7e, 0x00, 0x17, 0x49, 0x7b}, + {0x64, 0xb0, 0x84, 0xab, 0x5c, 0xfb, 0x85, 0x2d, 0x14, 0xbc, 0xf3, 0x89, 0xd2, 0x10, + 0x78, 0x49, 0x0c, 0xce, 0x15, 0x7b, 0x44, 0xdc, 0x6a, 0x47, 0x7b, 0xfd, 0x44, 0xf8, + 0x76, 0xa3, 0x2b, 0x12, 0xdd, 0xa2, 0x53, 0xdd, 0x28, 0x1b, 0x34, 0x54, 0x3f, 0xfc, + 0x42, 0xdf, 0x5b, 0x90, 0x17, 0xaa, 0xf4, 0xf8, 0xd2, 0x4d, 0xd9, 0x92, 0xf5, 0x0f, + 0x7d, 0xd3, 0x8c, 0xe0, 0x0f, 0x62, 0x03, 0x1d, 0x54, 0xe5, 0xb4, 0xa2, 0xcd, 0x32, + 0x02, 0xc2, 0x7f, 0x18, 0x5d, 0x11, 0x42, 0xfd, 0xd0, 0x9e, 0xd9, 0x79, 0xd4, 0x7d, + 0xbe, 0xb4, 0xab, 0x2e, 0x4c, 0xec, 0x68, 0x2b, 0xf5, 0x0b, 0xc7, 0x02}, + {0xbb, 0x2f, 0x0b, 0x5d, 0x4b, 0xec, 0x87, 0xa2, 0xca, 0x82, 0x48, 0x07, 0x90, 0x57, + 0x5c, 0x41, 0x5c, 0x81, 0xd0, 0xc1, 0x1e, 0xa6, 0x44, 0xe0, 0xe0, 0xf5, 0x9e, 0x40, + 0x0a, 0x4f, 0x33, 0x26, 0xe1, 0x72, 0x8d, 0x45, 0xbf, 0x32, 0xe5, 0xac, 0xb5, 0x3c, + 0xb7, 0x7c, 0xe0, 0x68, 0xe7, 0x5b, 0xe7, 0xbd, 0x8b, 0xee, 0x94, 0x7d, 0xcf, 0x56, + 0x03, 0x3a, 0xb4, 0xfe, 0xe3, 0x97, 0x06, 0x6b, 0xc0, 0xa3, 0x62, 0xdf, 0x4a, 0xf0, + 0xc8, 0xb6, 0x5d, 0xa4, 0x6d, 0x07, 0xef, 0x00, 0xf0, 0x3e, 0xa9, 0xd2, 0xf0, 0x49, + 0x58, 0xb9, 0x9c, 0x9c, 0xae, 0x2f, 0x1b, 0x44, 0x43, 0x7f, 0xc3, 0x1c}, + {0x4f, 0x32, 0xc7, 0x5c, 0x5a, 0x56, 0x8f, 0x50, 0x22, 0xa9, 0x06, 0xe5, 0xc0, 0xc4, + 0x61, 0xd0, 0x19, 0xac, 0x45, 0x5c, 0xdb, 0xab, 0x18, 0xfb, 0x4a, 0x31, 0x80, 0x03, + 0xc1, 0x09, 0x68, 0x6c, 0xb9, 0xae, 0xce, 0xc9, 0xf1, 0x56, 0x66, 0xd7, 0x6a, 0x65, + 0xe5, 0x18, 0xf8, 0x15, 0x5b, 0x1c, 0x34, 0x23, 0x4c, 0x84, 0x32, 0x28, 0xe7, 0x26, + 0x38, 0x68, 0x19, 0x2f, 0x77, 0x6f, 0x34, 0x3a, 0xc8, 0x6a, 0xda, 0xe2, 0x12, 0x51, + 0xd5, 0xd2, 0xed, 0x51, 0xe8, 0xb1, 0x31, 0x03, 0xbd, 0xe9, 0x62, 0x72, 0xc6, 0x8e, + 0xdd, 0x46, 0x07, 0x96, 0xd0, 0xc5, 0xf7, 0x6e, 0x9f, 0x1b, 0x91, 0x05}, + {0xbb, 0x0e, 0xdf, 0xf5, 0x83, 0x99, 0x33, 0xc1, 0xac, 0x4c, 0x2c, 0x51, 0x8f, 0x75, + 0xf3, 0xc0, 0xe1, 0x98, 0xb3, 0x0b, 0x0a, 0x13, 0xf1, 0x2c, 0x62, 0x0c, 0x27, 0xaa, + 0xf9, 0xec, 0x3c, 0x6b, 0xef, 0xea, 0x2e, 0x51, 0xf3, 0xac, 0x49, 0x53, 0x49, 0xcb, + 0xc1, 0x1c, 0xd3, 0x41, 0xc1, 0x20, 0x8d, 0x68, 0x9a, 0xa9, 0x07, 0x0c, 0x18, 0x24, + 0x17, 0x2d, 0x4b, 0xc6, 0xd1, 0xf9, 0x5e, 0x55, 0x08, 0xbd, 0x73, 0x3b, 0xba, 0x70, + 0xa7, 0x36, 0x0c, 0xbf, 0xaf, 0xa3, 0x08, 0xef, 0x4a, 0x62, 0xf2, 0x46, 0x09, 0xb4, + 0x98, 0xff, 0x37, 0x57, 0x9d, 0x74, 0x81, 0x33, 0xe1, 0x4d, 0x5f, 0x67}, + {0xfc, 0x82, 0x17, 0x6b, 0x03, 0x52, 0x2c, 0x0e, 0xb4, 0x83, 0xad, 0x6c, 0x81, 0x6c, + 0x81, 0x64, 0x3e, 0x07, 0x64, 0x69, 0xd9, 0xbd, 0xdc, 0xd0, 0x20, 0xc5, 0x64, 0x01, + 0xf7, 0x9d, 0xd9, 0x13, 0x1d, 0xb3, 0xda, 0x3b, 0xd9, 0xf6, 0x2f, 0xa1, 0xfe, 0x2d, + 0x65, 0x9d, 0x0f, 0xd8, 0x25, 0x07, 0x87, 0x94, 0xbe, 0x9a, 0xf3, 0x4f, 0x9c, 0x01, + 0x43, 0x3c, 0xcd, 0x82, 0xb8, 0x50, 0xf4, 0x60, 0xca, 0xc0, 0xe5, 0x21, 0xc3, 0x5e, + 0x4b, 0x01, 0xa2, 0xbf, 0x19, 0xd7, 0xc9, 0x69, 0xcb, 0x4f, 0xa0, 0x23, 0x00, 0x75, + 0x18, 0x1c, 0x5f, 0x4e, 0x80, 0xac, 0xed, 0x55, 0x9e, 0xde, 0x06, 0x1c}, + {0xe2, 0xc4, 0x3e, 0xa3, 0xd6, 0x7a, 0x0f, 0x99, 0x8e, 0xe0, 0x2e, 0xbe, 0x38, 0xf9, + 0x08, 0x66, 0x15, 0x45, 0x28, 0x63, 0xc5, 0x43, 0xa1, 0x9c, 0x0d, 0xb6, 0x2d, 0xec, + 0x1f, 0x8a, 0xf3, 0x4c, 0xaa, 0x69, 0x6d, 0xff, 0x40, 0x2b, 0xd5, 0xff, 0xbb, 0x49, + 0x40, 0xdc, 0x18, 0x0b, 0x53, 0x34, 0x97, 0x98, 0x4d, 0xa3, 0x2f, 0x5c, 0x4a, 0x5e, + 0x2d, 0xba, 0x32, 0x7d, 0x8e, 0x6f, 0x09, 0x78, 0xe7, 0x5c, 0xfa, 0x0d, 0x65, 0xaa, + 0xaa, 0xa0, 0x8c, 0x47, 0xb5, 0x48, 0x2a, 0x9e, 0xc4, 0xf9, 0x5b, 0x72, 0x03, 0x70, + 0x7d, 0xcc, 0x09, 0x4f, 0xbe, 0x1a, 0x09, 0x26, 0x3a, 0xad, 0x3c, 0x37}, + {0x7c, 0xf5, 0xc9, 0x82, 0x4d, 0x63, 0x94, 0xb2, 0x36, 0x45, 0x93, 0x24, 0xe1, 0xfd, + 0xcb, 0x1f, 0x5a, 0xdb, 0x8c, 0x41, 0xb3, 0x4d, 0x9c, 0x9e, 0xfc, 0x19, 0x44, 0x45, + 0xd9, 0xf3, 0x40, 0x00, 0xad, 0xbb, 0xdd, 0x89, 0xfb, 0xa8, 0xbe, 0xf1, 0xcb, 0xae, + 0xae, 0x61, 0xbc, 0x2c, 0xcb, 0x3b, 0x9d, 0x8d, 0x9b, 0x1f, 0xbb, 0xa7, 0x58, 0x8f, + 0x86, 0xa6, 0x12, 0x51, 0xda, 0x7e, 0x54, 0x21, 0xd3, 0x86, 0x59, 0xfd, 0x39, 0xe9, + 0xfd, 0xde, 0x0c, 0x38, 0x0a, 0x51, 0x89, 0x2c, 0x27, 0xf4, 0xb9, 0x19, 0x31, 0xbb, + 0x07, 0xa4, 0x2b, 0xb7, 0xf4, 0x4d, 0x25, 0x4a, 0x33, 0x0a, 0x55, 0x63}, + {0x37, 0xcf, 0x69, 0xb5, 0xed, 0xd6, 0x07, 0x65, 0xe1, 0x2e, 0xa5, 0x0c, 0xb0, 0x29, + 0x84, 0x17, 0x5d, 0xd6, 0x6b, 0xeb, 0x90, 0x00, 0x7c, 0xea, 0x51, 0x8f, 0xf7, 0xda, + 0xc7, 0x62, 0xea, 0x3e, 0x49, 0x7b, 0x54, 0x72, 0x45, 0x58, 0xba, 0x9b, 0xe0, 0x08, + 0xc4, 0xe2, 0xfa, 0xc6, 0x05, 0xf3, 0x8d, 0xf1, 0x34, 0xc7, 0x69, 0xfa, 0xe8, 0x60, + 0x7a, 0x76, 0x7d, 0xaa, 0xaf, 0x2b, 0xa9, 0x39, 0x4e, 0x27, 0x93, 0xe6, 0x13, 0xc7, + 0x24, 0x9d, 0x75, 0xd3, 0xdb, 0x68, 0x77, 0x85, 0x63, 0x5f, 0x9a, 0xb3, 0x8a, 0xeb, + 0x60, 0x55, 0x52, 0x70, 0xcd, 0xc4, 0xc9, 0x65, 0x06, 0x6a, 0x43, 0x68}, + {0x27, 0x3f, 0x2f, 0x20, 0xe8, 0x35, 0x02, 0xbc, 0xb0, 0x75, 0xf9, 0x64, 0xe2, 0x00, + 0x5c, 0xc7, 0x16, 0x24, 0x8c, 0xa3, 0xd5, 0xe9, 0xa4, 0x91, 0xf9, 0x89, 0xb7, 0x8a, + 0xf6, 0xe7, 0xb6, 0x17, 0x7c, 0x10, 0x20, 0xe8, 0x17, 0xd3, 0x56, 0x1e, 0x65, 0xe9, + 0x0a, 0x84, 0x44, 0x68, 0x26, 0xc5, 0x7a, 0xfc, 0x0f, 0x32, 0xc6, 0xa1, 0xe0, 0xc1, + 0x72, 0x14, 0x61, 0x91, 0x9c, 0x66, 0x73, 0x53, 0x57, 0x52, 0x0e, 0x9a, 0xab, 0x14, + 0x28, 0x5d, 0xfc, 0xb3, 0xca, 0xc9, 0x84, 0x20, 0x8f, 0x90, 0xca, 0x1e, 0x2d, 0x5b, + 0x88, 0xf5, 0xca, 0xaf, 0x11, 0x7d, 0xf8, 0x78, 0xa6, 0xb5, 0xb4, 0x1c}, + {0x6c, 0xfc, 0x4a, 0x39, 0x6b, 0xc0, 0x64, 0xb6, 0xb1, 0x5f, 0xda, 0x98, 0x24, 0xde, + 0x88, 0x0c, 0x34, 0xd8, 0xca, 0x4b, 0x16, 0x03, 0x8d, 0x4f, 0xa2, 0x34, 0x74, 0xde, + 0x78, 0xca, 0x0b, 0x33, 0xe7, 0x07, 0xa0, 0xa2, 0x62, 0xaa, 0x74, 0x6b, 0xb1, 0xc7, + 0x71, 0xf0, 0xb0, 0xe0, 0x11, 0xf3, 0x23, 0xe2, 0x0b, 0x00, 0x38, 0xe4, 0x07, 0x57, + 0xac, 0x6e, 0xef, 0x82, 0x2d, 0xfd, 0xc0, 0x2d, 0x4e, 0x74, 0x19, 0x11, 0x84, 0xff, + 0x2e, 0x98, 0x24, 0x47, 0x07, 0x2b, 0x96, 0x5e, 0x69, 0xf9, 0xfb, 0x53, 0xc9, 0xbf, + 0x4f, 0xc1, 0x8a, 0xc5, 0xf5, 0x1c, 0x9f, 0x36, 0x1b, 0xbe, 0x31, 0x3c}, + {0xee, 0x8a, 0x94, 0x08, 0x4d, 0x86, 0xf4, 0xb0, 0x6f, 0x1c, 0xba, 0x91, 0xee, 0x19, + 0xdc, 0x07, 0x58, 0xa1, 0xac, 0xa6, 0xae, 0xcd, 0x75, 0x79, 0xbb, 0xd4, 0x62, 0x42, + 0x13, 0x61, 0x0b, 0x33, 0x72, 0x42, 0xcb, 0xf9, 0x93, 0xbc, 0x68, 0xc1, 0x98, 0xdb, + 0xce, 0xc7, 0x1f, 0x71, 0xb8, 0xae, 0x7a, 0x8d, 0xac, 0x34, 0xaa, 0x52, 0x0e, 0x7f, + 0xbb, 0x55, 0x7d, 0x7e, 0x09, 0xc1, 0xce, 0x41, 0x8a, 0x80, 0x6d, 0xa2, 0xd7, 0x19, + 0x96, 0xf7, 0x6d, 0x15, 0x9e, 0x1d, 0x9e, 0xd4, 0x1f, 0xbb, 0x27, 0xdf, 0xa1, 0xdb, + 0x6c, 0xc3, 0xd7, 0x73, 0x7d, 0x77, 0x28, 0x1f, 0xd9, 0x4c, 0xb4, 0x26}, + {0x75, 0x74, 0x38, 0x8f, 0x47, 0x48, 0xf0, 0x51, 0x3c, 0xcb, 0xbe, 0x9c, 0xf4, 0xbc, + 0x5d, 0xb2, 0x55, 0x20, 0x9f, 0xd9, 0x44, 0x12, 0xab, 0x9a, 0xd6, 0xa5, 0x10, 0x1c, + 0x6c, 0x9e, 0x70, 0x2c, 0x83, 0x03, 0x73, 0x62, 0x93, 0xf2, 0xb7, 0xe1, 0x2c, 0x8a, + 0xca, 0xeb, 0xff, 0x79, 0x52, 0x4b, 0x14, 0x13, 0xd4, 0xbf, 0x8a, 0x77, 0xfc, 0xda, + 0x0f, 0x61, 0x72, 0x9c, 0x14, 0x10, 0xeb, 0x7d, 0x7a, 0xee, 0x66, 0x87, 0x6a, 0xaf, + 0x62, 0xcb, 0x0e, 0xcd, 0x53, 0x55, 0x04, 0xec, 0xcb, 0x66, 0xb5, 0xe4, 0x0b, 0x0f, + 0x38, 0x01, 0x80, 0x58, 0xea, 0xe2, 0x2c, 0xf6, 0x9f, 0x8e, 0xe6, 0x08}, + {0xad, 0x30, 0xc1, 0x4b, 0x0a, 0x50, 0xad, 0x34, 0x9c, 0xd4, 0x0b, 0x3d, 0x49, 0xdb, + 0x38, 0x8d, 0xbe, 0x89, 0x0a, 0x50, 0x98, 0x3d, 0x5c, 0xa2, 0x09, 0x3b, 0xba, 0xee, + 0x87, 0x3f, 0x1f, 0x2f, 0xf9, 0xf2, 0xb8, 0x0a, 0xd5, 0x09, 0x2d, 0x2f, 0xdf, 0x23, + 0x59, 0xc5, 0x8d, 0x21, 0xb9, 0xac, 0xb9, 0x6c, 0x76, 0x73, 0x26, 0x34, 0x8f, 0x4a, + 0xf5, 0x19, 0xf7, 0x38, 0xd7, 0x3b, 0xb1, 0x4c, 0x4a, 0xb6, 0x15, 0xe5, 0x75, 0x8c, + 0x84, 0xf7, 0x38, 0x90, 0x4a, 0xdb, 0xba, 0x01, 0x95, 0xa5, 0x50, 0x1b, 0x75, 0x3f, + 0x3f, 0x31, 0x0d, 0xc2, 0xe8, 0x2e, 0xae, 0xc0, 0x53, 0xe3, 0xa1, 0x19}, + {0xc3, 0x05, 0xfa, 0xba, 0x60, 0x75, 0x1c, 0x7d, 0x61, 0x5e, 0xe5, 0xc6, 0xa0, 0xa0, + 0xe1, 0xb3, 0x73, 0x64, 0xd6, 0xc0, 0x18, 0x97, 0x52, 0xe3, 0x86, 0x34, 0x0c, 0xc2, + 0x11, 0x6b, 0x54, 0x41, 0xbd, 0xbd, 0x96, 0xd5, 0xcd, 0x72, 0x21, 0xb4, 0x40, 0xfc, + 0xee, 0x98, 0x43, 0x45, 0xe0, 0x93, 0xb5, 0x09, 0x41, 0xb4, 0x47, 0x53, 0xb1, 0x9f, + 0x34, 0xae, 0x66, 0x02, 0x99, 0xd3, 0x6b, 0x73, 0xb4, 0xb3, 0x34, 0x93, 0x50, 0x2d, + 0x53, 0x85, 0x73, 0x65, 0x81, 0x60, 0x4b, 0x11, 0xfd, 0x46, 0x75, 0x83, 0x5c, 0x42, + 0x30, 0x5f, 0x5f, 0xcc, 0x5c, 0xab, 0x7f, 0xb8, 0xa2, 0x95, 0x22, 0x41}, + {0xe9, 0xd6, 0x7e, 0xf5, 0x88, 0x9b, 0xc9, 0x19, 0x25, 0xc8, 0xf8, 0x6d, 0x26, 0xcb, + 0x93, 0x53, 0x73, 0xd2, 0x0a, 0xb3, 0x13, 0x32, 0xee, 0x5c, 0x34, 0x2e, 0x2d, 0xb5, + 0xeb, 0x53, 0xe1, 0x14, 0xc6, 0xea, 0x93, 0xe2, 0x61, 0x52, 0x65, 0x2e, 0xdb, 0xac, + 0x33, 0x21, 0x03, 0x92, 0x5a, 0x84, 0x6b, 0x99, 0x00, 0x79, 0xcb, 0x75, 0x09, 0x46, + 0x80, 0xdd, 0x5a, 0x19, 0x8d, 0xbb, 0x60, 0x07, 0x8a, 0x81, 0xe6, 0xcd, 0x17, 0x1a, + 0x3e, 0x41, 0x84, 0xa0, 0x69, 0xed, 0xa9, 0x6d, 0x15, 0x57, 0xb1, 0xcc, 0xca, 0x46, + 0x8f, 0x26, 0xbf, 0x2c, 0xf2, 0xc5, 0x3a, 0xc3, 0x9b, 0xbe, 0x34, 0x6b}, + {0xb2, 0xc0, 0x78, 0x3a, 0x64, 0x2f, 0xdf, 0xf3, 0x7c, 0x02, 0x2e, 0xf2, 0x1e, 0x97, + 0x3e, 0x4c, 0xa3, 0xb5, 0xc1, 0x49, 0x5e, 0x1c, 0x7d, 0xec, 0x2d, 0xdd, 0x22, 0x09, + 0x8f, 0xc1, 0x12, 0x20, 0xd3, 0xf2, 0x71, 0x65, 0x65, 0x69, 0xfc, 0x11, 0x7a, 0x73, + 0x0e, 0x53, 0x45, 0xe8, 0xc9, 0xc6, 0x35, 0x50, 0xfe, 0xd4, 0xa2, 0xe7, 0x3a, 0xe3, + 0x0b, 0xd3, 0x6d, 0x2e, 0xb6, 0xc7, 0xb9, 0x01, 0x29, 0x9d, 0xc8, 0x5a, 0xe5, 0x55, + 0x0b, 0x88, 0x63, 0xa7, 0xa0, 0x45, 0x1f, 0x24, 0x83, 0x14, 0x1f, 0x6c, 0xe7, 0xc2, + 0xdf, 0xef, 0x36, 0x3d, 0xe8, 0xad, 0x4b, 0x4e, 0x78, 0x5b, 0xaf, 0x08}, + {0x33, 0x25, 0x1f, 0x88, 0xdc, 0x99, 0x34, 0x28, 0xb6, 0x23, 0x93, 0x77, 0xda, 0x25, + 0x05, 0x9d, 0xf4, 0x41, 0x34, 0x67, 0xfb, 0xdd, 0x7a, 0x89, 0x8d, 0x16, 0x3a, 0x16, + 0x71, 0x9d, 0xb7, 0x32, 0x4b, 0x2c, 0xcc, 0x89, 0xd2, 0x14, 0x73, 0xe2, 0x8d, 0x17, + 0x87, 0xa2, 0x11, 0xbd, 0xe4, 0x4b, 0xce, 0x64, 0x33, 0xfa, 0xd6, 0x28, 0xd5, 0x18, + 0x6e, 0x82, 0xd9, 0xaf, 0xd5, 0xc1, 0x23, 0x64, 0x6a, 0xb3, 0xfc, 0xed, 0xd9, 0xf8, + 0x85, 0xcc, 0xf9, 0xe5, 0x46, 0x37, 0x8f, 0xc2, 0xbc, 0x22, 0xcd, 0xd3, 0xe5, 0xf9, + 0x38, 0xe3, 0x9d, 0xe4, 0xcc, 0x2d, 0x3e, 0xc1, 0xfb, 0x5e, 0x0a, 0x48}, + {0x71, 0x20, 0x62, 0x01, 0x0b, 0xe7, 0x51, 0x0b, 0xc5, 0xaf, 0x1d, 0x8b, 0xcf, 0x05, + 0xb5, 0x06, 0xcd, 0xab, 0x5a, 0xef, 0x61, 0xb0, 0x6b, 0x2c, 0x31, 0xbf, 0xb7, 0x0c, + 0x60, 0x27, 0xaa, 0x47, 0x1f, 0x22, 0xce, 0x42, 0xe4, 0x4c, 0x61, 0xb6, 0x28, 0x39, + 0x05, 0x4c, 0xcc, 0x9d, 0x19, 0x6e, 0x03, 0xbe, 0x1c, 0xdc, 0xa4, 0xb4, 0x3f, 0x66, + 0x06, 0x8e, 0x1c, 0x69, 0x47, 0x1d, 0xb3, 0x24, 0xc3, 0xf8, 0x15, 0xc0, 0xed, 0x1e, + 0x54, 0x2a, 0x7c, 0x3f, 0x69, 0x7c, 0x7e, 0xfe, 0xa4, 0x11, 0xd6, 0x78, 0xa2, 0x4e, + 0x13, 0x66, 0xaf, 0xf0, 0x94, 0xa0, 0xdd, 0x14, 0x5d, 0x58, 0x5b, 0x54}, + {0x0f, 0x3a, 0xd4, 0xa0, 0x5e, 0x27, 0xbf, 0x67, 0xbe, 0xee, 0x9b, 0x08, 0x34, 0x8e, + 0xe6, 0xad, 0x2e, 0xe7, 0x79, 0xd4, 0x4c, 0x13, 0x89, 0x42, 0x54, 0x54, 0xba, 0x32, + 0xc3, 0xf9, 0x62, 0x0f, 0xe1, 0x21, 0xb3, 0xe3, 0xd0, 0xe4, 0x04, 0x62, 0x95, 0x1e, + 0xff, 0x28, 0x7a, 0x63, 0xaa, 0x3b, 0x9e, 0xbd, 0x99, 0x5b, 0xfd, 0xcf, 0x0c, 0x0b, + 0x71, 0xd0, 0xc8, 0x64, 0x3e, 0xdc, 0x22, 0x4d, 0x39, 0x5f, 0x3b, 0xd6, 0x89, 0x65, + 0xb4, 0xfc, 0x61, 0xcf, 0xcb, 0x57, 0x3f, 0x6a, 0xae, 0x5c, 0x05, 0xfa, 0x3a, 0x95, + 0xd2, 0xc2, 0xba, 0xfe, 0x36, 0x14, 0x37, 0x36, 0x1a, 0xa0, 0x0f, 0x1c}, + {0xff, 0x3d, 0x94, 0x22, 0xb6, 0x04, 0xc6, 0xd2, 0xa0, 0xb3, 0xcf, 0x44, 0xce, 0xbe, + 0x8c, 0xbc, 0x78, 0x86, 0x80, 0x97, 0xf3, 0x4f, 0x25, 0x5d, 0xbf, 0xa6, 0x1c, 0x3b, + 0x4f, 0x61, 0xa3, 0x0f, 0x50, 0x6a, 0x93, 0x8c, 0x0e, 0x2b, 0x08, 0x69, 0xb6, 0xc5, + 0xda, 0xc1, 0x35, 0xa0, 0xc9, 0xf9, 0x34, 0xb6, 0xdf, 0xc4, 0x54, 0x3e, 0xb7, 0x6f, + 0x40, 0xc1, 0x2b, 0x1d, 0x9b, 0x41, 0x05, 0x40, 0xf0, 0x82, 0xbe, 0xb9, 0xbd, 0xfe, + 0x03, 0xa0, 0x90, 0xac, 0x44, 0x3a, 0xaf, 0xc1, 0x89, 0x20, 0x8e, 0xfa, 0x54, 0x19, + 0x91, 0x9f, 0x49, 0xf8, 0x42, 0xab, 0x40, 0xef, 0x8a, 0x21, 0xba, 0x1f}, + {0x3e, 0xf5, 0xc8, 0xfa, 0x48, 0x94, 0x54, 0xab, 0x41, 0x37, 0xa6, 0x7b, 0x9a, 0xe8, + 0xf6, 0x81, 0x01, 0x5e, 0x2b, 0x6c, 0x7d, 0x6c, 0xfd, 0x74, 0x42, 0x6e, 0xc8, 0xa8, + 0xca, 0x3a, 0x2e, 0x39, 0x94, 0x01, 0x7b, 0x3e, 0x04, 0x57, 0x3e, 0x4f, 0x7f, 0xaf, + 0xda, 0x08, 0xee, 0x3e, 0x1d, 0xa8, 0xf1, 0xde, 0xdc, 0x99, 0xab, 0xc6, 0x39, 0xc8, + 0xd5, 0x61, 0x77, 0xff, 0x13, 0x5d, 0x53, 0x6c, 0xaf, 0x35, 0x8a, 0x3e, 0xe9, 0x34, + 0xbd, 0x4c, 0x16, 0xe8, 0x87, 0x58, 0x44, 0x81, 0x07, 0x2e, 0xab, 0xb0, 0x9a, 0xf2, + 0x76, 0x9c, 0x31, 0x19, 0x3b, 0xc1, 0x0a, 0xd5, 0xe4, 0x7f, 0xe1, 0x25}, + {0x76, 0xf6, 0x04, 0x1e, 0xd7, 0x9b, 0x28, 0x0a, 0x95, 0x0f, 0x42, 0xd6, 0x52, 0x1c, + 0x8e, 0x20, 0xab, 0x1f, 0x69, 0x34, 0xb0, 0xd8, 0x86, 0x51, 0x51, 0xb3, 0x9f, 0x2a, + 0x44, 0x51, 0x57, 0x25, 0xa7, 0x21, 0xf1, 0x76, 0xf5, 0x7f, 0x5f, 0x91, 0xe3, 0x87, + 0xcd, 0x2f, 0x27, 0x32, 0x4a, 0xc3, 0x26, 0xe5, 0x1b, 0x4d, 0xde, 0x2f, 0xba, 0xcc, + 0x9b, 0x89, 0x69, 0x89, 0x8f, 0x82, 0xba, 0x6b, 0x01, 0x39, 0xfe, 0x90, 0x66, 0xbc, + 0xd1, 0xe2, 0xd5, 0x7a, 0x99, 0xa0, 0x18, 0x4a, 0xb5, 0x4c, 0xd4, 0x60, 0x84, 0xaf, + 0x14, 0x69, 0x1d, 0x97, 0xe4, 0x7b, 0x6b, 0x7f, 0x4f, 0x50, 0x9d, 0x55}, + {0xd5, 0x54, 0xeb, 0xb3, 0x78, 0x83, 0x73, 0xa7, 0x7c, 0x3c, 0x55, 0xa5, 0x66, 0xd3, + 0x69, 0x1d, 0xba, 0x00, 0x28, 0xf9, 0x62, 0xcf, 0x26, 0x0a, 0x17, 0x32, 0x7e, 0x80, + 0xd5, 0x12, 0xab, 0x01, 0xfd, 0x66, 0xd2, 0xf6, 0xe7, 0x91, 0x48, 0x9c, 0x1b, 0x78, + 0x07, 0x03, 0x9b, 0xa1, 0x44, 0x07, 0x3b, 0xe2, 0x61, 0x60, 0x1d, 0x8f, 0x38, 0x88, + 0x0e, 0xd5, 0x4b, 0x35, 0xa3, 0xa6, 0x3e, 0x12, 0x96, 0x2d, 0xe3, 0x41, 0x90, 0x18, + 0x8d, 0x11, 0x48, 0x58, 0x31, 0xd8, 0xc2, 0xe3, 0xed, 0xb9, 0xd9, 0x45, 0x32, 0xd8, + 0x71, 0x42, 0xab, 0x1e, 0x54, 0xa1, 0x18, 0xc9, 0xe2, 0x61, 0x39, 0x4a}, + {0xa0, 0xbb, 0xe6, 0xf8, 0xe0, 0x3b, 0xdc, 0x71, 0x0a, 0xe3, 0xff, 0x7e, 0x34, 0xf8, + 0xce, 0xd6, 0x6a, 0x47, 0x3a, 0xe1, 0x5f, 0x42, 0x92, 0xa9, 0x63, 0xb7, 0x1d, 0xfb, + 0xe3, 0xbc, 0xd6, 0x2c, 0x1e, 0x3f, 0x23, 0xf3, 0x44, 0xd6, 0x27, 0x03, 0x16, 0xf0, + 0xfc, 0x34, 0x0e, 0x26, 0x9a, 0x49, 0x79, 0xb9, 0xda, 0xf2, 0x16, 0xa7, 0xb5, 0x83, + 0x1f, 0x11, 0xd4, 0x9b, 0xad, 0xee, 0xac, 0x68, 0x10, 0xc2, 0xd7, 0xf3, 0x0e, 0xc9, + 0xb4, 0x38, 0x0c, 0x04, 0xad, 0xb7, 0x24, 0x6e, 0x8e, 0x30, 0x23, 0x3e, 0xe7, 0xb7, + 0xf1, 0xd9, 0x60, 0x38, 0x97, 0xf5, 0x08, 0xb5, 0xd5, 0x60, 0x57, 0x59}, + {0x97, 0x63, 0xaa, 0x04, 0xe1, 0xbf, 0x29, 0x61, 0xcb, 0xfc, 0xa7, 0xa4, 0x08, 0x00, + 0x96, 0x8f, 0x58, 0x94, 0x90, 0x7d, 0x89, 0xc0, 0x8b, 0x3f, 0xa9, 0x91, 0xb2, 0xdc, + 0x3e, 0xa4, 0x9f, 0x70, 0x90, 0x27, 0x02, 0xfd, 0xeb, 0xcb, 0x2a, 0x88, 0x60, 0x57, + 0x11, 0xc4, 0x05, 0x33, 0xaf, 0x89, 0xf4, 0x73, 0x34, 0x7d, 0xe3, 0x92, 0xf4, 0x65, + 0x2b, 0x5a, 0x51, 0x54, 0xdf, 0xc5, 0xb2, 0x2c, 0xca, 0x2a, 0xfd, 0x63, 0x8c, 0x5d, + 0x0a, 0xeb, 0xff, 0x4e, 0x69, 0x2e, 0x66, 0xc1, 0x2b, 0xd2, 0x3a, 0xb0, 0xcb, 0xf8, + 0x6e, 0xf3, 0x23, 0x27, 0x1f, 0x13, 0xc8, 0xf0, 0xec, 0x29, 0xf0, 0x70}, + {0x33, 0x3e, 0xed, 0x2e, 0xb3, 0x07, 0x13, 0x46, 0xe7, 0x81, 0x55, 0xa4, 0x33, 0x2f, + 0x04, 0xae, 0x66, 0x03, 0x5f, 0x19, 0xd3, 0x49, 0x44, 0xc9, 0x58, 0x48, 0x31, 0x6c, + 0x8a, 0x5d, 0x7d, 0x0b, 0xb9, 0xb0, 0x10, 0x5e, 0xaa, 0xaf, 0x6a, 0x2a, 0xa9, 0x1a, + 0x04, 0xef, 0x70, 0xa3, 0xf0, 0x78, 0x1f, 0xd6, 0x3a, 0xaa, 0x77, 0xfb, 0x3e, 0x77, + 0xe1, 0xd9, 0x4b, 0xa7, 0xa2, 0xa5, 0xec, 0x44, 0x43, 0xd5, 0x95, 0x7b, 0x32, 0x48, + 0xd4, 0x25, 0x1d, 0x0f, 0x34, 0xa3, 0x00, 0x83, 0xd3, 0x70, 0x2b, 0xc5, 0xe1, 0x60, + 0x1c, 0x53, 0x1c, 0xde, 0xe4, 0xe9, 0x7d, 0x2c, 0x51, 0x24, 0x22, 0x27}, + {0x2e, 0x34, 0xc5, 0x49, 0xaf, 0x92, 0xbc, 0x1a, 0xd0, 0xfa, 0xe6, 0xb2, 0x11, 0xd8, + 0xee, 0xff, 0x29, 0x4e, 0xc8, 0xfc, 0x8d, 0x8c, 0xa2, 0xef, 0x43, 0xc5, 0x4c, 0xa4, + 0x18, 0xdf, 0xb5, 0x11, 0xfc, 0x75, 0xa9, 0x42, 0x8a, 0xbb, 0x7b, 0xbf, 0x58, 0xa3, + 0xad, 0x96, 0x77, 0x39, 0x5c, 0x8c, 0x48, 0xaa, 0xed, 0xcd, 0x6f, 0xc7, 0x7f, 0xe2, + 0xa6, 0x20, 0xbc, 0xf6, 0xd7, 0x5f, 0x73, 0x19, 0x66, 0x42, 0xc8, 0x42, 0xd0, 0x90, + 0xab, 0xe3, 0x7e, 0x54, 0x19, 0x7f, 0x0f, 0x8e, 0x84, 0xeb, 0xb9, 0x97, 0xa4, 0x65, + 0xd0, 0xa1, 0x03, 0x25, 0x5f, 0x89, 0xdf, 0x91, 0x11, 0x91, 0xef, 0x0f}}; diff --git a/crypto/ed25519-donna/ed25519-donna-basepoint-table.h b/crypto/ed25519_donna/ed25519_donna_basepoint_table.h similarity index 100% rename from crypto/ed25519-donna/ed25519-donna-basepoint-table.h rename to crypto/ed25519_donna/ed25519_donna_basepoint_table.h diff --git a/crypto/ed25519_donna/ed25519_donna_impl_base.c b/crypto/ed25519_donna/ed25519_donna_impl_base.c new file mode 100644 index 00000000000..778f245788f --- /dev/null +++ b/crypto/ed25519_donna/ed25519_donna_impl_base.c @@ -0,0 +1,829 @@ +#include +#include "ed25519_donna.h" +#include "../memzero.h" + +/* sqrt(x) is such an integer y that 0 <= y <= p - 1, y % 2 = 0, and y^2 = x (mod p). */ +/* d = -121665 / 121666 */ +#if !defined(NDEBUG) +static const bignum25519 ALIGN(16) fe_d = { + 0x35978a3, + 0x0d37284, + 0x3156ebd, + 0x06a0a0e, + 0x001c029, + 0x179e898, + 0x3a03cbb, + 0x1ce7198, + 0x2e2b6ff, + 0x1480db3}; /* d */ +#endif +static const bignum25519 ALIGN(16) fe_sqrtm1 = { + 0x20ea0b0, + 0x186c9d2, + 0x08f189d, + 0x035697f, + 0x0bd0c60, + 0x1fbd7a7, + 0x2804c9e, + 0x1e16569, + 0x004fc1d, + 0x0ae0c92}; /* sqrt(-1) */ +//static const bignum25519 ALIGN(16) fe_d2 = { +// 0x2b2f159, 0x1a6e509, 0x22add7a, 0x0d4141d, 0x0038052, 0x0f3d130, 0x3407977, 0x19ce331, 0x1c56dff, 0x0901b67}; /* 2 * d */ + +/* A = 2 * (1 - d) / (1 + d) = 486662 */ +static const bignum25519 ALIGN(16) fe_ma2 = { + 0x33de3c9, + 0x1fff236, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff}; /* -A^2 */ +static const bignum25519 ALIGN(16) fe_ma = { + 0x3f892e7, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff, + 0x3ffffff, + 0x1ffffff}; /* -A */ +static const bignum25519 ALIGN(16) fe_fffb1 = { + 0x1e3bdff, + 0x025a2b3, + 0x18e5bab, + 0x0ba36ac, + 0x0b9afed, + 0x004e61c, + 0x31d645f, + 0x09d1bea, + 0x102529e, + 0x0063810}; /* sqrt(-2 * A * (A + 2)) */ +static const bignum25519 ALIGN(16) fe_fffb2 = { + 0x383650d, + 0x066df27, + 0x10405a4, + 0x1cfdd48, + 0x2b887f2, + 0x1e9a041, + 0x1d7241f, + 0x0612dc5, + 0x35fba5d, + 0x0cbe787}; /* sqrt(2 * A * (A + 2)) */ +static const bignum25519 ALIGN(16) fe_fffb3 = { + 0x0cfd387, + 0x1209e3a, + 0x3bad4fc, + 0x18ad34d, + 0x2ff6c02, + 0x0f25d12, + 0x15cdfe0, + 0x0e208ed, + 0x32eb3df, + 0x062d7bb}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ +static const bignum25519 ALIGN(16) fe_fffb4 = { + 0x2b39186, + 0x14640ed, + 0x14930a7, + 0x04509fa, + 0x3b91bf0, + 0x0f7432e, + 0x07a443f, + 0x17f24d8, + 0x031067d, + 0x0690fcc}; /* sqrt(sqrt(-1) * A * (A + 2)) */ + +/* + Timing safe memory compare +*/ +int ed25519_verify(const unsigned char* x, const unsigned char* y, size_t len) { + size_t differentbits = 0; + while(len--) differentbits |= (*x++ ^ *y++); + return (int)(1 & ((differentbits - 1) >> 8)); +} + +/* + conversions +*/ + +void ge25519_p1p1_to_partial(ge25519* r, const ge25519_p1p1* p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); +} + +void ge25519_p1p1_to_full(ge25519* r, const ge25519_p1p1* p) { + curve25519_mul(r->x, p->x, p->t); + curve25519_mul(r->y, p->y, p->z); + curve25519_mul(r->z, p->z, p->t); + curve25519_mul(r->t, p->x, p->y); +} + +void ge25519_full_to_pniels(ge25519_pniels* p, const ge25519* r) { + curve25519_sub(p->ysubx, r->y, r->x); + curve25519_add(p->xaddy, r->y, r->x); + curve25519_copy(p->z, r->z); + curve25519_mul(p->t2d, r->t, ge25519_ec2d); +} + +/* + adding & doubling +*/ + +void ge25519_double_p1p1(ge25519_p1p1* r, const ge25519* p) { + bignum25519 a = {0}, b = {0}, c = {0}; + + curve25519_square(a, p->x); + curve25519_square(b, p->y); + curve25519_square(c, p->z); + curve25519_add_reduce(c, c, c); + curve25519_add(r->x, p->x, p->y); + curve25519_square(r->x, r->x); + curve25519_add(r->y, b, a); + curve25519_sub(r->z, b, a); + curve25519_sub_after_basic(r->x, r->x, r->y); + curve25519_sub_after_basic(r->t, c, r->z); +} + +#ifndef ED25519_NO_PRECOMP +void ge25519_nielsadd2_p1p1( + ge25519_p1p1* r, + const ge25519* p, + const ge25519_niels* q, + unsigned char signbit) { + const bignum25519* qb = (const bignum25519*)q; + bignum25519* rb = (bignum25519*)r; + bignum25519 a = {0}, b = {0}, c = {0}; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ + curve25519_mul(r->x, b, qb[signbit ^ 1]); /* y for +, x for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_add_reduce(r->t, p->z, p->z); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2 + signbit], rb[2 + signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2 + (signbit ^ 1)], rb[2 + (signbit ^ 1)], c); /* t for +, z for - */ +} +#endif + +void ge25519_pnielsadd_p1p1( + ge25519_p1p1* r, + const ge25519* p, + const ge25519_pniels* q, + unsigned char signbit) { + const bignum25519* qb = (const bignum25519*)q; + bignum25519* rb = (bignum25519*)r; + bignum25519 a = {0}, b = {0}, c = {0}; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ + curve25519_mul(r->x, b, qb[signbit ^ 1]); /* xaddy for +, ysubx for - */ + curve25519_add(r->y, r->x, a); + curve25519_sub(r->x, r->x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(r->t, p->z, q->z); + curve25519_add_reduce(r->t, r->t, r->t); + curve25519_copy(r->z, r->t); + curve25519_add(rb[2 + signbit], rb[2 + signbit], c); /* z for +, t for - */ + curve25519_sub(rb[2 + (signbit ^ 1)], rb[2 + (signbit ^ 1)], c); /* t for +, z for - */ +} + +void ge25519_double_partial(ge25519* r, const ge25519* p) { + ge25519_p1p1 t = {0}; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_partial(r, &t); +} + +void ge25519_double(ge25519* r, const ge25519* p) { + ge25519_p1p1 t = {0}; + ge25519_double_p1p1(&t, p); + ge25519_p1p1_to_full(r, &t); +} + +void ge25519_nielsadd2(ge25519* r, const ge25519_niels* q) { + bignum25519 a = {0}, b = {0}, c = {0}, e = {0}, f = {0}, g = {0}, h = {0}; + + curve25519_sub(a, r->y, r->x); + curve25519_add(b, r->y, r->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(e, b, q->xaddy); + curve25519_add(h, e, a); + curve25519_sub(e, e, a); + curve25519_mul(c, r->t, q->t2d); + curve25519_add(f, r->z, r->z); + curve25519_add_after_basic(g, f, c); + curve25519_sub_after_basic(f, f, c); + curve25519_mul(r->x, e, f); + curve25519_mul(r->y, h, g); + curve25519_mul(r->z, g, f); + curve25519_mul(r->t, e, h); +} + +void ge25519_pnielsadd(ge25519_pniels* r, const ge25519* p, const ge25519_pniels* q) { + bignum25519 a = {0}, b = {0}, c = {0}, x = {0}, y = {0}, z = {0}, t = {0}; + + curve25519_sub(a, p->y, p->x); + curve25519_add(b, p->y, p->x); + curve25519_mul(a, a, q->ysubx); + curve25519_mul(x, b, q->xaddy); + curve25519_add(y, x, a); + curve25519_sub(x, x, a); + curve25519_mul(c, p->t, q->t2d); + curve25519_mul(t, p->z, q->z); + curve25519_add(t, t, t); + curve25519_add_after_basic(z, t, c); + curve25519_sub_after_basic(t, t, c); + curve25519_mul(r->xaddy, x, t); + curve25519_mul(r->ysubx, y, z); + curve25519_mul(r->z, z, t); + curve25519_mul(r->t2d, x, y); + curve25519_copy(y, r->ysubx); + curve25519_sub(r->ysubx, r->ysubx, r->xaddy); + curve25519_add(r->xaddy, r->xaddy, y); + curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); +} + +/* + pack & unpack +*/ + +void ge25519_pack(unsigned char r[32], const ge25519* p) { + bignum25519 tx = {0}, ty = {0}, zi = {0}; + unsigned char parity[32] = {0}; + curve25519_recip(zi, p->z); + curve25519_mul(tx, p->x, zi); + curve25519_mul(ty, p->y, zi); + curve25519_contract(r, ty); + curve25519_contract(parity, tx); + r[31] ^= ((parity[0] & 1) << 7); +} + +int ge25519_unpack_negative_vartime(ge25519* r, const unsigned char p[32]) { + const unsigned char zero[32] = {0}; + const bignum25519 one = {1}; + unsigned char parity = p[31] >> 7; + unsigned char check[32] = {0}; + bignum25519 t = {0}, root = {0}, num = {0}, den = {0}, d3 = {0}; + + curve25519_expand(r->y, p); + curve25519_copy(r->z, one); + curve25519_square(num, r->y); /* x = y^2 */ + curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ + curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ + curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ + + /* Computation of sqrt(num/den) */ + /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ + curve25519_square(t, den); + curve25519_mul(d3, t, den); + curve25519_square(r->x, d3); + curve25519_mul(r->x, r->x, den); + curve25519_mul(r->x, r->x, num); + curve25519_pow_two252m3(r->x, r->x); + + /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ + curve25519_mul(r->x, r->x, d3); + curve25519_mul(r->x, r->x, num); + + /* 3. Check if either of the roots works: */ + curve25519_square(t, r->x); + curve25519_mul(t, t, den); + curve25519_sub_reduce(root, t, num); + curve25519_contract(check, root); + if(!ed25519_verify(check, zero, 32)) { + curve25519_add_reduce(t, t, num); + curve25519_contract(check, t); + if(!ed25519_verify(check, zero, 32)) return 0; + curve25519_mul(r->x, r->x, ge25519_sqrtneg1); + } + + curve25519_contract(check, r->x); + if((check[0] & 1) == parity) { + curve25519_copy(t, r->x); + curve25519_neg(r->x, t); + } + curve25519_mul(r->t, r->x, r->y); + return 1; +} + +/* + scalarmults +*/ + +void ge25519_set_neutral(ge25519* r) { + memzero(r, sizeof(ge25519)); + r->y[0] = 1; + r->z[0] = 1; +} + +#define S1_SWINDOWSIZE 5 +#define S1_TABLE_SIZE (1 << (S1_SWINDOWSIZE - 2)) +#ifdef ED25519_NO_PRECOMP +#define S2_SWINDOWSIZE 5 +#else +#define S2_SWINDOWSIZE 7 +#endif +#define S2_TABLE_SIZE (1 << (S2_SWINDOWSIZE - 2)) + +/* computes [s1]p1 + [s2]base */ +void ge25519_double_scalarmult_vartime( + ge25519* r, + const ge25519* p1, + const bignum256modm s1, + const bignum256modm s2) { + signed char slide1[256] = {0}, slide2[256] = {0}; + ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; +#ifdef ED25519_NO_PRECOMP + ge25519_pniels pre2[S2_TABLE_SIZE] = {0}; +#endif + ge25519 dp = {0}; + ge25519_p1p1 t = {0}; + int32_t i = 0; + + memzero(&t, sizeof(ge25519_p1p1)); + contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); + contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); + + ge25519_double(&dp, p1); + ge25519_full_to_pniels(pre1, p1); + for(i = 0; i < S1_TABLE_SIZE - 1; i++) ge25519_pnielsadd(&pre1[i + 1], &dp, &pre1[i]); + +#ifdef ED25519_NO_PRECOMP + ge25519_double(&dp, &ge25519_basepoint); + ge25519_full_to_pniels(pre2, &ge25519_basepoint); + for(i = 0; i < S2_TABLE_SIZE - 1; i++) ge25519_pnielsadd(&pre2[i + 1], &dp, &pre2[i]); +#endif + + ge25519_set_neutral(r); + + i = 255; + while((i >= 0) && !(slide1[i] | slide2[i])) i--; + + for(; i >= 0; i--) { + ge25519_double_p1p1(&t, r); + + if(slide1[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1( + &t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); + } + + if(slide2[i]) { + ge25519_p1p1_to_full(r, &t); +#ifdef ED25519_NO_PRECOMP + ge25519_pnielsadd_p1p1( + &t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); +#else + ge25519_nielsadd2_p1p1( + &t, + r, + &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], + (unsigned char)slide2[i] >> 7); +#endif + } + + ge25519_p1p1_to_partial(r, &t); + } + curve25519_mul(r->t, t.x, t.y); + memzero(slide1, sizeof(slide1)); + memzero(slide2, sizeof(slide2)); +} + +/* computes [s1]p1 + [s2]p2 */ +#if USE_MONERO +void ge25519_double_scalarmult_vartime2( + ge25519* r, + const ge25519* p1, + const bignum256modm s1, + const ge25519* p2, + const bignum256modm s2) { + signed char slide1[256] = {0}, slide2[256] = {0}; + ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; + ge25519_pniels pre2[S1_TABLE_SIZE] = {0}; + ge25519 dp = {0}; + ge25519_p1p1 t = {0}; + int32_t i = 0; + + memzero(&t, sizeof(ge25519_p1p1)); + contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); + contract256_slidingwindow_modm(slide2, s2, S1_SWINDOWSIZE); + + ge25519_double(&dp, p1); + ge25519_full_to_pniels(pre1, p1); + for(i = 0; i < S1_TABLE_SIZE - 1; i++) ge25519_pnielsadd(&pre1[i + 1], &dp, &pre1[i]); + + ge25519_double(&dp, p2); + ge25519_full_to_pniels(pre2, p2); + for(i = 0; i < S1_TABLE_SIZE - 1; i++) ge25519_pnielsadd(&pre2[i + 1], &dp, &pre2[i]); + + ge25519_set_neutral(r); + + i = 255; + while((i >= 0) && !(slide1[i] | slide2[i])) i--; + + for(; i >= 0; i--) { + ge25519_double_p1p1(&t, r); + + if(slide1[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1( + &t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); + } + + if(slide2[i]) { + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1( + &t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); + } + + ge25519_p1p1_to_partial(r, &t); + } + curve25519_mul(r->t, t.x, t.y); + memzero(slide1, sizeof(slide1)); + memzero(slide2, sizeof(slide2)); +} +#endif + +/* + * The following conditional move stuff uses conditional moves. + * I will check on which compilers this works, and provide suitable + * workarounds for those where it doesn't. + * + * This works on gcc 4.x and above with -O3. Don't use -O2, this will + * cause the code to not generate conditional moves. Don't use any -march= + * with less than i686 on x86 + */ +static void ge25519_cmove_stride4(long* r, long* p, long* pos, long* n, int stride) { + long x0 = r[0], x1 = r[1], x2 = r[2], x3 = r[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; + for(; p < n; p += stride) { + volatile int flag = (p == pos); + y0 = p[0]; + y1 = p[1]; + y2 = p[2]; + y3 = p[3]; + x0 = flag ? y0 : x0; + x1 = flag ? y1 : x1; + x2 = flag ? y2 : x2; + x3 = flag ? y3 : x3; + } + r[0] = x0; + r[1] = x1; + r[2] = x2; + r[3] = x3; +} +#define HAS_CMOVE_STRIDE4 + +static void ge25519_cmove_stride4b(long* r, long* p, long* pos, long* n, int stride) { + long x0 = p[0], x1 = p[1], x2 = p[2], x3 = p[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; + for(p += stride; p < n; p += stride) { + volatile int flag = (p == pos); + y0 = p[0]; + y1 = p[1]; + y2 = p[2]; + y3 = p[3]; + x0 = flag ? y0 : x0; + x1 = flag ? y1 : x1; + x2 = flag ? y2 : x2; + x3 = flag ? y3 : x3; + } + r[0] = x0; + r[1] = x1; + r[2] = x2; + r[3] = x3; +} +#define HAS_CMOVE_STRIDE4B + +void ge25519_move_conditional_pniels_array( + ge25519_pniels* r, + const ge25519_pniels* p, + int pos, + int n) { +#ifdef HAS_CMOVE_STRIDE4B + size_t i = 0; + for(i = 0; i < sizeof(ge25519_pniels) / sizeof(long); i += 4) { + ge25519_cmove_stride4b( + ((long*)r) + i, + ((long*)p) + i, + ((long*)(p + pos)) + i, + ((long*)(p + n)) + i, + sizeof(ge25519_pniels) / sizeof(long)); + } +#else + size_t i = 0; + for(i = 0; i < n; i++) { + ge25519_move_conditional_pniels(r, p + i, pos == i); + } +#endif +} + +void ge25519_move_conditional_niels_array(ge25519_niels* r, const uint8_t p[8][96], int pos, int n) { + size_t i = 0; + for(i = 0; i < 96 / sizeof(long); i += 4) { + ge25519_cmove_stride4( + ((long*)r) + i, + ((long*)p) + i, + ((long*)(p + pos)) + i, + ((long*)(p + n)) + i, + 96 / sizeof(long)); + } +} + +/* computes [s1]p1, constant time */ +void ge25519_scalarmult(ge25519* r, const ge25519* p1, const bignum256modm s1) { + signed char slide1[64] = {0}; + ge25519_pniels pre1[9] = {0}; + ge25519_pniels pre = {0}; + ge25519 d1 = {0}; + ge25519_p1p1 t = {0}; + int32_t i = 0; + + contract256_window4_modm(slide1, s1); + + ge25519_full_to_pniels(pre1 + 1, p1); + ge25519_double(&d1, p1); + + ge25519_set_neutral(r); + ge25519_full_to_pniels(pre1, r); + + ge25519_full_to_pniels(pre1 + 2, &d1); + for(i = 1; i < 7; i++) { + ge25519_pnielsadd(&pre1[i + 2], &d1, &pre1[i]); + } + + for(i = 63; i >= 0; i--) { + int k = abs(slide1[i]); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_p1p1(&t, r); + ge25519_move_conditional_pniels_array(&pre, pre1, k, 9); + ge25519_p1p1_to_full(r, &t); + ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7); + ge25519_p1p1_to_partial(r, &t); + } + curve25519_mul(r->t, t.x, t.y); + memzero(slide1, sizeof(slide1)); +} + +void ge25519_scalarmult_base_choose_niels( + ge25519_niels* t, + const uint8_t table[256][96], + uint32_t pos, + signed char b) { + bignum25519 neg = {0}; + uint32_t sign = (uint32_t)((unsigned char)b >> 7); + uint32_t mask = ~(sign - 1); + uint32_t u = (b + mask) ^ mask; + + /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ + uint8_t packed[96] = {0}; + packed[0] = 1; + packed[32] = 1; + + ge25519_move_conditional_niels_array((ge25519_niels*)packed, &table[pos * 8], u - 1, 8); + + /* expand in to t */ + curve25519_expand(t->ysubx, packed + 0); + curve25519_expand(t->xaddy, packed + 32); + curve25519_expand(t->t2d, packed + 64); + + /* adjust for sign */ + curve25519_swap_conditional(t->ysubx, t->xaddy, sign); + curve25519_neg(neg, t->t2d); + curve25519_swap_conditional(t->t2d, neg, sign); +} + +/* computes [s]basepoint */ +void ge25519_scalarmult_base_niels( + ge25519* r, + const uint8_t basepoint_table[256][96], + const bignum256modm s) { + signed char b[64] = {0}; + uint32_t i = 0; + ge25519_niels t = {0}; + + contract256_window4_modm(b, s); + + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); + curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); + curve25519_add_reduce(r->y, t.xaddy, t.ysubx); + memzero(r->z, sizeof(bignum25519)); + curve25519_copy(r->t, t.t2d); + r->z[0] = 2; + for(i = 3; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double_partial(r, r); + ge25519_double(r, r); + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); + curve25519_mul(t.t2d, t.t2d, ge25519_ecd); + ge25519_nielsadd2(r, &t); + for(i = 2; i < 64; i += 2) { + ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); + ge25519_nielsadd2(r, &t); + } +} + +int ge25519_check(const ge25519* r) { + /* return (z % q != 0 and + x * y % q == z * t % q and + (y * y - x * x - z * z - ed25519.d * t * t) % q == 0) + */ + + bignum25519 z = {0}, lhs = {0}, rhs = {0}, tmp = {0}, res = {0}; + curve25519_reduce(z, r->z); + + curve25519_mul(lhs, r->x, r->y); + curve25519_mul(rhs, r->z, r->t); + curve25519_sub_reduce(lhs, lhs, rhs); + + curve25519_square(res, r->y); + curve25519_square(tmp, r->x); + curve25519_sub_reduce(res, res, tmp); + curve25519_square(tmp, r->z); + curve25519_sub_reduce(res, res, tmp); + curve25519_square(tmp, r->t); + curve25519_mul(tmp, tmp, ge25519_ecd); + curve25519_sub_reduce(res, res, tmp); + + const int c1 = curve25519_isnonzero(z); + const int c2 = curve25519_isnonzero(lhs); + const int c3 = curve25519_isnonzero(res); + return c1 & (c2 ^ 0x1) & (c3 ^ 0x1); +} + +int ge25519_eq(const ge25519* a, const ge25519* b) { + int eq = 1; + bignum25519 t1 = {0}, t2 = {0}; + + eq &= ge25519_check(a); + eq &= ge25519_check(b); + + curve25519_mul(t1, a->x, b->z); + curve25519_mul(t2, b->x, a->z); + curve25519_sub_reduce(t1, t1, t2); + eq &= curve25519_isnonzero(t1) ^ 1; + + curve25519_mul(t1, a->y, b->z); + curve25519_mul(t2, b->y, a->z); + curve25519_sub_reduce(t1, t1, t2); + eq &= curve25519_isnonzero(t1) ^ 1; + + return eq; +} + +void ge25519_copy(ge25519* dst, const ge25519* src) { + curve25519_copy(dst->x, src->x); + curve25519_copy(dst->y, src->y); + curve25519_copy(dst->z, src->z); + curve25519_copy(dst->t, src->t); +} + +void ge25519_set_base(ge25519* r) { + ge25519_copy(r, &ge25519_basepoint); +} + +void ge25519_mul8(ge25519* r, const ge25519* t) { + ge25519_double_partial(r, t); + ge25519_double_partial(r, r); + ge25519_double(r, r); +} + +void ge25519_neg_partial(ge25519* r) { + curve25519_neg(r->x, r->x); +} + +void ge25519_neg_full(ge25519* r) { + curve25519_neg(r->x, r->x); + curve25519_neg(r->t, r->t); +} + +void ge25519_reduce(ge25519* r, const ge25519* t) { + curve25519_reduce(r->x, t->x); + curve25519_reduce(r->y, t->y); + curve25519_reduce(r->z, t->z); + curve25519_reduce(r->t, t->t); +} + +void ge25519_norm(ge25519* r, const ge25519* t) { + bignum25519 zinv = {0}; + curve25519_recip(zinv, t->z); + curve25519_mul(r->x, t->x, zinv); + curve25519_mul(r->y, t->y, zinv); + curve25519_mul(r->t, r->x, r->y); + curve25519_set(r->z, 1); +} + +void ge25519_add(ge25519* r, const ge25519* p, const ge25519* q, unsigned char signbit) { + ge25519_pniels P_ni = {0}; + ge25519_p1p1 P_11 = {0}; + + ge25519_full_to_pniels(&P_ni, q); + ge25519_pnielsadd_p1p1(&P_11, p, &P_ni, signbit); + ge25519_p1p1_to_full(r, &P_11); +} + +void ge25519_fromfe_frombytes_vartime(ge25519* r, const unsigned char* s) { + bignum25519 u = {0}, v = {0}, w = {0}, x = {0}, y = {0}, z = {0}; + unsigned char sign = 0; + + curve25519_expand_reduce(u, s); + + curve25519_square(v, u); + curve25519_add_reduce(v, v, v); /* 2 * u^2 */ + curve25519_set(w, 1); + curve25519_add_reduce(w, v, w); /* w = 2 * u^2 + 1 */ + + curve25519_square(x, w); /* w^2 */ + curve25519_mul(y, fe_ma2, v); /* -2 * A^2 * u^2 */ + curve25519_add_reduce(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ + + curve25519_divpowm1(r->x, w, x); /* (w / x)^(m + 1) */ + curve25519_square(y, r->x); + curve25519_mul(x, y, x); + curve25519_sub_reduce(y, w, x); + curve25519_copy(z, fe_ma); + + if(curve25519_isnonzero(y)) { + curve25519_add_reduce(y, w, x); + if(curve25519_isnonzero(y)) { + goto negative; + } else { + curve25519_mul(r->x, r->x, fe_fffb1); + } + } else { + curve25519_mul(r->x, r->x, fe_fffb2); + } + curve25519_mul(r->x, r->x, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ + curve25519_mul(z, z, v); /* -2 * A * u^2 */ + sign = 0; + goto setsign; +negative: + curve25519_mul(x, x, fe_sqrtm1); + curve25519_sub_reduce(y, w, x); + if(curve25519_isnonzero(y)) { + assert((curve25519_add_reduce(y, w, x), !curve25519_isnonzero(y))); + curve25519_mul(r->x, r->x, fe_fffb3); + } else { + curve25519_mul(r->x, r->x, fe_fffb4); + } + /* r->x = sqrt(A * (A + 2) * w / x) */ + /* z = -A */ + sign = 1; +setsign: + if(curve25519_isnegative(r->x) != sign) { + assert(curve25519_isnonzero(r->x)); + curve25519_neg(r->x, r->x); + } + curve25519_add_reduce(r->z, z, w); + curve25519_sub_reduce(r->y, z, w); + curve25519_mul(r->x, r->x, r->z); + + // Partial form, saving from T coord computation . + // Later is mul8 discarding T anyway. + // rt = ((rx * ry % q) * inv(rz)) % q + // curve25519_mul(x, r->x, r->y); + // curve25519_recip(z, r->z); + // curve25519_mul(r->t, x, z); + +#if !defined(NDEBUG) + { + bignum25519 check_x = {0}, check_y = {0}, check_iz = {0}, check_v = {0}; + curve25519_recip(check_iz, r->z); + curve25519_mul(check_x, r->x, check_iz); + curve25519_mul(check_y, r->y, check_iz); + curve25519_square(check_x, check_x); + curve25519_square(check_y, check_y); + curve25519_mul(check_v, check_x, check_y); + curve25519_mul(check_v, fe_d, check_v); + curve25519_add_reduce(check_v, check_v, check_x); + curve25519_sub_reduce(check_v, check_v, check_y); + curve25519_set(check_x, 1); + curve25519_add_reduce(check_v, check_v, check_x); + assert(!curve25519_isnonzero(check_v)); + } +#endif +} + +int ge25519_unpack_vartime(ge25519* r, const unsigned char* s) { + int res = ge25519_unpack_negative_vartime(r, s); + ge25519_neg_full(r); + return res; +} + +void ge25519_scalarmult_base_wrapper(ge25519* r, const bignum256modm s) { + ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s); +} diff --git a/crypto/ed25519_donna/ed25519_donna_impl_base.h b/crypto/ed25519_donna/ed25519_donna_impl_base.h new file mode 100644 index 00000000000..8e690ef8018 --- /dev/null +++ b/crypto/ed25519_donna/ed25519_donna_impl_base.h @@ -0,0 +1,127 @@ +/* + Timing safe memory compare +*/ +int ed25519_verify(const unsigned char* x, const unsigned char* y, size_t len); + +/* + conversions +*/ + +void ge25519_p1p1_to_partial(ge25519* r, const ge25519_p1p1* p); + +void ge25519_p1p1_to_full(ge25519* r, const ge25519_p1p1* p); + +void ge25519_full_to_pniels(ge25519_pniels* p, const ge25519* r); + +/* + adding & doubling +*/ + +void ge25519_double_p1p1(ge25519_p1p1* r, const ge25519* p); + +#ifndef ED25519_NO_PRECOMP +void ge25519_nielsadd2_p1p1( + ge25519_p1p1* r, + const ge25519* p, + const ge25519_niels* q, + unsigned char signbit); +#endif + +/* computes [s1]p1 + [s2]p2 */ +//#if USE_MONERO +void ge25519_double_scalarmult_vartime2( + ge25519* r, + const ge25519* p1, + const bignum256modm s1, + const ge25519* p2, + const bignum256modm s2); +//#endif + +void ge25519_pnielsadd_p1p1( + ge25519_p1p1* r, + const ge25519* p, + const ge25519_pniels* q, + unsigned char signbit); + +void ge25519_double_partial(ge25519* r, const ge25519* p); + +void ge25519_double(ge25519* r, const ge25519* p); + +void ge25519_nielsadd2(ge25519* r, const ge25519_niels* q); + +void ge25519_pnielsadd(ge25519_pniels* r, const ge25519* p, const ge25519_pniels* q); + +/* + pack & unpack +*/ + +void ge25519_pack(unsigned char r[32], const ge25519* p); + +int ge25519_unpack_negative_vartime(ge25519* r, const unsigned char p[32]); + +/* + scalarmults +*/ + +void ge25519_set_neutral(ge25519* r); + +/* computes [s1]p1 + [s2]base */ +void ge25519_double_scalarmult_vartime( + ge25519* r, + const ge25519* p1, + const bignum256modm s1, + const bignum256modm s2); + +/* computes [s1]p1, constant time */ +void ge25519_scalarmult(ge25519* r, const ge25519* p1, const bignum256modm s1); + +void ge25519_scalarmult_base_choose_niels( + ge25519_niels* t, + const uint8_t table[256][96], + uint32_t pos, + signed char b); + +/* computes [s]basepoint */ +void ge25519_scalarmult_base_niels( + ge25519* r, + const uint8_t basepoint_table[256][96], + const bignum256modm s); + +/* check if r is on curve */ +int ge25519_check(const ge25519* r); + +/* a == b */ +int ge25519_eq(const ge25519* a, const ge25519* b); + +/* copies one point to another */ +void ge25519_copy(ge25519* dst, const ge25519* src); + +/* sets B point to r */ +void ge25519_set_base(ge25519* r); + +/* 8*P */ +void ge25519_mul8(ge25519* r, const ge25519* t); + +/* -P */ +void ge25519_neg_partial(ge25519* r); + +/* -P */ +void ge25519_neg_full(ge25519* r); + +/* reduce all coords */ +void ge25519_reduce(ge25519* r, const ge25519* t); + +/* normalizes coords. (x, y, 1, x*y) */ +void ge25519_norm(ge25519* r, const ge25519* t); + +/* Simple addition */ +void ge25519_add(ge25519* r, const ge25519* a, const ge25519* b, unsigned char signbit); + +/* point from bytes, used in H_p() */ +void ge25519_fromfe_frombytes_vartime(ge25519* r, const unsigned char* s); + +/* point from bytes */ +int ge25519_unpack_vartime(ge25519* r, const unsigned char* s); + +/* aG, wrapper for niels base mult. */ +void ge25519_scalarmult_base_wrapper(ge25519* r, const bignum256modm s); diff --git a/crypto/ed25519_donna/ed25519_donna_portable.h b/crypto/ed25519_donna/ed25519_donna_portable.h new file mode 100644 index 00000000000..d344c9e2aeb --- /dev/null +++ b/crypto/ed25519_donna/ed25519_donna_portable.h @@ -0,0 +1,22 @@ +#define mul32x32_64(a, b) (((uint64_t)(a)) * (b)) + +#include +#include +#include + +#define DONNA_INLINE +#undef ALIGN +#define ALIGN(x) __attribute__((aligned(x))) + +static inline void U32TO8_LE(unsigned char* p, const uint32_t v) { + p[0] = (unsigned char)(v); + p[1] = (unsigned char)(v >> 8); + p[2] = (unsigned char)(v >> 16); + p[3] = (unsigned char)(v >> 24); +} + +static inline uint32_t U8TO32_LE(const unsigned char* p) { + return ( + ((uint32_t)(p[0])) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16) | + ((uint32_t)(p[3]) << 24)); +} diff --git a/crypto/ed25519-donna/ed25519-hash-custom.h b/crypto/ed25519_donna/ed25519_hash_custom.h similarity index 100% rename from crypto/ed25519-donna/ed25519-hash-custom.h rename to crypto/ed25519_donna/ed25519_hash_custom.h diff --git a/crypto/ed25519-donna/ed25519-hash-custom-keccak.h b/crypto/ed25519_donna/ed25519_hash_custom_keccak.h similarity index 100% rename from crypto/ed25519-donna/ed25519-hash-custom-keccak.h rename to crypto/ed25519_donna/ed25519_hash_custom_keccak.h diff --git a/crypto/ed25519-donna/ed25519-hash-custom-sha3.h b/crypto/ed25519_donna/ed25519_hash_custom_sha3.h similarity index 100% rename from crypto/ed25519-donna/ed25519-hash-custom-sha3.h rename to crypto/ed25519_donna/ed25519_hash_custom_sha3.h diff --git a/crypto/ed25519-donna/ed25519-keccak.c b/crypto/ed25519_donna/ed25519_keccak.c similarity index 66% rename from crypto/ed25519-donna/ed25519-keccak.c rename to crypto/ed25519_donna/ed25519_keccak.c index fb3fd72f6d0..7b33b6bfe53 100644 --- a/crypto/ed25519-donna/ed25519-keccak.c +++ b/crypto/ed25519_donna/ed25519_keccak.c @@ -4,8 +4,8 @@ #include -#include "ed25519-keccak.h" -#include "ed25519-hash-custom-keccak.h" +#include "ed25519_keccak.h" +#include "ed25519_hash_custom_keccak.h" #define ED25519_SUFFIX _keccak diff --git a/crypto/ed25519_donna/ed25519_keccak.h b/crypto/ed25519_donna/ed25519_keccak.h new file mode 100644 index 00000000000..4c315a75ea1 --- /dev/null +++ b/crypto/ed25519_donna/ed25519_keccak.h @@ -0,0 +1,38 @@ +#include "../options.h" + +#if USE_KECCAK + +#ifndef ED25519_KECCAK_H +#define ED25519_KECCAK_H + +#include "ed25519.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void ed25519_publickey_keccak(const ed25519_secret_key sk, ed25519_public_key pk); + +int ed25519_sign_open_keccak( + const unsigned char* m, + size_t mlen, + const ed25519_public_key pk, + const ed25519_signature RS); +void ed25519_sign_keccak( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + ed25519_signature RS); + +int ed25519_scalarmult_keccak( + ed25519_public_key res, + const ed25519_secret_key sk, + const ed25519_public_key pk); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_KECCAK_H + +#endif // USE_KECCAK \ No newline at end of file diff --git a/crypto/ed25519-donna/ed25519-sha3.c b/crypto/ed25519_donna/ed25519_sha3.c similarity index 53% rename from crypto/ed25519-donna/ed25519-sha3.c rename to crypto/ed25519_donna/ed25519_sha3.c index 6a7687d0d1a..e172ef874e5 100644 --- a/crypto/ed25519-donna/ed25519-sha3.c +++ b/crypto/ed25519_donna/ed25519_sha3.c @@ -1,7 +1,7 @@ #include -#include "ed25519-sha3.h" -#include "ed25519-hash-custom-sha3.h" +#include "ed25519_sha3.h" +#include "ed25519_hash_custom_sha3.h" #define ED25519_SUFFIX _sha3 diff --git a/crypto/ed25519_donna/ed25519_sha3.h b/crypto/ed25519_donna/ed25519_sha3.h new file mode 100644 index 00000000000..1085c1b20df --- /dev/null +++ b/crypto/ed25519_donna/ed25519_sha3.h @@ -0,0 +1,32 @@ +#ifndef ED25519_SHA3_H +#define ED25519_SHA3_H + +#include "ed25519.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +void ed25519_publickey_sha3(const ed25519_secret_key sk, ed25519_public_key pk); + +int ed25519_sign_open_sha3( + const unsigned char* m, + size_t mlen, + const ed25519_public_key pk, + const ed25519_signature RS); +void ed25519_sign_sha3( + const unsigned char* m, + size_t mlen, + const ed25519_secret_key sk, + ed25519_signature RS); + +int ed25519_scalarmult_sha3( + ed25519_public_key res, + const ed25519_secret_key sk, + const ed25519_public_key pk); + +#if defined(__cplusplus) +} +#endif + +#endif // ED25519_SHA3_H diff --git a/crypto/ed25519_donna/modm_donna_32bit.c b/crypto/ed25519_donna/modm_donna_32bit.c new file mode 100644 index 00000000000..6489ea20c72 --- /dev/null +++ b/crypto/ed25519_donna/modm_donna_32bit.c @@ -0,0 +1,800 @@ +/* + Public domain by Andrew M. +*/ + +#include "ed25519_donna.h" + +/* + Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 + + k = 32 + b = 1 << 8 = 256 + m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed + mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b +*/ + +static const bignum256modm modm_m = { + 0x1cf5d3ed, + 0x20498c69, + 0x2f79cd65, + 0x37be77a8, + 0x00000014, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00001000}; + +static const bignum256modm modm_mu = { + 0x0a2c131b, + 0x3673968c, + 0x06329a7e, + 0x01885742, + 0x3fffeb21, + 0x3fffffff, + 0x3fffffff, + 0x3fffffff, + 0x000fffff}; + +static bignum256modm_element_t lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { + return (a - b) >> 31; +} + +/* see HAC, Alg. 14.42 Step 4 */ +void reduce256_modm(bignum256modm r) { + bignum256modm t = {0}; + bignum256modm_element_t b = 0, pb = 0, mask = 0; + + /* t = r - m */ + pb = 0; + pb += modm_m[0]; + b = lt_modm(r[0], pb); + t[0] = (r[0] - pb + (b << 30)); + pb = b; + pb += modm_m[1]; + b = lt_modm(r[1], pb); + t[1] = (r[1] - pb + (b << 30)); + pb = b; + pb += modm_m[2]; + b = lt_modm(r[2], pb); + t[2] = (r[2] - pb + (b << 30)); + pb = b; + pb += modm_m[3]; + b = lt_modm(r[3], pb); + t[3] = (r[3] - pb + (b << 30)); + pb = b; + pb += modm_m[4]; + b = lt_modm(r[4], pb); + t[4] = (r[4] - pb + (b << 30)); + pb = b; + pb += modm_m[5]; + b = lt_modm(r[5], pb); + t[5] = (r[5] - pb + (b << 30)); + pb = b; + pb += modm_m[6]; + b = lt_modm(r[6], pb); + t[6] = (r[6] - pb + (b << 30)); + pb = b; + pb += modm_m[7]; + b = lt_modm(r[7], pb); + t[7] = (r[7] - pb + (b << 30)); + pb = b; + pb += modm_m[8]; + b = lt_modm(r[8], pb); + t[8] = (r[8] - pb + (b << 16)); + + /* keep r if r was smaller than m */ + mask = b - 1; + r[0] ^= mask & (r[0] ^ t[0]); + r[1] ^= mask & (r[1] ^ t[1]); + r[2] ^= mask & (r[2] ^ t[2]); + r[3] ^= mask & (r[3] ^ t[3]); + r[4] ^= mask & (r[4] ^ t[4]); + r[5] ^= mask & (r[5] ^ t[5]); + r[6] ^= mask & (r[6] ^ t[6]); + r[7] ^= mask & (r[7] ^ t[7]); + r[8] ^= mask & (r[8] ^ t[8]); +} + +/* + Barrett reduction, see HAC, Alg. 14.42 + + Instead of passing in x, pre-process in to q1 and r1 for efficiency +*/ +void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { + bignum256modm q3 = {0}, r2 = {0}; + uint64_t c = 0; + bignum256modm_element_t f = 0, b = 0, pb = 0; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements + q2 = mu * q1 + q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ + c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); + c >>= 30; + c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + + mul32x32_64(modm_mu[8], q1[0]); + f = (bignum256modm_element_t)c; + q3[0] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); + f = (bignum256modm_element_t)c; + q3[0] |= (f << 6) & 0x3fffffff; + q3[1] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + + mul32x32_64(modm_mu[8], q1[2]); + f = (bignum256modm_element_t)c; + q3[1] |= (f << 6) & 0x3fffffff; + q3[2] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); + f = (bignum256modm_element_t)c; + q3[2] |= (f << 6) & 0x3fffffff; + q3[3] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + + mul32x32_64(modm_mu[8], q1[4]); + f = (bignum256modm_element_t)c; + q3[3] |= (f << 6) & 0x3fffffff; + q3[4] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); + f = (bignum256modm_element_t)c; + q3[4] |= (f << 6) & 0x3fffffff; + q3[5] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + + mul32x32_64(modm_mu[8], q1[6]); + f = (bignum256modm_element_t)c; + q3[5] |= (f << 6) & 0x3fffffff; + q3[6] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); + f = (bignum256modm_element_t)c; + q3[6] |= (f << 6) & 0x3fffffff; + q3[7] = (f >> 24) & 0x3f; + c >>= 30; + c += mul32x32_64(modm_mu[8], q1[8]); + f = (bignum256modm_element_t)c; + q3[7] |= (f << 6) & 0x3fffffff; + q3[8] = (bignum256modm_element_t)(c >> 24); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(32+1) = x & ((1 << 264) - 1) + r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */ + c = mul32x32_64(modm_m[0], q3[0]); + r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); + r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + + mul32x32_64(modm_m[2], q3[0]); + r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); + r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + + mul32x32_64(modm_m[4], q3[0]); + r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); + r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + + mul32x32_64(modm_m[6], q3[0]); + r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); + r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); + c >>= 30; + c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + + mul32x32_64(modm_m[8], q3[0]); + r2[8] = (bignum256modm_element_t)(c & 0xffffff); + + /* r = r1 - r2 + if (r < 0) r += (1 << 264) */ + pb = 0; + pb += r2[0]; + b = lt_modm(r1[0], pb); + r[0] = (r1[0] - pb + (b << 30)); + pb = b; + pb += r2[1]; + b = lt_modm(r1[1], pb); + r[1] = (r1[1] - pb + (b << 30)); + pb = b; + pb += r2[2]; + b = lt_modm(r1[2], pb); + r[2] = (r1[2] - pb + (b << 30)); + pb = b; + pb += r2[3]; + b = lt_modm(r1[3], pb); + r[3] = (r1[3] - pb + (b << 30)); + pb = b; + pb += r2[4]; + b = lt_modm(r1[4], pb); + r[4] = (r1[4] - pb + (b << 30)); + pb = b; + pb += r2[5]; + b = lt_modm(r1[5], pb); + r[5] = (r1[5] - pb + (b << 30)); + pb = b; + pb += r2[6]; + b = lt_modm(r1[6], pb); + r[6] = (r1[6] - pb + (b << 30)); + pb = b; + pb += r2[7]; + b = lt_modm(r1[7], pb); + r[7] = (r1[7] - pb + (b << 30)); + pb = b; + pb += r2[8]; + b = lt_modm(r1[8], pb); + r[8] = (r1[8] - pb + (b << 24)); + + reduce256_modm(r); + reduce256_modm(r); +} + +/* addition modulo m */ +void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm_element_t c = 0; + + c = x[0] + y[0]; + r[0] = c & 0x3fffffff; + c >>= 30; + c += x[1] + y[1]; + r[1] = c & 0x3fffffff; + c >>= 30; + c += x[2] + y[2]; + r[2] = c & 0x3fffffff; + c >>= 30; + c += x[3] + y[3]; + r[3] = c & 0x3fffffff; + c >>= 30; + c += x[4] + y[4]; + r[4] = c & 0x3fffffff; + c >>= 30; + c += x[5] + y[5]; + r[5] = c & 0x3fffffff; + c >>= 30; + c += x[6] + y[6]; + r[6] = c & 0x3fffffff; + c >>= 30; + c += x[7] + y[7]; + r[7] = c & 0x3fffffff; + c >>= 30; + c += x[8] + y[8]; + r[8] = c; + + reduce256_modm(r); +} + +/* -x modulo m */ +void neg256_modm(bignum256modm r, const bignum256modm x) { + bignum256modm_element_t b = 0, pb = 0; + + /* r = m - x */ + pb = 0; + pb += x[0]; + b = lt_modm(modm_m[0], pb); + r[0] = (modm_m[0] - pb + (b << 30)); + pb = b; + pb += x[1]; + b = lt_modm(modm_m[1], pb); + r[1] = (modm_m[1] - pb + (b << 30)); + pb = b; + pb += x[2]; + b = lt_modm(modm_m[2], pb); + r[2] = (modm_m[2] - pb + (b << 30)); + pb = b; + pb += x[3]; + b = lt_modm(modm_m[3], pb); + r[3] = (modm_m[3] - pb + (b << 30)); + pb = b; + pb += x[4]; + b = lt_modm(modm_m[4], pb); + r[4] = (modm_m[4] - pb + (b << 30)); + pb = b; + pb += x[5]; + b = lt_modm(modm_m[5], pb); + r[5] = (modm_m[5] - pb + (b << 30)); + pb = b; + pb += x[6]; + b = lt_modm(modm_m[6], pb); + r[6] = (modm_m[6] - pb + (b << 30)); + pb = b; + pb += x[7]; + b = lt_modm(modm_m[7], pb); + r[7] = (modm_m[7] - pb + (b << 30)); + pb = b; + pb += x[8]; + b = lt_modm(modm_m[8], pb); + r[8] = (modm_m[8] - pb + (b << 16)); + + // if x==0, reduction is required + reduce256_modm(r); +} + +/* consts for subtraction, > p */ +/* Emilia Kasper trick, https://www.imperialviolet.org/2010/12/04/ecc.html */ +static const uint32_t twoP[] = { + 0x5cf5d3ed, + 0x60498c68, + 0x6f79cd64, + 0x77be77a7, + 0x40000013, + 0x3fffffff, + 0x3fffffff, + 0x3fffffff, + 0xfff}; + +/* subtraction x-y % m */ +void sub256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm_element_t c = 0; + c = twoP[0] + x[0] - y[0]; + r[0] = c & 0x3fffffff; + c >>= 30; + c += twoP[1] + x[1] - y[1]; + r[1] = c & 0x3fffffff; + c >>= 30; + c += twoP[2] + x[2] - y[2]; + r[2] = c & 0x3fffffff; + c >>= 30; + c += twoP[3] + x[3] - y[3]; + r[3] = c & 0x3fffffff; + c >>= 30; + c += twoP[4] + x[4] - y[4]; + r[4] = c & 0x3fffffff; + c >>= 30; + c += twoP[5] + x[5] - y[5]; + r[5] = c & 0x3fffffff; + c >>= 30; + c += twoP[6] + x[6] - y[6]; + r[6] = c & 0x3fffffff; + c >>= 30; + c += twoP[7] + x[7] - y[7]; + r[7] = c & 0x3fffffff; + c >>= 30; + c += twoP[8] + x[8] - y[8]; + r[8] = c; + reduce256_modm(r); +} + +/* multiplication modulo m */ +void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { + bignum256modm r1 = {0}, q1 = {0}; + uint64_t c = 0; + bignum256modm_element_t f = 0; + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) + q1 = x >> 248 = 264 bits = 9 30 bit elements */ + c = mul32x32_64(x[0], y[0]); + f = (bignum256modm_element_t)c; + r1[0] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); + f = (bignum256modm_element_t)c; + r1[1] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); + f = (bignum256modm_element_t)c; + r1[2] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + + mul32x32_64(x[3], y[0]); + f = (bignum256modm_element_t)c; + r1[3] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); + f = (bignum256modm_element_t)c; + r1[4] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); + f = (bignum256modm_element_t)c; + r1[5] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + + mul32x32_64(x[6], y[0]); + f = (bignum256modm_element_t)c; + r1[6] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); + f = (bignum256modm_element_t)c; + r1[7] = (f & 0x3fffffff); + c >>= 30; + c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); + f = (bignum256modm_element_t)c; + r1[8] = (f & 0x00ffffff); + q1[0] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); + f = (bignum256modm_element_t)c; + q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; + q1[1] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + + mul32x32_64(x[8], y[2]); + f = (bignum256modm_element_t)c; + q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; + q1[2] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); + f = (bignum256modm_element_t)c; + q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; + q1[3] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); + f = (bignum256modm_element_t)c; + q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; + q1[4] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + + mul32x32_64(x[8], y[5]); + f = (bignum256modm_element_t)c; + q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; + q1[5] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); + f = (bignum256modm_element_t)c; + q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; + q1[6] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); + f = (bignum256modm_element_t)c; + q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; + q1[7] = (f >> 8) & 0x3fffff; + c >>= 30; + c += mul32x32_64(x[8], y[8]); + f = (bignum256modm_element_t)c; + q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; + q1[8] = (f >> 8) & 0x3fffff; + + barrett_reduce256_modm(r, q1, r1); +} + +void expand256_modm(bignum256modm out, const unsigned char* in, size_t len) { + unsigned char work[64] = {0}; + bignum256modm_element_t x[16] = {0}; + bignum256modm q1 = {0}; + + memcpy(work, in, len); + x[0] = U8TO32_LE(work + 0); + x[1] = U8TO32_LE(work + 4); + x[2] = U8TO32_LE(work + 8); + x[3] = U8TO32_LE(work + 12); + x[4] = U8TO32_LE(work + 16); + x[5] = U8TO32_LE(work + 20); + x[6] = U8TO32_LE(work + 24); + x[7] = U8TO32_LE(work + 28); + x[8] = U8TO32_LE(work + 32); + x[9] = U8TO32_LE(work + 36); + x[10] = U8TO32_LE(work + 40); + x[11] = U8TO32_LE(work + 44); + x[12] = U8TO32_LE(work + 48); + x[13] = U8TO32_LE(work + 52); + x[14] = U8TO32_LE(work + 56); + x[15] = U8TO32_LE(work + 60); + + /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ + out[0] = (x[0]) & 0x3fffffff; + out[1] = ((x[0] >> 30) | (x[1] << 2)) & 0x3fffffff; + out[2] = ((x[1] >> 28) | (x[2] << 4)) & 0x3fffffff; + out[3] = ((x[2] >> 26) | (x[3] << 6)) & 0x3fffffff; + out[4] = ((x[3] >> 24) | (x[4] << 8)) & 0x3fffffff; + out[5] = ((x[4] >> 22) | (x[5] << 10)) & 0x3fffffff; + out[6] = ((x[5] >> 20) | (x[6] << 12)) & 0x3fffffff; + out[7] = ((x[6] >> 18) | (x[7] << 14)) & 0x3fffffff; + out[8] = ((x[7] >> 16) | (x[8] << 16)) & 0x00ffffff; + + /* 8*31 = 248 bits, no need to reduce */ + if(len < 32) return; + + /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ + q1[0] = ((x[7] >> 24) | (x[8] << 8)) & 0x3fffffff; + q1[1] = ((x[8] >> 22) | (x[9] << 10)) & 0x3fffffff; + q1[2] = ((x[9] >> 20) | (x[10] << 12)) & 0x3fffffff; + q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; + q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; + q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; + q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; + q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; + q1[8] = ((x[15] >> 8)); + + barrett_reduce256_modm(out, q1, out); +} + +void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { + bignum256modm_element_t x[8] = {0}; + + x[0] = U8TO32_LE(in + 0); + x[1] = U8TO32_LE(in + 4); + x[2] = U8TO32_LE(in + 8); + x[3] = U8TO32_LE(in + 12); + x[4] = U8TO32_LE(in + 16); + x[5] = U8TO32_LE(in + 20); + x[6] = U8TO32_LE(in + 24); + x[7] = U8TO32_LE(in + 28); + + out[0] = (x[0]) & 0x3fffffff; + out[1] = ((x[0] >> 30) | (x[1] << 2)) & 0x3fffffff; + out[2] = ((x[1] >> 28) | (x[2] << 4)) & 0x3fffffff; + out[3] = ((x[2] >> 26) | (x[3] << 6)) & 0x3fffffff; + out[4] = ((x[3] >> 24) | (x[4] << 8)) & 0x3fffffff; + out[5] = ((x[4] >> 22) | (x[5] << 10)) & 0x3fffffff; + out[6] = ((x[5] >> 20) | (x[6] << 12)) & 0x3fffffff; + out[7] = ((x[6] >> 18) | (x[7] << 14)) & 0x3fffffff; + out[8] = ((x[7] >> 16)) & 0x0000ffff; +} + +int is_reduced256_modm(const bignum256modm in) { + int i = 0; + uint32_t res1 = 0; + uint32_t res2 = 0; + for(i = 8; i >= 0; i--) { + res1 = (res1 << 1) | (in[i] < modm_m[i]); + res2 = (res2 << 1) | (in[i] > modm_m[i]); + } + return res1 > res2; +} + +void contract256_modm(unsigned char out[32], const bignum256modm in) { + U32TO8_LE(out + 0, (in[0]) | (in[1] << 30)); + U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); + U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); + U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); + U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); + U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); + U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); + U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); +} + +void contract256_window4_modm(signed char r[64], const bignum256modm in) { + char carry = 0; + signed char* quads = r; + bignum256modm_element_t i = 0, j = 0, v = 0; + + for(i = 0; i < 8; i += 2) { + v = in[i]; + for(j = 0; j < 7; j++) { + *quads++ = (v & 15); + v >>= 4; + } + v |= (in[i + 1] << 2); + for(j = 0; j < 8; j++) { + *quads++ = (v & 15); + v >>= 4; + } + } + v = in[8]; + *quads++ = (v & 15); + v >>= 4; + *quads++ = (v & 15); + v >>= 4; + *quads++ = (v & 15); + v >>= 4; + *quads++ = (v & 15); + v >>= 4; + + /* making it signed */ + carry = 0; + for(i = 0; i < 63; i++) { + r[i] += carry; + r[i + 1] += (r[i] >> 4); + r[i] &= 15; + carry = (r[i] >> 3); + r[i] -= (carry << 4); + } + r[63] += carry; +} + +void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { + int i = 0, j = 0, k = 0, b = 0; + int m = (1 << (windowsize - 1)) - 1, soplen = 256; + signed char* bits = r; + bignum256modm_element_t v = 0; + + /* first put the binary expansion into r */ + for(i = 0; i < 8; i++) { + v = s[i]; + for(j = 0; j < 30; j++, v >>= 1) *bits++ = (v & 1); + } + v = s[8]; + for(j = 0; j < 16; j++, v >>= 1) *bits++ = (v & 1); + + /* Making it sliding window */ + for(j = 0; j < soplen; j++) { + if(!r[j]) continue; + + for(b = 1; (b < (soplen - j)) && (b <= 6); b++) { + if((r[j] + (r[j + b] << b)) <= m) { + r[j] += r[j + b] << b; + r[j + b] = 0; + } else if((r[j] - (r[j + b] << b)) >= -m) { + r[j] -= r[j + b] << b; + for(k = j + b; k < soplen; k++) { + if(!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else if(r[j + b]) { + break; + } + } + } +} + +void set256_modm(bignum256modm r, uint64_t v) { + r[0] = (bignum256modm_element_t)(v & 0x3fffffff); + v >>= 30; + r[1] = (bignum256modm_element_t)(v & 0x3fffffff); + v >>= 30; + r[2] = (bignum256modm_element_t)(v & 0x3fffffff); + r[3] = 0; + r[4] = 0; + r[5] = 0; + r[6] = 0; + r[7] = 0; + r[8] = 0; +} + +int get256_modm(uint64_t* v, const bignum256modm r) { + *v = 0; + int con1 = 0; + +#define NONZ(x) ((((((int64_t)(x)) - 1) >> 32) + 1) & 1) + bignum256modm_element_t c = 0; + c = r[0]; + *v += (uint64_t)c & 0x3fffffff; + c >>= 30; // 30 + c += r[1]; + *v += ((uint64_t)c & 0x3fffffff) << 30; + c >>= 30; // 60 + c += r[2]; + *v += ((uint64_t)c & 0xf) << 60; + con1 |= NONZ(c >> 4); + c >>= 30; // 64 bits + c += r[3]; + con1 |= NONZ(c); + c >>= 30; + c += r[4]; + con1 |= NONZ(c); + c >>= 30; + c += r[5]; + con1 |= NONZ(c); + c >>= 30; + c += r[6]; + con1 |= NONZ(c); + c >>= 30; + c += r[7]; + con1 |= NONZ(c); + c >>= 30; + c += r[8]; + con1 |= NONZ(c); + c >>= 30; + con1 |= NONZ(c); +#undef NONZ + + return con1 ^ 1; +} + +int eq256_modm(const bignum256modm x, const bignum256modm y) { + size_t differentbits = 0; + int len = bignum256modm_limb_size; + while(len--) { + differentbits |= (*x++ ^ *y++); + } + return (int)(1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); +} + +int cmp256_modm(const bignum256modm x, const bignum256modm y) { + int len = 2 * bignum256modm_limb_size; + uint32_t a_gt = 0; + uint32_t b_gt = 0; + + // 16B chunks + while(len--) { + const uint32_t ln = (const uint32_t)len; + const uint32_t a = (x[ln >> 1] >> 16 * (ln & 1)) & 0xffff; + const uint32_t b = (y[ln >> 1] >> 16 * (ln & 1)) & 0xffff; + + const uint32_t limb_a_gt = ((b - a) >> 16) & 1; + const uint32_t limb_b_gt = ((a - b) >> 16) & 1; + a_gt |= limb_a_gt & ~b_gt; + b_gt |= limb_b_gt & ~a_gt; + } + + return a_gt - b_gt; +} + +int iszero256_modm(const bignum256modm x) { + size_t differentbits = 0; + int len = bignum256modm_limb_size; + while(len--) { + differentbits |= (*x++); + } + return (int)(1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); +} + +void copy256_modm(bignum256modm r, const bignum256modm x) { + r[0] = x[0]; + r[1] = x[1]; + r[2] = x[2]; + r[3] = x[3]; + r[4] = x[4]; + r[5] = x[5]; + r[6] = x[6]; + r[7] = x[7]; + r[8] = x[8]; +} + +int check256_modm(const bignum256modm x) { + int ok = 1; + bignum256modm t = {0}, z = {0}; + + ok &= iszero256_modm(x) ^ 1; + barrett_reduce256_modm(t, z, x); + ok &= eq256_modm(t, x); + return ok; +} + +void mulsub256_modm( + bignum256modm r, + const bignum256modm a, + const bignum256modm b, + const bignum256modm c) { + //(cc - aa * bb) % l + bignum256modm t = {0}; + mul256_modm(t, a, b); + sub256_modm(r, c, t); +} + +void muladd256_modm( + bignum256modm r, + const bignum256modm a, + const bignum256modm b, + const bignum256modm c) { + //(cc + aa * bb) % l + bignum256modm t = {0}; + mul256_modm(t, a, b); + add256_modm(r, c, t); +} diff --git a/crypto/ed25519-donna/modm-donna-32bit.h b/crypto/ed25519_donna/modm_donna_32bit.h similarity index 86% rename from crypto/ed25519-donna/modm-donna-32bit.h rename to crypto/ed25519_donna/modm_donna_32bit.h index 98090f2fee8..021edc19eb7 100644 --- a/crypto/ed25519-donna/modm-donna-32bit.h +++ b/crypto/ed25519_donna/modm_donna_32bit.h @@ -2,7 +2,6 @@ Public domain by Andrew M. */ - /* Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 @@ -40,7 +39,7 @@ void sub256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y); /* multiplication modulo m */ void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y); -void expand256_modm(bignum256modm out, const unsigned char *in, size_t len); +void expand256_modm(bignum256modm out, const unsigned char* in, size_t len); void expand_raw256_modm(bignum256modm out, const unsigned char in[32]); @@ -56,7 +55,7 @@ void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, i void set256_modm(bignum256modm r, uint64_t v); /* scalar value to 64bit uint */ -int get256_modm(uint64_t * v, const bignum256modm r); +int get256_modm(uint64_t* v, const bignum256modm r); /* equality test on two reduced scalar values */ int eq256_modm(const bignum256modm x, const bignum256modm y); @@ -74,7 +73,15 @@ void copy256_modm(bignum256modm r, const bignum256modm x); int check256_modm(const bignum256modm x); /* (cc - aa * bb) % l */ -void mulsub256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c); +void mulsub256_modm( + bignum256modm r, + const bignum256modm a, + const bignum256modm b, + const bignum256modm c); /* (cc + aa * bb) % l */ -void muladd256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c); +void muladd256_modm( + bignum256modm r, + const bignum256modm a, + const bignum256modm b, + const bignum256modm c); diff --git a/crypto/groestl.c b/crypto/groestl.c index d913c76e05f..a77da80f4b0 100644 --- a/crypto/groestl.c +++ b/crypto/groestl.c @@ -38,750 +38,718 @@ #include "groestl.h" #include "memzero.h" - -#define C32e(x) ((SPH_C32(x) >> 24) \ - | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ - | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ - | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) -#define dec32e_aligned sph_dec32le_aligned -#define enc32e sph_enc32le -#define B32_0(x) ((x) & 0xFF) -#define B32_1(x) (((x) >> 8) & 0xFF) -#define B32_2(x) (((x) >> 16) & 0xFF) -#define B32_3(x) ((x) >> 24) - -#define R32u(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) -#define R32d(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) - -#define PC32up(j, r) ((sph_u32)((j) + (r))) -#define PC32dn(j, r) 0 -#define QC32up(j, r) SPH_C32(0xFFFFFFFF) -#define QC32dn(j, r) (((sph_u32)(r) << 24) ^ SPH_T32(~((sph_u32)(j) << 24))) - -#define C64e(x) ((SPH_C64(x) >> 56) \ - | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ - | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ - | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ - | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ - | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ - | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ - | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) -#define dec64e_aligned sph_dec64le_aligned -#define enc64e sph_enc64le -#define B64_0(x) ((x) & 0xFF) -#define B64_1(x) (((x) >> 8) & 0xFF) -#define B64_2(x) (((x) >> 16) & 0xFF) -#define B64_3(x) (((x) >> 24) & 0xFF) -#define B64_4(x) (((x) >> 32) & 0xFF) -#define B64_5(x) (((x) >> 40) & 0xFF) -#define B64_6(x) (((x) >> 48) & 0xFF) -#define B64_7(x) ((x) >> 56) -#define R64 SPH_ROTL64 -#define PC64(j, r) ((sph_u64)((j) + (r))) -#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) - +#define C32e(x) \ + ((SPH_C32(x) >> 24) | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) | \ + ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) +#define dec32e_aligned sph_dec32le_aligned +#define enc32e sph_enc32le +#define B32_0(x) ((x)&0xFF) +#define B32_1(x) (((x) >> 8) & 0xFF) +#define B32_2(x) (((x) >> 16) & 0xFF) +#define B32_3(x) ((x) >> 24) + +#define R32u(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) +#define R32d(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) + +#define PC32up(j, r) ((sph_u32)((j) + (r))) +#define PC32dn(j, r) 0 +#define QC32up(j, r) SPH_C32(0xFFFFFFFF) +#define QC32dn(j, r) (((sph_u32)(r) << 24) ^ SPH_T32(~((sph_u32)(j) << 24))) + +#define C64e(x) \ + ((SPH_C64(x) >> 56) | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) | \ + ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) | \ + ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) | \ + ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) | \ + ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) | \ + ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) | \ + ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le +#define B64_0(x) ((x)&0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define R64 SPH_ROTL64 +#define PC64(j, r) ((sph_u64)((j) + (r))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) static const sph_u32 T0up[] = { - C32e(0xc632f4a5), C32e(0xf86f9784), C32e(0xee5eb099), C32e(0xf67a8c8d), - C32e(0xffe8170d), C32e(0xd60adcbd), C32e(0xde16c8b1), C32e(0x916dfc54), - C32e(0x6090f050), C32e(0x02070503), C32e(0xce2ee0a9), C32e(0x56d1877d), - C32e(0xe7cc2b19), C32e(0xb513a662), C32e(0x4d7c31e6), C32e(0xec59b59a), - C32e(0x8f40cf45), C32e(0x1fa3bc9d), C32e(0x8949c040), C32e(0xfa689287), - C32e(0xefd03f15), C32e(0xb29426eb), C32e(0x8ece40c9), C32e(0xfbe61d0b), - C32e(0x416e2fec), C32e(0xb31aa967), C32e(0x5f431cfd), C32e(0x456025ea), - C32e(0x23f9dabf), C32e(0x535102f7), C32e(0xe445a196), C32e(0x9b76ed5b), - C32e(0x75285dc2), C32e(0xe1c5241c), C32e(0x3dd4e9ae), C32e(0x4cf2be6a), - C32e(0x6c82ee5a), C32e(0x7ebdc341), C32e(0xf5f30602), C32e(0x8352d14f), - C32e(0x688ce45c), C32e(0x515607f4), C32e(0xd18d5c34), C32e(0xf9e11808), - C32e(0xe24cae93), C32e(0xab3e9573), C32e(0x6297f553), C32e(0x2a6b413f), - C32e(0x081c140c), C32e(0x9563f652), C32e(0x46e9af65), C32e(0x9d7fe25e), - C32e(0x30487828), C32e(0x37cff8a1), C32e(0x0a1b110f), C32e(0x2febc4b5), - C32e(0x0e151b09), C32e(0x247e5a36), C32e(0x1badb69b), C32e(0xdf98473d), - C32e(0xcda76a26), C32e(0x4ef5bb69), C32e(0x7f334ccd), C32e(0xea50ba9f), - C32e(0x123f2d1b), C32e(0x1da4b99e), C32e(0x58c49c74), C32e(0x3446722e), - C32e(0x3641772d), C32e(0xdc11cdb2), C32e(0xb49d29ee), C32e(0x5b4d16fb), - C32e(0xa4a501f6), C32e(0x76a1d74d), C32e(0xb714a361), C32e(0x7d3449ce), - C32e(0x52df8d7b), C32e(0xdd9f423e), C32e(0x5ecd9371), C32e(0x13b1a297), - C32e(0xa6a204f5), C32e(0xb901b868), C32e(0x00000000), C32e(0xc1b5742c), - C32e(0x40e0a060), C32e(0xe3c2211f), C32e(0x793a43c8), C32e(0xb69a2ced), - C32e(0xd40dd9be), C32e(0x8d47ca46), C32e(0x671770d9), C32e(0x72afdd4b), - C32e(0x94ed79de), C32e(0x98ff67d4), C32e(0xb09323e8), C32e(0x855bde4a), - C32e(0xbb06bd6b), C32e(0xc5bb7e2a), C32e(0x4f7b34e5), C32e(0xedd73a16), - C32e(0x86d254c5), C32e(0x9af862d7), C32e(0x6699ff55), C32e(0x11b6a794), - C32e(0x8ac04acf), C32e(0xe9d93010), C32e(0x040e0a06), C32e(0xfe669881), - C32e(0xa0ab0bf0), C32e(0x78b4cc44), C32e(0x25f0d5ba), C32e(0x4b753ee3), - C32e(0xa2ac0ef3), C32e(0x5d4419fe), C32e(0x80db5bc0), C32e(0x0580858a), - C32e(0x3fd3ecad), C32e(0x21fedfbc), C32e(0x70a8d848), C32e(0xf1fd0c04), - C32e(0x63197adf), C32e(0x772f58c1), C32e(0xaf309f75), C32e(0x42e7a563), - C32e(0x20705030), C32e(0xe5cb2e1a), C32e(0xfdef120e), C32e(0xbf08b76d), - C32e(0x8155d44c), C32e(0x18243c14), C32e(0x26795f35), C32e(0xc3b2712f), - C32e(0xbe8638e1), C32e(0x35c8fda2), C32e(0x88c74fcc), C32e(0x2e654b39), - C32e(0x936af957), C32e(0x55580df2), C32e(0xfc619d82), C32e(0x7ab3c947), - C32e(0xc827efac), C32e(0xba8832e7), C32e(0x324f7d2b), C32e(0xe642a495), - C32e(0xc03bfba0), C32e(0x19aab398), C32e(0x9ef668d1), C32e(0xa322817f), - C32e(0x44eeaa66), C32e(0x54d6827e), C32e(0x3bdde6ab), C32e(0x0b959e83), - C32e(0x8cc945ca), C32e(0xc7bc7b29), C32e(0x6b056ed3), C32e(0x286c443c), - C32e(0xa72c8b79), C32e(0xbc813de2), C32e(0x1631271d), C32e(0xad379a76), - C32e(0xdb964d3b), C32e(0x649efa56), C32e(0x74a6d24e), C32e(0x1436221e), - C32e(0x92e476db), C32e(0x0c121e0a), C32e(0x48fcb46c), C32e(0xb88f37e4), - C32e(0x9f78e75d), C32e(0xbd0fb26e), C32e(0x43692aef), C32e(0xc435f1a6), - C32e(0x39dae3a8), C32e(0x31c6f7a4), C32e(0xd38a5937), C32e(0xf274868b), - C32e(0xd5835632), C32e(0x8b4ec543), C32e(0x6e85eb59), C32e(0xda18c2b7), - C32e(0x018e8f8c), C32e(0xb11dac64), C32e(0x9cf16dd2), C32e(0x49723be0), - C32e(0xd81fc7b4), C32e(0xacb915fa), C32e(0xf3fa0907), C32e(0xcfa06f25), - C32e(0xca20eaaf), C32e(0xf47d898e), C32e(0x476720e9), C32e(0x10382818), - C32e(0x6f0b64d5), C32e(0xf0738388), C32e(0x4afbb16f), C32e(0x5cca9672), - C32e(0x38546c24), C32e(0x575f08f1), C32e(0x732152c7), C32e(0x9764f351), - C32e(0xcbae6523), C32e(0xa125847c), C32e(0xe857bf9c), C32e(0x3e5d6321), - C32e(0x96ea7cdd), C32e(0x611e7fdc), C32e(0x0d9c9186), C32e(0x0f9b9485), - C32e(0xe04bab90), C32e(0x7cbac642), C32e(0x712657c4), C32e(0xcc29e5aa), - C32e(0x90e373d8), C32e(0x06090f05), C32e(0xf7f40301), C32e(0x1c2a3612), - C32e(0xc23cfea3), C32e(0x6a8be15f), C32e(0xaebe10f9), C32e(0x69026bd0), - C32e(0x17bfa891), C32e(0x9971e858), C32e(0x3a536927), C32e(0x27f7d0b9), - C32e(0xd9914838), C32e(0xebde3513), C32e(0x2be5ceb3), C32e(0x22775533), - C32e(0xd204d6bb), C32e(0xa9399070), C32e(0x07878089), C32e(0x33c1f2a7), - C32e(0x2decc1b6), C32e(0x3c5a6622), C32e(0x15b8ad92), C32e(0xc9a96020), - C32e(0x875cdb49), C32e(0xaab01aff), C32e(0x50d88878), C32e(0xa52b8e7a), - C32e(0x03898a8f), C32e(0x594a13f8), C32e(0x09929b80), C32e(0x1a233917), - C32e(0x651075da), C32e(0xd7845331), C32e(0x84d551c6), C32e(0xd003d3b8), - C32e(0x82dc5ec3), C32e(0x29e2cbb0), C32e(0x5ac39977), C32e(0x1e2d3311), - C32e(0x7b3d46cb), C32e(0xa8b71ffc), C32e(0x6d0c61d6), C32e(0x2c624e3a) -}; + C32e(0xc632f4a5), C32e(0xf86f9784), C32e(0xee5eb099), C32e(0xf67a8c8d), C32e(0xffe8170d), + C32e(0xd60adcbd), C32e(0xde16c8b1), C32e(0x916dfc54), C32e(0x6090f050), C32e(0x02070503), + C32e(0xce2ee0a9), C32e(0x56d1877d), C32e(0xe7cc2b19), C32e(0xb513a662), C32e(0x4d7c31e6), + C32e(0xec59b59a), C32e(0x8f40cf45), C32e(0x1fa3bc9d), C32e(0x8949c040), C32e(0xfa689287), + C32e(0xefd03f15), C32e(0xb29426eb), C32e(0x8ece40c9), C32e(0xfbe61d0b), C32e(0x416e2fec), + C32e(0xb31aa967), C32e(0x5f431cfd), C32e(0x456025ea), C32e(0x23f9dabf), C32e(0x535102f7), + C32e(0xe445a196), C32e(0x9b76ed5b), C32e(0x75285dc2), C32e(0xe1c5241c), C32e(0x3dd4e9ae), + C32e(0x4cf2be6a), C32e(0x6c82ee5a), C32e(0x7ebdc341), C32e(0xf5f30602), C32e(0x8352d14f), + C32e(0x688ce45c), C32e(0x515607f4), C32e(0xd18d5c34), C32e(0xf9e11808), C32e(0xe24cae93), + C32e(0xab3e9573), C32e(0x6297f553), C32e(0x2a6b413f), C32e(0x081c140c), C32e(0x9563f652), + C32e(0x46e9af65), C32e(0x9d7fe25e), C32e(0x30487828), C32e(0x37cff8a1), C32e(0x0a1b110f), + C32e(0x2febc4b5), C32e(0x0e151b09), C32e(0x247e5a36), C32e(0x1badb69b), C32e(0xdf98473d), + C32e(0xcda76a26), C32e(0x4ef5bb69), C32e(0x7f334ccd), C32e(0xea50ba9f), C32e(0x123f2d1b), + C32e(0x1da4b99e), C32e(0x58c49c74), C32e(0x3446722e), C32e(0x3641772d), C32e(0xdc11cdb2), + C32e(0xb49d29ee), C32e(0x5b4d16fb), C32e(0xa4a501f6), C32e(0x76a1d74d), C32e(0xb714a361), + C32e(0x7d3449ce), C32e(0x52df8d7b), C32e(0xdd9f423e), C32e(0x5ecd9371), C32e(0x13b1a297), + C32e(0xa6a204f5), C32e(0xb901b868), C32e(0x00000000), C32e(0xc1b5742c), C32e(0x40e0a060), + C32e(0xe3c2211f), C32e(0x793a43c8), C32e(0xb69a2ced), C32e(0xd40dd9be), C32e(0x8d47ca46), + C32e(0x671770d9), C32e(0x72afdd4b), C32e(0x94ed79de), C32e(0x98ff67d4), C32e(0xb09323e8), + C32e(0x855bde4a), C32e(0xbb06bd6b), C32e(0xc5bb7e2a), C32e(0x4f7b34e5), C32e(0xedd73a16), + C32e(0x86d254c5), C32e(0x9af862d7), C32e(0x6699ff55), C32e(0x11b6a794), C32e(0x8ac04acf), + C32e(0xe9d93010), C32e(0x040e0a06), C32e(0xfe669881), C32e(0xa0ab0bf0), C32e(0x78b4cc44), + C32e(0x25f0d5ba), C32e(0x4b753ee3), C32e(0xa2ac0ef3), C32e(0x5d4419fe), C32e(0x80db5bc0), + C32e(0x0580858a), C32e(0x3fd3ecad), C32e(0x21fedfbc), C32e(0x70a8d848), C32e(0xf1fd0c04), + C32e(0x63197adf), C32e(0x772f58c1), C32e(0xaf309f75), C32e(0x42e7a563), C32e(0x20705030), + C32e(0xe5cb2e1a), C32e(0xfdef120e), C32e(0xbf08b76d), C32e(0x8155d44c), C32e(0x18243c14), + C32e(0x26795f35), C32e(0xc3b2712f), C32e(0xbe8638e1), C32e(0x35c8fda2), C32e(0x88c74fcc), + C32e(0x2e654b39), C32e(0x936af957), C32e(0x55580df2), C32e(0xfc619d82), C32e(0x7ab3c947), + C32e(0xc827efac), C32e(0xba8832e7), C32e(0x324f7d2b), C32e(0xe642a495), C32e(0xc03bfba0), + C32e(0x19aab398), C32e(0x9ef668d1), C32e(0xa322817f), C32e(0x44eeaa66), C32e(0x54d6827e), + C32e(0x3bdde6ab), C32e(0x0b959e83), C32e(0x8cc945ca), C32e(0xc7bc7b29), C32e(0x6b056ed3), + C32e(0x286c443c), C32e(0xa72c8b79), C32e(0xbc813de2), C32e(0x1631271d), C32e(0xad379a76), + C32e(0xdb964d3b), C32e(0x649efa56), C32e(0x74a6d24e), C32e(0x1436221e), C32e(0x92e476db), + C32e(0x0c121e0a), C32e(0x48fcb46c), C32e(0xb88f37e4), C32e(0x9f78e75d), C32e(0xbd0fb26e), + C32e(0x43692aef), C32e(0xc435f1a6), C32e(0x39dae3a8), C32e(0x31c6f7a4), C32e(0xd38a5937), + C32e(0xf274868b), C32e(0xd5835632), C32e(0x8b4ec543), C32e(0x6e85eb59), C32e(0xda18c2b7), + C32e(0x018e8f8c), C32e(0xb11dac64), C32e(0x9cf16dd2), C32e(0x49723be0), C32e(0xd81fc7b4), + C32e(0xacb915fa), C32e(0xf3fa0907), C32e(0xcfa06f25), C32e(0xca20eaaf), C32e(0xf47d898e), + C32e(0x476720e9), C32e(0x10382818), C32e(0x6f0b64d5), C32e(0xf0738388), C32e(0x4afbb16f), + C32e(0x5cca9672), C32e(0x38546c24), C32e(0x575f08f1), C32e(0x732152c7), C32e(0x9764f351), + C32e(0xcbae6523), C32e(0xa125847c), C32e(0xe857bf9c), C32e(0x3e5d6321), C32e(0x96ea7cdd), + C32e(0x611e7fdc), C32e(0x0d9c9186), C32e(0x0f9b9485), C32e(0xe04bab90), C32e(0x7cbac642), + C32e(0x712657c4), C32e(0xcc29e5aa), C32e(0x90e373d8), C32e(0x06090f05), C32e(0xf7f40301), + C32e(0x1c2a3612), C32e(0xc23cfea3), C32e(0x6a8be15f), C32e(0xaebe10f9), C32e(0x69026bd0), + C32e(0x17bfa891), C32e(0x9971e858), C32e(0x3a536927), C32e(0x27f7d0b9), C32e(0xd9914838), + C32e(0xebde3513), C32e(0x2be5ceb3), C32e(0x22775533), C32e(0xd204d6bb), C32e(0xa9399070), + C32e(0x07878089), C32e(0x33c1f2a7), C32e(0x2decc1b6), C32e(0x3c5a6622), C32e(0x15b8ad92), + C32e(0xc9a96020), C32e(0x875cdb49), C32e(0xaab01aff), C32e(0x50d88878), C32e(0xa52b8e7a), + C32e(0x03898a8f), C32e(0x594a13f8), C32e(0x09929b80), C32e(0x1a233917), C32e(0x651075da), + C32e(0xd7845331), C32e(0x84d551c6), C32e(0xd003d3b8), C32e(0x82dc5ec3), C32e(0x29e2cbb0), + C32e(0x5ac39977), C32e(0x1e2d3311), C32e(0x7b3d46cb), C32e(0xa8b71ffc), C32e(0x6d0c61d6), + C32e(0x2c624e3a)}; static const sph_u32 T0dn[] = { - C32e(0xf497a5c6), C32e(0x97eb84f8), C32e(0xb0c799ee), C32e(0x8cf78df6), - C32e(0x17e50dff), C32e(0xdcb7bdd6), C32e(0xc8a7b1de), C32e(0xfc395491), - C32e(0xf0c05060), C32e(0x05040302), C32e(0xe087a9ce), C32e(0x87ac7d56), - C32e(0x2bd519e7), C32e(0xa67162b5), C32e(0x319ae64d), C32e(0xb5c39aec), - C32e(0xcf05458f), C32e(0xbc3e9d1f), C32e(0xc0094089), C32e(0x92ef87fa), - C32e(0x3fc515ef), C32e(0x267febb2), C32e(0x4007c98e), C32e(0x1ded0bfb), - C32e(0x2f82ec41), C32e(0xa97d67b3), C32e(0x1cbefd5f), C32e(0x258aea45), - C32e(0xda46bf23), C32e(0x02a6f753), C32e(0xa1d396e4), C32e(0xed2d5b9b), - C32e(0x5deac275), C32e(0x24d91ce1), C32e(0xe97aae3d), C32e(0xbe986a4c), - C32e(0xeed85a6c), C32e(0xc3fc417e), C32e(0x06f102f5), C32e(0xd11d4f83), - C32e(0xe4d05c68), C32e(0x07a2f451), C32e(0x5cb934d1), C32e(0x18e908f9), - C32e(0xaedf93e2), C32e(0x954d73ab), C32e(0xf5c45362), C32e(0x41543f2a), - C32e(0x14100c08), C32e(0xf6315295), C32e(0xaf8c6546), C32e(0xe2215e9d), - C32e(0x78602830), C32e(0xf86ea137), C32e(0x11140f0a), C32e(0xc45eb52f), - C32e(0x1b1c090e), C32e(0x5a483624), C32e(0xb6369b1b), C32e(0x47a53ddf), - C32e(0x6a8126cd), C32e(0xbb9c694e), C32e(0x4cfecd7f), C32e(0xbacf9fea), - C32e(0x2d241b12), C32e(0xb93a9e1d), C32e(0x9cb07458), C32e(0x72682e34), - C32e(0x776c2d36), C32e(0xcda3b2dc), C32e(0x2973eeb4), C32e(0x16b6fb5b), - C32e(0x0153f6a4), C32e(0xd7ec4d76), C32e(0xa37561b7), C32e(0x49face7d), - C32e(0x8da47b52), C32e(0x42a13edd), C32e(0x93bc715e), C32e(0xa2269713), - C32e(0x0457f5a6), C32e(0xb86968b9), C32e(0x00000000), C32e(0x74992cc1), - C32e(0xa0806040), C32e(0x21dd1fe3), C32e(0x43f2c879), C32e(0x2c77edb6), - C32e(0xd9b3bed4), C32e(0xca01468d), C32e(0x70ced967), C32e(0xdde44b72), - C32e(0x7933de94), C32e(0x672bd498), C32e(0x237be8b0), C32e(0xde114a85), - C32e(0xbd6d6bbb), C32e(0x7e912ac5), C32e(0x349ee54f), C32e(0x3ac116ed), - C32e(0x5417c586), C32e(0x622fd79a), C32e(0xffcc5566), C32e(0xa7229411), - C32e(0x4a0fcf8a), C32e(0x30c910e9), C32e(0x0a080604), C32e(0x98e781fe), - C32e(0x0b5bf0a0), C32e(0xccf04478), C32e(0xd54aba25), C32e(0x3e96e34b), - C32e(0x0e5ff3a2), C32e(0x19bafe5d), C32e(0x5b1bc080), C32e(0x850a8a05), - C32e(0xec7ead3f), C32e(0xdf42bc21), C32e(0xd8e04870), C32e(0x0cf904f1), - C32e(0x7ac6df63), C32e(0x58eec177), C32e(0x9f4575af), C32e(0xa5846342), - C32e(0x50403020), C32e(0x2ed11ae5), C32e(0x12e10efd), C32e(0xb7656dbf), - C32e(0xd4194c81), C32e(0x3c301418), C32e(0x5f4c3526), C32e(0x719d2fc3), - C32e(0x3867e1be), C32e(0xfd6aa235), C32e(0x4f0bcc88), C32e(0x4b5c392e), - C32e(0xf93d5793), C32e(0x0daaf255), C32e(0x9de382fc), C32e(0xc9f4477a), - C32e(0xef8bacc8), C32e(0x326fe7ba), C32e(0x7d642b32), C32e(0xa4d795e6), - C32e(0xfb9ba0c0), C32e(0xb3329819), C32e(0x6827d19e), C32e(0x815d7fa3), - C32e(0xaa886644), C32e(0x82a87e54), C32e(0xe676ab3b), C32e(0x9e16830b), - C32e(0x4503ca8c), C32e(0x7b9529c7), C32e(0x6ed6d36b), C32e(0x44503c28), - C32e(0x8b5579a7), C32e(0x3d63e2bc), C32e(0x272c1d16), C32e(0x9a4176ad), - C32e(0x4dad3bdb), C32e(0xfac85664), C32e(0xd2e84e74), C32e(0x22281e14), - C32e(0x763fdb92), C32e(0x1e180a0c), C32e(0xb4906c48), C32e(0x376be4b8), - C32e(0xe7255d9f), C32e(0xb2616ebd), C32e(0x2a86ef43), C32e(0xf193a6c4), - C32e(0xe372a839), C32e(0xf762a431), C32e(0x59bd37d3), C32e(0x86ff8bf2), - C32e(0x56b132d5), C32e(0xc50d438b), C32e(0xebdc596e), C32e(0xc2afb7da), - C32e(0x8f028c01), C32e(0xac7964b1), C32e(0x6d23d29c), C32e(0x3b92e049), - C32e(0xc7abb4d8), C32e(0x1543faac), C32e(0x09fd07f3), C32e(0x6f8525cf), - C32e(0xea8fafca), C32e(0x89f38ef4), C32e(0x208ee947), C32e(0x28201810), - C32e(0x64ded56f), C32e(0x83fb88f0), C32e(0xb1946f4a), C32e(0x96b8725c), - C32e(0x6c702438), C32e(0x08aef157), C32e(0x52e6c773), C32e(0xf3355197), - C32e(0x658d23cb), C32e(0x84597ca1), C32e(0xbfcb9ce8), C32e(0x637c213e), - C32e(0x7c37dd96), C32e(0x7fc2dc61), C32e(0x911a860d), C32e(0x941e850f), - C32e(0xabdb90e0), C32e(0xc6f8427c), C32e(0x57e2c471), C32e(0xe583aacc), - C32e(0x733bd890), C32e(0x0f0c0506), C32e(0x03f501f7), C32e(0x3638121c), - C32e(0xfe9fa3c2), C32e(0xe1d45f6a), C32e(0x1047f9ae), C32e(0x6bd2d069), - C32e(0xa82e9117), C32e(0xe8295899), C32e(0x6974273a), C32e(0xd04eb927), - C32e(0x48a938d9), C32e(0x35cd13eb), C32e(0xce56b32b), C32e(0x55443322), - C32e(0xd6bfbbd2), C32e(0x904970a9), C32e(0x800e8907), C32e(0xf266a733), - C32e(0xc15ab62d), C32e(0x6678223c), C32e(0xad2a9215), C32e(0x608920c9), - C32e(0xdb154987), C32e(0x1a4fffaa), C32e(0x88a07850), C32e(0x8e517aa5), - C32e(0x8a068f03), C32e(0x13b2f859), C32e(0x9b128009), C32e(0x3934171a), - C32e(0x75cada65), C32e(0x53b531d7), C32e(0x5113c684), C32e(0xd3bbb8d0), - C32e(0x5e1fc382), C32e(0xcb52b029), C32e(0x99b4775a), C32e(0x333c111e), - C32e(0x46f6cb7b), C32e(0x1f4bfca8), C32e(0x61dad66d), C32e(0x4e583a2c) -}; + C32e(0xf497a5c6), C32e(0x97eb84f8), C32e(0xb0c799ee), C32e(0x8cf78df6), C32e(0x17e50dff), + C32e(0xdcb7bdd6), C32e(0xc8a7b1de), C32e(0xfc395491), C32e(0xf0c05060), C32e(0x05040302), + C32e(0xe087a9ce), C32e(0x87ac7d56), C32e(0x2bd519e7), C32e(0xa67162b5), C32e(0x319ae64d), + C32e(0xb5c39aec), C32e(0xcf05458f), C32e(0xbc3e9d1f), C32e(0xc0094089), C32e(0x92ef87fa), + C32e(0x3fc515ef), C32e(0x267febb2), C32e(0x4007c98e), C32e(0x1ded0bfb), C32e(0x2f82ec41), + C32e(0xa97d67b3), C32e(0x1cbefd5f), C32e(0x258aea45), C32e(0xda46bf23), C32e(0x02a6f753), + C32e(0xa1d396e4), C32e(0xed2d5b9b), C32e(0x5deac275), C32e(0x24d91ce1), C32e(0xe97aae3d), + C32e(0xbe986a4c), C32e(0xeed85a6c), C32e(0xc3fc417e), C32e(0x06f102f5), C32e(0xd11d4f83), + C32e(0xe4d05c68), C32e(0x07a2f451), C32e(0x5cb934d1), C32e(0x18e908f9), C32e(0xaedf93e2), + C32e(0x954d73ab), C32e(0xf5c45362), C32e(0x41543f2a), C32e(0x14100c08), C32e(0xf6315295), + C32e(0xaf8c6546), C32e(0xe2215e9d), C32e(0x78602830), C32e(0xf86ea137), C32e(0x11140f0a), + C32e(0xc45eb52f), C32e(0x1b1c090e), C32e(0x5a483624), C32e(0xb6369b1b), C32e(0x47a53ddf), + C32e(0x6a8126cd), C32e(0xbb9c694e), C32e(0x4cfecd7f), C32e(0xbacf9fea), C32e(0x2d241b12), + C32e(0xb93a9e1d), C32e(0x9cb07458), C32e(0x72682e34), C32e(0x776c2d36), C32e(0xcda3b2dc), + C32e(0x2973eeb4), C32e(0x16b6fb5b), C32e(0x0153f6a4), C32e(0xd7ec4d76), C32e(0xa37561b7), + C32e(0x49face7d), C32e(0x8da47b52), C32e(0x42a13edd), C32e(0x93bc715e), C32e(0xa2269713), + C32e(0x0457f5a6), C32e(0xb86968b9), C32e(0x00000000), C32e(0x74992cc1), C32e(0xa0806040), + C32e(0x21dd1fe3), C32e(0x43f2c879), C32e(0x2c77edb6), C32e(0xd9b3bed4), C32e(0xca01468d), + C32e(0x70ced967), C32e(0xdde44b72), C32e(0x7933de94), C32e(0x672bd498), C32e(0x237be8b0), + C32e(0xde114a85), C32e(0xbd6d6bbb), C32e(0x7e912ac5), C32e(0x349ee54f), C32e(0x3ac116ed), + C32e(0x5417c586), C32e(0x622fd79a), C32e(0xffcc5566), C32e(0xa7229411), C32e(0x4a0fcf8a), + C32e(0x30c910e9), C32e(0x0a080604), C32e(0x98e781fe), C32e(0x0b5bf0a0), C32e(0xccf04478), + C32e(0xd54aba25), C32e(0x3e96e34b), C32e(0x0e5ff3a2), C32e(0x19bafe5d), C32e(0x5b1bc080), + C32e(0x850a8a05), C32e(0xec7ead3f), C32e(0xdf42bc21), C32e(0xd8e04870), C32e(0x0cf904f1), + C32e(0x7ac6df63), C32e(0x58eec177), C32e(0x9f4575af), C32e(0xa5846342), C32e(0x50403020), + C32e(0x2ed11ae5), C32e(0x12e10efd), C32e(0xb7656dbf), C32e(0xd4194c81), C32e(0x3c301418), + C32e(0x5f4c3526), C32e(0x719d2fc3), C32e(0x3867e1be), C32e(0xfd6aa235), C32e(0x4f0bcc88), + C32e(0x4b5c392e), C32e(0xf93d5793), C32e(0x0daaf255), C32e(0x9de382fc), C32e(0xc9f4477a), + C32e(0xef8bacc8), C32e(0x326fe7ba), C32e(0x7d642b32), C32e(0xa4d795e6), C32e(0xfb9ba0c0), + C32e(0xb3329819), C32e(0x6827d19e), C32e(0x815d7fa3), C32e(0xaa886644), C32e(0x82a87e54), + C32e(0xe676ab3b), C32e(0x9e16830b), C32e(0x4503ca8c), C32e(0x7b9529c7), C32e(0x6ed6d36b), + C32e(0x44503c28), C32e(0x8b5579a7), C32e(0x3d63e2bc), C32e(0x272c1d16), C32e(0x9a4176ad), + C32e(0x4dad3bdb), C32e(0xfac85664), C32e(0xd2e84e74), C32e(0x22281e14), C32e(0x763fdb92), + C32e(0x1e180a0c), C32e(0xb4906c48), C32e(0x376be4b8), C32e(0xe7255d9f), C32e(0xb2616ebd), + C32e(0x2a86ef43), C32e(0xf193a6c4), C32e(0xe372a839), C32e(0xf762a431), C32e(0x59bd37d3), + C32e(0x86ff8bf2), C32e(0x56b132d5), C32e(0xc50d438b), C32e(0xebdc596e), C32e(0xc2afb7da), + C32e(0x8f028c01), C32e(0xac7964b1), C32e(0x6d23d29c), C32e(0x3b92e049), C32e(0xc7abb4d8), + C32e(0x1543faac), C32e(0x09fd07f3), C32e(0x6f8525cf), C32e(0xea8fafca), C32e(0x89f38ef4), + C32e(0x208ee947), C32e(0x28201810), C32e(0x64ded56f), C32e(0x83fb88f0), C32e(0xb1946f4a), + C32e(0x96b8725c), C32e(0x6c702438), C32e(0x08aef157), C32e(0x52e6c773), C32e(0xf3355197), + C32e(0x658d23cb), C32e(0x84597ca1), C32e(0xbfcb9ce8), C32e(0x637c213e), C32e(0x7c37dd96), + C32e(0x7fc2dc61), C32e(0x911a860d), C32e(0x941e850f), C32e(0xabdb90e0), C32e(0xc6f8427c), + C32e(0x57e2c471), C32e(0xe583aacc), C32e(0x733bd890), C32e(0x0f0c0506), C32e(0x03f501f7), + C32e(0x3638121c), C32e(0xfe9fa3c2), C32e(0xe1d45f6a), C32e(0x1047f9ae), C32e(0x6bd2d069), + C32e(0xa82e9117), C32e(0xe8295899), C32e(0x6974273a), C32e(0xd04eb927), C32e(0x48a938d9), + C32e(0x35cd13eb), C32e(0xce56b32b), C32e(0x55443322), C32e(0xd6bfbbd2), C32e(0x904970a9), + C32e(0x800e8907), C32e(0xf266a733), C32e(0xc15ab62d), C32e(0x6678223c), C32e(0xad2a9215), + C32e(0x608920c9), C32e(0xdb154987), C32e(0x1a4fffaa), C32e(0x88a07850), C32e(0x8e517aa5), + C32e(0x8a068f03), C32e(0x13b2f859), C32e(0x9b128009), C32e(0x3934171a), C32e(0x75cada65), + C32e(0x53b531d7), C32e(0x5113c684), C32e(0xd3bbb8d0), C32e(0x5e1fc382), C32e(0xcb52b029), + C32e(0x99b4775a), C32e(0x333c111e), C32e(0x46f6cb7b), C32e(0x1f4bfca8), C32e(0x61dad66d), + C32e(0x4e583a2c)}; static const sph_u32 T1up[] = { - C32e(0xc6c632f4), C32e(0xf8f86f97), C32e(0xeeee5eb0), C32e(0xf6f67a8c), - C32e(0xffffe817), C32e(0xd6d60adc), C32e(0xdede16c8), C32e(0x91916dfc), - C32e(0x606090f0), C32e(0x02020705), C32e(0xcece2ee0), C32e(0x5656d187), - C32e(0xe7e7cc2b), C32e(0xb5b513a6), C32e(0x4d4d7c31), C32e(0xecec59b5), - C32e(0x8f8f40cf), C32e(0x1f1fa3bc), C32e(0x898949c0), C32e(0xfafa6892), - C32e(0xefefd03f), C32e(0xb2b29426), C32e(0x8e8ece40), C32e(0xfbfbe61d), - C32e(0x41416e2f), C32e(0xb3b31aa9), C32e(0x5f5f431c), C32e(0x45456025), - C32e(0x2323f9da), C32e(0x53535102), C32e(0xe4e445a1), C32e(0x9b9b76ed), - C32e(0x7575285d), C32e(0xe1e1c524), C32e(0x3d3dd4e9), C32e(0x4c4cf2be), - C32e(0x6c6c82ee), C32e(0x7e7ebdc3), C32e(0xf5f5f306), C32e(0x838352d1), - C32e(0x68688ce4), C32e(0x51515607), C32e(0xd1d18d5c), C32e(0xf9f9e118), - C32e(0xe2e24cae), C32e(0xabab3e95), C32e(0x626297f5), C32e(0x2a2a6b41), - C32e(0x08081c14), C32e(0x959563f6), C32e(0x4646e9af), C32e(0x9d9d7fe2), - C32e(0x30304878), C32e(0x3737cff8), C32e(0x0a0a1b11), C32e(0x2f2febc4), - C32e(0x0e0e151b), C32e(0x24247e5a), C32e(0x1b1badb6), C32e(0xdfdf9847), - C32e(0xcdcda76a), C32e(0x4e4ef5bb), C32e(0x7f7f334c), C32e(0xeaea50ba), - C32e(0x12123f2d), C32e(0x1d1da4b9), C32e(0x5858c49c), C32e(0x34344672), - C32e(0x36364177), C32e(0xdcdc11cd), C32e(0xb4b49d29), C32e(0x5b5b4d16), - C32e(0xa4a4a501), C32e(0x7676a1d7), C32e(0xb7b714a3), C32e(0x7d7d3449), - C32e(0x5252df8d), C32e(0xdddd9f42), C32e(0x5e5ecd93), C32e(0x1313b1a2), - C32e(0xa6a6a204), C32e(0xb9b901b8), C32e(0x00000000), C32e(0xc1c1b574), - C32e(0x4040e0a0), C32e(0xe3e3c221), C32e(0x79793a43), C32e(0xb6b69a2c), - C32e(0xd4d40dd9), C32e(0x8d8d47ca), C32e(0x67671770), C32e(0x7272afdd), - C32e(0x9494ed79), C32e(0x9898ff67), C32e(0xb0b09323), C32e(0x85855bde), - C32e(0xbbbb06bd), C32e(0xc5c5bb7e), C32e(0x4f4f7b34), C32e(0xededd73a), - C32e(0x8686d254), C32e(0x9a9af862), C32e(0x666699ff), C32e(0x1111b6a7), - C32e(0x8a8ac04a), C32e(0xe9e9d930), C32e(0x04040e0a), C32e(0xfefe6698), - C32e(0xa0a0ab0b), C32e(0x7878b4cc), C32e(0x2525f0d5), C32e(0x4b4b753e), - C32e(0xa2a2ac0e), C32e(0x5d5d4419), C32e(0x8080db5b), C32e(0x05058085), - C32e(0x3f3fd3ec), C32e(0x2121fedf), C32e(0x7070a8d8), C32e(0xf1f1fd0c), - C32e(0x6363197a), C32e(0x77772f58), C32e(0xafaf309f), C32e(0x4242e7a5), - C32e(0x20207050), C32e(0xe5e5cb2e), C32e(0xfdfdef12), C32e(0xbfbf08b7), - C32e(0x818155d4), C32e(0x1818243c), C32e(0x2626795f), C32e(0xc3c3b271), - C32e(0xbebe8638), C32e(0x3535c8fd), C32e(0x8888c74f), C32e(0x2e2e654b), - C32e(0x93936af9), C32e(0x5555580d), C32e(0xfcfc619d), C32e(0x7a7ab3c9), - C32e(0xc8c827ef), C32e(0xbaba8832), C32e(0x32324f7d), C32e(0xe6e642a4), - C32e(0xc0c03bfb), C32e(0x1919aab3), C32e(0x9e9ef668), C32e(0xa3a32281), - C32e(0x4444eeaa), C32e(0x5454d682), C32e(0x3b3bdde6), C32e(0x0b0b959e), - C32e(0x8c8cc945), C32e(0xc7c7bc7b), C32e(0x6b6b056e), C32e(0x28286c44), - C32e(0xa7a72c8b), C32e(0xbcbc813d), C32e(0x16163127), C32e(0xadad379a), - C32e(0xdbdb964d), C32e(0x64649efa), C32e(0x7474a6d2), C32e(0x14143622), - C32e(0x9292e476), C32e(0x0c0c121e), C32e(0x4848fcb4), C32e(0xb8b88f37), - C32e(0x9f9f78e7), C32e(0xbdbd0fb2), C32e(0x4343692a), C32e(0xc4c435f1), - C32e(0x3939dae3), C32e(0x3131c6f7), C32e(0xd3d38a59), C32e(0xf2f27486), - C32e(0xd5d58356), C32e(0x8b8b4ec5), C32e(0x6e6e85eb), C32e(0xdada18c2), - C32e(0x01018e8f), C32e(0xb1b11dac), C32e(0x9c9cf16d), C32e(0x4949723b), - C32e(0xd8d81fc7), C32e(0xacacb915), C32e(0xf3f3fa09), C32e(0xcfcfa06f), - C32e(0xcaca20ea), C32e(0xf4f47d89), C32e(0x47476720), C32e(0x10103828), - C32e(0x6f6f0b64), C32e(0xf0f07383), C32e(0x4a4afbb1), C32e(0x5c5cca96), - C32e(0x3838546c), C32e(0x57575f08), C32e(0x73732152), C32e(0x979764f3), - C32e(0xcbcbae65), C32e(0xa1a12584), C32e(0xe8e857bf), C32e(0x3e3e5d63), - C32e(0x9696ea7c), C32e(0x61611e7f), C32e(0x0d0d9c91), C32e(0x0f0f9b94), - C32e(0xe0e04bab), C32e(0x7c7cbac6), C32e(0x71712657), C32e(0xcccc29e5), - C32e(0x9090e373), C32e(0x0606090f), C32e(0xf7f7f403), C32e(0x1c1c2a36), - C32e(0xc2c23cfe), C32e(0x6a6a8be1), C32e(0xaeaebe10), C32e(0x6969026b), - C32e(0x1717bfa8), C32e(0x999971e8), C32e(0x3a3a5369), C32e(0x2727f7d0), - C32e(0xd9d99148), C32e(0xebebde35), C32e(0x2b2be5ce), C32e(0x22227755), - C32e(0xd2d204d6), C32e(0xa9a93990), C32e(0x07078780), C32e(0x3333c1f2), - C32e(0x2d2decc1), C32e(0x3c3c5a66), C32e(0x1515b8ad), C32e(0xc9c9a960), - C32e(0x87875cdb), C32e(0xaaaab01a), C32e(0x5050d888), C32e(0xa5a52b8e), - C32e(0x0303898a), C32e(0x59594a13), C32e(0x0909929b), C32e(0x1a1a2339), - C32e(0x65651075), C32e(0xd7d78453), C32e(0x8484d551), C32e(0xd0d003d3), - C32e(0x8282dc5e), C32e(0x2929e2cb), C32e(0x5a5ac399), C32e(0x1e1e2d33), - C32e(0x7b7b3d46), C32e(0xa8a8b71f), C32e(0x6d6d0c61), C32e(0x2c2c624e) -}; + C32e(0xc6c632f4), C32e(0xf8f86f97), C32e(0xeeee5eb0), C32e(0xf6f67a8c), C32e(0xffffe817), + C32e(0xd6d60adc), C32e(0xdede16c8), C32e(0x91916dfc), C32e(0x606090f0), C32e(0x02020705), + C32e(0xcece2ee0), C32e(0x5656d187), C32e(0xe7e7cc2b), C32e(0xb5b513a6), C32e(0x4d4d7c31), + C32e(0xecec59b5), C32e(0x8f8f40cf), C32e(0x1f1fa3bc), C32e(0x898949c0), C32e(0xfafa6892), + C32e(0xefefd03f), C32e(0xb2b29426), C32e(0x8e8ece40), C32e(0xfbfbe61d), C32e(0x41416e2f), + C32e(0xb3b31aa9), C32e(0x5f5f431c), C32e(0x45456025), C32e(0x2323f9da), C32e(0x53535102), + C32e(0xe4e445a1), C32e(0x9b9b76ed), C32e(0x7575285d), C32e(0xe1e1c524), C32e(0x3d3dd4e9), + C32e(0x4c4cf2be), C32e(0x6c6c82ee), C32e(0x7e7ebdc3), C32e(0xf5f5f306), C32e(0x838352d1), + C32e(0x68688ce4), C32e(0x51515607), C32e(0xd1d18d5c), C32e(0xf9f9e118), C32e(0xe2e24cae), + C32e(0xabab3e95), C32e(0x626297f5), C32e(0x2a2a6b41), C32e(0x08081c14), C32e(0x959563f6), + C32e(0x4646e9af), C32e(0x9d9d7fe2), C32e(0x30304878), C32e(0x3737cff8), C32e(0x0a0a1b11), + C32e(0x2f2febc4), C32e(0x0e0e151b), C32e(0x24247e5a), C32e(0x1b1badb6), C32e(0xdfdf9847), + C32e(0xcdcda76a), C32e(0x4e4ef5bb), C32e(0x7f7f334c), C32e(0xeaea50ba), C32e(0x12123f2d), + C32e(0x1d1da4b9), C32e(0x5858c49c), C32e(0x34344672), C32e(0x36364177), C32e(0xdcdc11cd), + C32e(0xb4b49d29), C32e(0x5b5b4d16), C32e(0xa4a4a501), C32e(0x7676a1d7), C32e(0xb7b714a3), + C32e(0x7d7d3449), C32e(0x5252df8d), C32e(0xdddd9f42), C32e(0x5e5ecd93), C32e(0x1313b1a2), + C32e(0xa6a6a204), C32e(0xb9b901b8), C32e(0x00000000), C32e(0xc1c1b574), C32e(0x4040e0a0), + C32e(0xe3e3c221), C32e(0x79793a43), C32e(0xb6b69a2c), C32e(0xd4d40dd9), C32e(0x8d8d47ca), + C32e(0x67671770), C32e(0x7272afdd), C32e(0x9494ed79), C32e(0x9898ff67), C32e(0xb0b09323), + C32e(0x85855bde), C32e(0xbbbb06bd), C32e(0xc5c5bb7e), C32e(0x4f4f7b34), C32e(0xededd73a), + C32e(0x8686d254), C32e(0x9a9af862), C32e(0x666699ff), C32e(0x1111b6a7), C32e(0x8a8ac04a), + C32e(0xe9e9d930), C32e(0x04040e0a), C32e(0xfefe6698), C32e(0xa0a0ab0b), C32e(0x7878b4cc), + C32e(0x2525f0d5), C32e(0x4b4b753e), C32e(0xa2a2ac0e), C32e(0x5d5d4419), C32e(0x8080db5b), + C32e(0x05058085), C32e(0x3f3fd3ec), C32e(0x2121fedf), C32e(0x7070a8d8), C32e(0xf1f1fd0c), + C32e(0x6363197a), C32e(0x77772f58), C32e(0xafaf309f), C32e(0x4242e7a5), C32e(0x20207050), + C32e(0xe5e5cb2e), C32e(0xfdfdef12), C32e(0xbfbf08b7), C32e(0x818155d4), C32e(0x1818243c), + C32e(0x2626795f), C32e(0xc3c3b271), C32e(0xbebe8638), C32e(0x3535c8fd), C32e(0x8888c74f), + C32e(0x2e2e654b), C32e(0x93936af9), C32e(0x5555580d), C32e(0xfcfc619d), C32e(0x7a7ab3c9), + C32e(0xc8c827ef), C32e(0xbaba8832), C32e(0x32324f7d), C32e(0xe6e642a4), C32e(0xc0c03bfb), + C32e(0x1919aab3), C32e(0x9e9ef668), C32e(0xa3a32281), C32e(0x4444eeaa), C32e(0x5454d682), + C32e(0x3b3bdde6), C32e(0x0b0b959e), C32e(0x8c8cc945), C32e(0xc7c7bc7b), C32e(0x6b6b056e), + C32e(0x28286c44), C32e(0xa7a72c8b), C32e(0xbcbc813d), C32e(0x16163127), C32e(0xadad379a), + C32e(0xdbdb964d), C32e(0x64649efa), C32e(0x7474a6d2), C32e(0x14143622), C32e(0x9292e476), + C32e(0x0c0c121e), C32e(0x4848fcb4), C32e(0xb8b88f37), C32e(0x9f9f78e7), C32e(0xbdbd0fb2), + C32e(0x4343692a), C32e(0xc4c435f1), C32e(0x3939dae3), C32e(0x3131c6f7), C32e(0xd3d38a59), + C32e(0xf2f27486), C32e(0xd5d58356), C32e(0x8b8b4ec5), C32e(0x6e6e85eb), C32e(0xdada18c2), + C32e(0x01018e8f), C32e(0xb1b11dac), C32e(0x9c9cf16d), C32e(0x4949723b), C32e(0xd8d81fc7), + C32e(0xacacb915), C32e(0xf3f3fa09), C32e(0xcfcfa06f), C32e(0xcaca20ea), C32e(0xf4f47d89), + C32e(0x47476720), C32e(0x10103828), C32e(0x6f6f0b64), C32e(0xf0f07383), C32e(0x4a4afbb1), + C32e(0x5c5cca96), C32e(0x3838546c), C32e(0x57575f08), C32e(0x73732152), C32e(0x979764f3), + C32e(0xcbcbae65), C32e(0xa1a12584), C32e(0xe8e857bf), C32e(0x3e3e5d63), C32e(0x9696ea7c), + C32e(0x61611e7f), C32e(0x0d0d9c91), C32e(0x0f0f9b94), C32e(0xe0e04bab), C32e(0x7c7cbac6), + C32e(0x71712657), C32e(0xcccc29e5), C32e(0x9090e373), C32e(0x0606090f), C32e(0xf7f7f403), + C32e(0x1c1c2a36), C32e(0xc2c23cfe), C32e(0x6a6a8be1), C32e(0xaeaebe10), C32e(0x6969026b), + C32e(0x1717bfa8), C32e(0x999971e8), C32e(0x3a3a5369), C32e(0x2727f7d0), C32e(0xd9d99148), + C32e(0xebebde35), C32e(0x2b2be5ce), C32e(0x22227755), C32e(0xd2d204d6), C32e(0xa9a93990), + C32e(0x07078780), C32e(0x3333c1f2), C32e(0x2d2decc1), C32e(0x3c3c5a66), C32e(0x1515b8ad), + C32e(0xc9c9a960), C32e(0x87875cdb), C32e(0xaaaab01a), C32e(0x5050d888), C32e(0xa5a52b8e), + C32e(0x0303898a), C32e(0x59594a13), C32e(0x0909929b), C32e(0x1a1a2339), C32e(0x65651075), + C32e(0xd7d78453), C32e(0x8484d551), C32e(0xd0d003d3), C32e(0x8282dc5e), C32e(0x2929e2cb), + C32e(0x5a5ac399), C32e(0x1e1e2d33), C32e(0x7b7b3d46), C32e(0xa8a8b71f), C32e(0x6d6d0c61), + C32e(0x2c2c624e)}; static const sph_u32 T1dn[] = { - C32e(0xa5f497a5), C32e(0x8497eb84), C32e(0x99b0c799), C32e(0x8d8cf78d), - C32e(0x0d17e50d), C32e(0xbddcb7bd), C32e(0xb1c8a7b1), C32e(0x54fc3954), - C32e(0x50f0c050), C32e(0x03050403), C32e(0xa9e087a9), C32e(0x7d87ac7d), - C32e(0x192bd519), C32e(0x62a67162), C32e(0xe6319ae6), C32e(0x9ab5c39a), - C32e(0x45cf0545), C32e(0x9dbc3e9d), C32e(0x40c00940), C32e(0x8792ef87), - C32e(0x153fc515), C32e(0xeb267feb), C32e(0xc94007c9), C32e(0x0b1ded0b), - C32e(0xec2f82ec), C32e(0x67a97d67), C32e(0xfd1cbefd), C32e(0xea258aea), - C32e(0xbfda46bf), C32e(0xf702a6f7), C32e(0x96a1d396), C32e(0x5bed2d5b), - C32e(0xc25deac2), C32e(0x1c24d91c), C32e(0xaee97aae), C32e(0x6abe986a), - C32e(0x5aeed85a), C32e(0x41c3fc41), C32e(0x0206f102), C32e(0x4fd11d4f), - C32e(0x5ce4d05c), C32e(0xf407a2f4), C32e(0x345cb934), C32e(0x0818e908), - C32e(0x93aedf93), C32e(0x73954d73), C32e(0x53f5c453), C32e(0x3f41543f), - C32e(0x0c14100c), C32e(0x52f63152), C32e(0x65af8c65), C32e(0x5ee2215e), - C32e(0x28786028), C32e(0xa1f86ea1), C32e(0x0f11140f), C32e(0xb5c45eb5), - C32e(0x091b1c09), C32e(0x365a4836), C32e(0x9bb6369b), C32e(0x3d47a53d), - C32e(0x266a8126), C32e(0x69bb9c69), C32e(0xcd4cfecd), C32e(0x9fbacf9f), - C32e(0x1b2d241b), C32e(0x9eb93a9e), C32e(0x749cb074), C32e(0x2e72682e), - C32e(0x2d776c2d), C32e(0xb2cda3b2), C32e(0xee2973ee), C32e(0xfb16b6fb), - C32e(0xf60153f6), C32e(0x4dd7ec4d), C32e(0x61a37561), C32e(0xce49face), - C32e(0x7b8da47b), C32e(0x3e42a13e), C32e(0x7193bc71), C32e(0x97a22697), - C32e(0xf50457f5), C32e(0x68b86968), C32e(0x00000000), C32e(0x2c74992c), - C32e(0x60a08060), C32e(0x1f21dd1f), C32e(0xc843f2c8), C32e(0xed2c77ed), - C32e(0xbed9b3be), C32e(0x46ca0146), C32e(0xd970ced9), C32e(0x4bdde44b), - C32e(0xde7933de), C32e(0xd4672bd4), C32e(0xe8237be8), C32e(0x4ade114a), - C32e(0x6bbd6d6b), C32e(0x2a7e912a), C32e(0xe5349ee5), C32e(0x163ac116), - C32e(0xc55417c5), C32e(0xd7622fd7), C32e(0x55ffcc55), C32e(0x94a72294), - C32e(0xcf4a0fcf), C32e(0x1030c910), C32e(0x060a0806), C32e(0x8198e781), - C32e(0xf00b5bf0), C32e(0x44ccf044), C32e(0xbad54aba), C32e(0xe33e96e3), - C32e(0xf30e5ff3), C32e(0xfe19bafe), C32e(0xc05b1bc0), C32e(0x8a850a8a), - C32e(0xadec7ead), C32e(0xbcdf42bc), C32e(0x48d8e048), C32e(0x040cf904), - C32e(0xdf7ac6df), C32e(0xc158eec1), C32e(0x759f4575), C32e(0x63a58463), - C32e(0x30504030), C32e(0x1a2ed11a), C32e(0x0e12e10e), C32e(0x6db7656d), - C32e(0x4cd4194c), C32e(0x143c3014), C32e(0x355f4c35), C32e(0x2f719d2f), - C32e(0xe13867e1), C32e(0xa2fd6aa2), C32e(0xcc4f0bcc), C32e(0x394b5c39), - C32e(0x57f93d57), C32e(0xf20daaf2), C32e(0x829de382), C32e(0x47c9f447), - C32e(0xacef8bac), C32e(0xe7326fe7), C32e(0x2b7d642b), C32e(0x95a4d795), - C32e(0xa0fb9ba0), C32e(0x98b33298), C32e(0xd16827d1), C32e(0x7f815d7f), - C32e(0x66aa8866), C32e(0x7e82a87e), C32e(0xabe676ab), C32e(0x839e1683), - C32e(0xca4503ca), C32e(0x297b9529), C32e(0xd36ed6d3), C32e(0x3c44503c), - C32e(0x798b5579), C32e(0xe23d63e2), C32e(0x1d272c1d), C32e(0x769a4176), - C32e(0x3b4dad3b), C32e(0x56fac856), C32e(0x4ed2e84e), C32e(0x1e22281e), - C32e(0xdb763fdb), C32e(0x0a1e180a), C32e(0x6cb4906c), C32e(0xe4376be4), - C32e(0x5de7255d), C32e(0x6eb2616e), C32e(0xef2a86ef), C32e(0xa6f193a6), - C32e(0xa8e372a8), C32e(0xa4f762a4), C32e(0x3759bd37), C32e(0x8b86ff8b), - C32e(0x3256b132), C32e(0x43c50d43), C32e(0x59ebdc59), C32e(0xb7c2afb7), - C32e(0x8c8f028c), C32e(0x64ac7964), C32e(0xd26d23d2), C32e(0xe03b92e0), - C32e(0xb4c7abb4), C32e(0xfa1543fa), C32e(0x0709fd07), C32e(0x256f8525), - C32e(0xafea8faf), C32e(0x8e89f38e), C32e(0xe9208ee9), C32e(0x18282018), - C32e(0xd564ded5), C32e(0x8883fb88), C32e(0x6fb1946f), C32e(0x7296b872), - C32e(0x246c7024), C32e(0xf108aef1), C32e(0xc752e6c7), C32e(0x51f33551), - C32e(0x23658d23), C32e(0x7c84597c), C32e(0x9cbfcb9c), C32e(0x21637c21), - C32e(0xdd7c37dd), C32e(0xdc7fc2dc), C32e(0x86911a86), C32e(0x85941e85), - C32e(0x90abdb90), C32e(0x42c6f842), C32e(0xc457e2c4), C32e(0xaae583aa), - C32e(0xd8733bd8), C32e(0x050f0c05), C32e(0x0103f501), C32e(0x12363812), - C32e(0xa3fe9fa3), C32e(0x5fe1d45f), C32e(0xf91047f9), C32e(0xd06bd2d0), - C32e(0x91a82e91), C32e(0x58e82958), C32e(0x27697427), C32e(0xb9d04eb9), - C32e(0x3848a938), C32e(0x1335cd13), C32e(0xb3ce56b3), C32e(0x33554433), - C32e(0xbbd6bfbb), C32e(0x70904970), C32e(0x89800e89), C32e(0xa7f266a7), - C32e(0xb6c15ab6), C32e(0x22667822), C32e(0x92ad2a92), C32e(0x20608920), - C32e(0x49db1549), C32e(0xff1a4fff), C32e(0x7888a078), C32e(0x7a8e517a), - C32e(0x8f8a068f), C32e(0xf813b2f8), C32e(0x809b1280), C32e(0x17393417), - C32e(0xda75cada), C32e(0x3153b531), C32e(0xc65113c6), C32e(0xb8d3bbb8), - C32e(0xc35e1fc3), C32e(0xb0cb52b0), C32e(0x7799b477), C32e(0x11333c11), - C32e(0xcb46f6cb), C32e(0xfc1f4bfc), C32e(0xd661dad6), C32e(0x3a4e583a) -}; - -#define DECL_STATE_SMALL \ - sph_u32 H[16] = {0}; - -#define READ_STATE_SMALL(sc) do { \ - memcpy(H, (sc)->state.narrow, sizeof H); \ - } while (0) - -#define WRITE_STATE_SMALL(sc) do { \ - memcpy((sc)->state.narrow, H, sizeof H); \ - } while (0) - -#define XCAT(x, y) XCAT_(x, y) -#define XCAT_(x, y) x ## y - -#define RSTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ - t[d0] = T0up[B32_0(a[b0])] \ - ^ T1up[B32_1(a[b1])] \ - ^ T2up[B32_2(a[b2])] \ - ^ T3up[B32_3(a[b3])] \ - ^ T0dn[B32_0(a[b4])] \ - ^ T1dn[B32_1(a[b5])] \ - ^ T2dn[B32_2(a[b6])] \ - ^ T3dn[B32_3(a[b7])]; \ - t[d1] = T0dn[B32_0(a[b0])] \ - ^ T1dn[B32_1(a[b1])] \ - ^ T2dn[B32_2(a[b2])] \ - ^ T3dn[B32_3(a[b3])] \ - ^ T0up[B32_0(a[b4])] \ - ^ T1up[B32_1(a[b5])] \ - ^ T2up[B32_2(a[b6])] \ - ^ T3up[B32_3(a[b7])]; \ - } while (0) - -#define ROUND_SMALL_P(a, r) do { \ - sph_u32 t[16]; \ - a[0x0] ^= PC32up(0x00, r); \ - a[0x1] ^= PC32dn(0x00, r); \ - a[0x2] ^= PC32up(0x10, r); \ - a[0x3] ^= PC32dn(0x10, r); \ - a[0x4] ^= PC32up(0x20, r); \ - a[0x5] ^= PC32dn(0x20, r); \ - a[0x6] ^= PC32up(0x30, r); \ - a[0x7] ^= PC32dn(0x30, r); \ - a[0x8] ^= PC32up(0x40, r); \ - a[0x9] ^= PC32dn(0x40, r); \ - a[0xA] ^= PC32up(0x50, r); \ - a[0xB] ^= PC32dn(0x50, r); \ - a[0xC] ^= PC32up(0x60, r); \ - a[0xD] ^= PC32dn(0x60, r); \ - a[0xE] ^= PC32up(0x70, r); \ - a[0xF] ^= PC32dn(0x70, r); \ - RSTT(0x0, 0x1, a, 0x0, 0x2, 0x4, 0x6, 0x9, 0xB, 0xD, 0xF); \ - RSTT(0x2, 0x3, a, 0x2, 0x4, 0x6, 0x8, 0xB, 0xD, 0xF, 0x1); \ - RSTT(0x4, 0x5, a, 0x4, 0x6, 0x8, 0xA, 0xD, 0xF, 0x1, 0x3); \ - RSTT(0x6, 0x7, a, 0x6, 0x8, 0xA, 0xC, 0xF, 0x1, 0x3, 0x5); \ - RSTT(0x8, 0x9, a, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7); \ - RSTT(0xA, 0xB, a, 0xA, 0xC, 0xE, 0x0, 0x3, 0x5, 0x7, 0x9); \ - RSTT(0xC, 0xD, a, 0xC, 0xE, 0x0, 0x2, 0x5, 0x7, 0x9, 0xB); \ - RSTT(0xE, 0xF, a, 0xE, 0x0, 0x2, 0x4, 0x7, 0x9, 0xB, 0xD); \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define ROUND_SMALL_Q(a, r) do { \ - sph_u32 t[16]; \ - a[0x0] ^= QC32up(0x00, r); \ - a[0x1] ^= QC32dn(0x00, r); \ - a[0x2] ^= QC32up(0x10, r); \ - a[0x3] ^= QC32dn(0x10, r); \ - a[0x4] ^= QC32up(0x20, r); \ - a[0x5] ^= QC32dn(0x20, r); \ - a[0x6] ^= QC32up(0x30, r); \ - a[0x7] ^= QC32dn(0x30, r); \ - a[0x8] ^= QC32up(0x40, r); \ - a[0x9] ^= QC32dn(0x40, r); \ - a[0xA] ^= QC32up(0x50, r); \ - a[0xB] ^= QC32dn(0x50, r); \ - a[0xC] ^= QC32up(0x60, r); \ - a[0xD] ^= QC32dn(0x60, r); \ - a[0xE] ^= QC32up(0x70, r); \ - a[0xF] ^= QC32dn(0x70, r); \ - RSTT(0x0, 0x1, a, 0x2, 0x6, 0xA, 0xE, 0x1, 0x5, 0x9, 0xD); \ - RSTT(0x2, 0x3, a, 0x4, 0x8, 0xC, 0x0, 0x3, 0x7, 0xB, 0xF); \ - RSTT(0x4, 0x5, a, 0x6, 0xA, 0xE, 0x2, 0x5, 0x9, 0xD, 0x1); \ - RSTT(0x6, 0x7, a, 0x8, 0xC, 0x0, 0x4, 0x7, 0xB, 0xF, 0x3); \ - RSTT(0x8, 0x9, a, 0xA, 0xE, 0x2, 0x6, 0x9, 0xD, 0x1, 0x5); \ - RSTT(0xA, 0xB, a, 0xC, 0x0, 0x4, 0x8, 0xB, 0xF, 0x3, 0x7); \ - RSTT(0xC, 0xD, a, 0xE, 0x2, 0x6, 0xA, 0xD, 0x1, 0x5, 0x9); \ - RSTT(0xE, 0xF, a, 0x0, 0x4, 0x8, 0xC, 0xF, 0x3, 0x7, 0xB); \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define PERM_SMALL_P(a) do { \ - int r; \ - for (r = 0; r < 10; r ++) \ - ROUND_SMALL_P(a, r); \ - } while (0) - -#define PERM_SMALL_Q(a) do { \ - int r; \ - for (r = 0; r < 10; r ++) \ - ROUND_SMALL_Q(a, r); \ - } while (0) - - -#define COMPRESS_SMALL do { \ - sph_u32 g[16], m[16]; \ - size_t u; \ - for (u = 0; u < 16; u ++) { \ - m[u] = dec32e_aligned(buf + (u << 2)); \ - g[u] = m[u] ^ H[u]; \ - } \ - PERM_SMALL_P(g); \ - PERM_SMALL_Q(m); \ - for (u = 0; u < 16; u ++) \ - H[u] ^= g[u] ^ m[u]; \ - } while (0) - -#define FINAL_SMALL do { \ - sph_u32 x[16]; \ - size_t u; \ - memcpy(x, H, sizeof x); \ - PERM_SMALL_P(x); \ - for (u = 0; u < 16; u ++) \ - H[u] ^= x[u]; \ - } while (0) - -#define DECL_STATE_BIG \ - sph_u32 H[32] = {0}; - -#define READ_STATE_BIG(sc) do { \ - memcpy(H, (sc)->state.narrow, sizeof H); \ - } while (0) - -#define WRITE_STATE_BIG(sc) do { \ - memcpy((sc)->state.narrow, H, sizeof H); \ - } while (0) - - -#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ - sph_u32 fu2 = T0up[B32_2(a[b2])]; \ - sph_u32 fd2 = T0dn[B32_2(a[b2])]; \ - sph_u32 fu3 = T1up[B32_3(a[b3])]; \ - sph_u32 fd3 = T1dn[B32_3(a[b3])]; \ - sph_u32 fu6 = T0up[B32_2(a[b6])]; \ - sph_u32 fd6 = T0dn[B32_2(a[b6])]; \ - sph_u32 fu7 = T1up[B32_3(a[b7])]; \ - sph_u32 fd7 = T1dn[B32_3(a[b7])]; \ - t[d0] = T0up[B32_0(a[b0])] \ - ^ T1up[B32_1(a[b1])] \ - ^ R32u(fu2, fd2) \ - ^ R32u(fu3, fd3) \ - ^ T0dn[B32_0(a[b4])] \ - ^ T1dn[B32_1(a[b5])] \ - ^ R32d(fu6, fd6) \ - ^ R32d(fu7, fd7); \ - t[d1] = T0dn[B32_0(a[b0])] \ - ^ T1dn[B32_1(a[b1])] \ - ^ R32d(fu2, fd2) \ - ^ R32d(fu3, fd3) \ - ^ T0up[B32_0(a[b4])] \ - ^ T1up[B32_1(a[b5])] \ - ^ R32u(fu6, fd6) \ - ^ R32u(fu7, fd7); \ - } while (0) - - -#define ROUND_BIG_P(a, r) do { \ - sph_u32 t[32]; \ - size_t u; \ - a[0x00] ^= PC32up(0x00, r); \ - a[0x01] ^= PC32dn(0x00, r); \ - a[0x02] ^= PC32up(0x10, r); \ - a[0x03] ^= PC32dn(0x10, r); \ - a[0x04] ^= PC32up(0x20, r); \ - a[0x05] ^= PC32dn(0x20, r); \ - a[0x06] ^= PC32up(0x30, r); \ - a[0x07] ^= PC32dn(0x30, r); \ - a[0x08] ^= PC32up(0x40, r); \ - a[0x09] ^= PC32dn(0x40, r); \ - a[0x0A] ^= PC32up(0x50, r); \ - a[0x0B] ^= PC32dn(0x50, r); \ - a[0x0C] ^= PC32up(0x60, r); \ - a[0x0D] ^= PC32dn(0x60, r); \ - a[0x0E] ^= PC32up(0x70, r); \ - a[0x0F] ^= PC32dn(0x70, r); \ - a[0x10] ^= PC32up(0x80, r); \ - a[0x11] ^= PC32dn(0x80, r); \ - a[0x12] ^= PC32up(0x90, r); \ - a[0x13] ^= PC32dn(0x90, r); \ - a[0x14] ^= PC32up(0xA0, r); \ - a[0x15] ^= PC32dn(0xA0, r); \ - a[0x16] ^= PC32up(0xB0, r); \ - a[0x17] ^= PC32dn(0xB0, r); \ - a[0x18] ^= PC32up(0xC0, r); \ - a[0x19] ^= PC32dn(0xC0, r); \ - a[0x1A] ^= PC32up(0xD0, r); \ - a[0x1B] ^= PC32dn(0xD0, r); \ - a[0x1C] ^= PC32up(0xE0, r); \ - a[0x1D] ^= PC32dn(0xE0, r); \ - a[0x1E] ^= PC32up(0xF0, r); \ - a[0x1F] ^= PC32dn(0xF0, r); \ - for (u = 0; u < 32; u += 8) { \ - RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ - u + 0x00, (u + 0x02) & 0x1F, \ - (u + 0x04) & 0x1F, (u + 0x06) & 0x1F, \ - (u + 0x09) & 0x1F, (u + 0x0B) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x17) & 0x1F); \ - RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ - u + 0x02, (u + 0x04) & 0x1F, \ - (u + 0x06) & 0x1F, (u + 0x08) & 0x1F, \ - (u + 0x0B) & 0x1F, (u + 0x0D) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x19) & 0x1F); \ - RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ - u + 0x04, (u + 0x06) & 0x1F, \ - (u + 0x08) & 0x1F, (u + 0x0A) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x0F) & 0x1F, \ - (u + 0x11) & 0x1F, (u + 0x1B) & 0x1F); \ - RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ - u + 0x06, (u + 0x08) & 0x1F, \ - (u + 0x0A) & 0x1F, (u + 0x0C) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x11) & 0x1F, \ - (u + 0x13) & 0x1F, (u + 0x1D) & 0x1F); \ - } \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define ROUND_BIG_Q(a, r) do { \ - sph_u32 t[32]; \ - size_t u; \ - a[0x00] ^= QC32up(0x00, r); \ - a[0x01] ^= QC32dn(0x00, r); \ - a[0x02] ^= QC32up(0x10, r); \ - a[0x03] ^= QC32dn(0x10, r); \ - a[0x04] ^= QC32up(0x20, r); \ - a[0x05] ^= QC32dn(0x20, r); \ - a[0x06] ^= QC32up(0x30, r); \ - a[0x07] ^= QC32dn(0x30, r); \ - a[0x08] ^= QC32up(0x40, r); \ - a[0x09] ^= QC32dn(0x40, r); \ - a[0x0A] ^= QC32up(0x50, r); \ - a[0x0B] ^= QC32dn(0x50, r); \ - a[0x0C] ^= QC32up(0x60, r); \ - a[0x0D] ^= QC32dn(0x60, r); \ - a[0x0E] ^= QC32up(0x70, r); \ - a[0x0F] ^= QC32dn(0x70, r); \ - a[0x10] ^= QC32up(0x80, r); \ - a[0x11] ^= QC32dn(0x80, r); \ - a[0x12] ^= QC32up(0x90, r); \ - a[0x13] ^= QC32dn(0x90, r); \ - a[0x14] ^= QC32up(0xA0, r); \ - a[0x15] ^= QC32dn(0xA0, r); \ - a[0x16] ^= QC32up(0xB0, r); \ - a[0x17] ^= QC32dn(0xB0, r); \ - a[0x18] ^= QC32up(0xC0, r); \ - a[0x19] ^= QC32dn(0xC0, r); \ - a[0x1A] ^= QC32up(0xD0, r); \ - a[0x1B] ^= QC32dn(0xD0, r); \ - a[0x1C] ^= QC32up(0xE0, r); \ - a[0x1D] ^= QC32dn(0xE0, r); \ - a[0x1E] ^= QC32up(0xF0, r); \ - a[0x1F] ^= QC32dn(0xF0, r); \ - for (u = 0; u < 32; u += 8) { \ - RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ - (u + 0x02) & 0x1F, (u + 0x06) & 0x1F, \ - (u + 0x0A) & 0x1F, (u + 0x16) & 0x1F, \ - (u + 0x01) & 0x1F, (u + 0x05) & 0x1F, \ - (u + 0x09) & 0x1F, (u + 0x0D) & 0x1F); \ - RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ - (u + 0x04) & 0x1F, (u + 0x08) & 0x1F, \ - (u + 0x0C) & 0x1F, (u + 0x18) & 0x1F, \ - (u + 0x03) & 0x1F, (u + 0x07) & 0x1F, \ - (u + 0x0B) & 0x1F, (u + 0x0F) & 0x1F); \ - RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ - (u + 0x06) & 0x1F, (u + 0x0A) & 0x1F, \ - (u + 0x0E) & 0x1F, (u + 0x1A) & 0x1F, \ - (u + 0x05) & 0x1F, (u + 0x09) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x11) & 0x1F); \ - RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ - (u + 0x08) & 0x1F, (u + 0x0C) & 0x1F, \ - (u + 0x10) & 0x1F, (u + 0x1C) & 0x1F, \ - (u + 0x07) & 0x1F, (u + 0x0B) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x13) & 0x1F); \ - } \ - memcpy(a, t, sizeof t); \ - } while (0) - - -#define PERM_BIG_P(a) do { \ - int r; \ - for (r = 0; r < 14; r ++) \ - ROUND_BIG_P(a, r); \ - } while (0) - -#define PERM_BIG_Q(a) do { \ - int r; \ - for (r = 0; r < 14; r ++) \ - ROUND_BIG_Q(a, r); \ - } while (0) - - -#define COMPRESS_BIG do { \ - sph_u32 g[32], m[32]; \ - size_t uu; \ - for (uu = 0; uu < 32; uu ++) { \ - m[uu] = dec32e_aligned(buf + (uu << 2)); \ - g[uu] = m[uu] ^ H[uu]; \ - } \ - PERM_BIG_P(g); \ - PERM_BIG_Q(m); \ - for (uu = 0; uu < 32; uu ++) \ - H[uu] ^= g[uu] ^ m[uu]; \ - } while (0) - -#define FINAL_BIG do { \ - sph_u32 x[32]; \ - size_t uu; \ - memcpy(x, H, sizeof x); \ - PERM_BIG_P(x); \ - for (uu = 0; uu < 32; uu ++) \ - H[uu] ^= x[uu]; \ - } while (0) - - -static void -groestl_big_init(sph_groestl_big_context *sc, unsigned out_size) -{ - size_t u = 0; - - sc->ptr = 0; - for (u = 0; u < 31; u ++) - sc->state.narrow[u] = 0; - sc->state.narrow[31] = ((sph_u32)(out_size & 0xFF) << 24) - | ((sph_u32)(out_size & 0xFF00) << 8); - sc->count = 0; + C32e(0xa5f497a5), C32e(0x8497eb84), C32e(0x99b0c799), C32e(0x8d8cf78d), C32e(0x0d17e50d), + C32e(0xbddcb7bd), C32e(0xb1c8a7b1), C32e(0x54fc3954), C32e(0x50f0c050), C32e(0x03050403), + C32e(0xa9e087a9), C32e(0x7d87ac7d), C32e(0x192bd519), C32e(0x62a67162), C32e(0xe6319ae6), + C32e(0x9ab5c39a), C32e(0x45cf0545), C32e(0x9dbc3e9d), C32e(0x40c00940), C32e(0x8792ef87), + C32e(0x153fc515), C32e(0xeb267feb), C32e(0xc94007c9), C32e(0x0b1ded0b), C32e(0xec2f82ec), + C32e(0x67a97d67), C32e(0xfd1cbefd), C32e(0xea258aea), C32e(0xbfda46bf), C32e(0xf702a6f7), + C32e(0x96a1d396), C32e(0x5bed2d5b), C32e(0xc25deac2), C32e(0x1c24d91c), C32e(0xaee97aae), + C32e(0x6abe986a), C32e(0x5aeed85a), C32e(0x41c3fc41), C32e(0x0206f102), C32e(0x4fd11d4f), + C32e(0x5ce4d05c), C32e(0xf407a2f4), C32e(0x345cb934), C32e(0x0818e908), C32e(0x93aedf93), + C32e(0x73954d73), C32e(0x53f5c453), C32e(0x3f41543f), C32e(0x0c14100c), C32e(0x52f63152), + C32e(0x65af8c65), C32e(0x5ee2215e), C32e(0x28786028), C32e(0xa1f86ea1), C32e(0x0f11140f), + C32e(0xb5c45eb5), C32e(0x091b1c09), C32e(0x365a4836), C32e(0x9bb6369b), C32e(0x3d47a53d), + C32e(0x266a8126), C32e(0x69bb9c69), C32e(0xcd4cfecd), C32e(0x9fbacf9f), C32e(0x1b2d241b), + C32e(0x9eb93a9e), C32e(0x749cb074), C32e(0x2e72682e), C32e(0x2d776c2d), C32e(0xb2cda3b2), + C32e(0xee2973ee), C32e(0xfb16b6fb), C32e(0xf60153f6), C32e(0x4dd7ec4d), C32e(0x61a37561), + C32e(0xce49face), C32e(0x7b8da47b), C32e(0x3e42a13e), C32e(0x7193bc71), C32e(0x97a22697), + C32e(0xf50457f5), C32e(0x68b86968), C32e(0x00000000), C32e(0x2c74992c), C32e(0x60a08060), + C32e(0x1f21dd1f), C32e(0xc843f2c8), C32e(0xed2c77ed), C32e(0xbed9b3be), C32e(0x46ca0146), + C32e(0xd970ced9), C32e(0x4bdde44b), C32e(0xde7933de), C32e(0xd4672bd4), C32e(0xe8237be8), + C32e(0x4ade114a), C32e(0x6bbd6d6b), C32e(0x2a7e912a), C32e(0xe5349ee5), C32e(0x163ac116), + C32e(0xc55417c5), C32e(0xd7622fd7), C32e(0x55ffcc55), C32e(0x94a72294), C32e(0xcf4a0fcf), + C32e(0x1030c910), C32e(0x060a0806), C32e(0x8198e781), C32e(0xf00b5bf0), C32e(0x44ccf044), + C32e(0xbad54aba), C32e(0xe33e96e3), C32e(0xf30e5ff3), C32e(0xfe19bafe), C32e(0xc05b1bc0), + C32e(0x8a850a8a), C32e(0xadec7ead), C32e(0xbcdf42bc), C32e(0x48d8e048), C32e(0x040cf904), + C32e(0xdf7ac6df), C32e(0xc158eec1), C32e(0x759f4575), C32e(0x63a58463), C32e(0x30504030), + C32e(0x1a2ed11a), C32e(0x0e12e10e), C32e(0x6db7656d), C32e(0x4cd4194c), C32e(0x143c3014), + C32e(0x355f4c35), C32e(0x2f719d2f), C32e(0xe13867e1), C32e(0xa2fd6aa2), C32e(0xcc4f0bcc), + C32e(0x394b5c39), C32e(0x57f93d57), C32e(0xf20daaf2), C32e(0x829de382), C32e(0x47c9f447), + C32e(0xacef8bac), C32e(0xe7326fe7), C32e(0x2b7d642b), C32e(0x95a4d795), C32e(0xa0fb9ba0), + C32e(0x98b33298), C32e(0xd16827d1), C32e(0x7f815d7f), C32e(0x66aa8866), C32e(0x7e82a87e), + C32e(0xabe676ab), C32e(0x839e1683), C32e(0xca4503ca), C32e(0x297b9529), C32e(0xd36ed6d3), + C32e(0x3c44503c), C32e(0x798b5579), C32e(0xe23d63e2), C32e(0x1d272c1d), C32e(0x769a4176), + C32e(0x3b4dad3b), C32e(0x56fac856), C32e(0x4ed2e84e), C32e(0x1e22281e), C32e(0xdb763fdb), + C32e(0x0a1e180a), C32e(0x6cb4906c), C32e(0xe4376be4), C32e(0x5de7255d), C32e(0x6eb2616e), + C32e(0xef2a86ef), C32e(0xa6f193a6), C32e(0xa8e372a8), C32e(0xa4f762a4), C32e(0x3759bd37), + C32e(0x8b86ff8b), C32e(0x3256b132), C32e(0x43c50d43), C32e(0x59ebdc59), C32e(0xb7c2afb7), + C32e(0x8c8f028c), C32e(0x64ac7964), C32e(0xd26d23d2), C32e(0xe03b92e0), C32e(0xb4c7abb4), + C32e(0xfa1543fa), C32e(0x0709fd07), C32e(0x256f8525), C32e(0xafea8faf), C32e(0x8e89f38e), + C32e(0xe9208ee9), C32e(0x18282018), C32e(0xd564ded5), C32e(0x8883fb88), C32e(0x6fb1946f), + C32e(0x7296b872), C32e(0x246c7024), C32e(0xf108aef1), C32e(0xc752e6c7), C32e(0x51f33551), + C32e(0x23658d23), C32e(0x7c84597c), C32e(0x9cbfcb9c), C32e(0x21637c21), C32e(0xdd7c37dd), + C32e(0xdc7fc2dc), C32e(0x86911a86), C32e(0x85941e85), C32e(0x90abdb90), C32e(0x42c6f842), + C32e(0xc457e2c4), C32e(0xaae583aa), C32e(0xd8733bd8), C32e(0x050f0c05), C32e(0x0103f501), + C32e(0x12363812), C32e(0xa3fe9fa3), C32e(0x5fe1d45f), C32e(0xf91047f9), C32e(0xd06bd2d0), + C32e(0x91a82e91), C32e(0x58e82958), C32e(0x27697427), C32e(0xb9d04eb9), C32e(0x3848a938), + C32e(0x1335cd13), C32e(0xb3ce56b3), C32e(0x33554433), C32e(0xbbd6bfbb), C32e(0x70904970), + C32e(0x89800e89), C32e(0xa7f266a7), C32e(0xb6c15ab6), C32e(0x22667822), C32e(0x92ad2a92), + C32e(0x20608920), C32e(0x49db1549), C32e(0xff1a4fff), C32e(0x7888a078), C32e(0x7a8e517a), + C32e(0x8f8a068f), C32e(0xf813b2f8), C32e(0x809b1280), C32e(0x17393417), C32e(0xda75cada), + C32e(0x3153b531), C32e(0xc65113c6), C32e(0xb8d3bbb8), C32e(0xc35e1fc3), C32e(0xb0cb52b0), + C32e(0x7799b477), C32e(0x11333c11), C32e(0xcb46f6cb), C32e(0xfc1f4bfc), C32e(0xd661dad6), + C32e(0x3a4e583a)}; + +#define DECL_STATE_SMALL sph_u32 H[16] = {0}; + +#define READ_STATE_SMALL(sc) \ + do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while(0) + +#define WRITE_STATE_SMALL(sc) \ + do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while(0) + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x##y + +#define RSTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) \ + do { \ + t[d0] = T0up[B32_0(a[b0])] ^ T1up[B32_1(a[b1])] ^ T2up[B32_2(a[b2])] ^ \ + T3up[B32_3(a[b3])] ^ T0dn[B32_0(a[b4])] ^ T1dn[B32_1(a[b5])] ^ \ + T2dn[B32_2(a[b6])] ^ T3dn[B32_3(a[b7])]; \ + t[d1] = T0dn[B32_0(a[b0])] ^ T1dn[B32_1(a[b1])] ^ T2dn[B32_2(a[b2])] ^ \ + T3dn[B32_3(a[b3])] ^ T0up[B32_0(a[b4])] ^ T1up[B32_1(a[b5])] ^ \ + T2up[B32_2(a[b6])] ^ T3up[B32_3(a[b7])]; \ + } while(0) + +#define ROUND_SMALL_P(a, r) \ + do { \ + sph_u32 t[16]; \ + a[0x0] ^= PC32up(0x00, r); \ + a[0x1] ^= PC32dn(0x00, r); \ + a[0x2] ^= PC32up(0x10, r); \ + a[0x3] ^= PC32dn(0x10, r); \ + a[0x4] ^= PC32up(0x20, r); \ + a[0x5] ^= PC32dn(0x20, r); \ + a[0x6] ^= PC32up(0x30, r); \ + a[0x7] ^= PC32dn(0x30, r); \ + a[0x8] ^= PC32up(0x40, r); \ + a[0x9] ^= PC32dn(0x40, r); \ + a[0xA] ^= PC32up(0x50, r); \ + a[0xB] ^= PC32dn(0x50, r); \ + a[0xC] ^= PC32up(0x60, r); \ + a[0xD] ^= PC32dn(0x60, r); \ + a[0xE] ^= PC32up(0x70, r); \ + a[0xF] ^= PC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x0, 0x2, 0x4, 0x6, 0x9, 0xB, 0xD, 0xF); \ + RSTT(0x2, 0x3, a, 0x2, 0x4, 0x6, 0x8, 0xB, 0xD, 0xF, 0x1); \ + RSTT(0x4, 0x5, a, 0x4, 0x6, 0x8, 0xA, 0xD, 0xF, 0x1, 0x3); \ + RSTT(0x6, 0x7, a, 0x6, 0x8, 0xA, 0xC, 0xF, 0x1, 0x3, 0x5); \ + RSTT(0x8, 0x9, a, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7); \ + RSTT(0xA, 0xB, a, 0xA, 0xC, 0xE, 0x0, 0x3, 0x5, 0x7, 0x9); \ + RSTT(0xC, 0xD, a, 0xC, 0xE, 0x0, 0x2, 0x5, 0x7, 0x9, 0xB); \ + RSTT(0xE, 0xF, a, 0xE, 0x0, 0x2, 0x4, 0x7, 0x9, 0xB, 0xD); \ + memcpy(a, t, sizeof t); \ + } while(0) + +#define ROUND_SMALL_Q(a, r) \ + do { \ + sph_u32 t[16]; \ + a[0x0] ^= QC32up(0x00, r); \ + a[0x1] ^= QC32dn(0x00, r); \ + a[0x2] ^= QC32up(0x10, r); \ + a[0x3] ^= QC32dn(0x10, r); \ + a[0x4] ^= QC32up(0x20, r); \ + a[0x5] ^= QC32dn(0x20, r); \ + a[0x6] ^= QC32up(0x30, r); \ + a[0x7] ^= QC32dn(0x30, r); \ + a[0x8] ^= QC32up(0x40, r); \ + a[0x9] ^= QC32dn(0x40, r); \ + a[0xA] ^= QC32up(0x50, r); \ + a[0xB] ^= QC32dn(0x50, r); \ + a[0xC] ^= QC32up(0x60, r); \ + a[0xD] ^= QC32dn(0x60, r); \ + a[0xE] ^= QC32up(0x70, r); \ + a[0xF] ^= QC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x2, 0x6, 0xA, 0xE, 0x1, 0x5, 0x9, 0xD); \ + RSTT(0x2, 0x3, a, 0x4, 0x8, 0xC, 0x0, 0x3, 0x7, 0xB, 0xF); \ + RSTT(0x4, 0x5, a, 0x6, 0xA, 0xE, 0x2, 0x5, 0x9, 0xD, 0x1); \ + RSTT(0x6, 0x7, a, 0x8, 0xC, 0x0, 0x4, 0x7, 0xB, 0xF, 0x3); \ + RSTT(0x8, 0x9, a, 0xA, 0xE, 0x2, 0x6, 0x9, 0xD, 0x1, 0x5); \ + RSTT(0xA, 0xB, a, 0xC, 0x0, 0x4, 0x8, 0xB, 0xF, 0x3, 0x7); \ + RSTT(0xC, 0xD, a, 0xE, 0x2, 0x6, 0xA, 0xD, 0x1, 0x5, 0x9); \ + RSTT(0xE, 0xF, a, 0x0, 0x4, 0x8, 0xC, 0xF, 0x3, 0x7, 0xB); \ + memcpy(a, t, sizeof t); \ + } while(0) + +#define PERM_SMALL_P(a) \ + do { \ + int r; \ + for(r = 0; r < 10; r++) ROUND_SMALL_P(a, r); \ + } while(0) + +#define PERM_SMALL_Q(a) \ + do { \ + int r; \ + for(r = 0; r < 10; r++) ROUND_SMALL_Q(a, r); \ + } while(0) + +#define COMPRESS_SMALL \ + do { \ + sph_u32 g[16], m[16]; \ + size_t u; \ + for(u = 0; u < 16; u++) { \ + m[u] = dec32e_aligned(buf + (u << 2)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_SMALL_P(g); \ + PERM_SMALL_Q(m); \ + for(u = 0; u < 16; u++) H[u] ^= g[u] ^ m[u]; \ + } while(0) + +#define FINAL_SMALL \ + do { \ + sph_u32 x[16]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_SMALL_P(x); \ + for(u = 0; u < 16; u++) H[u] ^= x[u]; \ + } while(0) + +#define DECL_STATE_BIG sph_u32 H[32] = {0}; + +#define READ_STATE_BIG(sc) \ + do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while(0) + +#define WRITE_STATE_BIG(sc) \ + do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while(0) + +#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) \ + do { \ + sph_u32 fu2 = T0up[B32_2(a[b2])]; \ + sph_u32 fd2 = T0dn[B32_2(a[b2])]; \ + sph_u32 fu3 = T1up[B32_3(a[b3])]; \ + sph_u32 fd3 = T1dn[B32_3(a[b3])]; \ + sph_u32 fu6 = T0up[B32_2(a[b6])]; \ + sph_u32 fd6 = T0dn[B32_2(a[b6])]; \ + sph_u32 fu7 = T1up[B32_3(a[b7])]; \ + sph_u32 fd7 = T1dn[B32_3(a[b7])]; \ + t[d0] = T0up[B32_0(a[b0])] ^ T1up[B32_1(a[b1])] ^ R32u(fu2, fd2) ^ R32u(fu3, fd3) ^ \ + T0dn[B32_0(a[b4])] ^ T1dn[B32_1(a[b5])] ^ R32d(fu6, fd6) ^ R32d(fu7, fd7); \ + t[d1] = T0dn[B32_0(a[b0])] ^ T1dn[B32_1(a[b1])] ^ R32d(fu2, fd2) ^ R32d(fu3, fd3) ^ \ + T0up[B32_0(a[b4])] ^ T1up[B32_1(a[b5])] ^ R32u(fu6, fd6) ^ R32u(fu7, fd7); \ + } while(0) + +#define ROUND_BIG_P(a, r) \ + do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= PC32up(0x00, r); \ + a[0x01] ^= PC32dn(0x00, r); \ + a[0x02] ^= PC32up(0x10, r); \ + a[0x03] ^= PC32dn(0x10, r); \ + a[0x04] ^= PC32up(0x20, r); \ + a[0x05] ^= PC32dn(0x20, r); \ + a[0x06] ^= PC32up(0x30, r); \ + a[0x07] ^= PC32dn(0x30, r); \ + a[0x08] ^= PC32up(0x40, r); \ + a[0x09] ^= PC32dn(0x40, r); \ + a[0x0A] ^= PC32up(0x50, r); \ + a[0x0B] ^= PC32dn(0x50, r); \ + a[0x0C] ^= PC32up(0x60, r); \ + a[0x0D] ^= PC32dn(0x60, r); \ + a[0x0E] ^= PC32up(0x70, r); \ + a[0x0F] ^= PC32dn(0x70, r); \ + a[0x10] ^= PC32up(0x80, r); \ + a[0x11] ^= PC32dn(0x80, r); \ + a[0x12] ^= PC32up(0x90, r); \ + a[0x13] ^= PC32dn(0x90, r); \ + a[0x14] ^= PC32up(0xA0, r); \ + a[0x15] ^= PC32dn(0xA0, r); \ + a[0x16] ^= PC32up(0xB0, r); \ + a[0x17] ^= PC32dn(0xB0, r); \ + a[0x18] ^= PC32up(0xC0, r); \ + a[0x19] ^= PC32dn(0xC0, r); \ + a[0x1A] ^= PC32up(0xD0, r); \ + a[0x1B] ^= PC32dn(0xD0, r); \ + a[0x1C] ^= PC32up(0xE0, r); \ + a[0x1D] ^= PC32dn(0xE0, r); \ + a[0x1E] ^= PC32up(0xF0, r); \ + a[0x1F] ^= PC32dn(0xF0, r); \ + for(u = 0; u < 32; u += 8) { \ + RBTT( \ + u + 0x00, \ + (u + 0x01) & 0x1F, \ + a, \ + u + 0x00, \ + (u + 0x02) & 0x1F, \ + (u + 0x04) & 0x1F, \ + (u + 0x06) & 0x1F, \ + (u + 0x09) & 0x1F, \ + (u + 0x0B) & 0x1F, \ + (u + 0x0D) & 0x1F, \ + (u + 0x17) & 0x1F); \ + RBTT( \ + u + 0x02, \ + (u + 0x03) & 0x1F, \ + a, \ + u + 0x02, \ + (u + 0x04) & 0x1F, \ + (u + 0x06) & 0x1F, \ + (u + 0x08) & 0x1F, \ + (u + 0x0B) & 0x1F, \ + (u + 0x0D) & 0x1F, \ + (u + 0x0F) & 0x1F, \ + (u + 0x19) & 0x1F); \ + RBTT( \ + u + 0x04, \ + (u + 0x05) & 0x1F, \ + a, \ + u + 0x04, \ + (u + 0x06) & 0x1F, \ + (u + 0x08) & 0x1F, \ + (u + 0x0A) & 0x1F, \ + (u + 0x0D) & 0x1F, \ + (u + 0x0F) & 0x1F, \ + (u + 0x11) & 0x1F, \ + (u + 0x1B) & 0x1F); \ + RBTT( \ + u + 0x06, \ + (u + 0x07) & 0x1F, \ + a, \ + u + 0x06, \ + (u + 0x08) & 0x1F, \ + (u + 0x0A) & 0x1F, \ + (u + 0x0C) & 0x1F, \ + (u + 0x0F) & 0x1F, \ + (u + 0x11) & 0x1F, \ + (u + 0x13) & 0x1F, \ + (u + 0x1D) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while(0) + +#define ROUND_BIG_Q(a, r) \ + do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= QC32up(0x00, r); \ + a[0x01] ^= QC32dn(0x00, r); \ + a[0x02] ^= QC32up(0x10, r); \ + a[0x03] ^= QC32dn(0x10, r); \ + a[0x04] ^= QC32up(0x20, r); \ + a[0x05] ^= QC32dn(0x20, r); \ + a[0x06] ^= QC32up(0x30, r); \ + a[0x07] ^= QC32dn(0x30, r); \ + a[0x08] ^= QC32up(0x40, r); \ + a[0x09] ^= QC32dn(0x40, r); \ + a[0x0A] ^= QC32up(0x50, r); \ + a[0x0B] ^= QC32dn(0x50, r); \ + a[0x0C] ^= QC32up(0x60, r); \ + a[0x0D] ^= QC32dn(0x60, r); \ + a[0x0E] ^= QC32up(0x70, r); \ + a[0x0F] ^= QC32dn(0x70, r); \ + a[0x10] ^= QC32up(0x80, r); \ + a[0x11] ^= QC32dn(0x80, r); \ + a[0x12] ^= QC32up(0x90, r); \ + a[0x13] ^= QC32dn(0x90, r); \ + a[0x14] ^= QC32up(0xA0, r); \ + a[0x15] ^= QC32dn(0xA0, r); \ + a[0x16] ^= QC32up(0xB0, r); \ + a[0x17] ^= QC32dn(0xB0, r); \ + a[0x18] ^= QC32up(0xC0, r); \ + a[0x19] ^= QC32dn(0xC0, r); \ + a[0x1A] ^= QC32up(0xD0, r); \ + a[0x1B] ^= QC32dn(0xD0, r); \ + a[0x1C] ^= QC32up(0xE0, r); \ + a[0x1D] ^= QC32dn(0xE0, r); \ + a[0x1E] ^= QC32up(0xF0, r); \ + a[0x1F] ^= QC32dn(0xF0, r); \ + for(u = 0; u < 32; u += 8) { \ + RBTT( \ + u + 0x00, \ + (u + 0x01) & 0x1F, \ + a, \ + (u + 0x02) & 0x1F, \ + (u + 0x06) & 0x1F, \ + (u + 0x0A) & 0x1F, \ + (u + 0x16) & 0x1F, \ + (u + 0x01) & 0x1F, \ + (u + 0x05) & 0x1F, \ + (u + 0x09) & 0x1F, \ + (u + 0x0D) & 0x1F); \ + RBTT( \ + u + 0x02, \ + (u + 0x03) & 0x1F, \ + a, \ + (u + 0x04) & 0x1F, \ + (u + 0x08) & 0x1F, \ + (u + 0x0C) & 0x1F, \ + (u + 0x18) & 0x1F, \ + (u + 0x03) & 0x1F, \ + (u + 0x07) & 0x1F, \ + (u + 0x0B) & 0x1F, \ + (u + 0x0F) & 0x1F); \ + RBTT( \ + u + 0x04, \ + (u + 0x05) & 0x1F, \ + a, \ + (u + 0x06) & 0x1F, \ + (u + 0x0A) & 0x1F, \ + (u + 0x0E) & 0x1F, \ + (u + 0x1A) & 0x1F, \ + (u + 0x05) & 0x1F, \ + (u + 0x09) & 0x1F, \ + (u + 0x0D) & 0x1F, \ + (u + 0x11) & 0x1F); \ + RBTT( \ + u + 0x06, \ + (u + 0x07) & 0x1F, \ + a, \ + (u + 0x08) & 0x1F, \ + (u + 0x0C) & 0x1F, \ + (u + 0x10) & 0x1F, \ + (u + 0x1C) & 0x1F, \ + (u + 0x07) & 0x1F, \ + (u + 0x0B) & 0x1F, \ + (u + 0x0F) & 0x1F, \ + (u + 0x13) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while(0) + +#define PERM_BIG_P(a) \ + do { \ + int r; \ + for(r = 0; r < 14; r++) ROUND_BIG_P(a, r); \ + } while(0) + +#define PERM_BIG_Q(a) \ + do { \ + int r; \ + for(r = 0; r < 14; r++) ROUND_BIG_Q(a, r); \ + } while(0) + +#define COMPRESS_BIG \ + do { \ + sph_u32 g[32], m[32]; \ + size_t uu; \ + for(uu = 0; uu < 32; uu++) { \ + m[uu] = dec32e_aligned(buf + (uu << 2)); \ + g[uu] = m[uu] ^ H[uu]; \ + } \ + PERM_BIG_P(g); \ + PERM_BIG_Q(m); \ + for(uu = 0; uu < 32; uu++) H[uu] ^= g[uu] ^ m[uu]; \ + } while(0) + +#define FINAL_BIG \ + do { \ + sph_u32 x[32]; \ + size_t uu; \ + memcpy(x, H, sizeof x); \ + PERM_BIG_P(x); \ + for(uu = 0; uu < 32; uu++) H[uu] ^= x[uu]; \ + } while(0) + +static void groestl_big_init(sph_groestl_big_context* sc, unsigned out_size) { + size_t u = 0; + + sc->ptr = 0; + for(u = 0; u < 31; u++) sc->state.narrow[u] = 0; + sc->state.narrow[31] = ((sph_u32)(out_size & 0xFF) << 24) | + ((sph_u32)(out_size & 0xFF00) << 8); + sc->count = 0; } -static void -groestl_big_core(sph_groestl_big_context *sc, const void *data, size_t len) -{ - if (len == 0) { - return; - } - - unsigned char *buf = NULL; - size_t ptr = 0; - DECL_STATE_BIG - - buf = sc->buf; - ptr = sc->ptr; - if (len < (sizeof sc->buf) - ptr) { - memcpy(buf + ptr, data, len); - ptr += len; - sc->ptr = ptr; - return; - } - - READ_STATE_BIG(sc); - while (len > 0) { - size_t clen = 0; - - clen = (sizeof sc->buf) - ptr; - if (clen > len) - clen = len; - memcpy(buf + ptr, data, clen); - ptr += clen; - data = (const unsigned char *)data + clen; - len -= clen; - if (ptr == sizeof sc->buf) { - COMPRESS_BIG; - sc->count ++; - ptr = 0; - } - } - WRITE_STATE_BIG(sc); - sc->ptr = ptr; +static void groestl_big_core(sph_groestl_big_context* sc, const void* data, size_t len) { + if(len == 0) { + return; + } + + unsigned char* buf = NULL; + size_t ptr = 0; + DECL_STATE_BIG + + buf = sc->buf; + ptr = sc->ptr; + if(len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE_BIG(sc); + while(len > 0) { + size_t clen = 0; + + clen = (sizeof sc->buf) - ptr; + if(clen > len) clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char*)data + clen; + len -= clen; + if(ptr == sizeof sc->buf) { + COMPRESS_BIG; + sc->count++; + ptr = 0; + } + } + WRITE_STATE_BIG(sc); + sc->ptr = ptr; } -static void -groestl_big_close(sph_groestl_big_context *sc, - unsigned ub, unsigned n, void *dst, size_t out_len) -{ - unsigned char pad[136] = {0}; - size_t ptr = 0, pad_len = 0, u2 = 0; - sph_u64 count = 0; - unsigned z = 0; - DECL_STATE_BIG - - ptr = sc->ptr; - z = 0x80 >> n; - pad[0] = ((ub & -z) | z) & 0xFF; - if (ptr < 120) { - pad_len = 128 - ptr; - count = SPH_T64(sc->count + 1); - } else { - pad_len = 256 - ptr; - count = SPH_T64(sc->count + 2); - } - memzero(pad + 1, pad_len - 9); - sph_enc64be(pad + pad_len - 8, count); - groestl_big_core(sc, pad, pad_len); - READ_STATE_BIG(sc); - FINAL_BIG; - for (u2 = 0; u2 < 16; u2 ++) - enc32e(pad + (u2 << 2), H[u2 + 16]); - memcpy(dst, pad + 64 - out_len, out_len); - groestl_big_init(sc, (unsigned)out_len << 3); +static void groestl_big_close( + sph_groestl_big_context* sc, + unsigned ub, + unsigned n, + void* dst, + size_t out_len) { + unsigned char pad[136] = {0}; + size_t ptr = 0, pad_len = 0, u2 = 0; + sph_u64 count = 0; + unsigned z = 0; + DECL_STATE_BIG + + ptr = sc->ptr; + z = 0x80 >> n; + pad[0] = ((ub & -z) | z) & 0xFF; + if(ptr < 120) { + pad_len = 128 - ptr; + count = SPH_T64(sc->count + 1); + } else { + pad_len = 256 - ptr; + count = SPH_T64(sc->count + 2); + } + memzero(pad + 1, pad_len - 9); + sph_enc64be(pad + pad_len - 8, count); + groestl_big_core(sc, pad, pad_len); + READ_STATE_BIG(sc); + FINAL_BIG; + for(u2 = 0; u2 < 16; u2++) enc32e(pad + (u2 << 2), H[u2 + 16]); + memcpy(dst, pad + 64 - out_len, out_len); + groestl_big_init(sc, (unsigned)out_len << 3); } -void -groestl512_Init(void *cc) -{ - groestl_big_init((sph_groestl_big_context *)cc, 512); +void groestl512_Init(void* cc) { + groestl_big_init((sph_groestl_big_context*)cc, 512); } -void -groestl512_Update(void *cc, const void *data, size_t len) -{ - groestl_big_core((sph_groestl_big_context *)cc, data, len); +void groestl512_Update(void* cc, const void* data, size_t len) { + groestl_big_core((sph_groestl_big_context*)cc, data, len); } -void -groestl512_Final(void *cc, void *dst) -{ - groestl_big_close((sph_groestl_big_context *)cc, 0, 0, dst, 64); +void groestl512_Final(void* cc, void* dst) { + groestl_big_close((sph_groestl_big_context*)cc, 0, 0, dst, 64); } -void -groestl512_DoubleTrunc(void *cc, void *dst) -{ - char buf[64] = {0}; +void groestl512_DoubleTrunc(void* cc, void* dst) { + char buf[64] = {0}; - groestl512_Final(cc, buf); - groestl512_Update(cc, buf, sizeof(buf)); - groestl512_Final(cc, buf); - memcpy(dst, buf, 32); + groestl512_Final(cc, buf); + groestl512_Update(cc, buf, sizeof(buf)); + groestl512_Final(cc, buf); + memcpy(dst, buf, 32); } diff --git a/crypto/groestl.h b/crypto/groestl.h index 7dd89d28a84..a4871deff2c 100644 --- a/crypto/groestl.h +++ b/crypto/groestl.h @@ -49,13 +49,13 @@ * memcpy()). */ typedef struct { - unsigned char buf[128]; /* first field, for alignment */ - size_t ptr; - union { - uint64_t wide[16]; - uint32_t narrow[32]; - } state; - uint64_t count; + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + union { + uint64_t wide[16]; + uint32_t narrow[32]; + } state; + uint64_t count; } sph_groestl_big_context; typedef sph_groestl_big_context GROESTL512_CTX; @@ -66,7 +66,7 @@ typedef sph_groestl_big_context GROESTL512_CTX; * @param cc the Groestl-512 context (pointer to a * GROESTL512_CTX) */ -void groestl512_Init(void *cc); +void groestl512_Init(void* cc); /** * Process some data bytes. It is acceptable that len is zero @@ -76,7 +76,7 @@ void groestl512_Init(void *cc); * @param data the input data * @param len the input data length (in bytes) */ -void groestl512_Update(void *cc, const void *data, size_t len); +void groestl512_Update(void* cc, const void* data, size_t len); /** * Terminate the current Groestl-512 computation and output the result into @@ -87,9 +87,9 @@ void groestl512_Update(void *cc, const void *data, size_t len); * @param cc the Groestl-512 context * @param dst the destination buffer */ -void groestl512_Final(void *cc, void *dst); +void groestl512_Final(void* cc, void* dst); /* Calculate double Groestl-512 hash and truncate it to 256-bits. */ -void groestl512_DoubleTrunc(void *cc, void *dst); +void groestl512_DoubleTrunc(void* cc, void* dst); #endif diff --git a/crypto/groestl_internal.h b/crypto/groestl_internal.h index 3c675d8eac9..3859ff5326e 100644 --- a/crypto/groestl_internal.h +++ b/crypto/groestl_internal.h @@ -67,70 +67,66 @@ typedef int32_t sph_s32; typedef uint64_t sph_u64; typedef int64_t sph_s64; -#define SPH_C32(x) ((sph_u32)(x)) -#define SPH_C64(x) ((sph_u64)(x)) +#define SPH_C32(x) ((sph_u32)(x)) +#define SPH_C64(x) ((sph_u64)(x)) #else #error We need at least C99 compiler #endif -#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) -#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n)))) -#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n))) +#define SPH_T32(x) ((x)&SPH_C32(0xFFFFFFFF)) +#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n)))) +#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n))) -#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) -#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n)))) -#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n))) +#define SPH_T64(x) ((x)&SPH_C64(0xFFFFFFFFFFFFFFFF)) +#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n)))) +#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n))) /* * 32-bit x86, aka "i386 compatible". */ #if defined __i386__ || defined _M_IX86 -#define SPH_DETECT_LITTLE_ENDIAN 1 -#define SPH_DETECT_BIG_ENDIAN 0 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_BIG_ENDIAN 0 /* * 64-bit x86, hereafter known as "amd64". */ #elif defined __x86_64 || defined _M_X64 -#define SPH_DETECT_LITTLE_ENDIAN 1 -#define SPH_DETECT_BIG_ENDIAN 0 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_BIG_ENDIAN 0 /* * ARM, little-endian. */ #elif defined __arm__ && __ARMEL__ -#define SPH_DETECT_LITTLE_ENDIAN 1 -#define SPH_DETECT_BIG_ENDIAN 0 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_BIG_ENDIAN 0 /* * ARM64, little-endian. */ #elif defined __aarch64__ -#define SPH_DETECT_LITTLE_ENDIAN 1 -#define SPH_DETECT_BIG_ENDIAN 0 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_BIG_ENDIAN 0 #endif - #if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN -#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN +#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN #endif #if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN -#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN +#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN #endif -static inline sph_u32 -sph_bswap32(sph_u32 x) -{ - x = SPH_T32((x << 16) | (x >> 16)); - x = ((x & SPH_C32(0xFF00FF00)) >> 8) - | ((x & SPH_C32(0x00FF00FF)) << 8); - return x; +static inline sph_u32 sph_bswap32(sph_u32 x) { + x = SPH_T32((x << 16) | (x >> 16)); + x = ((x & SPH_C32(0xFF00FF00)) >> 8) | ((x & SPH_C32(0x00FF00FF)) << 8); + return x; } /** @@ -139,43 +135,31 @@ sph_bswap32(sph_u32 x) * @param x the input value * @return the byte-swapped value */ -static inline sph_u64 -sph_bswap64(sph_u64 x) -{ - x = SPH_T64((x << 32) | (x >> 32)); - x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) - | ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16); - x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) - | ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8); - return x; +static inline sph_u64 sph_bswap64(sph_u64 x) { + x = SPH_T64((x << 32) | (x >> 32)); + x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) | ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16); + x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) | ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8); + return x; } -static inline void -sph_enc16be(void *dst, unsigned val) -{ - ((unsigned char *)dst)[0] = (val >> 8); - ((unsigned char *)dst)[1] = val; +static inline void sph_enc16be(void* dst, unsigned val) { + ((unsigned char*)dst)[0] = (val >> 8); + ((unsigned char*)dst)[1] = val; } -static inline unsigned -sph_dec16be(const void *src) -{ - return ((unsigned)(((const unsigned char *)src)[0]) << 8) - | (unsigned)(((const unsigned char *)src)[1]); +static inline unsigned sph_dec16be(const void* src) { + return ((unsigned)(((const unsigned char*)src)[0]) << 8) | + (unsigned)(((const unsigned char*)src)[1]); } -static inline void -sph_enc16le(void *dst, unsigned val) -{ - ((unsigned char *)dst)[0] = val; - ((unsigned char *)dst)[1] = val >> 8; +static inline void sph_enc16le(void* dst, unsigned val) { + ((unsigned char*)dst)[0] = val; + ((unsigned char*)dst)[1] = val >> 8; } -static inline unsigned -sph_dec16le(const void *src) -{ - return (unsigned)(((const unsigned char *)src)[0]) - | ((unsigned)(((const unsigned char *)src)[1]) << 8); +static inline unsigned sph_dec16le(const void* src) { + return (unsigned)(((const unsigned char*)src)[0]) | + ((unsigned)(((const unsigned char*)src)[1]) << 8); } /** @@ -184,13 +168,11 @@ sph_dec16le(const void *src) * @param dst the destination buffer * @param val the 32-bit value to encode */ -static inline void -sph_enc32be(void *dst, sph_u32 val) -{ - ((unsigned char *)dst)[0] = (val >> 24); - ((unsigned char *)dst)[1] = (val >> 16); - ((unsigned char *)dst)[2] = (val >> 8); - ((unsigned char *)dst)[3] = val; +static inline void sph_enc32be(void* dst, sph_u32 val) { + ((unsigned char*)dst)[0] = (val >> 24); + ((unsigned char*)dst)[1] = (val >> 16); + ((unsigned char*)dst)[2] = (val >> 8); + ((unsigned char*)dst)[3] = val; } /** @@ -200,18 +182,16 @@ sph_enc32be(void *dst, sph_u32 val) * @param dst the destination buffer (32-bit aligned) * @param val the value to encode */ -static inline void -sph_enc32be_aligned(void *dst, sph_u32 val) -{ +static inline void sph_enc32be_aligned(void* dst, sph_u32 val) { #if SPH_LITTLE_ENDIAN - *(sph_u32 *)dst = sph_bswap32(val); + *(sph_u32*)dst = sph_bswap32(val); #elif SPH_BIG_ENDIAN - *(sph_u32 *)dst = val; + *(sph_u32*)dst = val; #else - ((unsigned char *)dst)[0] = (val >> 24); - ((unsigned char *)dst)[1] = (val >> 16); - ((unsigned char *)dst)[2] = (val >> 8); - ((unsigned char *)dst)[3] = val; + ((unsigned char*)dst)[0] = (val >> 24); + ((unsigned char*)dst)[1] = (val >> 16); + ((unsigned char*)dst)[2] = (val >> 8); + ((unsigned char*)dst)[3] = val; #endif } @@ -221,13 +201,11 @@ sph_enc32be_aligned(void *dst, sph_u32 val) * @param src the source buffer * @return the decoded value */ -static inline sph_u32 -sph_dec32be(const void *src) -{ - return ((sph_u32)(((const unsigned char *)src)[0]) << 24) - | ((sph_u32)(((const unsigned char *)src)[1]) << 16) - | ((sph_u32)(((const unsigned char *)src)[2]) << 8) - | (sph_u32)(((const unsigned char *)src)[3]); +static inline sph_u32 sph_dec32be(const void* src) { + return ((sph_u32)(((const unsigned char*)src)[0]) << 24) | + ((sph_u32)(((const unsigned char*)src)[1]) << 16) | + ((sph_u32)(((const unsigned char*)src)[2]) << 8) | + (sph_u32)(((const unsigned char*)src)[3]); } /** @@ -237,18 +215,16 @@ sph_dec32be(const void *src) * @param src the source buffer (32-bit aligned) * @return the decoded value */ -static inline sph_u32 -sph_dec32be_aligned(const void *src) -{ +static inline sph_u32 sph_dec32be_aligned(const void* src) { #if SPH_LITTLE_ENDIAN - return sph_bswap32(*(const sph_u32 *)src); + return sph_bswap32(*(const sph_u32*)src); #elif SPH_BIG_ENDIAN - return *(const sph_u32 *)src; + return *(const sph_u32*)src; #else - return ((sph_u32)(((const unsigned char *)src)[0]) << 24) - | ((sph_u32)(((const unsigned char *)src)[1]) << 16) - | ((sph_u32)(((const unsigned char *)src)[2]) << 8) - | (sph_u32)(((const unsigned char *)src)[3]); + return ((sph_u32)(((const unsigned char*)src)[0]) << 24) | + ((sph_u32)(((const unsigned char*)src)[1]) << 16) | + ((sph_u32)(((const unsigned char*)src)[2]) << 8) | + (sph_u32)(((const unsigned char*)src)[3]); #endif } @@ -258,13 +234,11 @@ sph_dec32be_aligned(const void *src) * @param dst the destination buffer * @param val the 32-bit value to encode */ -static inline void -sph_enc32le(void *dst, sph_u32 val) -{ - ((unsigned char *)dst)[0] = val; - ((unsigned char *)dst)[1] = (val >> 8); - ((unsigned char *)dst)[2] = (val >> 16); - ((unsigned char *)dst)[3] = (val >> 24); +static inline void sph_enc32le(void* dst, sph_u32 val) { + ((unsigned char*)dst)[0] = val; + ((unsigned char*)dst)[1] = (val >> 8); + ((unsigned char*)dst)[2] = (val >> 16); + ((unsigned char*)dst)[3] = (val >> 24); } /** @@ -274,18 +248,16 @@ sph_enc32le(void *dst, sph_u32 val) * @param dst the destination buffer (32-bit aligned) * @param val the value to encode */ -static inline void -sph_enc32le_aligned(void *dst, sph_u32 val) -{ +static inline void sph_enc32le_aligned(void* dst, sph_u32 val) { #if SPH_LITTLE_ENDIAN - *(sph_u32 *)dst = val; + *(sph_u32*)dst = val; #elif SPH_BIG_ENDIAN - *(sph_u32 *)dst = sph_bswap32(val); + *(sph_u32*)dst = sph_bswap32(val); #else - ((unsigned char *)dst)[0] = val; - ((unsigned char *)dst)[1] = (val >> 8); - ((unsigned char *)dst)[2] = (val >> 16); - ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char*)dst)[0] = val; + ((unsigned char*)dst)[1] = (val >> 8); + ((unsigned char*)dst)[2] = (val >> 16); + ((unsigned char*)dst)[3] = (val >> 24); #endif } @@ -295,13 +267,11 @@ sph_enc32le_aligned(void *dst, sph_u32 val) * @param src the source buffer * @return the decoded value */ -static inline sph_u32 -sph_dec32le(const void *src) -{ - return (sph_u32)(((const unsigned char *)src)[0]) - | ((sph_u32)(((const unsigned char *)src)[1]) << 8) - | ((sph_u32)(((const unsigned char *)src)[2]) << 16) - | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +static inline sph_u32 sph_dec32le(const void* src) { + return (sph_u32)(((const unsigned char*)src)[0]) | + ((sph_u32)(((const unsigned char*)src)[1]) << 8) | + ((sph_u32)(((const unsigned char*)src)[2]) << 16) | + ((sph_u32)(((const unsigned char*)src)[3]) << 24); } /** @@ -311,18 +281,16 @@ sph_dec32le(const void *src) * @param src the source buffer (32-bit aligned) * @return the decoded value */ -static inline sph_u32 -sph_dec32le_aligned(const void *src) -{ +static inline sph_u32 sph_dec32le_aligned(const void* src) { #if SPH_LITTLE_ENDIAN - return *(const sph_u32 *)src; + return *(const sph_u32*)src; #elif SPH_BIG_ENDIAN - return sph_bswap32(*(const sph_u32 *)src); + return sph_bswap32(*(const sph_u32*)src); #else - return (sph_u32)(((const unsigned char *)src)[0]) - | ((sph_u32)(((const unsigned char *)src)[1]) << 8) - | ((sph_u32)(((const unsigned char *)src)[2]) << 16) - | ((sph_u32)(((const unsigned char *)src)[3]) << 24); + return (sph_u32)(((const unsigned char*)src)[0]) | + ((sph_u32)(((const unsigned char*)src)[1]) << 8) | + ((sph_u32)(((const unsigned char*)src)[2]) << 16) | + ((sph_u32)(((const unsigned char*)src)[3]) << 24); #endif } @@ -332,17 +300,15 @@ sph_dec32le_aligned(const void *src) * @param dst the destination buffer * @param val the 64-bit value to encode */ -static inline void -sph_enc64be(void *dst, sph_u64 val) -{ - ((unsigned char *)dst)[0] = (val >> 56); - ((unsigned char *)dst)[1] = (val >> 48); - ((unsigned char *)dst)[2] = (val >> 40); - ((unsigned char *)dst)[3] = (val >> 32); - ((unsigned char *)dst)[4] = (val >> 24); - ((unsigned char *)dst)[5] = (val >> 16); - ((unsigned char *)dst)[6] = (val >> 8); - ((unsigned char *)dst)[7] = val; +static inline void sph_enc64be(void* dst, sph_u64 val) { + ((unsigned char*)dst)[0] = (val >> 56); + ((unsigned char*)dst)[1] = (val >> 48); + ((unsigned char*)dst)[2] = (val >> 40); + ((unsigned char*)dst)[3] = (val >> 32); + ((unsigned char*)dst)[4] = (val >> 24); + ((unsigned char*)dst)[5] = (val >> 16); + ((unsigned char*)dst)[6] = (val >> 8); + ((unsigned char*)dst)[7] = val; } /** @@ -352,22 +318,20 @@ sph_enc64be(void *dst, sph_u64 val) * @param dst the destination buffer (64-bit aligned) * @param val the value to encode */ -static inline void -sph_enc64be_aligned(void *dst, sph_u64 val) -{ +static inline void sph_enc64be_aligned(void* dst, sph_u64 val) { #if SPH_LITTLE_ENDIAN - *(sph_u64 *)dst = sph_bswap64(val); + *(sph_u64*)dst = sph_bswap64(val); #elif SPH_BIG_ENDIAN - *(sph_u64 *)dst = val; + *(sph_u64*)dst = val; #else - ((unsigned char *)dst)[0] = (val >> 56); - ((unsigned char *)dst)[1] = (val >> 48); - ((unsigned char *)dst)[2] = (val >> 40); - ((unsigned char *)dst)[3] = (val >> 32); - ((unsigned char *)dst)[4] = (val >> 24); - ((unsigned char *)dst)[5] = (val >> 16); - ((unsigned char *)dst)[6] = (val >> 8); - ((unsigned char *)dst)[7] = val; + ((unsigned char*)dst)[0] = (val >> 56); + ((unsigned char*)dst)[1] = (val >> 48); + ((unsigned char*)dst)[2] = (val >> 40); + ((unsigned char*)dst)[3] = (val >> 32); + ((unsigned char*)dst)[4] = (val >> 24); + ((unsigned char*)dst)[5] = (val >> 16); + ((unsigned char*)dst)[6] = (val >> 8); + ((unsigned char*)dst)[7] = val; #endif } @@ -377,17 +341,15 @@ sph_enc64be_aligned(void *dst, sph_u64 val) * @param src the source buffer * @return the decoded value */ -static inline sph_u64 -sph_dec64be(const void *src) -{ - return ((sph_u64)(((const unsigned char *)src)[0]) << 56) - | ((sph_u64)(((const unsigned char *)src)[1]) << 48) - | ((sph_u64)(((const unsigned char *)src)[2]) << 40) - | ((sph_u64)(((const unsigned char *)src)[3]) << 32) - | ((sph_u64)(((const unsigned char *)src)[4]) << 24) - | ((sph_u64)(((const unsigned char *)src)[5]) << 16) - | ((sph_u64)(((const unsigned char *)src)[6]) << 8) - | (sph_u64)(((const unsigned char *)src)[7]); +static inline sph_u64 sph_dec64be(const void* src) { + return ((sph_u64)(((const unsigned char*)src)[0]) << 56) | + ((sph_u64)(((const unsigned char*)src)[1]) << 48) | + ((sph_u64)(((const unsigned char*)src)[2]) << 40) | + ((sph_u64)(((const unsigned char*)src)[3]) << 32) | + ((sph_u64)(((const unsigned char*)src)[4]) << 24) | + ((sph_u64)(((const unsigned char*)src)[5]) << 16) | + ((sph_u64)(((const unsigned char*)src)[6]) << 8) | + (sph_u64)(((const unsigned char*)src)[7]); } /** @@ -397,22 +359,20 @@ sph_dec64be(const void *src) * @param src the source buffer (64-bit aligned) * @return the decoded value */ -static inline sph_u64 -sph_dec64be_aligned(const void *src) -{ +static inline sph_u64 sph_dec64be_aligned(const void* src) { #if SPH_LITTLE_ENDIAN - return sph_bswap64(*(const sph_u64 *)src); + return sph_bswap64(*(const sph_u64*)src); #elif SPH_BIG_ENDIAN - return *(const sph_u64 *)src; + return *(const sph_u64*)src; #else - return ((sph_u64)(((const unsigned char *)src)[0]) << 56) - | ((sph_u64)(((const unsigned char *)src)[1]) << 48) - | ((sph_u64)(((const unsigned char *)src)[2]) << 40) - | ((sph_u64)(((const unsigned char *)src)[3]) << 32) - | ((sph_u64)(((const unsigned char *)src)[4]) << 24) - | ((sph_u64)(((const unsigned char *)src)[5]) << 16) - | ((sph_u64)(((const unsigned char *)src)[6]) << 8) - | (sph_u64)(((const unsigned char *)src)[7]); + return ((sph_u64)(((const unsigned char*)src)[0]) << 56) | + ((sph_u64)(((const unsigned char*)src)[1]) << 48) | + ((sph_u64)(((const unsigned char*)src)[2]) << 40) | + ((sph_u64)(((const unsigned char*)src)[3]) << 32) | + ((sph_u64)(((const unsigned char*)src)[4]) << 24) | + ((sph_u64)(((const unsigned char*)src)[5]) << 16) | + ((sph_u64)(((const unsigned char*)src)[6]) << 8) | + (sph_u64)(((const unsigned char*)src)[7]); #endif } @@ -422,17 +382,15 @@ sph_dec64be_aligned(const void *src) * @param dst the destination buffer * @param val the 64-bit value to encode */ -static inline void -sph_enc64le(void *dst, sph_u64 val) -{ - ((unsigned char *)dst)[0] = val; - ((unsigned char *)dst)[1] = (val >> 8); - ((unsigned char *)dst)[2] = (val >> 16); - ((unsigned char *)dst)[3] = (val >> 24); - ((unsigned char *)dst)[4] = (val >> 32); - ((unsigned char *)dst)[5] = (val >> 40); - ((unsigned char *)dst)[6] = (val >> 48); - ((unsigned char *)dst)[7] = (val >> 56); +static inline void sph_enc64le(void* dst, sph_u64 val) { + ((unsigned char*)dst)[0] = val; + ((unsigned char*)dst)[1] = (val >> 8); + ((unsigned char*)dst)[2] = (val >> 16); + ((unsigned char*)dst)[3] = (val >> 24); + ((unsigned char*)dst)[4] = (val >> 32); + ((unsigned char*)dst)[5] = (val >> 40); + ((unsigned char*)dst)[6] = (val >> 48); + ((unsigned char*)dst)[7] = (val >> 56); } /** @@ -442,22 +400,20 @@ sph_enc64le(void *dst, sph_u64 val) * @param dst the destination buffer (64-bit aligned) * @param val the value to encode */ -static inline void -sph_enc64le_aligned(void *dst, sph_u64 val) -{ +static inline void sph_enc64le_aligned(void* dst, sph_u64 val) { #if SPH_LITTLE_ENDIAN - *(sph_u64 *)dst = val; + *(sph_u64*)dst = val; #elif SPH_BIG_ENDIAN - *(sph_u64 *)dst = sph_bswap64(val); + *(sph_u64*)dst = sph_bswap64(val); #else - ((unsigned char *)dst)[0] = val; - ((unsigned char *)dst)[1] = (val >> 8); - ((unsigned char *)dst)[2] = (val >> 16); - ((unsigned char *)dst)[3] = (val >> 24); - ((unsigned char *)dst)[4] = (val >> 32); - ((unsigned char *)dst)[5] = (val >> 40); - ((unsigned char *)dst)[6] = (val >> 48); - ((unsigned char *)dst)[7] = (val >> 56); + ((unsigned char*)dst)[0] = val; + ((unsigned char*)dst)[1] = (val >> 8); + ((unsigned char*)dst)[2] = (val >> 16); + ((unsigned char*)dst)[3] = (val >> 24); + ((unsigned char*)dst)[4] = (val >> 32); + ((unsigned char*)dst)[5] = (val >> 40); + ((unsigned char*)dst)[6] = (val >> 48); + ((unsigned char*)dst)[7] = (val >> 56); #endif } @@ -467,17 +423,15 @@ sph_enc64le_aligned(void *dst, sph_u64 val) * @param src the source buffer * @return the decoded value */ -static inline sph_u64 -sph_dec64le(const void *src) -{ - return (sph_u64)(((const unsigned char *)src)[0]) - | ((sph_u64)(((const unsigned char *)src)[1]) << 8) - | ((sph_u64)(((const unsigned char *)src)[2]) << 16) - | ((sph_u64)(((const unsigned char *)src)[3]) << 24) - | ((sph_u64)(((const unsigned char *)src)[4]) << 32) - | ((sph_u64)(((const unsigned char *)src)[5]) << 40) - | ((sph_u64)(((const unsigned char *)src)[6]) << 48) - | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +static inline sph_u64 sph_dec64le(const void* src) { + return (sph_u64)(((const unsigned char*)src)[0]) | + ((sph_u64)(((const unsigned char*)src)[1]) << 8) | + ((sph_u64)(((const unsigned char*)src)[2]) << 16) | + ((sph_u64)(((const unsigned char*)src)[3]) << 24) | + ((sph_u64)(((const unsigned char*)src)[4]) << 32) | + ((sph_u64)(((const unsigned char*)src)[5]) << 40) | + ((sph_u64)(((const unsigned char*)src)[6]) << 48) | + ((sph_u64)(((const unsigned char*)src)[7]) << 56); } /** @@ -487,22 +441,20 @@ sph_dec64le(const void *src) * @param src the source buffer (64-bit aligned) * @return the decoded value */ -static inline sph_u64 -sph_dec64le_aligned(const void *src) -{ +static inline sph_u64 sph_dec64le_aligned(const void* src) { #if SPH_LITTLE_ENDIAN - return *(const sph_u64 *)src; + return *(const sph_u64*)src; #elif SPH_BIG_ENDIAN - return sph_bswap64(*(const sph_u64 *)src); + return sph_bswap64(*(const sph_u64*)src); #else - return (sph_u64)(((const unsigned char *)src)[0]) - | ((sph_u64)(((const unsigned char *)src)[1]) << 8) - | ((sph_u64)(((const unsigned char *)src)[2]) << 16) - | ((sph_u64)(((const unsigned char *)src)[3]) << 24) - | ((sph_u64)(((const unsigned char *)src)[4]) << 32) - | ((sph_u64)(((const unsigned char *)src)[5]) << 40) - | ((sph_u64)(((const unsigned char *)src)[6]) << 48) - | ((sph_u64)(((const unsigned char *)src)[7]) << 56); + return (sph_u64)(((const unsigned char*)src)[0]) | + ((sph_u64)(((const unsigned char*)src)[1]) << 8) | + ((sph_u64)(((const unsigned char*)src)[2]) << 16) | + ((sph_u64)(((const unsigned char*)src)[3]) << 24) | + ((sph_u64)(((const unsigned char*)src)[4]) << 32) | + ((sph_u64)(((const unsigned char*)src)[5]) << 40) | + ((sph_u64)(((const unsigned char*)src)[6]) << 48) | + ((sph_u64)(((const unsigned char*)src)[7]) << 56); #endif } diff --git a/crypto/hasher.c b/crypto/hasher.c index d82a6acc2e5..799ea633513 100644 --- a/crypto/hasher.c +++ b/crypto/hasher.c @@ -24,134 +24,141 @@ #include "ripemd160.h" const uint32_t sha256_initial_tapsighash_state[8] = { - 0xf504a425UL, 0xd7f8783bUL, 0x1363868aUL, 0xe3e55658UL, - 0x6eee945dUL, 0xbc7888ddUL, 0x02a6e2c3UL, 0x1873fe9fUL, + 0xf504a425UL, + 0xd7f8783bUL, + 0x1363868aUL, + 0xe3e55658UL, + 0x6eee945dUL, + 0xbc7888ddUL, + 0x02a6e2c3UL, + 0x1873fe9fUL, }; -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; +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) { + switch(hasher->type) { case HASHER_SHA2: case HASHER_SHA2D: case HASHER_SHA2_RIPEMD: - sha256_Init(&hasher->ctx.sha2); - break; + sha256_Init(&hasher->ctx.sha2); + break; case HASHER_SHA2_TAPSIGHASH: - sha256_Init_ex(&hasher->ctx.sha2, sha256_initial_tapsighash_state, 512); - break; + sha256_Init_ex(&hasher->ctx.sha2, sha256_initial_tapsighash_state, 512); + break; case HASHER_SHA3: #if USE_KECCAK case HASHER_SHA3K: #endif - sha3_256_Init(&hasher->ctx.sha3); - break; + sha3_256_Init(&hasher->ctx.sha3); + break; case HASHER_BLAKE: case HASHER_BLAKED: case HASHER_BLAKE_RIPEMD: - blake256_Init(&hasher->ctx.blake); - break; + blake256_Init(&hasher->ctx.blake); + break; case HASHER_GROESTLD_TRUNC: - groestl512_Init(&hasher->ctx.groestl); - break; + groestl512_Init(&hasher->ctx.groestl); + break; case HASHER_BLAKE2B: - blake2b_Init(&hasher->ctx.blake2b, 32); - break; + blake2b_Init(&hasher->ctx.blake2b, 32); + break; case HASHER_BLAKE2B_PERSONAL: - blake2b_InitPersonal(&hasher->ctx.blake2b, 32, hasher->param, - hasher->param_size); - break; - } + 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_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_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) { +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: case HASHER_SHA2_TAPSIGHASH: - sha256_Update(&hasher->ctx.sha2, data, length); - break; + 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; + 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; + blake256_Update(&hasher->ctx.blake, data, length); + break; case HASHER_GROESTLD_TRUNC: - groestl512_Update(&hasher->ctx.groestl, data, length); - break; + groestl512_Update(&hasher->ctx.groestl, data, length); + break; case HASHER_BLAKE2B: case HASHER_BLAKE2B_PERSONAL: - blake2b_Update(&hasher->ctx.blake2b, data, length); - break; - } + blake2b_Update(&hasher->ctx.blake2b, data, length); + break; + } } -void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) { - switch (hasher->type) { +void hasher_Final(Hasher* hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) { + switch(hasher->type) { case HASHER_SHA2: case HASHER_SHA2_TAPSIGHASH: - sha256_Final(&hasher->ctx.sha2, hash); - break; + 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; + 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; + sha256_Final(&hasher->ctx.sha2, hash); + ripemd160(hash, HASHER_DIGEST_LENGTH, hash); + break; case HASHER_SHA3: - sha3_Final(&hasher->ctx.sha3, hash); - break; + sha3_Final(&hasher->ctx.sha3, hash); + break; #if USE_KECCAK case HASHER_SHA3K: - keccak_Final(&hasher->ctx.sha3, hash); - break; + keccak_Final(&hasher->ctx.sha3, hash); + break; #endif case HASHER_BLAKE: - blake256_Final(&hasher->ctx.blake, hash); - break; + 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; + 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; + blake256_Final(&hasher->ctx.blake, hash); + ripemd160(hash, HASHER_DIGEST_LENGTH, hash); + break; case HASHER_GROESTLD_TRUNC: - groestl512_DoubleTrunc(&hasher->ctx.groestl, hash); - break; + groestl512_DoubleTrunc(&hasher->ctx.groestl, hash); + break; case HASHER_BLAKE2B: case HASHER_BLAKE2B_PERSONAL: - blake2b_Final(&hasher->ctx.blake2b, hash, 32); - break; - } + 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 = {0}; +void hasher_Raw( + HasherType type, + const uint8_t* data, + size_t length, + uint8_t hash[HASHER_DIGEST_LENGTH]) { + Hasher hasher = {0}; - hasher_Init(&hasher, type); - hasher_Update(&hasher, data, length); - hasher_Final(&hasher, hash); + hasher_Init(&hasher, type); + hasher_Update(&hasher, data, length); + hasher_Final(&hasher, hash); } diff --git a/crypto/hasher.h b/crypto/hasher.h index e58e74bae28..5130df41608 100644 --- a/crypto/hasher.h +++ b/crypto/hasher.h @@ -35,49 +35,51 @@ #define HASHER_DIGEST_LENGTH 32 typedef enum { - HASHER_SHA2, - HASHER_SHA2D, - HASHER_SHA2_RIPEMD, - HASHER_SHA2_TAPSIGHASH, + HASHER_SHA2, + HASHER_SHA2D, + HASHER_SHA2_RIPEMD, + HASHER_SHA2_TAPSIGHASH, - HASHER_SHA3, + HASHER_SHA3, #if USE_KECCAK - HASHER_SHA3K, + HASHER_SHA3K, #endif - HASHER_BLAKE, - HASHER_BLAKED, - HASHER_BLAKE_RIPEMD, + HASHER_BLAKE, + HASHER_BLAKED, + HASHER_BLAKE_RIPEMD, - HASHER_GROESTLD_TRUNC, /* Double Groestl512 hasher truncated to 256 bits */ + HASHER_GROESTLD_TRUNC, /* Double Groestl512 hasher truncated to 256 bits */ - HASHER_BLAKE2B, - HASHER_BLAKE2B_PERSONAL, + HASHER_BLAKE2B, + HASHER_BLAKE2B_PERSONAL, } HasherType; typedef struct { - HasherType type; + 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; + 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; + 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_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]); +void hasher_Raw( + HasherType type, + const uint8_t* data, + size_t length, + uint8_t hash[HASHER_DIGEST_LENGTH]); #endif diff --git a/crypto/hmac.c b/crypto/hmac.c index 654f2d6e83d..1ee02711ae1 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -27,150 +27,160 @@ #include "memzero.h" #include "options.h" -void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, - const uint32_t keylen) { - static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH]; - memzero(i_key_pad, SHA256_BLOCK_LENGTH); - if (keylen > SHA256_BLOCK_LENGTH) { - sha256_Raw(key, keylen, i_key_pad); - } else { - memcpy(i_key_pad, key, keylen); - } - for (int i = 0; i < SHA256_BLOCK_LENGTH; i++) { - hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; - i_key_pad[i] ^= 0x36; - } - sha256_Init(&(hctx->ctx)); - sha256_Update(&(hctx->ctx), i_key_pad, SHA256_BLOCK_LENGTH); - memzero(i_key_pad, sizeof(i_key_pad)); +void hmac_sha256_Init(HMAC_SHA256_CTX* hctx, const uint8_t* key, const uint32_t keylen) { + static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH]; + memzero(i_key_pad, SHA256_BLOCK_LENGTH); + if(keylen > SHA256_BLOCK_LENGTH) { + sha256_Raw(key, keylen, i_key_pad); + } else { + memcpy(i_key_pad, key, keylen); + } + for(int i = 0; i < SHA256_BLOCK_LENGTH; i++) { + hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; + i_key_pad[i] ^= 0x36; + } + sha256_Init(&(hctx->ctx)); + sha256_Update(&(hctx->ctx), i_key_pad, SHA256_BLOCK_LENGTH); + memzero(i_key_pad, sizeof(i_key_pad)); } -void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, - const uint32_t msglen) { - sha256_Update(&(hctx->ctx), msg, msglen); +void hmac_sha256_Update(HMAC_SHA256_CTX* hctx, const uint8_t* msg, const uint32_t msglen) { + sha256_Update(&(hctx->ctx), msg, msglen); } -void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac) { - sha256_Final(&(hctx->ctx), hmac); - sha256_Init(&(hctx->ctx)); - sha256_Update(&(hctx->ctx), hctx->o_key_pad, SHA256_BLOCK_LENGTH); - sha256_Update(&(hctx->ctx), hmac, SHA256_DIGEST_LENGTH); - sha256_Final(&(hctx->ctx), hmac); - memzero(hctx, sizeof(HMAC_SHA256_CTX)); +void hmac_sha256_Final(HMAC_SHA256_CTX* hctx, uint8_t* hmac) { + sha256_Final(&(hctx->ctx), hmac); + sha256_Init(&(hctx->ctx)); + sha256_Update(&(hctx->ctx), hctx->o_key_pad, SHA256_BLOCK_LENGTH); + sha256_Update(&(hctx->ctx), hmac, SHA256_DIGEST_LENGTH); + sha256_Final(&(hctx->ctx), hmac); + memzero(hctx, sizeof(HMAC_SHA256_CTX)); } -void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, - const uint32_t msglen, uint8_t *hmac) { - static CONFIDENTIAL HMAC_SHA256_CTX hctx; - hmac_sha256_Init(&hctx, key, keylen); - hmac_sha256_Update(&hctx, msg, msglen); - hmac_sha256_Final(&hctx, hmac); +void hmac_sha256( + const uint8_t* key, + const uint32_t keylen, + const uint8_t* msg, + const uint32_t msglen, + uint8_t* hmac) { + static CONFIDENTIAL HMAC_SHA256_CTX hctx; + hmac_sha256_Init(&hctx, key, keylen); + hmac_sha256_Update(&hctx, msg, msglen); + hmac_sha256_Final(&hctx, hmac); } -void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, - uint32_t *opad_digest, uint32_t *ipad_digest) { - static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; - - memzero(key_pad, sizeof(key_pad)); - if (keylen > SHA256_BLOCK_LENGTH) { - static CONFIDENTIAL SHA256_CTX context; - sha256_Init(&context); - sha256_Update(&context, key, keylen); - sha256_Final(&context, (uint8_t *)key_pad); - } else { - memcpy(key_pad, key, keylen); - } - - /* compute o_key_pad and its digest */ - for (int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) { - uint32_t data = 0; +void hmac_sha256_prepare( + const uint8_t* key, + const uint32_t keylen, + uint32_t* opad_digest, + uint32_t* ipad_digest) { + static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; + + memzero(key_pad, sizeof(key_pad)); + if(keylen > SHA256_BLOCK_LENGTH) { + static CONFIDENTIAL SHA256_CTX context; + sha256_Init(&context); + sha256_Update(&context, key, keylen); + sha256_Final(&context, (uint8_t*)key_pad); + } else { + memcpy(key_pad, key, keylen); + } + + /* compute o_key_pad and its digest */ + for(int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) { + uint32_t data = 0; #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(key_pad[i], data); + REVERSE32(key_pad[i], data); #else - data = key_pad[i]; + data = key_pad[i]; #endif - key_pad[i] = data ^ 0x5c5c5c5c; - } - sha256_Transform(sha256_initial_hash_value, key_pad, opad_digest); - - /* convert o_key_pad to i_key_pad and compute its digest */ - for (int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) { - key_pad[i] = key_pad[i] ^ 0x5c5c5c5c ^ 0x36363636; - } - sha256_Transform(sha256_initial_hash_value, key_pad, ipad_digest); - memzero(key_pad, sizeof(key_pad)); + key_pad[i] = data ^ 0x5c5c5c5c; + } + sha256_Transform(sha256_initial_hash_value, key_pad, opad_digest); + + /* convert o_key_pad to i_key_pad and compute its digest */ + for(int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) { + key_pad[i] = key_pad[i] ^ 0x5c5c5c5c ^ 0x36363636; + } + sha256_Transform(sha256_initial_hash_value, key_pad, ipad_digest); + memzero(key_pad, sizeof(key_pad)); } -void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, - const uint32_t keylen) { - static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH]; - memzero(i_key_pad, SHA512_BLOCK_LENGTH); - if (keylen > SHA512_BLOCK_LENGTH) { - sha512_Raw(key, keylen, i_key_pad); - } else { - memcpy(i_key_pad, key, keylen); - } - for (int i = 0; i < SHA512_BLOCK_LENGTH; i++) { - hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; - i_key_pad[i] ^= 0x36; - } - sha512_Init(&(hctx->ctx)); - sha512_Update(&(hctx->ctx), i_key_pad, SHA512_BLOCK_LENGTH); - memzero(i_key_pad, sizeof(i_key_pad)); +void hmac_sha512_Init(HMAC_SHA512_CTX* hctx, const uint8_t* key, const uint32_t keylen) { + static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH]; + memzero(i_key_pad, SHA512_BLOCK_LENGTH); + if(keylen > SHA512_BLOCK_LENGTH) { + sha512_Raw(key, keylen, i_key_pad); + } else { + memcpy(i_key_pad, key, keylen); + } + for(int i = 0; i < SHA512_BLOCK_LENGTH; i++) { + hctx->o_key_pad[i] = i_key_pad[i] ^ 0x5c; + i_key_pad[i] ^= 0x36; + } + sha512_Init(&(hctx->ctx)); + sha512_Update(&(hctx->ctx), i_key_pad, SHA512_BLOCK_LENGTH); + memzero(i_key_pad, sizeof(i_key_pad)); } -void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, - const uint32_t msglen) { - sha512_Update(&(hctx->ctx), msg, msglen); +void hmac_sha512_Update(HMAC_SHA512_CTX* hctx, const uint8_t* msg, const uint32_t msglen) { + sha512_Update(&(hctx->ctx), msg, msglen); } -void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac) { - sha512_Final(&(hctx->ctx), hmac); - sha512_Init(&(hctx->ctx)); - sha512_Update(&(hctx->ctx), hctx->o_key_pad, SHA512_BLOCK_LENGTH); - sha512_Update(&(hctx->ctx), hmac, SHA512_DIGEST_LENGTH); - sha512_Final(&(hctx->ctx), hmac); - memzero(hctx, sizeof(HMAC_SHA512_CTX)); +void hmac_sha512_Final(HMAC_SHA512_CTX* hctx, uint8_t* hmac) { + sha512_Final(&(hctx->ctx), hmac); + sha512_Init(&(hctx->ctx)); + sha512_Update(&(hctx->ctx), hctx->o_key_pad, SHA512_BLOCK_LENGTH); + sha512_Update(&(hctx->ctx), hmac, SHA512_DIGEST_LENGTH); + sha512_Final(&(hctx->ctx), hmac); + memzero(hctx, sizeof(HMAC_SHA512_CTX)); } -void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, - const uint32_t msglen, uint8_t *hmac) { - HMAC_SHA512_CTX hctx = {0}; - hmac_sha512_Init(&hctx, key, keylen); - hmac_sha512_Update(&hctx, msg, msglen); - hmac_sha512_Final(&hctx, hmac); +void hmac_sha512( + const uint8_t* key, + const uint32_t keylen, + const uint8_t* msg, + const uint32_t msglen, + uint8_t* hmac) { + HMAC_SHA512_CTX hctx = {0}; + hmac_sha512_Init(&hctx, key, keylen); + hmac_sha512_Update(&hctx, msg, msglen); + hmac_sha512_Final(&hctx, hmac); } -void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, - uint64_t *opad_digest, uint64_t *ipad_digest) { - static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; - - memzero(key_pad, sizeof(key_pad)); - if (keylen > SHA512_BLOCK_LENGTH) { - static CONFIDENTIAL SHA512_CTX context; - sha512_Init(&context); - sha512_Update(&context, key, keylen); - sha512_Final(&context, (uint8_t *)key_pad); - } else { - memcpy(key_pad, key, keylen); - } - - /* compute o_key_pad and its digest */ - for (int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) { - uint64_t data = 0; +void hmac_sha512_prepare( + const uint8_t* key, + const uint32_t keylen, + uint64_t* opad_digest, + uint64_t* ipad_digest) { + static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; + + memzero(key_pad, sizeof(key_pad)); + if(keylen > SHA512_BLOCK_LENGTH) { + static CONFIDENTIAL SHA512_CTX context; + sha512_Init(&context); + sha512_Update(&context, key, keylen); + sha512_Final(&context, (uint8_t*)key_pad); + } else { + memcpy(key_pad, key, keylen); + } + + /* compute o_key_pad and its digest */ + for(int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) { + uint64_t data = 0; #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE64(key_pad[i], data); + REVERSE64(key_pad[i], data); #else - data = key_pad[i]; + data = key_pad[i]; #endif - key_pad[i] = data ^ 0x5c5c5c5c5c5c5c5c; - } - sha512_Transform(sha512_initial_hash_value, key_pad, opad_digest); - - /* convert o_key_pad to i_key_pad and compute its digest */ - for (int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) { - key_pad[i] = key_pad[i] ^ 0x5c5c5c5c5c5c5c5c ^ 0x3636363636363636; - } - sha512_Transform(sha512_initial_hash_value, key_pad, ipad_digest); - memzero(key_pad, sizeof(key_pad)); + key_pad[i] = data ^ 0x5c5c5c5c5c5c5c5c; + } + sha512_Transform(sha512_initial_hash_value, key_pad, opad_digest); + + /* convert o_key_pad to i_key_pad and compute its digest */ + for(int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) { + key_pad[i] = key_pad[i] ^ 0x5c5c5c5c5c5c5c5c ^ 0x3636363636363636; + } + sha512_Transform(sha512_initial_hash_value, key_pad, ipad_digest); + memzero(key_pad, sizeof(key_pad)); } diff --git a/crypto/hmac.h b/crypto/hmac.h index 3921a171e07..21a4f8da67e 100644 --- a/crypto/hmac.h +++ b/crypto/hmac.h @@ -28,33 +28,43 @@ #include "sha2.h" typedef struct _HMAC_SHA256_CTX { - uint8_t o_key_pad[SHA256_BLOCK_LENGTH]; - SHA256_CTX ctx; + uint8_t o_key_pad[SHA256_BLOCK_LENGTH]; + SHA256_CTX ctx; } HMAC_SHA256_CTX; typedef struct _HMAC_SHA512_CTX { - uint8_t o_key_pad[SHA512_BLOCK_LENGTH]; - SHA512_CTX ctx; + uint8_t o_key_pad[SHA512_BLOCK_LENGTH]; + SHA512_CTX ctx; } HMAC_SHA512_CTX; -void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, - const uint32_t keylen); -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(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, - 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_Init(HMAC_SHA256_CTX* hctx, const uint8_t* key, const uint32_t keylen); +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( + const uint8_t* key, + const uint32_t keylen, + const uint8_t* msg, + 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_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, - const uint32_t keylen); -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(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, - 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_Init(HMAC_SHA512_CTX* hctx, const uint8_t* key, const uint32_t keylen); +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( + const uint8_t* key, + const uint32_t keylen, + const uint8_t* msg, + 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); #endif diff --git a/crypto/hmac_drbg.c b/crypto/hmac_drbg.c index 1ed1401b8a5..3115c11f227 100644 --- a/crypto/hmac_drbg.c +++ b/crypto/hmac_drbg.c @@ -25,106 +25,117 @@ #include "memzero.h" #include "sha2.h" -static void update_k(HMAC_DRBG_CTX *ctx, uint8_t domain, const uint8_t *data1, - size_t len1, const uint8_t *data2, size_t len2) { - // Computes K = HMAC(K, V || domain || data1 || data 2). +static void update_k( + HMAC_DRBG_CTX* ctx, + uint8_t domain, + const uint8_t* data1, + size_t len1, + const uint8_t* data2, + size_t len2) { + // Computes K = HMAC(K, V || domain || data1 || data 2). - // First hash operation of HMAC. - uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - if (len1 + len2 == 0) { - ctx->v[8] = 0x00800000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; - sha256_Transform(ctx->idig, ctx->v, h); - ctx->v[8] = 0x80000000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - } else { - SHA256_CTX sha_ctx = {0}; - memcpy(sha_ctx.state, ctx->idig, SHA256_DIGEST_LENGTH); - for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { + // First hash operation of HMAC. + uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; + if(len1 + len2 == 0) { + ctx->v[8] = 0x00800000; + ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; + sha256_Transform(ctx->idig, ctx->v, h); + ctx->v[8] = 0x80000000; + ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + } else { + SHA256_CTX sha_ctx = {0}; + memcpy(sha_ctx.state, ctx->idig, SHA256_DIGEST_LENGTH); + for(size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(ctx->v[i], sha_ctx.buffer[i]); + REVERSE32(ctx->v[i], sha_ctx.buffer[i]); #else - sha_ctx.buffer[i] = ctx->v[i]; + sha_ctx.buffer[i] = ctx->v[i]; #endif - } - ((uint8_t *)sha_ctx.buffer)[SHA256_DIGEST_LENGTH] = domain; - sha_ctx.bitcount = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; - sha256_Update(&sha_ctx, data1, len1); - sha256_Update(&sha_ctx, data2, len2); - sha256_Final(&sha_ctx, (uint8_t *)h); + } + ((uint8_t*)sha_ctx.buffer)[SHA256_DIGEST_LENGTH] = domain; + sha_ctx.bitcount = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; + sha256_Update(&sha_ctx, data1, len1); + sha256_Update(&sha_ctx, data2, len2); + sha256_Final(&sha_ctx, (uint8_t*)h); #if BYTE_ORDER == LITTLE_ENDIAN - for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) - REVERSE32(h[i], h[i]); + for(size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) REVERSE32(h[i], h[i]); #endif - } + } - // Second hash operation of HMAC. - h[8] = 0x80000000; - h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - sha256_Transform(ctx->odig, h, h); + // Second hash operation of HMAC. + h[8] = 0x80000000; + h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + sha256_Transform(ctx->odig, h, h); - // Precompute the inner digest and outer digest of K. - h[8] = 0; - h[15] = 0; - for (size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { - h[i] ^= 0x36363636; - } - sha256_Transform(sha256_initial_hash_value, h, ctx->idig); + // Precompute the inner digest and outer digest of K. + h[8] = 0; + h[15] = 0; + for(size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { + h[i] ^= 0x36363636; + } + sha256_Transform(sha256_initial_hash_value, h, ctx->idig); - for (size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { - h[i] = h[i] ^ 0x36363636 ^ 0x5c5c5c5c; - } - sha256_Transform(sha256_initial_hash_value, h, ctx->odig); - memzero(h, sizeof(h)); + for(size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { + h[i] = h[i] ^ 0x36363636 ^ 0x5c5c5c5c; + } + sha256_Transform(sha256_initial_hash_value, h, ctx->odig); + memzero(h, sizeof(h)); } -static void update_v(HMAC_DRBG_CTX *ctx) { - sha256_Transform(ctx->idig, ctx->v, ctx->v); - sha256_Transform(ctx->odig, ctx->v, ctx->v); +static void update_v(HMAC_DRBG_CTX* ctx) { + sha256_Transform(ctx->idig, ctx->v, ctx->v); + sha256_Transform(ctx->odig, ctx->v, ctx->v); } -void hmac_drbg_init(HMAC_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_len, const uint8_t *nonce, - size_t nonce_len) { - uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; +void hmac_drbg_init( + HMAC_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t entropy_len, + const uint8_t* nonce, + size_t nonce_len) { + uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - // Precompute the inner digest and outer digest of K = 0x00 ... 0x00. - memset(h, 0x36, sizeof(h)); - sha256_Transform(sha256_initial_hash_value, h, ctx->idig); - memset(h, 0x5c, sizeof(h)); - sha256_Transform(sha256_initial_hash_value, h, ctx->odig); + // Precompute the inner digest and outer digest of K = 0x00 ... 0x00. + memset(h, 0x36, sizeof(h)); + sha256_Transform(sha256_initial_hash_value, h, ctx->idig); + memset(h, 0x5c, sizeof(h)); + sha256_Transform(sha256_initial_hash_value, h, ctx->odig); - // Let V = 0x01 ... 0x01. - memset(ctx->v, 1, SHA256_DIGEST_LENGTH); - for (size_t i = 9; i < 15; i++) ctx->v[i] = 0; - ctx->v[8] = 0x80000000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + // Let V = 0x01 ... 0x01. + memset(ctx->v, 1, SHA256_DIGEST_LENGTH); + for(size_t i = 9; i < 15; i++) ctx->v[i] = 0; + ctx->v[8] = 0x80000000; + ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - hmac_drbg_reseed(ctx, entropy, entropy_len, nonce, nonce_len); + hmac_drbg_reseed(ctx, entropy, entropy_len, nonce, nonce_len); - memzero(h, sizeof(h)); + memzero(h, sizeof(h)); } -void hmac_drbg_reseed(HMAC_DRBG_CTX *ctx, const uint8_t *entropy, size_t len, - const uint8_t *addin, size_t addin_len) { - update_k(ctx, 0, entropy, len, addin, addin_len); - update_v(ctx); - if (len == 0) return; - update_k(ctx, 1, entropy, len, addin, addin_len); - update_v(ctx); +void hmac_drbg_reseed( + HMAC_DRBG_CTX* ctx, + const uint8_t* entropy, + size_t len, + const uint8_t* addin, + size_t addin_len) { + update_k(ctx, 0, entropy, len, addin, addin_len); + update_v(ctx); + if(len == 0) return; + update_k(ctx, 1, entropy, len, addin, addin_len); + update_v(ctx); } -void hmac_drbg_generate(HMAC_DRBG_CTX *ctx, uint8_t *buf, size_t len) { - size_t i = 0; - while (i < len) { - update_v(ctx); - for (size_t j = 0; j < 8 && i < len; j++) { - uint32_t r = ctx->v[j]; - for (int k = 24; k >= 0 && i < len; k -= 8) { - buf[i++] = (r >> k) & 0xFF; - } +void hmac_drbg_generate(HMAC_DRBG_CTX* ctx, uint8_t* buf, size_t len) { + size_t i = 0; + while(i < len) { + update_v(ctx); + for(size_t j = 0; j < 8 && i < len; j++) { + uint32_t r = ctx->v[j]; + for(int k = 24; k >= 0 && i < len; k -= 8) { + buf[i++] = (r >> k) & 0xFF; + } + } } - } - update_k(ctx, 0, NULL, 0, NULL, 0); - update_v(ctx); + update_k(ctx, 0, NULL, 0, NULL, 0); + update_v(ctx); } diff --git a/crypto/hmac_drbg.h b/crypto/hmac_drbg.h index 6a8f3978c39..f6d3f3732fd 100644 --- a/crypto/hmac_drbg.h +++ b/crypto/hmac_drbg.h @@ -29,15 +29,23 @@ // HMAC based Deterministic Random Bit Generator with SHA-256 typedef struct _HMAC_DRBG_CTX { - uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t v[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; + uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t v[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; } HMAC_DRBG_CTX; -void hmac_drbg_init(HMAC_DRBG_CTX *ctx, const uint8_t *buf, size_t len, - const uint8_t *nonce, size_t nonce_len); -void hmac_drbg_reseed(HMAC_DRBG_CTX *ctx, const uint8_t *buf, size_t len, - const uint8_t *addin, size_t addin_len); -void hmac_drbg_generate(HMAC_DRBG_CTX *ctx, uint8_t *buf, size_t len); +void hmac_drbg_init( + HMAC_DRBG_CTX* ctx, + const uint8_t* buf, + size_t len, + const uint8_t* nonce, + size_t nonce_len); +void hmac_drbg_reseed( + HMAC_DRBG_CTX* ctx, + const uint8_t* buf, + size_t len, + const uint8_t* addin, + size_t addin_len); +void hmac_drbg_generate(HMAC_DRBG_CTX* ctx, uint8_t* buf, size_t len); #endif diff --git a/crypto/memzero.c b/crypto/memzero.c index 823ded6ff31..64866ee56cb 100644 --- a/crypto/memzero.c +++ b/crypto/memzero.c @@ -1,5 +1,5 @@ #ifndef __STDC_WANT_LIB_EXT1__ -#define __STDC_WANT_LIB_EXT1__ 1 // C11's bounds-checking interface. +#define __STDC_WANT_LIB_EXT1__ 1 // C11's bounds-checking interface. #endif #include @@ -18,8 +18,7 @@ #endif // GNU C Library version 2.25 or later. -#if defined(__GLIBC__) && \ - (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) +#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) #define HAVE_EXPLICIT_BZERO 1 #endif @@ -46,30 +45,30 @@ // 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) { +void memzero(void* const pnt, const size_t len) { #ifdef _WIN32 - SecureZeroMemory(pnt, len); + SecureZeroMemory(pnt, len); #elif defined(HAVE_MEMSET_S) - memset_s(pnt, (rsize_t)len, 0, (rsize_t)len); + 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); + explicit_memset(pnt, 0, len); #else - volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile)pnt; - size_t i = (size_t)0U; + volatile unsigned char* volatile pnt_ = (volatile unsigned char* volatile)pnt; + size_t i = (size_t)0U; - while (i < len) { - pnt_[i++] = 0U; - } + while(i < len) { + pnt_[i++] = 0U; + } #endif - // explicitly mark the memory as overwritten for the Clang MemorySanitizer - // this is only included at compile time if MemorySanitizer is enabled and - // should not come with any downsides during regular builds + // explicitly mark the memory as overwritten for the Clang MemorySanitizer + // this is only included at compile time if MemorySanitizer is enabled and + // should not come with any downsides during regular builds #if defined(__has_feature) #if __has_feature(memory_sanitizer) - memset(pnt, 0, len); + memset(pnt, 0, len); #endif #endif } diff --git a/crypto/monero/base58.c b/crypto/monero/base58.c index fc576805141..1ca9dfafd94 100644 --- a/crypto/monero/base58.c +++ b/crypto/monero/base58.c @@ -40,254 +40,258 @@ #include #include "../base58.h" #include "../byte_order.h" -#include "int-util.h" +#include "int_util.h" #include "../sha2.h" -const size_t alphabet_size = 58; // sizeof(b58digits_ordered) - 1; +const size_t alphabet_size = 58; // sizeof(b58digits_ordered) - 1; const size_t full_encoded_block_size = 11; -const size_t encoded_block_sizes[] = { - 0, 2, 3, 5, 6, 7, 9, 10, full_encoded_block_size}; -const size_t full_block_size = - sizeof(encoded_block_sizes) / sizeof(encoded_block_sizes[0]) - 1; +const size_t encoded_block_sizes[] = {0, 2, 3, 5, 6, 7, 9, 10, full_encoded_block_size}; +const size_t full_block_size = sizeof(encoded_block_sizes) / sizeof(encoded_block_sizes[0]) - 1; const size_t addr_checksum_size = 4; const size_t max_bin_data_size = 72; const int decoded_block_sizes[] = {0, -1, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8}; #define reverse_alphabet(letter) ((int8_t)b58digits_map[(int)letter]) -uint64_t uint_8be_to_64(const uint8_t *data, size_t size) { - assert(1 <= size && size <= sizeof(uint64_t)); +uint64_t uint_8be_to_64(const uint8_t* data, size_t size) { + assert(1 <= size && size <= sizeof(uint64_t)); - uint64_t res = 0; - switch (9 - size) { + uint64_t res = 0; + switch(9 - size) { case 1: - res |= *data++; /* FALLTHRU */ + res |= *data++; /* FALLTHRU */ case 2: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 3: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 4: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 5: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 6: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 7: - res <<= 8; - res |= *data++; /* FALLTHRU */ + res <<= 8; + res |= *data++; /* FALLTHRU */ case 8: - res <<= 8; - res |= *data; - break; + res <<= 8; + res |= *data; + break; default: - assert(false); - } + assert(false); + } - return res; + return res; } -void uint_64_to_8be(uint64_t num, size_t size, uint8_t *data) { - assert(1 <= size && size <= sizeof(uint64_t)); +void uint_64_to_8be(uint64_t num, size_t size, uint8_t* data) { + assert(1 <= size && size <= sizeof(uint64_t)); #if BYTE_ORDER == LITTLE_ENDIAN - uint64_t num_be = SWAP64(num); + uint64_t num_be = SWAP64(num); #else - uint64_t num_be = num; + uint64_t num_be = num; #endif - memcpy(data, (uint8_t *)(&num_be) + sizeof(uint64_t) - size, size); + memcpy(data, (uint8_t*)(&num_be) + sizeof(uint64_t) - size, size); } -void encode_block(const char *block, size_t size, char *res) { - assert(1 <= size && size <= full_block_size); - - uint64_t num = uint_8be_to_64((uint8_t *)(block), size); - int i = ((int)(encoded_block_sizes[size])) - 1; - while (0 <= i) { - uint64_t remainder = num % alphabet_size; - num /= alphabet_size; - res[i] = b58digits_ordered[remainder]; - --i; - } -} +void encode_block(const char* block, size_t size, char* res) { + assert(1 <= size && size <= full_block_size); -bool decode_block(const char *block, size_t size, char *res) { - assert(1 <= size && size <= full_encoded_block_size); + uint64_t num = uint_8be_to_64((uint8_t*)(block), size); + int i = ((int)(encoded_block_sizes[size])) - 1; + while(0 <= i) { + uint64_t remainder = num % alphabet_size; + num /= alphabet_size; + res[i] = b58digits_ordered[remainder]; + --i; + } +} - int res_size = decoded_block_sizes[size]; - if (res_size <= 0) { - return false; // Invalid block size - } +bool decode_block(const char* block, size_t size, char* res) { + assert(1 <= size && size <= full_encoded_block_size); - uint64_t res_num = 0; - uint64_t order = 1; - for (size_t i = size - 1; i < size; --i) { - if (block[i] & 0x80) { - return false; // Invalid symbol + int res_size = decoded_block_sizes[size]; + if(res_size <= 0) { + return false; // Invalid block size } - int digit = reverse_alphabet(block[i]); - if (digit < 0) { - return false; // Invalid symbol + + uint64_t res_num = 0; + uint64_t order = 1; + for(size_t i = size - 1; i < size; --i) { + if(block[i] & 0x80) { + return false; // Invalid symbol + } + int digit = reverse_alphabet(block[i]); + if(digit < 0) { + return false; // Invalid symbol + } + + uint64_t product_hi = 0; + uint64_t tmp = res_num + mul128(order, (uint64_t)digit, &product_hi); + if(tmp < res_num || 0 != product_hi) { + return false; // Overflow + } + + res_num = tmp; + // The original code comment for the order multiplication says + // "Never overflows, 58^10 < 2^64" + // This is incorrect since it overflows on the 11th iteration + // However, there is no negative impact since the result is unused + order *= alphabet_size; } - uint64_t product_hi = 0; - uint64_t tmp = res_num + mul128(order, (uint64_t)digit, &product_hi); - if (tmp < res_num || 0 != product_hi) { - return false; // Overflow + if((size_t)res_size < full_block_size && (UINT64_C(1) << (8 * res_size)) <= res_num) + return false; // Overflow + + uint_64_to_8be(res_num, res_size, (uint8_t*)(res)); + + return true; +} + +bool xmr_base58_encode(char* b58, size_t* b58sz, const void* data, size_t binsz) { + if(binsz == 0) { + if(b58sz) { + *b58sz = 0; + } + return true; } - res_num = tmp; - // The original code comment for the order multiplication says - // "Never overflows, 58^10 < 2^64" - // This is incorrect since it overflows on the 11th iteration - // However, there is no negative impact since the result is unused - order *= alphabet_size; - } + const char* data_bin = data; + size_t full_block_count = binsz / full_block_size; + size_t last_block_size = binsz % full_block_size; + size_t res_size = + full_block_count * full_encoded_block_size + encoded_block_sizes[last_block_size]; + + if(b58sz) { + if(res_size > *b58sz) { + return false; + } + *b58sz = res_size; + } - if ((size_t)res_size < full_block_size && - (UINT64_C(1) << (8 * res_size)) <= res_num) - return false; // Overflow + for(size_t i = 0; i < full_block_count; ++i) { + encode_block( + data_bin + i * full_block_size, full_block_size, b58 + i * full_encoded_block_size); + } - uint_64_to_8be(res_num, res_size, (uint8_t *)(res)); + if(0 < last_block_size) { + encode_block( + data_bin + full_block_count * full_block_size, + last_block_size, + b58 + full_block_count * full_encoded_block_size); + } - return true; + return true; } -bool xmr_base58_encode(char *b58, size_t *b58sz, const void *data, - size_t binsz) { - if (binsz == 0) { - if (b58sz) { - *b58sz = 0; +bool xmr_base58_decode(const char* b58, size_t b58sz, void* data, size_t* binsz) { + if(b58sz == 0) { + *binsz = 0; + return true; + } + + size_t full_block_count = b58sz / full_encoded_block_size; + size_t last_block_size = b58sz % full_encoded_block_size; + int last_block_decoded_size = decoded_block_sizes[last_block_size]; + if(last_block_decoded_size < 0) { + *binsz = 0; + return false; // Invalid enc length + } + + size_t data_size = full_block_count * full_block_size + last_block_decoded_size; + if(*binsz < data_size) { + *binsz = 0; + return false; } - return true; - } - const char *data_bin = data; - size_t full_block_count = binsz / full_block_size; - size_t last_block_size = binsz % full_block_size; - size_t res_size = full_block_count * full_encoded_block_size + - encoded_block_sizes[last_block_size]; + char* data_bin = data; + for(size_t i = 0; i < full_block_count; ++i) { + if(!decode_block( + b58 + i * full_encoded_block_size, + full_encoded_block_size, + data_bin + i * full_block_size)) { + *binsz = 0; + return false; + } + } - if (b58sz) { - if (res_size > *b58sz) { - return false; + if(0 < last_block_size) { + if(!decode_block( + b58 + full_block_count * full_encoded_block_size, + last_block_size, + data_bin + full_block_count * full_block_size)) { + *binsz = 0; + return false; + } } - *b58sz = res_size; - } - for (size_t i = 0; i < full_block_count; ++i) { - encode_block(data_bin + i * full_block_size, full_block_size, - b58 + i * full_encoded_block_size); - } + *binsz = data_size; + return true; +} + +int xmr_base58_addr_encode_check( + uint64_t tag, + const uint8_t* data, + size_t binsz, + char* b58, + size_t b58sz) { + if(binsz > max_bin_data_size || tag > 127) { // tag varint + return false; + } - if (0 < last_block_size) { - encode_block(data_bin + full_block_count * full_block_size, last_block_size, - b58 + full_block_count * full_encoded_block_size); - } + size_t b58size = b58sz; + uint8_t buf[(binsz + 1) + HASHER_DIGEST_LENGTH]; + memset(buf, 0, sizeof(buf)); + uint8_t* hash = buf + binsz + 1; + buf[0] = (uint8_t)tag; + memcpy(buf + 1, data, binsz); + hasher_Raw(HASHER_SHA3K, buf, binsz + 1, hash); - return true; + bool r = xmr_base58_encode(b58, &b58size, buf, binsz + 1 + addr_checksum_size); + return (int)(!r ? 0 : b58size); } -bool xmr_base58_decode(const char *b58, size_t b58sz, void *data, - size_t *binsz) { - if (b58sz == 0) { - *binsz = 0; - return true; - } - - size_t full_block_count = b58sz / full_encoded_block_size; - size_t last_block_size = b58sz % full_encoded_block_size; - int last_block_decoded_size = decoded_block_sizes[last_block_size]; - if (last_block_decoded_size < 0) { - *binsz = 0; - return false; // Invalid enc length - } - - size_t data_size = - full_block_count * full_block_size + last_block_decoded_size; - if (*binsz < data_size) { - *binsz = 0; - return false; - } - - char *data_bin = data; - for (size_t i = 0; i < full_block_count; ++i) { - if (!decode_block(b58 + i * full_encoded_block_size, - full_encoded_block_size, - data_bin + i * full_block_size)) { - *binsz = 0; - return false; +int xmr_base58_addr_decode_check( + const char* addr, + size_t sz, + uint64_t* tag, + void* data, + size_t datalen) { + size_t buflen = 1 + max_bin_data_size + addr_checksum_size; + uint8_t buf[buflen]; + memset(buf, 0, sizeof(buf)); + uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; + + if(!xmr_base58_decode(addr, sz, buf, &buflen)) { + return 0; } - } - - if (0 < last_block_size) { - if (!decode_block(b58 + full_block_count * full_encoded_block_size, - last_block_size, - data_bin + full_block_count * full_block_size)) { - *binsz = 0; - return false; + + if(buflen <= addr_checksum_size + 1) { + return 0; } - } - *binsz = data_size; - return true; -} + size_t res_size = buflen - addr_checksum_size - 1; + if(datalen < res_size) { + return 0; + } -int xmr_base58_addr_encode_check(uint64_t tag, const uint8_t *data, - size_t binsz, char *b58, size_t b58sz) { - if (binsz > max_bin_data_size || tag > 127) { // tag varint - return false; - } - - size_t b58size = b58sz; - uint8_t buf[(binsz + 1) + HASHER_DIGEST_LENGTH]; - memset(buf, 0, sizeof(buf)); - uint8_t *hash = buf + binsz + 1; - buf[0] = (uint8_t)tag; - memcpy(buf + 1, data, binsz); - hasher_Raw(HASHER_SHA3K, buf, binsz + 1, hash); - - bool r = - xmr_base58_encode(b58, &b58size, buf, binsz + 1 + addr_checksum_size); - return (int)(!r ? 0 : b58size); -} + hasher_Raw(HASHER_SHA3K, buf, buflen - addr_checksum_size, hash); + if(memcmp(hash, buf + buflen - addr_checksum_size, addr_checksum_size) != 0) { + return 0; + } + + *tag = buf[0]; + if(*tag > 127) { + return false; // varint + } -int xmr_base58_addr_decode_check(const char *addr, size_t sz, uint64_t *tag, - void *data, size_t datalen) { - size_t buflen = 1 + max_bin_data_size + addr_checksum_size; - uint8_t buf[buflen]; - memset(buf, 0, sizeof(buf)); - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - - if (!xmr_base58_decode(addr, sz, buf, &buflen)) { - return 0; - } - - if (buflen <= addr_checksum_size + 1) { - return 0; - } - - size_t res_size = buflen - addr_checksum_size - 1; - if (datalen < res_size) { - return 0; - } - - hasher_Raw(HASHER_SHA3K, buf, buflen - addr_checksum_size, hash); - if (memcmp(hash, buf + buflen - addr_checksum_size, addr_checksum_size) != - 0) { - return 0; - } - - *tag = buf[0]; - if (*tag > 127) { - return false; // varint - } - - memcpy(data, buf + 1, res_size); - return (int)res_size; + memcpy(data, buf + 1, res_size); + return (int)res_size; } #endif // USE_MONERO \ No newline at end of file diff --git a/crypto/monero/base58.h b/crypto/monero/base58.h index 2cb0b094104..adcafadd177 100644 --- a/crypto/monero/base58.h +++ b/crypto/monero/base58.h @@ -40,14 +40,20 @@ #include "../hasher.h" #include "../options.h" -int xmr_base58_addr_encode_check(uint64_t tag, const uint8_t *data, - size_t binsz, char *b58, size_t b58sz); -int xmr_base58_addr_decode_check(const char *addr, size_t sz, uint64_t *tag, - void *data, size_t datalen); -bool xmr_base58_encode(char *b58, size_t *b58sz, const void *data, - size_t binsz); -bool xmr_base58_decode(const char *b58, size_t b58sz, void *data, - size_t *binsz); +int xmr_base58_addr_encode_check( + uint64_t tag, + const uint8_t* data, + size_t binsz, + char* b58, + size_t b58sz); +int xmr_base58_addr_decode_check( + const char* addr, + size_t sz, + uint64_t* tag, + void* data, + size_t datalen); +bool xmr_base58_encode(char* b58, size_t* b58sz, const void* data, size_t binsz); +bool xmr_base58_decode(const char* b58, size_t b58sz, void* data, size_t* binsz); #endif diff --git a/crypto/monero/int-util.h b/crypto/monero/int_util.h similarity index 56% rename from crypto/monero/int-util.h rename to crypto/monero/int_util.h index a2cd8a8c9f1..fb627b62e3a 100644 --- a/crypto/monero/int-util.h +++ b/crypto/monero/int_util.h @@ -38,45 +38,44 @@ #include #include -static inline uint64_t hi_dword(uint64_t val) { return val >> 32; } +static inline uint64_t hi_dword(uint64_t val) { + return val >> 32; +} -static inline uint64_t lo_dword(uint64_t val) { return val & 0xFFFFFFFF; } +static inline uint64_t lo_dword(uint64_t val) { + return val & 0xFFFFFFFF; +} -static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, - uint64_t* product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = hi_dword(multiplier); - uint64_t b = lo_dword(multiplier); - uint64_t c = hi_dword(multiplicand); - uint64_t d = lo_dword(multiplicand); +static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { + // multiplier = ab = a * 2^32 + b + // multiplicand = cd = c * 2^32 + d + // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d + uint64_t a = hi_dword(multiplier); + uint64_t b = lo_dword(multiplier); + uint64_t c = hi_dword(multiplicand); + uint64_t d = lo_dword(multiplicand); - uint64_t ac = a * c; - uint64_t ad = a * d; - uint64_t bc = b * c; - uint64_t bd = b * d; + uint64_t ac = a * c; + uint64_t ad = a * d; + uint64_t bc = b * c; + uint64_t bd = b * d; - uint64_t adbc = ad + bc; - uint64_t adbc_carry = adbc < ad ? 1 : 0; + uint64_t adbc = ad + bc; + uint64_t adbc_carry = adbc < ad ? 1 : 0; - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - assert(ac <= *product_hi); + // multiplier * multiplicand = product_hi * 2^64 + product_lo + uint64_t product_lo = bd + (adbc << 32); + uint64_t product_lo_carry = product_lo < bd ? 1 : 0; + *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; + assert(ac <= *product_hi); - return product_lo; + return product_lo; } -#define SWAP64(x) \ - ((((uint64_t)(x)&0x00000000000000ff) << 56) | \ - (((uint64_t)(x)&0x000000000000ff00) << 40) | \ - (((uint64_t)(x)&0x0000000000ff0000) << 24) | \ - (((uint64_t)(x)&0x00000000ff000000) << 8) | \ - (((uint64_t)(x)&0x000000ff00000000) >> 8) | \ - (((uint64_t)(x)&0x0000ff0000000000) >> 24) | \ - (((uint64_t)(x)&0x00ff000000000000) >> 40) | \ - (((uint64_t)(x)&0xff00000000000000) >> 56)) +#define SWAP64(x) \ + ((((uint64_t)(x)&0x00000000000000ff) << 56) | (((uint64_t)(x)&0x000000000000ff00) << 40) | \ + (((uint64_t)(x)&0x0000000000ff0000) << 24) | (((uint64_t)(x)&0x00000000ff000000) << 8) | \ + (((uint64_t)(x)&0x000000ff00000000) >> 8) | (((uint64_t)(x)&0x0000ff0000000000) >> 24) | \ + (((uint64_t)(x)&0x00ff000000000000) >> 40) | (((uint64_t)(x)&0xff00000000000000) >> 56)) #endif // USE_MONERO \ No newline at end of file diff --git a/crypto/monero/monero.h b/crypto/monero/monero.h index 207951656ba..96ff9dd5c79 100644 --- a/crypto/monero/monero.h +++ b/crypto/monero/monero.h @@ -19,6 +19,6 @@ #include "serialize.h" #include "xmr.h" -#endif // TREZOR_CRYPTO_MONERO_H +#endif // TREZOR_CRYPTO_MONERO_H -#endif // USE_MONERO +#endif // USE_MONERO diff --git a/crypto/monero/serialize.c b/crypto/monero/serialize.c index 25c43e102f9..0023c9699d7 100644 --- a/crypto/monero/serialize.c +++ b/crypto/monero/serialize.c @@ -7,51 +7,51 @@ #include "serialize.h" int xmr_size_varint(uint64_t num) { - int ctr = 1; - while (num >= 0x80) { - ++ctr; - num >>= 7; - } - return ctr; + int ctr = 1; + while(num >= 0x80) { + ++ctr; + num >>= 7; + } + return ctr; } -int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num) { - unsigned ctr = 0; - while (num >= 0x80 && ctr < buff_size) { - *buff = (uint8_t)(((num)&0x7f) | 0x80); - ++buff; - ++ctr; - num >>= 7; - } - - /* writes the last one to dest */ - if (ctr < buff_size) { - *buff = (uint8_t)num; - ++ctr; - } - return ctr <= buff_size ? (int)ctr : -1; +int xmr_write_varint(uint8_t* buff, size_t buff_size, uint64_t num) { + unsigned ctr = 0; + while(num >= 0x80 && ctr < buff_size) { + *buff = (uint8_t)(((num)&0x7f) | 0x80); + ++buff; + ++ctr; + num >>= 7; + } + + /* writes the last one to dest */ + if(ctr < buff_size) { + *buff = (uint8_t)num; + ++ctr; + } + return ctr <= buff_size ? (int)ctr : -1; } -int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val) { - unsigned read = 0; - int finished_ok = 0; - *val = 0; +int xmr_read_varint(uint8_t* buff, size_t buff_size, uint64_t* val) { + unsigned read = 0; + int finished_ok = 0; + *val = 0; - for (int shift = 0; read < buff_size; shift += 7, ++read) { - uint8_t byte = buff[read]; - if ((byte == 0 && shift != 0) || (shift >= 63 && byte > 1)) { - return -1; - } + for(int shift = 0; read < buff_size; shift += 7, ++read) { + uint8_t byte = buff[read]; + if((byte == 0 && shift != 0) || (shift >= 63 && byte > 1)) { + return -1; + } - *val |= (uint64_t)(byte & 0x7f) << shift; + *val |= (uint64_t)(byte & 0x7f) << shift; - /* If there is no next */ - if ((byte & 0x80) == 0) { - finished_ok = 1; - break; + /* If there is no next */ + if((byte & 0x80) == 0) { + finished_ok = 1; + break; + } } - } - return finished_ok ? (int)read + 1 : -2; + return finished_ok ? (int)read + 1 : -2; } #endif // USE_MONERO diff --git a/crypto/monero/serialize.h b/crypto/monero/serialize.h index e13e042e9c6..9f890369439 100644 --- a/crypto/monero/serialize.h +++ b/crypto/monero/serialize.h @@ -11,9 +11,9 @@ #include int xmr_size_varint(uint64_t num); -int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num); -int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val); +int xmr_write_varint(uint8_t* buff, size_t buff_size, uint64_t num); +int xmr_read_varint(uint8_t* buff, size_t buff_size, uint64_t* val); -#endif // TREZOR_XMR_SERIALIZE_H +#endif // TREZOR_XMR_SERIALIZE_H -#endif // USE_MONERO +#endif // USE_MONERO diff --git a/crypto/monero/xmr.c b/crypto/monero/xmr.c index 9e349cbe89b..917200624d7 100644 --- a/crypto/monero/xmr.c +++ b/crypto/monero/xmr.c @@ -6,149 +6,197 @@ #include "xmr.h" #include "../byte_order.h" -#include "int-util.h" +#include "int_util.h" #include "../rand.h" #include "serialize.h" const ge25519 ALIGN(16) xmr_h = { - {0x1861ec7, 0x1ceac77, 0x2f11626, 0x1f261d3, 0x346107c, 0x06d8c4a, - 0x254201d, 0x1675c09, 0x1301c3f, 0x0211d73}, - {0x326feb4, 0x12e30cc, 0x0cf54b4, 0x1117305, 0x318f5d5, 0x06cf754, - 0x2e578a1, 0x1daf058, 0x34430a1, 0x04410e9}, - {0x0fde4d2, 0x0774049, 0x22ca951, 0x05aec2b, 0x07a36a5, 0x1394f13, - 0x3c5385c, 0x1adb924, 0x2b6c581, 0x0a55fa4}, - {0x24517f7, 0x05ee936, 0x3acf5d9, 0x14b08aa, 0x3363738, 0x1051745, - 0x360601e, 0x0f3f2c9, 0x1ead2cd, 0x1d3e3df}}; - -void ge25519_set_xmr_h(ge25519 *r) { ge25519_copy(r, &xmr_h); } + {0x1861ec7, + 0x1ceac77, + 0x2f11626, + 0x1f261d3, + 0x346107c, + 0x06d8c4a, + 0x254201d, + 0x1675c09, + 0x1301c3f, + 0x0211d73}, + {0x326feb4, + 0x12e30cc, + 0x0cf54b4, + 0x1117305, + 0x318f5d5, + 0x06cf754, + 0x2e578a1, + 0x1daf058, + 0x34430a1, + 0x04410e9}, + {0x0fde4d2, + 0x0774049, + 0x22ca951, + 0x05aec2b, + 0x07a36a5, + 0x1394f13, + 0x3c5385c, + 0x1adb924, + 0x2b6c581, + 0x0a55fa4}, + {0x24517f7, + 0x05ee936, + 0x3acf5d9, + 0x14b08aa, + 0x3363738, + 0x1051745, + 0x360601e, + 0x0f3f2c9, + 0x1ead2cd, + 0x1d3e3df}}; + +void ge25519_set_xmr_h(ge25519* r) { + ge25519_copy(r, &xmr_h); +} void xmr_random_scalar(bignum256modm m) { - unsigned char buff[32] = {0}; - random_buffer(buff, sizeof(buff)); - expand256_modm(m, buff, sizeof(buff)); + unsigned char buff[32] = {0}; + random_buffer(buff, sizeof(buff)); + expand256_modm(m, buff, sizeof(buff)); } -void xmr_fast_hash(uint8_t *hash, const void *data, size_t length) { - hasher_Raw(HASHER_SHA3K, data, length, hash); +void xmr_fast_hash(uint8_t* hash, const void* data, size_t length) { + hasher_Raw(HASHER_SHA3K, data, length, hash); } -void xmr_hasher_init(Hasher *hasher) { hasher_Init(hasher, HASHER_SHA3K); } +void xmr_hasher_init(Hasher* hasher) { + hasher_Init(hasher, HASHER_SHA3K); +} -void xmr_hasher_update(Hasher *hasher, const void *data, size_t length) { - hasher_Update(hasher, data, length); +void xmr_hasher_update(Hasher* hasher, const void* data, size_t length) { + hasher_Update(hasher, data, length); } -void xmr_hasher_final(Hasher *hasher, uint8_t *hash) { - hasher_Final(hasher, hash); +void xmr_hasher_final(Hasher* hasher, uint8_t* hash) { + hasher_Final(hasher, hash); } -void xmr_hasher_copy(Hasher *dst, const Hasher *src) { - memcpy(dst, src, sizeof(Hasher)); +void xmr_hasher_copy(Hasher* dst, const Hasher* src) { + memcpy(dst, src, sizeof(Hasher)); } -void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length) { - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - hasher_Raw(HASHER_SHA3K, data, length, hash); - expand256_modm(r, hash, HASHER_DIGEST_LENGTH); +void xmr_hash_to_scalar(bignum256modm r, const void* data, size_t length) { + uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; + hasher_Raw(HASHER_SHA3K, data, length, hash); + expand256_modm(r, hash, HASHER_DIGEST_LENGTH); } -void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length) { - ge25519 point2 = {0}; - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - hasher_Raw(HASHER_SHA3K, data, length, hash); +void xmr_hash_to_ec(ge25519* P, const void* data, size_t length) { + ge25519 point2 = {0}; + uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; + hasher_Raw(HASHER_SHA3K, data, length, hash); - ge25519_fromfe_frombytes_vartime(&point2, hash); - ge25519_mul8(P, &point2); + ge25519_fromfe_frombytes_vartime(&point2, hash); + ge25519_mul8(P, &point2); } -void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p, - uint32_t output_index) { - uint8_t buff[32 + 8] = {0}; - ge25519_pack(buff, p); - int written = xmr_write_varint(buff + 32, 8, output_index); - xmr_hash_to_scalar(s, buff, 32u + written); +void xmr_derivation_to_scalar(bignum256modm s, const ge25519* p, uint32_t output_index) { + uint8_t buff[32 + 8] = {0}; + ge25519_pack(buff, p); + int written = xmr_write_varint(buff + 32, 8, output_index); + xmr_hash_to_scalar(s, buff, 32u + written); } -void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A, - const bignum256modm b) { - ge25519 bA = {0}; - ge25519_scalarmult(&bA, A, b); - ge25519_mul8(r, &bA); +void xmr_generate_key_derivation(ge25519* r, const ge25519* A, const bignum256modm b) { + ge25519 bA = {0}; + ge25519_scalarmult(&bA, A, b); + ge25519_mul8(r, &bA); } -void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx, - const bignum256modm base) { - xmr_derivation_to_scalar(s, deriv, idx); - add256_modm(s, s, base); +void xmr_derive_private_key( + bignum256modm s, + const ge25519* deriv, + uint32_t idx, + const bignum256modm base) { + xmr_derivation_to_scalar(s, deriv, idx); + add256_modm(s, s, base); } -void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx, - const ge25519 *base) { - bignum256modm s = {0}; - ge25519 p2 = {0}; +void xmr_derive_public_key(ge25519* r, const ge25519* deriv, uint32_t idx, const ge25519* base) { + bignum256modm s = {0}; + ge25519 p2 = {0}; - xmr_derivation_to_scalar(s, deriv, idx); - ge25519_scalarmult_base_niels(&p2, ge25519_niels_base_multiples, s); - ge25519_add(r, base, &p2, 0); + xmr_derivation_to_scalar(s, deriv, idx); + ge25519_scalarmult_base_niels(&p2, ge25519_niels_base_multiples, s); + ge25519_add(r, base, &p2, 0); } -void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b, - const ge25519 *B) { - // aG + bB, G is basepoint - ge25519 aG = {0}, bB = {0}; - ge25519_scalarmult_base_niels(&aG, ge25519_niels_base_multiples, a); - ge25519_scalarmult(&bB, B, b); - ge25519_add(r, &aG, &bB, 0); +void xmr_add_keys2(ge25519* r, const bignum256modm a, const bignum256modm b, const ge25519* B) { + // aG + bB, G is basepoint + ge25519 aG = {0}, bB = {0}; + ge25519_scalarmult_base_niels(&aG, ge25519_niels_base_multiples, a); + ge25519_scalarmult(&bB, B, b); + ge25519_add(r, &aG, &bB, 0); } -void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a, - const bignum256modm b, const ge25519 *B) { - // aG + bB, G is basepoint - ge25519_double_scalarmult_vartime(r, B, b, a); +void xmr_add_keys2_vartime( + ge25519* r, + const bignum256modm a, + const bignum256modm b, + const ge25519* B) { + // aG + bB, G is basepoint + ge25519_double_scalarmult_vartime(r, B, b, a); } -void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B) { - // aA + bB - ge25519 aA = {0}, bB = {0}; - ge25519_scalarmult(&aA, A, a); - ge25519_scalarmult(&bB, B, b); - ge25519_add(r, &aA, &bB, 0); +void xmr_add_keys3( + ge25519* r, + const bignum256modm a, + const ge25519* A, + const bignum256modm b, + const ge25519* B) { + // aA + bB + ge25519 aA = {0}, bB = {0}; + ge25519_scalarmult(&aA, A, a); + ge25519_scalarmult(&bB, B, b); + ge25519_add(r, &aA, &bB, 0); } -void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B) { - // aA + bB - ge25519_double_scalarmult_vartime2(r, A, a, B, b); +void xmr_add_keys3_vartime( + ge25519* r, + const bignum256modm a, + const ge25519* A, + const bignum256modm b, + const ge25519* B) { + // aA + bB + ge25519_double_scalarmult_vartime2(r, A, a, B, b); } -void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, - uint32_t minor, const bignum256modm m) { - const char prefix[] = "SubAddr"; - unsigned char buff[32] = {0}; - contract256_modm(buff, m); +void xmr_get_subaddress_secret_key( + bignum256modm r, + uint32_t major, + uint32_t minor, + const bignum256modm m) { + const char prefix[] = "SubAddr"; + unsigned char buff[32] = {0}; + contract256_modm(buff, m); - char data[sizeof(prefix) + sizeof(buff) + 2 * sizeof(uint32_t)] = {0}; - memcpy(data, prefix, sizeof(prefix)); - memcpy(data + sizeof(prefix), buff, sizeof(buff)); + char data[sizeof(prefix) + sizeof(buff) + 2 * sizeof(uint32_t)] = {0}; + memcpy(data, prefix, sizeof(prefix)); + memcpy(data + sizeof(prefix), buff, sizeof(buff)); #if BYTE_ORDER == BIG_ENDIAN - REVERSE32(major, major); - REVERSE32(minor, minor); + REVERSE32(major, major); + REVERSE32(minor, minor); #endif - memcpy(data + sizeof(prefix) + sizeof(buff), &major, sizeof(uint32_t)); - memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor, - sizeof(uint32_t)); + memcpy(data + sizeof(prefix) + sizeof(buff), &major, sizeof(uint32_t)); + memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor, sizeof(uint32_t)); - xmr_hash_to_scalar(r, data, sizeof(data)); + xmr_hash_to_scalar(r, data, sizeof(data)); } -void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount) { - // C = aG + bH - bignum256modm b = {0}; - set256_modm(b, amount); - xmr_add_keys2(r, a, b, &xmr_h); +void xmr_gen_c(ge25519* r, const bignum256modm a, uint64_t amount) { + // C = aG + bH + bignum256modm b = {0}; + set256_modm(b, amount); + xmr_add_keys2(r, a, b, &xmr_h); } #endif // USE_MONERO diff --git a/crypto/monero/xmr.h b/crypto/monero/xmr.h index 8cb5cf5776e..16c2aec5e24 100644 --- a/crypto/monero/xmr.h +++ b/crypto/monero/xmr.h @@ -7,7 +7,7 @@ #ifndef TREZOR_CRYPTO_XMR_H #define TREZOR_CRYPTO_XMR_H -#include "../ed25519-donna/ed25519-donna.h" +#include "../ed25519_donna/ed25519_donna.h" #include "../hasher.h" extern const ge25519 ALIGN(16) xmr_h; @@ -15,66 +15,79 @@ extern const ge25519 ALIGN(16) xmr_h; typedef unsigned char xmr_key_t[32]; typedef struct xmr_ctkey { - xmr_key_t dest; - xmr_key_t mask; + xmr_key_t dest; + xmr_key_t mask; } xmr_ctkey_t; /* sets H point to r */ -void ge25519_set_xmr_h(ge25519 *r); +void ge25519_set_xmr_h(ge25519* r); /* random scalar value */ void xmr_random_scalar(bignum256modm m); /* cn_fast_hash */ -void xmr_fast_hash(uint8_t *hash, const void *data, size_t length); +void xmr_fast_hash(uint8_t* hash, const void* data, size_t length); /* incremental hashing wrappers */ -void xmr_hasher_init(Hasher *hasher); -void xmr_hasher_update(Hasher *hasher, const void *data, size_t length); -void xmr_hasher_final(Hasher *hasher, uint8_t *hash); -void xmr_hasher_copy(Hasher *dst, const Hasher *src); +void xmr_hasher_init(Hasher* hasher); +void xmr_hasher_update(Hasher* hasher, const void* data, size_t length); +void xmr_hasher_final(Hasher* hasher, uint8_t* hash); +void xmr_hasher_copy(Hasher* dst, const Hasher* src); /* H_s(buffer) */ -void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length); +void xmr_hash_to_scalar(bignum256modm r, const void* data, size_t length); /* H_p(buffer) */ -void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length); +void xmr_hash_to_ec(ge25519* P, const void* data, size_t length); /* derivation to scalar value */ -void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p, - uint32_t output_index); +void xmr_derivation_to_scalar(bignum256modm s, const ge25519* p, uint32_t output_index); /* derivation */ -void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A, - const bignum256modm b); +void xmr_generate_key_derivation(ge25519* r, const ge25519* A, const bignum256modm b); /* H_s(derivation || varint(output_index)) + base */ -void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx, - const bignum256modm base); +void xmr_derive_private_key( + bignum256modm s, + const ge25519* deriv, + uint32_t idx, + const bignum256modm base); /* H_s(derivation || varint(output_index))G + base */ -void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx, - const ge25519 *base); +void xmr_derive_public_key(ge25519* r, const ge25519* deriv, uint32_t idx, const ge25519* base); /* aG + bB, G is basepoint */ -void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b, - const ge25519 *B); -void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a, - const bignum256modm b, const ge25519 *B); +void xmr_add_keys2(ge25519* r, const bignum256modm a, const bignum256modm b, const ge25519* B); +void xmr_add_keys2_vartime( + ge25519* r, + const bignum256modm a, + const bignum256modm b, + const ge25519* B); /* aA + bB */ -void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B); -void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B); +void xmr_add_keys3( + ge25519* r, + const bignum256modm a, + const ge25519* A, + const bignum256modm b, + const ge25519* B); +void xmr_add_keys3_vartime( + ge25519* r, + const bignum256modm a, + const ge25519* A, + const bignum256modm b, + const ge25519* B); /* subaddress secret */ -void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, - uint32_t minor, const bignum256modm m); +void xmr_get_subaddress_secret_key( + bignum256modm r, + uint32_t major, + uint32_t minor, + const bignum256modm m); /* Generates Pedersen commitment C = aG + bH */ -void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount); +void xmr_gen_c(ge25519* r, const bignum256modm a, uint64_t amount); -#endif // TREZOR_CRYPTO_XMR_H +#endif // TREZOR_CRYPTO_XMR_H -#endif // USE_MONERO +#endif // USE_MONERO diff --git a/crypto/nem.c b/crypto/nem.c index 231ee5e798c..391c1e6fcae 100644 --- a/crypto/nem.c +++ b/crypto/nem.c @@ -29,485 +29,575 @@ #include #include "base32.h" -#include "ed25519-donna/ed25519-keccak.h" +#include "ed25519_donna/ed25519_keccak.h" #include "memzero.h" #include "ripemd160.h" #include "sha3.h" #define CAN_WRITE(NEEDED) ((ctx->offset + (NEEDED)) <= ctx->size) -#define SERIALIZE_U32(DATA) \ - do { \ - if (!nem_write_u32(ctx, (DATA))) return false; \ - } while (0) -#define SERIALIZE_U64(DATA) \ - do { \ - if (!nem_write_u64(ctx, (DATA))) return false; \ - } while (0) -#define SERIALIZE_TAGGED(DATA, LENGTH) \ - do { \ - if (!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; \ - } while (0) - -const char *nem_network_name(uint8_t network) { - switch (network) { +#define SERIALIZE_U32(DATA) \ + do { \ + if(!nem_write_u32(ctx, (DATA))) return false; \ + } while(0) +#define SERIALIZE_U64(DATA) \ + do { \ + if(!nem_write_u64(ctx, (DATA))) return false; \ + } while(0) +#define SERIALIZE_TAGGED(DATA, LENGTH) \ + do { \ + if(!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; \ + } while(0) + +const char* nem_network_name(uint8_t network) { + switch(network) { case NEM_NETWORK_MAINNET: - return "NEM Mainnet"; + return "NEM Mainnet"; case NEM_NETWORK_TESTNET: - return "NEM Testnet"; + return "NEM Testnet"; case NEM_NETWORK_MIJIN: - return "Mijin"; + return "Mijin"; default: - return NULL; - } + return NULL; + } } -static inline bool nem_write_checked(nem_transaction_ctx *ctx, - const uint8_t *data, uint32_t length) { - if (!CAN_WRITE(length)) { - return false; - } +static inline bool + nem_write_checked(nem_transaction_ctx* ctx, const uint8_t* data, uint32_t length) { + if(!CAN_WRITE(length)) { + return false; + } - memcpy(&ctx->buffer[ctx->offset], data, length); - ctx->offset += length; - return true; + memcpy(&ctx->buffer[ctx->offset], data, length); + ctx->offset += length; + return true; } -static inline bool nem_write_u32(nem_transaction_ctx *ctx, uint32_t data) { - if (!CAN_WRITE(4)) { - return false; - } +static inline bool nem_write_u32(nem_transaction_ctx* ctx, uint32_t data) { + if(!CAN_WRITE(4)) { + return false; + } - ctx->buffer[ctx->offset++] = (data >> 0) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 8) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 16) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 24) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 0) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 8) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 16) & 0xff; + ctx->buffer[ctx->offset++] = (data >> 24) & 0xff; - return true; + return true; } -static inline bool nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) { - SERIALIZE_U32((data >> 0) & 0xffffffff); - SERIALIZE_U32((data >> 32) & 0xffffffff); +static inline bool nem_write_u64(nem_transaction_ctx* ctx, uint64_t data) { + SERIALIZE_U32((data >> 0) & 0xffffffff); + SERIALIZE_U32((data >> 32) & 0xffffffff); - return true; + return true; } -static inline bool nem_write_tagged(nem_transaction_ctx *ctx, - const uint8_t *data, uint32_t length) { - SERIALIZE_U32(length); +static inline bool + nem_write_tagged(nem_transaction_ctx* ctx, const uint8_t* data, uint32_t length) { + SERIALIZE_U32(length); - return nem_write_checked(ctx, data, length); + return nem_write_checked(ctx, data, length); } -static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, - const char *name, const char *value) { - uint32_t name_length = strlen(name); - uint32_t value_length = strlen(value); +static inline bool + nem_write_mosaic_str(nem_transaction_ctx* ctx, const char* name, const char* value) { + uint32_t name_length = strlen(name); + uint32_t value_length = strlen(value); - SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + - value_length); - SERIALIZE_TAGGED((const uint8_t *)name, name_length); - SERIALIZE_TAGGED((const uint8_t *)value, value_length); + SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + value_length); + SERIALIZE_TAGGED((const uint8_t*)name, name_length); + SERIALIZE_TAGGED((const uint8_t*)value, value_length); - return true; + return true; } -static inline bool nem_write_mosaic_bool(nem_transaction_ctx *ctx, - const char *name, bool value) { - return nem_write_mosaic_str(ctx, name, value ? "true" : "false"); +static inline bool nem_write_mosaic_bool(nem_transaction_ctx* ctx, const char* name, bool value) { + return nem_write_mosaic_str(ctx, name, value ? "true" : "false"); } -static inline bool nem_write_mosaic_u64(nem_transaction_ctx *ctx, - const char *name, uint64_t value) { - char buffer[21] = {0}; +static inline bool + nem_write_mosaic_u64(nem_transaction_ctx* ctx, const char* name, uint64_t value) { + char buffer[21] = {0}; - if (bn_format_uint64(value, NULL, NULL, 0, 0, false, 0, buffer, - sizeof(buffer)) == 0) { - return false; - } + if(bn_format_uint64(value, NULL, NULL, 0, 0, false, 0, buffer, sizeof(buffer)) == 0) { + return false; + } - return nem_write_mosaic_str(ctx, name, buffer); + return nem_write_mosaic_str(ctx, name, buffer); } -void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, - uint8_t *address) { - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t* address) { + uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - /* 1. Perform 256-bit Sha3 on the public key */ - keccak_256(public_key, sizeof(ed25519_public_key), hash); + /* 1. Perform 256-bit Sha3 on the public key */ + keccak_256(public_key, sizeof(ed25519_public_key), hash); - /* 2. Perform 160-bit Ripemd of hash resulting from step 1. */ - ripemd160(hash, SHA3_256_DIGEST_LENGTH, &address[1]); + /* 2. Perform 160-bit Ripemd of hash resulting from step 1. */ + ripemd160(hash, SHA3_256_DIGEST_LENGTH, &address[1]); - /* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */ - address[0] = version; + /* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */ + address[0] = version; - /* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a + /* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a * checksum */ - keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); + keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); - /* 5. Concatenate output of step 3 and the checksum from step 4 */ - memcpy(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4); + /* 5. Concatenate output of step 3 and the checksum from step 4 */ + memcpy(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4); - memzero(hash, sizeof(hash)); + memzero(hash, sizeof(hash)); } -bool nem_get_address(const ed25519_public_key public_key, uint8_t version, - char *address) { - uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char* address) { + uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; - nem_get_address_raw(public_key, version, pubkeyhash); + nem_get_address_raw(public_key, version, pubkeyhash); - char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address, - NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648); + char* ret = base32_encode( + pubkeyhash, sizeof(pubkeyhash), address, NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648); - memzero(pubkeyhash, sizeof(pubkeyhash)); - return (ret != NULL); + memzero(pubkeyhash, sizeof(pubkeyhash)); + return (ret != NULL); } -bool nem_validate_address_raw(const uint8_t *address, uint8_t network) { - if (!nem_network_name(network) || address[0] != network) { - return false; - } +bool nem_validate_address_raw(const uint8_t* address, uint8_t network) { + if(!nem_network_name(network) || address[0] != network) { + return false; + } - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; + uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); - bool valid = (memcmp(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4) == 0); + keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); + bool valid = (memcmp(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4) == 0); - memzero(hash, sizeof(hash)); - return valid; + memzero(hash, sizeof(hash)); + return valid; } -bool nem_validate_address(const char *address, uint8_t network) { - uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; +bool nem_validate_address(const char* address, uint8_t network) { + uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; - if (strlen(address) != NEM_ADDRESS_SIZE) { - return false; - } + if(strlen(address) != NEM_ADDRESS_SIZE) { + return false; + } - uint8_t *ret = base32_decode(address, NEM_ADDRESS_SIZE, pubkeyhash, - sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648); - bool valid = (ret != NULL) && nem_validate_address_raw(pubkeyhash, network); + uint8_t* ret = base32_decode( + address, NEM_ADDRESS_SIZE, pubkeyhash, sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648); + bool valid = (ret != NULL) && nem_validate_address_raw(pubkeyhash, network); - memzero(pubkeyhash, sizeof(pubkeyhash)); - return valid; + memzero(pubkeyhash, sizeof(pubkeyhash)); + return valid; } -void nem_transaction_start(nem_transaction_ctx *ctx, - const ed25519_public_key public_key, uint8_t *buffer, - size_t size) { - memcpy(ctx->public_key, public_key, sizeof(ctx->public_key)); +void nem_transaction_start( + nem_transaction_ctx* ctx, + const ed25519_public_key public_key, + uint8_t* buffer, + size_t size) { + memcpy(ctx->public_key, public_key, sizeof(ctx->public_key)); - ctx->buffer = buffer; - ctx->offset = 0; - ctx->size = size; + ctx->buffer = buffer; + ctx->offset = 0; + ctx->size = size; } -size_t nem_transaction_end(nem_transaction_ctx *ctx, - const ed25519_secret_key private_key, - ed25519_signature signature) { - if (private_key != NULL && signature != NULL) { - ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, signature); - } +size_t nem_transaction_end( + nem_transaction_ctx* ctx, + const ed25519_secret_key private_key, + ed25519_signature signature) { + if(private_key != NULL && signature != NULL) { + ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, signature); + } - return ctx->offset; + return ctx->offset; } -bool nem_transaction_write_common(nem_transaction_ctx *ctx, uint32_t type, - uint32_t version, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, - uint32_t deadline) { - SERIALIZE_U32(type); - SERIALIZE_U32(version); - SERIALIZE_U32(timestamp); - SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); - SERIALIZE_U64(fee); - SERIALIZE_U32(deadline); - - return true; +bool nem_transaction_write_common( + nem_transaction_ctx* ctx, + uint32_t type, + uint32_t version, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline) { + SERIALIZE_U32(type); + SERIALIZE_U32(version); + SERIALIZE_U32(timestamp); + SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); + SERIALIZE_U64(fee); + SERIALIZE_U32(deadline); + + return true; } -bool nem_transaction_create_transfer(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const char *recipient, uint64_t amount, - const uint8_t *payload, uint32_t length, - bool encrypted, uint32_t mosaics) { - if (!signer) { - signer = ctx->public_key; - } - - if (!payload) { - length = 0; - } - - bool ret = - nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_TRANSFER, - (uint32_t)network << 24 | (mosaics ? 2 : 1), - timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_TAGGED((const uint8_t *)recipient, NEM_ADDRESS_SIZE); - SERIALIZE_U64(amount); - - if (length) { - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + length); - SERIALIZE_U32(encrypted ? 0x02 : 0x01); - SERIALIZE_TAGGED(payload, length); - } else { - SERIALIZE_U32(0); - } - - if (mosaics) { - SERIALIZE_U32(mosaics); - } - - return true; +bool nem_transaction_create_transfer( + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* recipient, + uint64_t amount, + const uint8_t* payload, + uint32_t length, + bool encrypted, + uint32_t mosaics) { + if(!signer) { + signer = ctx->public_key; + } + + if(!payload) { + length = 0; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_TRANSFER, + (uint32_t)network << 24 | (mosaics ? 2 : 1), + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + SERIALIZE_TAGGED((const uint8_t*)recipient, NEM_ADDRESS_SIZE); + SERIALIZE_U64(amount); + + if(length) { + SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + length); + SERIALIZE_U32(encrypted ? 0x02 : 0x01); + SERIALIZE_TAGGED(payload, length); + } else { + SERIALIZE_U32(0); + } + + if(mosaics) { + SERIALIZE_U32(mosaics); + } + + return true; } -bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, - const char *namespace, const char *mosaic, - uint64_t quantity) { - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length); - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_U64(quantity); - - return true; +bool nem_transaction_write_mosaic( + nem_transaction_ctx* ctx, + const char* namespace, + const char* mosaic, + uint64_t quantity) { + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = + sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + + SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length); + SERIALIZE_U32(identifier_length); + SERIALIZE_TAGGED((const uint8_t*)namespace, namespace_length); + SERIALIZE_TAGGED((const uint8_t*)mosaic, mosaic_length); + SERIALIZE_U64(quantity); + + return true; } -bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_MULTISIG, - (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_TAGGED(inner->buffer, inner->offset); - - return true; +bool nem_transaction_create_multisig( + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx* inner) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_MULTISIG, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + SERIALIZE_TAGGED(inner->buffer, inner->offset); + + return true; } bool nem_transaction_create_multisig_signature( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE, (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - char address[NEM_ADDRESS_SIZE + 1] = {0}; - nem_get_address(inner->public_key, network, address); - - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - keccak_256(inner->buffer, inner->offset, hash); - - SERIALIZE_U32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH); - SERIALIZE_TAGGED(hash, SHA3_256_DIGEST_LENGTH); - SERIALIZE_TAGGED((const uint8_t *)address, NEM_ADDRESS_SIZE); - - return true; + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx* inner) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + char address[NEM_ADDRESS_SIZE + 1] = {0}; + nem_get_address(inner->public_key, network, address); + + uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; + keccak_256(inner->buffer, inner->offset, hash); + + SERIALIZE_U32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH); + SERIALIZE_TAGGED(hash, SHA3_256_DIGEST_LENGTH); + SERIALIZE_TAGGED((const uint8_t*)address, NEM_ADDRESS_SIZE); + + return true; } bool nem_transaction_create_provision_namespace( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *parent, const char *rental_sink, + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* parent, + const char* rental_sink, uint64_t rental_fee) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - if (parent) { - SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(rental_fee); - SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace)); - SERIALIZE_TAGGED((const uint8_t *)parent, strlen(parent)); - } else { - SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(rental_fee); - SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace)); - SERIALIZE_U32(0xffffffff); - } - - return true; + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + if(parent) { + SERIALIZE_TAGGED((const uint8_t*)rental_sink, NEM_ADDRESS_SIZE); + SERIALIZE_U64(rental_fee); + SERIALIZE_TAGGED((const uint8_t*)namespace, strlen(namespace)); + SERIALIZE_TAGGED((const uint8_t*)parent, strlen(parent)); + } else { + SERIALIZE_TAGGED((const uint8_t*)rental_sink, NEM_ADDRESS_SIZE); + SERIALIZE_U64(rental_fee); + SERIALIZE_TAGGED((const uint8_t*)namespace, strlen(namespace)); + SERIALIZE_U32(0xffffffff); + } + + return true; } bool nem_transaction_create_mosaic_creation( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, const char *description, - uint32_t divisibility, uint64_t supply, bool mutable_supply, - bool transferable, uint32_t levy_type, uint64_t levy_fee, - const char *levy_address, const char *levy_namespace, - const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MOSAIC_CREATION, (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - // This length will be rewritten later on - nem_transaction_ctx state = {0}; - memcpy(&state, ctx, sizeof(state)); - - SERIALIZE_U32(0); - SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_TAGGED((const uint8_t *)description, strlen(description)); - SERIALIZE_U32(4); // Number of properties - - if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false; - if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false; - if (!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply)) - return false; - if (!nem_write_mosaic_bool(ctx, "transferable", transferable)) return false; - - if (levy_type) { - size_t levy_namespace_length = strlen(levy_namespace); - size_t levy_mosaic_length = strlen(levy_mosaic); - size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + - sizeof(uint32_t) + levy_mosaic_length; - - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + - sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t)); - SERIALIZE_U32(levy_type); - SERIALIZE_TAGGED((const uint8_t *)levy_address, NEM_ADDRESS_SIZE); - SERIALIZE_U32(levy_identifier_length); - SERIALIZE_TAGGED((const uint8_t *)levy_namespace, levy_namespace_length); - SERIALIZE_TAGGED((const uint8_t *)levy_mosaic, levy_mosaic_length); - SERIALIZE_U64(levy_fee); - } else { - SERIALIZE_U32(0); - } + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* mosaic, + const char* description, + uint32_t divisibility, + uint64_t supply, + bool mutable_supply, + bool transferable, + uint32_t levy_type, + uint64_t levy_fee, + const char* levy_address, + const char* levy_namespace, + const char* levy_mosaic, + const char* creation_sink, + uint64_t creation_fee) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_MOSAIC_CREATION, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = + sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + + // This length will be rewritten later on + nem_transaction_ctx state = {0}; + memcpy(&state, ctx, sizeof(state)); - // Rewrite length - nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t)); - - SERIALIZE_TAGGED((const uint8_t *)creation_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(creation_fee); - - return true; + SERIALIZE_U32(0); + SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); + SERIALIZE_U32(identifier_length); + SERIALIZE_TAGGED((const uint8_t*)namespace, namespace_length); + SERIALIZE_TAGGED((const uint8_t*)mosaic, mosaic_length); + SERIALIZE_TAGGED((const uint8_t*)description, strlen(description)); + SERIALIZE_U32(4); // Number of properties + + if(!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false; + if(!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false; + if(!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply)) return false; + if(!nem_write_mosaic_bool(ctx, "transferable", transferable)) return false; + + if(levy_type) { + size_t levy_namespace_length = strlen(levy_namespace); + size_t levy_mosaic_length = strlen(levy_mosaic); + size_t levy_identifier_length = + sizeof(uint32_t) + levy_namespace_length + sizeof(uint32_t) + levy_mosaic_length; + + SERIALIZE_U32( + sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + sizeof(uint32_t) + + levy_identifier_length + sizeof(uint64_t)); + SERIALIZE_U32(levy_type); + SERIALIZE_TAGGED((const uint8_t*)levy_address, NEM_ADDRESS_SIZE); + SERIALIZE_U32(levy_identifier_length); + SERIALIZE_TAGGED((const uint8_t*)levy_namespace, levy_namespace_length); + SERIALIZE_TAGGED((const uint8_t*)levy_mosaic, levy_mosaic_length); + SERIALIZE_U64(levy_fee); + } else { + SERIALIZE_U32(0); + } + + // Rewrite length + nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t)); + + SERIALIZE_TAGGED((const uint8_t*)creation_sink, NEM_ADDRESS_SIZE); + SERIALIZE_U64(creation_fee); + + return true; } bool nem_transaction_create_mosaic_supply_change( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, uint32_t type, uint64_t delta) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_U32(type); - SERIALIZE_U64(delta); - - return true; + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* mosaic, + uint32_t type, + uint64_t delta) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + size_t namespace_length = strlen(namespace); + size_t mosaic_length = strlen(mosaic); + size_t identifier_length = + sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; + + SERIALIZE_U32(identifier_length); + SERIALIZE_TAGGED((const uint8_t*)namespace, namespace_length); + SERIALIZE_TAGGED((const uint8_t*)mosaic, mosaic_length); + SERIALIZE_U32(type); + SERIALIZE_U64(delta); + + return true; } bool nem_transaction_create_aggregate_modification( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t modifications, bool relative_change) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION, - (uint32_t)network << 24 | (relative_change ? 2 : 1), timestamp, signer, - fee, deadline); - if (!ret) return false; - - SERIALIZE_U32(modifications); - - return true; + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t modifications, + bool relative_change) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION, + (uint32_t)network << 24 | (relative_change ? 2 : 1), + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + SERIALIZE_U32(modifications); + + return true; } bool nem_transaction_write_cosignatory_modification( - nem_transaction_ctx *ctx, uint32_t type, + nem_transaction_ctx* ctx, + uint32_t type, const ed25519_public_key cosignatory) { - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + - sizeof(ed25519_public_key)); - SERIALIZE_U32(type); - SERIALIZE_TAGGED(cosignatory, sizeof(ed25519_public_key)); + SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(ed25519_public_key)); + SERIALIZE_U32(type); + SERIALIZE_TAGGED(cosignatory, sizeof(ed25519_public_key)); - return true; + return true; } -bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, - int32_t relative_change) { - SERIALIZE_U32(sizeof(uint32_t)); - SERIALIZE_U32((uint32_t)relative_change); +bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx* ctx, int32_t relative_change) { + SERIALIZE_U32(sizeof(uint32_t)); + SERIALIZE_U32((uint32_t)relative_change); - return true; + return true; } bool nem_transaction_create_importance_transfer( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t mode, const ed25519_public_key remote) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_U32(mode); - SERIALIZE_TAGGED(remote, sizeof(ed25519_public_key)); - - return true; + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t mode, + const ed25519_public_key remote) { + if(!signer) { + signer = ctx->public_key; + } + + bool ret = nem_transaction_write_common( + ctx, + NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER, + (uint32_t)network << 24 | 1, + timestamp, + signer, + fee, + deadline); + if(!ret) return false; + + SERIALIZE_U32(mode); + SERIALIZE_TAGGED(remote, sizeof(ed25519_public_key)); + + return true; } #endif // USE_NEM diff --git a/crypto/nem.h b/crypto/nem.h index 321aa4c1988..38b7530d7a9 100644 --- a/crypto/nem.h +++ b/crypto/nem.h @@ -32,7 +32,7 @@ #include #include "bip32.h" -#include "ed25519-donna/ed25519.h" +#include "ed25519_donna/ed25519.h" #define NEM_LEVY_PERCENTILE_DIVISOR 4 #define NEM_MAX_DIVISIBILITY 6 @@ -56,106 +56,160 @@ #define NEM_SALT_SIZE sizeof(ed25519_public_key) -#define NEM_ENCRYPTED_SIZE(size) \ - (((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE) +#define NEM_ENCRYPTED_SIZE(size) (((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE) #define NEM_ENCRYPTED_PAYLOAD_SIZE(size) \ - (AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size)) + (AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size)) #define _NEM_PADDING_SIZE(buffer, size) ((buffer)[(size)-1]) -#define NEM_PADDING_SIZE(buffer, size) \ - (_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) \ - : _NEM_PADDING_SIZE(buffer, size)) +#define NEM_PADDING_SIZE(buffer, size) \ + (_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) : _NEM_PADDING_SIZE(buffer, size)) #define NEM_DECRYPTED_SIZE(buffer, size) ((size)-NEM_PADDING_SIZE(buffer, size)) typedef struct { - ed25519_public_key public_key; - uint8_t *buffer; - size_t offset; - size_t size; + ed25519_public_key public_key; + uint8_t* buffer; + size_t offset; + size_t size; } nem_transaction_ctx; -const char *nem_network_name(uint8_t network); - -void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, - uint8_t *address); -bool nem_get_address(const ed25519_public_key public_key, uint8_t version, - char *address); - -bool nem_validate_address_raw(const uint8_t *address, uint8_t network); -bool nem_validate_address(const char *address, uint8_t network); - -void nem_transaction_start(nem_transaction_ctx *ctx, - const ed25519_public_key public_key, uint8_t *buffer, - size_t size); -size_t nem_transaction_end(nem_transaction_ctx *ctx, - const ed25519_secret_key private_key, - ed25519_signature signature); - -bool nem_transaction_write_common(nem_transaction_ctx *context, uint32_t type, - uint32_t version, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, - uint32_t deadline); - -bool nem_transaction_create_transfer(nem_transaction_ctx *context, - uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const char *recipient, uint64_t amount, - const uint8_t *payload, uint32_t length, - bool encrypted, uint32_t mosaics); - -bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, - const char *namespace, const char *mosaic, - uint64_t quantity); - -bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner); +const char* nem_network_name(uint8_t network); + +void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t* address); +bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char* address); + +bool nem_validate_address_raw(const uint8_t* address, uint8_t network); +bool nem_validate_address(const char* address, uint8_t network); + +void nem_transaction_start( + nem_transaction_ctx* ctx, + const ed25519_public_key public_key, + uint8_t* buffer, + size_t size); +size_t nem_transaction_end( + nem_transaction_ctx* ctx, + const ed25519_secret_key private_key, + ed25519_signature signature); + +bool nem_transaction_write_common( + nem_transaction_ctx* context, + uint32_t type, + uint32_t version, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline); + +bool nem_transaction_create_transfer( + nem_transaction_ctx* context, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* recipient, + uint64_t amount, + const uint8_t* payload, + uint32_t length, + bool encrypted, + uint32_t mosaics); + +bool nem_transaction_write_mosaic( + nem_transaction_ctx* ctx, + const char* namespace, + const char* mosaic, + uint64_t quantity); + +bool nem_transaction_create_multisig( + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx* inner); bool nem_transaction_create_multisig_signature( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner); + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const nem_transaction_ctx* inner); bool nem_transaction_create_provision_namespace( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *parent, const char *rental_sink, + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* parent, + const char* rental_sink, uint64_t rental_fee); bool nem_transaction_create_mosaic_creation( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, const char *description, - uint32_t divisibility, uint64_t supply, bool mutable_supply, - bool transferable, uint32_t levy_type, uint64_t levy_fee, - const char *levy_address, const char *levy_namespace, - const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee); + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* mosaic, + const char* description, + uint32_t divisibility, + uint64_t supply, + bool mutable_supply, + bool transferable, + uint32_t levy_type, + uint64_t levy_fee, + const char* levy_address, + const char* levy_namespace, + const char* levy_mosaic, + const char* creation_sink, + uint64_t creation_fee); bool nem_transaction_create_mosaic_supply_change( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, uint32_t type, uint64_t delta); + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + const char* namespace, + const char* mosaic, + uint32_t type, + uint64_t delta); bool nem_transaction_create_aggregate_modification( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t modifications, bool relative_change); + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t modifications, + bool relative_change); bool nem_transaction_write_cosignatory_modification( - nem_transaction_ctx *ctx, uint32_t type, + nem_transaction_ctx* ctx, + uint32_t type, const ed25519_public_key cosignatory); -bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, - int32_t relative_change); +bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx* ctx, int32_t relative_change); bool nem_transaction_create_importance_transfer( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t mode, const ed25519_public_key remote); + nem_transaction_ctx* ctx, + uint8_t network, + uint32_t timestamp, + const ed25519_public_key signer, + uint64_t fee, + uint32_t deadline, + uint32_t mode, + const ed25519_public_key remote); #endif diff --git a/crypto/nist256p1.c b/crypto/nist256p1.c index 1082d334ca5..51dc569cd0c 100644 --- a/crypto/nist256p1.c +++ b/crypto/nist256p1.c @@ -24,31 +24,76 @@ #include "nist256p1.h" const ecdsa_curve nist256p1 = { - /* .prime */ {/*.val =*/{0x1fffffff, 0x1fffffff, 0x1fffffff, 0x000001ff, - 0x00000000, 0x00000000, 0x00040000, 0x1fe00000, - 0xffffff}}, + /* .prime */ {/*.val =*/{ + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0x000001ff, + 0x00000000, + 0x00000000, + 0x00040000, + 0x1fe00000, + 0xffffff}}, /* G */ - {/*.x =*/{/*.val =*/{0x1898c296, 0x0509ca2e, 0x1acce83d, 0x06fb025b, - 0x040f2770, 0x1372b1d2, 0x091fe2f3, 0x1e5c2588, - 0x6b17d1}}, - /*.y =*/{/*.val =*/{0x17bf51f5, 0x1db20341, 0x0c57b3b2, 0x1c66aed6, - 0x19e162bc, 0x15a53e07, 0x1e6e3b9f, 0x1c5fc34f, - 0x4fe342}}}, + {/*.x =*/{/*.val =*/{ + 0x1898c296, + 0x0509ca2e, + 0x1acce83d, + 0x06fb025b, + 0x040f2770, + 0x1372b1d2, + 0x091fe2f3, + 0x1e5c2588, + 0x6b17d1}}, + /*.y =*/{/*.val =*/{ + 0x17bf51f5, + 0x1db20341, + 0x0c57b3b2, + 0x1c66aed6, + 0x19e162bc, + 0x15a53e07, + 0x1e6e3b9f, + 0x1c5fc34f, + 0x4fe342}}}, /* order */ - {/*.val =*/{0x1c632551, 0x1dce5617, 0x05e7a13c, 0x0df55b4e, 0x1ffffbce, - 0x1fffffff, 0x0003ffff, 0x1fe00000, 0xffffff}}, + {/*.val =*/{ + 0x1c632551, + 0x1dce5617, + 0x05e7a13c, + 0x0df55b4e, + 0x1ffffbce, + 0x1fffffff, + 0x0003ffff, + 0x1fe00000, + 0xffffff}}, /* order_half */ - {/*.val =*/{0x1e3192a8, 0x0ee72b0b, 0x02f3d09e, 0x06faada7, 0x1ffffde7, - 0x1fffffff, 0x0001ffff, 0x1ff00000, 0x7fffff}}, + {/*.val =*/{ + 0x1e3192a8, + 0x0ee72b0b, + 0x02f3d09e, + 0x06faada7, + 0x1ffffde7, + 0x1fffffff, + 0x0001ffff, + 0x1ff00000, + 0x7fffff}}, /* a */ -3, /* b */ - {/*.val =*/{0x07d2604b, 0x1e71e1f1, 0x14ec3d8e, 0x1a0d6198, 0x086bc651, - 0x1eaabb4c, 0x0f9ecfae, 0x1b154752, 0x005ac635}} + {/*.val =*/{ + 0x07d2604b, + 0x1e71e1f1, + 0x14ec3d8e, + 0x1a0d6198, + 0x086bc651, + 0x1eaabb4c, + 0x0f9ecfae, + 0x1b154752, + 0x005ac635}} #if USE_PRECOMPUTED_CP , diff --git a/crypto/pbkdf2.c b/crypto/pbkdf2.c index d9e1422979f..e3ebe515e7f 100644 --- a/crypto/pbkdf2.c +++ b/crypto/pbkdf2.c @@ -27,153 +27,169 @@ #include "memzero.h" #include "sha2.h" -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) { - SHA256_CTX ctx = {0}; +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) { + SHA256_CTX ctx = {0}; #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(blocknr, blocknr); + REVERSE32(blocknr, blocknr); #endif - hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig); - memzero(pctx->g, sizeof(pctx->g)); - pctx->g[8] = 0x80000000; - pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig); + memzero(pctx->g, sizeof(pctx->g)); + pctx->g[8] = 0x80000000; + pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); - ctx.bitcount = SHA256_BLOCK_LENGTH * 8; - sha256_Update(&ctx, salt, saltlen); - sha256_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr)); - sha256_Final(&ctx, (uint8_t *)pctx->g); + memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); + ctx.bitcount = SHA256_BLOCK_LENGTH * 8; + sha256_Update(&ctx, salt, saltlen); + sha256_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr)); + sha256_Final(&ctx, (uint8_t*)pctx->g); #if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { - REVERSE32(pctx->g[k], pctx->g[k]); - } + for(uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { + REVERSE32(pctx->g[k], pctx->g[k]); + } #endif - sha256_Transform(pctx->odig, pctx->g, pctx->g); - memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH); - pctx->first = 1; + sha256_Transform(pctx->odig, pctx->g, pctx->g); + memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH); + pctx->first = 1; } -void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, - uint32_t iterations) { - for (uint32_t i = pctx->first; i < iterations; i++) { - sha256_Transform(pctx->idig, pctx->g, pctx->g); - sha256_Transform(pctx->odig, pctx->g, pctx->g); - for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) { - pctx->f[j] ^= pctx->g[j]; +void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX* pctx, uint32_t iterations) { + for(uint32_t i = pctx->first; i < iterations; i++) { + sha256_Transform(pctx->idig, pctx->g, pctx->g); + sha256_Transform(pctx->odig, pctx->g, pctx->g); + for(uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) { + pctx->f[j] ^= pctx->g[j]; + } } - } - pctx->first = 0; + pctx->first = 0; } -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) { #if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { - REVERSE32(pctx->f[k], pctx->f[k]); - } + for(uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { + REVERSE32(pctx->f[k], pctx->f[k]); + } #endif - memcpy(key, pctx->f, SHA256_DIGEST_LENGTH); - memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); + memcpy(key, pctx->f, SHA256_DIGEST_LENGTH); + memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); } -void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen) { - uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH; - uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH; - if (last_block_size) { - blocks_count++; - } else { - last_block_size = SHA256_DIGEST_LENGTH; - } - for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { - PBKDF2_HMAC_SHA256_CTX pctx = {0}; - pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen, blocknr); - pbkdf2_hmac_sha256_Update(&pctx, iterations); - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - pbkdf2_hmac_sha256_Final(&pctx, digest); - uint32_t key_offset = (blocknr - 1) * SHA256_DIGEST_LENGTH; - if (blocknr < blocks_count) { - memcpy(key + key_offset, digest, SHA256_DIGEST_LENGTH); +void pbkdf2_hmac_sha256( + const uint8_t* pass, + int passlen, + const uint8_t* salt, + int saltlen, + uint32_t iterations, + uint8_t* key, + int keylen) { + uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH; + uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH; + if(last_block_size) { + blocks_count++; } else { - memcpy(key + key_offset, digest, last_block_size); + last_block_size = SHA256_DIGEST_LENGTH; + } + for(uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { + PBKDF2_HMAC_SHA256_CTX pctx = {0}; + pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen, blocknr); + pbkdf2_hmac_sha256_Update(&pctx, iterations); + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + pbkdf2_hmac_sha256_Final(&pctx, digest); + uint32_t key_offset = (blocknr - 1) * SHA256_DIGEST_LENGTH; + if(blocknr < blocks_count) { + memcpy(key + key_offset, digest, SHA256_DIGEST_LENGTH); + } else { + memcpy(key + key_offset, digest, last_block_size); + } } - } } -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) { - SHA512_CTX ctx = {0}; +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) { + SHA512_CTX ctx = {0}; #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(blocknr, blocknr); + REVERSE32(blocknr, blocknr); #endif - hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig); - memzero(pctx->g, sizeof(pctx->g)); - pctx->g[8] = 0x8000000000000000; - pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8; + hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig); + memzero(pctx->g, sizeof(pctx->g)); + pctx->g[8] = 0x8000000000000000; + pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8; - memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); - ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8; - ctx.bitcount[1] = 0; - sha512_Update(&ctx, salt, saltlen); - sha512_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr)); - sha512_Final(&ctx, (uint8_t *)pctx->g); + memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); + ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8; + ctx.bitcount[1] = 0; + sha512_Update(&ctx, salt, saltlen); + sha512_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr)); + sha512_Final(&ctx, (uint8_t*)pctx->g); #if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { - REVERSE64(pctx->g[k], pctx->g[k]); - } + for(uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { + REVERSE64(pctx->g[k], pctx->g[k]); + } #endif - sha512_Transform(pctx->odig, pctx->g, pctx->g); - memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH); - pctx->first = 1; + sha512_Transform(pctx->odig, pctx->g, pctx->g); + memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH); + pctx->first = 1; } -void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, - uint32_t iterations) { - for (uint32_t i = pctx->first; i < iterations; i++) { - sha512_Transform(pctx->idig, pctx->g, pctx->g); - sha512_Transform(pctx->odig, pctx->g, pctx->g); - for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) { - pctx->f[j] ^= pctx->g[j]; +void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX* pctx, uint32_t iterations) { + for(uint32_t i = pctx->first; i < iterations; i++) { + sha512_Transform(pctx->idig, pctx->g, pctx->g); + sha512_Transform(pctx->odig, pctx->g, pctx->g); + for(uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) { + pctx->f[j] ^= pctx->g[j]; + } } - } - pctx->first = 0; + pctx->first = 0; } -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) { #if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { - REVERSE64(pctx->f[k], pctx->f[k]); - } + for(uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { + REVERSE64(pctx->f[k], pctx->f[k]); + } #endif - memcpy(key, pctx->f, SHA512_DIGEST_LENGTH); - memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX)); + memcpy(key, pctx->f, SHA512_DIGEST_LENGTH); + memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX)); } -void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen) { - uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH; - uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH; - if (last_block_size) { - blocks_count++; - } else { - last_block_size = SHA512_DIGEST_LENGTH; - } - for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { - PBKDF2_HMAC_SHA512_CTX pctx = {0}; - pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen, blocknr); - pbkdf2_hmac_sha512_Update(&pctx, iterations); - uint8_t digest[SHA512_DIGEST_LENGTH] = {0}; - pbkdf2_hmac_sha512_Final(&pctx, digest); - uint32_t key_offset = (blocknr - 1) * SHA512_DIGEST_LENGTH; - if (blocknr < blocks_count) { - memcpy(key + key_offset, digest, SHA512_DIGEST_LENGTH); +void pbkdf2_hmac_sha512( + const uint8_t* pass, + int passlen, + const uint8_t* salt, + int saltlen, + uint32_t iterations, + uint8_t* key, + int keylen) { + uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH; + uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH; + if(last_block_size) { + blocks_count++; } else { - memcpy(key + key_offset, digest, last_block_size); + last_block_size = SHA512_DIGEST_LENGTH; + } + for(uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { + PBKDF2_HMAC_SHA512_CTX pctx = {0}; + pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen, blocknr); + pbkdf2_hmac_sha512_Update(&pctx, iterations); + uint8_t digest[SHA512_DIGEST_LENGTH] = {0}; + pbkdf2_hmac_sha512_Final(&pctx, digest); + uint32_t key_offset = (blocknr - 1) * SHA512_DIGEST_LENGTH; + if(blocknr < blocks_count) { + memcpy(key + key_offset, digest, SHA512_DIGEST_LENGTH); + } else { + memcpy(key + key_offset, digest, last_block_size); + } } - } } diff --git a/crypto/pbkdf2.h b/crypto/pbkdf2.h index c2e3f04a6e9..22b580ff427 100644 --- a/crypto/pbkdf2.h +++ b/crypto/pbkdf2.h @@ -28,39 +28,55 @@ #include "sha2.h" typedef struct _PBKDF2_HMAC_SHA256_CTX { - uint32_t odig[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 g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; - char first; + uint32_t odig[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 g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; + char first; } PBKDF2_HMAC_SHA256_CTX; typedef struct _PBKDF2_HMAC_SHA512_CTX { - uint64_t odig[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 g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; - char first; + uint64_t odig[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 g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; + char first; } PBKDF2_HMAC_SHA512_CTX; -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); -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(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen); +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); +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( + const uint8_t* pass, + int passlen, + const uint8_t* salt, + int saltlen, + uint32_t iterations, + uint8_t* key, + int keylen); -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); -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(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen); +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); +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( + const uint8_t* pass, + int passlen, + const uint8_t* salt, + int saltlen, + uint32_t iterations, + uint8_t* key, + int keylen); #endif diff --git a/crypto/rand.c b/crypto/rand.c index e917b7f8d97..b35214285e8 100644 --- a/crypto/rand.c +++ b/crypto/rand.c @@ -46,7 +46,9 @@ static uint32_t seed = 0; -void random_reseed(const uint32_t value) { seed = value; } +void random_reseed(const uint32_t value) { + seed = value; +} // Original code: // uint32_t random32(void) { @@ -58,12 +60,12 @@ void random_reseed(const uint32_t value) { seed = value; } // Flipper Zero RNG code: uint32_t random32(void) { - return furi_hal_random_get(); + return furi_hal_random_get(); } // Flipper Zero RNG code: -void random_buffer(uint8_t *buf, size_t len) { - furi_hal_random_fill_buf(buf, len); +void random_buffer(uint8_t* buf, size_t len) { + furi_hal_random_fill_buf(buf, len); } #endif /* RAND_PLATFORM_INDEPENDENT */ @@ -84,17 +86,17 @@ void random_buffer(uint8_t *buf, size_t len) { // } uint32_t random_uniform(uint32_t n) { - uint32_t x = 0, max = 0xFFFFFFFF - (0xFFFFFFFF % n); - while ((x = random32()) >= max) - ; - return x / (max / n); + uint32_t x = 0, max = 0xFFFFFFFF - (0xFFFFFFFF % n); + while((x = random32()) >= max) + ; + return x / (max / n); } -void random_permute(char *str, size_t len) { - for (int i = len - 1; i >= 1; i--) { - int j = random_uniform(i + 1); - char t = str[j]; - str[j] = str[i]; - str[i] = t; - } +void random_permute(char* str, size_t len) { + for(int i = len - 1; i >= 1; i--) { + int j = random_uniform(i + 1); + char t = str[j]; + str[j] = str[i]; + str[i] = t; + } } diff --git a/crypto/rand.h b/crypto/rand.h index 49d9cfaf21d..fa854890f78 100644 --- a/crypto/rand.h +++ b/crypto/rand.h @@ -29,9 +29,9 @@ void random_reseed(const uint32_t value); uint32_t random32(void); -void random_buffer(uint8_t *buf, size_t len); +void random_buffer(uint8_t* buf, size_t len); uint32_t random_uniform(uint32_t n); -void random_permute(char *buf, size_t len); +void random_permute(char* buf, size_t len); #endif diff --git a/crypto/rc4.c b/crypto/rc4.c index fea73cab12b..b42ad24edee 100644 --- a/crypto/rc4.c +++ b/crypto/rc4.c @@ -22,35 +22,35 @@ #include "rc4.h" -static inline void rc4_swap(RC4_CTX *ctx, uint8_t i, uint8_t j) { - uint8_t temp = ctx->S[i]; - ctx->S[i] = ctx->S[j]; - ctx->S[j] = temp; +static inline void rc4_swap(RC4_CTX* ctx, uint8_t i, uint8_t j) { + uint8_t temp = ctx->S[i]; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = temp; } -void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length) { - ctx->i = 0; - ctx->j = 0; +void rc4_init(RC4_CTX* ctx, const uint8_t* key, size_t length) { + ctx->i = 0; + ctx->j = 0; - for (size_t i = 0; i < 256; i++) { - ctx->S[i] = i; - } + for(size_t i = 0; i < 256; i++) { + ctx->S[i] = i; + } - uint8_t j = 0; - for (size_t i = 0; i < 256; i++) { - j += ctx->S[i] + key[i % length]; - rc4_swap(ctx, i, j); - } + uint8_t j = 0; + for(size_t i = 0; i < 256; i++) { + j += ctx->S[i] + key[i % length]; + rc4_swap(ctx, i, j); + } } -void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length) { - for (size_t idx = 0; idx < length; idx++) { - ctx->i++; - ctx->j += ctx->S[ctx->i]; +void rc4_encrypt(RC4_CTX* ctx, uint8_t* buffer, size_t length) { + for(size_t idx = 0; idx < length; idx++) { + ctx->i++; + ctx->j += ctx->S[ctx->i]; - rc4_swap(ctx, ctx->i, ctx->j); + rc4_swap(ctx, ctx->i, ctx->j); - uint8_t K = ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; - buffer[idx] ^= K; - } + uint8_t K = ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; + buffer[idx] ^= K; + } } diff --git a/crypto/rc4.h b/crypto/rc4.h index 8ba8a9b25a0..860d331307a 100644 --- a/crypto/rc4.h +++ b/crypto/rc4.h @@ -27,11 +27,11 @@ #include typedef struct { - uint8_t S[256]; - uint8_t i, j; + uint8_t S[256]; + uint8_t i, j; } RC4_CTX; -void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length); -void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length); +void rc4_init(RC4_CTX* ctx, const uint8_t* key, size_t length); +void rc4_encrypt(RC4_CTX* ctx, uint8_t* buffer, size_t length); #endif diff --git a/crypto/rfc6979.c b/crypto/rfc6979.c index 96f4dfcbf6d..6bede6f5cf6 100644 --- a/crypto/rfc6979.c +++ b/crypto/rfc6979.c @@ -27,36 +27,39 @@ #include "memzero.h" #include "rfc6979.h" -void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, - const ecdsa_curve *curve, rfc6979_state *state) { - if (curve) { - bignum256 hash_bn = {0}; - bn_read_be(hash, &hash_bn); +void init_rfc6979( + const uint8_t* priv_key, + const uint8_t* hash, + const ecdsa_curve* curve, + rfc6979_state* state) { + if(curve) { + bignum256 hash_bn = {0}; + bn_read_be(hash, &hash_bn); - // Make sure hash is partly reduced modulo order - assert(bn_bitcount(&curve->order) >= 256); - bn_mod(&hash_bn, &curve->order); + // Make sure hash is partly reduced modulo order + assert(bn_bitcount(&curve->order) >= 256); + bn_mod(&hash_bn, &curve->order); - uint8_t hash_reduced[32] = {0}; - bn_write_be(&hash_bn, hash_reduced); - memzero(&hash_bn, sizeof(hash_bn)); - hmac_drbg_init(state, priv_key, 32, hash_reduced, 32); - memzero(hash_reduced, sizeof(hash_reduced)); - } else { - hmac_drbg_init(state, priv_key, 32, hash, 32); - } + uint8_t hash_reduced[32] = {0}; + bn_write_be(&hash_bn, hash_reduced); + memzero(&hash_bn, sizeof(hash_bn)); + hmac_drbg_init(state, priv_key, 32, hash_reduced, 32); + memzero(hash_reduced, sizeof(hash_reduced)); + } else { + hmac_drbg_init(state, priv_key, 32, hash, 32); + } } // generate next number from deterministic random number generator -void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) { - hmac_drbg_generate(state, rnd, 32); +void generate_rfc6979(uint8_t rnd[32], rfc6979_state* state) { + hmac_drbg_generate(state, rnd, 32); } // generate K in a deterministic way, according to RFC6979 // http://tools.ietf.org/html/rfc6979 -void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) { - uint8_t buf[32] = {0}; - generate_rfc6979(buf, state); - bn_read_be(buf, k); - memzero(buf, sizeof(buf)); +void generate_k_rfc6979(bignum256* k, rfc6979_state* state) { + uint8_t buf[32] = {0}; + generate_rfc6979(buf, state); + bn_read_be(buf, k); + memzero(buf, sizeof(buf)); } diff --git a/crypto/rfc6979.h b/crypto/rfc6979.h index e4cb9ff049f..02367c38e56 100644 --- a/crypto/rfc6979.h +++ b/crypto/rfc6979.h @@ -33,9 +33,12 @@ // rfc6979 pseudo random number generator state typedef HMAC_DRBG_CTX rfc6979_state; -void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, - const ecdsa_curve *curve, rfc6979_state *rng); -void generate_rfc6979(uint8_t rnd[32], rfc6979_state *rng); -void generate_k_rfc6979(bignum256 *k, rfc6979_state *rng); +void init_rfc6979( + const uint8_t* priv_key, + const uint8_t* hash, + const ecdsa_curve* curve, + rfc6979_state* rng); +void generate_rfc6979(uint8_t rnd[32], rfc6979_state* rng); +void generate_k_rfc6979(bignum256* k, rfc6979_state* rng); #endif diff --git a/crypto/ripemd160.c b/crypto/ripemd160.c index 5aef8b8d34d..7d7f3898b21 100644 --- a/crypto/ripemd160.c +++ b/crypto/ripemd160.c @@ -34,30 +34,27 @@ * 32-bit integer manipulation macros (little endian) */ #ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} +#define GET_UINT32_LE(n, b, i) \ + { \ + (n) = ((uint32_t)(b)[(i)]) | ((uint32_t)(b)[(i) + 1] << 8) | \ + ((uint32_t)(b)[(i) + 2] << 16) | ((uint32_t)(b)[(i) + 3] << 24); \ + } #endif #ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (uint8_t) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (uint8_t) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (uint8_t) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (uint8_t) ( ( (n) >> 24 ) & 0xFF ); \ -} +#define PUT_UINT32_LE(n, b, i) \ + { \ + (b)[(i)] = (uint8_t)(((n)) & 0xFF); \ + (b)[(i) + 1] = (uint8_t)(((n) >> 8) & 0xFF); \ + (b)[(i) + 2] = (uint8_t)(((n) >> 16) & 0xFF); \ + (b)[(i) + 3] = (uint8_t)(((n) >> 24) & 0xFF); \ + } #endif /* * RIPEMD-160 context setup */ -void ripemd160_Init(RIPEMD160_CTX *ctx) -{ +void ripemd160_Init(RIPEMD160_CTX* ctx) { memzero(ctx, sizeof(RIPEMD160_CTX)); ctx->total[0] = 0; ctx->total[1] = 0; @@ -72,26 +69,26 @@ void ripemd160_Init(RIPEMD160_CTX *ctx) /* * Process one block */ -void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_LENGTH] ) -{ - uint32_t A = 0, B = 0, C = 0, D = 0, E = 0, Ap = 0, Bp = 0, Cp = 0, Dp = 0, Ep = 0, X[16] = {0}; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); +void ripemd160_process(RIPEMD160_CTX* ctx, const uint8_t data[RIPEMD160_BLOCK_LENGTH]) { + uint32_t A = 0, B = 0, C = 0, D = 0, E = 0, Ap = 0, Bp = 0, Cp = 0, Dp = 0, Ep = 0, + X[16] = {0}; + + GET_UINT32_LE(X[0], data, 0); + GET_UINT32_LE(X[1], data, 4); + GET_UINT32_LE(X[2], data, 8); + GET_UINT32_LE(X[3], data, 12); + GET_UINT32_LE(X[4], data, 16); + GET_UINT32_LE(X[5], data, 20); + GET_UINT32_LE(X[6], data, 24); + GET_UINT32_LE(X[7], data, 28); + GET_UINT32_LE(X[8], data, 32); + GET_UINT32_LE(X[9], data, 36); + GET_UINT32_LE(X[10], data, 40); + GET_UINT32_LE(X[11], data, 44); + GET_UINT32_LE(X[12], data, 48); + GET_UINT32_LE(X[13], data, 52); + GET_UINT32_LE(X[14], data, 56); + GET_UINT32_LE(X[15], data, 60); A = Ap = ctx->state[0]; B = Bp = ctx->state[1]; @@ -99,149 +96,149 @@ void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_L D = Dp = ctx->state[3]; E = Ep = ctx->state[4]; -#define F1( x, y, z ) ( x ^ y ^ z ) -#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) -#define F3( x, y, z ) ( ( x | ~y ) ^ z ) -#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) -#define F5( x, y, z ) ( x ^ ( y | ~z ) ) - -#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) - -#define P( a, b, c, d, e, r, s, f, k ) \ - a += f( b, c, d ) + X[r] + k; \ - a = S( a, s ) + e; \ - c = S( c, 10 ); - -#define P2( a, b, c, d, e, r, s, rp, sp ) \ - P( a, b, c, d, e, r, s, F, K ); \ - P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); - -#define F F1 -#define K 0x00000000 -#define Fp F5 -#define Kp 0x50A28BE6 - P2( A, B, C, D, E, 0, 11, 5, 8 ); - P2( E, A, B, C, D, 1, 14, 14, 9 ); - P2( D, E, A, B, C, 2, 15, 7, 9 ); - P2( C, D, E, A, B, 3, 12, 0, 11 ); - P2( B, C, D, E, A, 4, 5, 9, 13 ); - P2( A, B, C, D, E, 5, 8, 2, 15 ); - P2( E, A, B, C, D, 6, 7, 11, 15 ); - P2( D, E, A, B, C, 7, 9, 4, 5 ); - P2( C, D, E, A, B, 8, 11, 13, 7 ); - P2( B, C, D, E, A, 9, 13, 6, 7 ); - P2( A, B, C, D, E, 10, 14, 15, 8 ); - P2( E, A, B, C, D, 11, 15, 8, 11 ); - P2( D, E, A, B, C, 12, 6, 1, 14 ); - P2( C, D, E, A, B, 13, 7, 10, 14 ); - P2( B, C, D, E, A, 14, 9, 3, 12 ); - P2( A, B, C, D, E, 15, 8, 12, 6 ); +#define F1(x, y, z) (x ^ y ^ z) +#define F2(x, y, z) ((x & y) | (~x & z)) +#define F3(x, y, z) ((x | ~y) ^ z) +#define F4(x, y, z) ((x & z) | (y & ~z)) +#define F5(x, y, z) (x ^ (y | ~z)) + +#define S(x, n) ((x << n) | (x >> (32 - n))) + +#define P(a, b, c, d, e, r, s, f, k) \ + a += f(b, c, d) + X[r] + k; \ + a = S(a, s) + e; \ + c = S(c, 10); + +#define P2(a, b, c, d, e, r, s, rp, sp) \ + P(a, b, c, d, e, r, s, F, K); \ + P(a##p, b##p, c##p, d##p, e##p, rp, sp, Fp, Kp); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2(A, B, C, D, E, 0, 11, 5, 8); + P2(E, A, B, C, D, 1, 14, 14, 9); + P2(D, E, A, B, C, 2, 15, 7, 9); + P2(C, D, E, A, B, 3, 12, 0, 11); + P2(B, C, D, E, A, 4, 5, 9, 13); + P2(A, B, C, D, E, 5, 8, 2, 15); + P2(E, A, B, C, D, 6, 7, 11, 15); + P2(D, E, A, B, C, 7, 9, 4, 5); + P2(C, D, E, A, B, 8, 11, 13, 7); + P2(B, C, D, E, A, 9, 13, 6, 7); + P2(A, B, C, D, E, 10, 14, 15, 8); + P2(E, A, B, C, D, 11, 15, 8, 11); + P2(D, E, A, B, C, 12, 6, 1, 14); + P2(C, D, E, A, B, 13, 7, 10, 14); + P2(B, C, D, E, A, 14, 9, 3, 12); + P2(A, B, C, D, E, 15, 8, 12, 6); #undef F #undef K #undef Fp #undef Kp -#define F F2 -#define K 0x5A827999 -#define Fp F4 -#define Kp 0x5C4DD124 - P2( E, A, B, C, D, 7, 7, 6, 9 ); - P2( D, E, A, B, C, 4, 6, 11, 13 ); - P2( C, D, E, A, B, 13, 8, 3, 15 ); - P2( B, C, D, E, A, 1, 13, 7, 7 ); - P2( A, B, C, D, E, 10, 11, 0, 12 ); - P2( E, A, B, C, D, 6, 9, 13, 8 ); - P2( D, E, A, B, C, 15, 7, 5, 9 ); - P2( C, D, E, A, B, 3, 15, 10, 11 ); - P2( B, C, D, E, A, 12, 7, 14, 7 ); - P2( A, B, C, D, E, 0, 12, 15, 7 ); - P2( E, A, B, C, D, 9, 15, 8, 12 ); - P2( D, E, A, B, C, 5, 9, 12, 7 ); - P2( C, D, E, A, B, 2, 11, 4, 6 ); - P2( B, C, D, E, A, 14, 7, 9, 15 ); - P2( A, B, C, D, E, 11, 13, 1, 13 ); - P2( E, A, B, C, D, 8, 12, 2, 11 ); +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2(E, A, B, C, D, 7, 7, 6, 9); + P2(D, E, A, B, C, 4, 6, 11, 13); + P2(C, D, E, A, B, 13, 8, 3, 15); + P2(B, C, D, E, A, 1, 13, 7, 7); + P2(A, B, C, D, E, 10, 11, 0, 12); + P2(E, A, B, C, D, 6, 9, 13, 8); + P2(D, E, A, B, C, 15, 7, 5, 9); + P2(C, D, E, A, B, 3, 15, 10, 11); + P2(B, C, D, E, A, 12, 7, 14, 7); + P2(A, B, C, D, E, 0, 12, 15, 7); + P2(E, A, B, C, D, 9, 15, 8, 12); + P2(D, E, A, B, C, 5, 9, 12, 7); + P2(C, D, E, A, B, 2, 11, 4, 6); + P2(B, C, D, E, A, 14, 7, 9, 15); + P2(A, B, C, D, E, 11, 13, 1, 13); + P2(E, A, B, C, D, 8, 12, 2, 11); #undef F #undef K #undef Fp #undef Kp -#define F F3 -#define K 0x6ED9EBA1 -#define Fp F3 -#define Kp 0x6D703EF3 - P2( D, E, A, B, C, 3, 11, 15, 9 ); - P2( C, D, E, A, B, 10, 13, 5, 7 ); - P2( B, C, D, E, A, 14, 6, 1, 15 ); - P2( A, B, C, D, E, 4, 7, 3, 11 ); - P2( E, A, B, C, D, 9, 14, 7, 8 ); - P2( D, E, A, B, C, 15, 9, 14, 6 ); - P2( C, D, E, A, B, 8, 13, 6, 6 ); - P2( B, C, D, E, A, 1, 15, 9, 14 ); - P2( A, B, C, D, E, 2, 14, 11, 12 ); - P2( E, A, B, C, D, 7, 8, 8, 13 ); - P2( D, E, A, B, C, 0, 13, 12, 5 ); - P2( C, D, E, A, B, 6, 6, 2, 14 ); - P2( B, C, D, E, A, 13, 5, 10, 13 ); - P2( A, B, C, D, E, 11, 12, 0, 13 ); - P2( E, A, B, C, D, 5, 7, 4, 7 ); - P2( D, E, A, B, C, 12, 5, 13, 5 ); +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2(D, E, A, B, C, 3, 11, 15, 9); + P2(C, D, E, A, B, 10, 13, 5, 7); + P2(B, C, D, E, A, 14, 6, 1, 15); + P2(A, B, C, D, E, 4, 7, 3, 11); + P2(E, A, B, C, D, 9, 14, 7, 8); + P2(D, E, A, B, C, 15, 9, 14, 6); + P2(C, D, E, A, B, 8, 13, 6, 6); + P2(B, C, D, E, A, 1, 15, 9, 14); + P2(A, B, C, D, E, 2, 14, 11, 12); + P2(E, A, B, C, D, 7, 8, 8, 13); + P2(D, E, A, B, C, 0, 13, 12, 5); + P2(C, D, E, A, B, 6, 6, 2, 14); + P2(B, C, D, E, A, 13, 5, 10, 13); + P2(A, B, C, D, E, 11, 12, 0, 13); + P2(E, A, B, C, D, 5, 7, 4, 7); + P2(D, E, A, B, C, 12, 5, 13, 5); #undef F #undef K #undef Fp #undef Kp -#define F F4 -#define K 0x8F1BBCDC -#define Fp F2 -#define Kp 0x7A6D76E9 - P2( C, D, E, A, B, 1, 11, 8, 15 ); - P2( B, C, D, E, A, 9, 12, 6, 5 ); - P2( A, B, C, D, E, 11, 14, 4, 8 ); - P2( E, A, B, C, D, 10, 15, 1, 11 ); - P2( D, E, A, B, C, 0, 14, 3, 14 ); - P2( C, D, E, A, B, 8, 15, 11, 14 ); - P2( B, C, D, E, A, 12, 9, 15, 6 ); - P2( A, B, C, D, E, 4, 8, 0, 14 ); - P2( E, A, B, C, D, 13, 9, 5, 6 ); - P2( D, E, A, B, C, 3, 14, 12, 9 ); - P2( C, D, E, A, B, 7, 5, 2, 12 ); - P2( B, C, D, E, A, 15, 6, 13, 9 ); - P2( A, B, C, D, E, 14, 8, 9, 12 ); - P2( E, A, B, C, D, 5, 6, 7, 5 ); - P2( D, E, A, B, C, 6, 5, 10, 15 ); - P2( C, D, E, A, B, 2, 12, 14, 8 ); +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2(C, D, E, A, B, 1, 11, 8, 15); + P2(B, C, D, E, A, 9, 12, 6, 5); + P2(A, B, C, D, E, 11, 14, 4, 8); + P2(E, A, B, C, D, 10, 15, 1, 11); + P2(D, E, A, B, C, 0, 14, 3, 14); + P2(C, D, E, A, B, 8, 15, 11, 14); + P2(B, C, D, E, A, 12, 9, 15, 6); + P2(A, B, C, D, E, 4, 8, 0, 14); + P2(E, A, B, C, D, 13, 9, 5, 6); + P2(D, E, A, B, C, 3, 14, 12, 9); + P2(C, D, E, A, B, 7, 5, 2, 12); + P2(B, C, D, E, A, 15, 6, 13, 9); + P2(A, B, C, D, E, 14, 8, 9, 12); + P2(E, A, B, C, D, 5, 6, 7, 5); + P2(D, E, A, B, C, 6, 5, 10, 15); + P2(C, D, E, A, B, 2, 12, 14, 8); #undef F #undef K #undef Fp #undef Kp -#define F F5 -#define K 0xA953FD4E -#define Fp F1 -#define Kp 0x00000000 - P2( B, C, D, E, A, 4, 9, 12, 8 ); - P2( A, B, C, D, E, 0, 15, 15, 5 ); - P2( E, A, B, C, D, 5, 5, 10, 12 ); - P2( D, E, A, B, C, 9, 11, 4, 9 ); - P2( C, D, E, A, B, 7, 6, 1, 12 ); - P2( B, C, D, E, A, 12, 8, 5, 5 ); - P2( A, B, C, D, E, 2, 13, 8, 14 ); - P2( E, A, B, C, D, 10, 12, 7, 6 ); - P2( D, E, A, B, C, 14, 5, 6, 8 ); - P2( C, D, E, A, B, 1, 12, 2, 13 ); - P2( B, C, D, E, A, 3, 13, 13, 6 ); - P2( A, B, C, D, E, 8, 14, 14, 5 ); - P2( E, A, B, C, D, 11, 11, 0, 15 ); - P2( D, E, A, B, C, 6, 8, 3, 13 ); - P2( C, D, E, A, B, 15, 5, 9, 11 ); - P2( B, C, D, E, A, 13, 6, 11, 11 ); +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2(B, C, D, E, A, 4, 9, 12, 8); + P2(A, B, C, D, E, 0, 15, 15, 5); + P2(E, A, B, C, D, 5, 5, 10, 12); + P2(D, E, A, B, C, 9, 11, 4, 9); + P2(C, D, E, A, B, 7, 6, 1, 12); + P2(B, C, D, E, A, 12, 8, 5, 5); + P2(A, B, C, D, E, 2, 13, 8, 14); + P2(E, A, B, C, D, 10, 12, 7, 6); + P2(D, E, A, B, C, 14, 5, 6, 8); + P2(C, D, E, A, B, 1, 12, 2, 13); + P2(B, C, D, E, A, 3, 13, 13, 6); + P2(A, B, C, D, E, 8, 14, 14, 5); + P2(E, A, B, C, D, 11, 11, 0, 15); + P2(D, E, A, B, C, 6, 8, 3, 13); + P2(C, D, E, A, B, 15, 5, 9, 11); + P2(B, C, D, E, A, 13, 6, 11, 11); #undef F #undef K #undef Fp #undef Kp - C = ctx->state[1] + C + Dp; + C = ctx->state[1] + C + Dp; ctx->state[1] = ctx->state[2] + D + Ep; ctx->state[2] = ctx->state[3] + E + Ap; ctx->state[3] = ctx->state[4] + A + Bp; @@ -253,80 +250,71 @@ void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_L /* * RIPEMD-160 process buffer */ -void ripemd160_Update( RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen ) -{ +void ripemd160_Update(RIPEMD160_CTX* ctx, const uint8_t* input, uint32_t ilen) { uint32_t fill = 0; uint32_t left = 0; - if( ilen == 0 ) - return; + if(ilen == 0) return; left = ctx->total[0] & 0x3F; fill = RIPEMD160_BLOCK_LENGTH - left; - ctx->total[0] += (uint32_t) ilen; + ctx->total[0] += (uint32_t)ilen; ctx->total[0] &= 0xFFFFFFFF; - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; + if(ctx->total[0] < (uint32_t)ilen) ctx->total[1]++; - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - ripemd160_process( ctx, ctx->buffer ); + if(left && ilen >= fill) { + memcpy((void*)(ctx->buffer + left), input, fill); + ripemd160_process(ctx, ctx->buffer); input += fill; - ilen -= fill; + ilen -= fill; left = 0; } - while( ilen >= RIPEMD160_BLOCK_LENGTH ) - { - ripemd160_process( ctx, input ); + while(ilen >= RIPEMD160_BLOCK_LENGTH) { + ripemd160_process(ctx, input); input += RIPEMD160_BLOCK_LENGTH; - ilen -= RIPEMD160_BLOCK_LENGTH; + ilen -= RIPEMD160_BLOCK_LENGTH; } - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); + if(ilen > 0) { + memcpy((void*)(ctx->buffer + left), input, ilen); } } -static const uint8_t ripemd160_padding[RIPEMD160_BLOCK_LENGTH] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; +static const uint8_t ripemd160_padding[RIPEMD160_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* * RIPEMD-160 final digest */ -void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH] ) -{ - uint32_t last = 0; uint32_t padn = 0; - uint32_t high = 0; uint32_t low = 0; +void ripemd160_Final(RIPEMD160_CTX* ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH]) { + uint32_t last = 0; + uint32_t padn = 0; + uint32_t high = 0; + uint32_t low = 0; uint8_t msglen[8] = {0}; - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); + high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); + PUT_UINT32_LE(low, msglen, 0); + PUT_UINT32_LE(high, msglen, 4); last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + padn = (last < 56) ? (56 - last) : (120 - last); - ripemd160_Update( ctx, ripemd160_padding, padn ); - ripemd160_Update( ctx, msglen, 8 ); + ripemd160_Update(ctx, ripemd160_padding, padn); + ripemd160_Update(ctx, msglen, 8); - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - PUT_UINT32_LE( ctx->state[4], output, 16 ); + PUT_UINT32_LE(ctx->state[0], output, 0); + PUT_UINT32_LE(ctx->state[1], output, 4); + PUT_UINT32_LE(ctx->state[2], output, 8); + PUT_UINT32_LE(ctx->state[3], output, 12); + PUT_UINT32_LE(ctx->state[4], output, 16); memzero(ctx, sizeof(RIPEMD160_CTX)); } @@ -334,10 +322,9 @@ void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH /* * output = RIPEMD-160( input buffer ) */ -void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]) -{ +void ripemd160(const uint8_t* msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]) { RIPEMD160_CTX ctx = {0}; - ripemd160_Init( &ctx ); - ripemd160_Update( &ctx, msg, msg_len ); - ripemd160_Final( &ctx, hash ); + ripemd160_Init(&ctx); + ripemd160_Update(&ctx, msg, msg_len); + ripemd160_Final(&ctx, hash); } diff --git a/crypto/ripemd160.h b/crypto/ripemd160.h index 8256b08a1a3..271e9ec5b88 100644 --- a/crypto/ripemd160.h +++ b/crypto/ripemd160.h @@ -7,16 +7,14 @@ #define RIPEMD160_DIGEST_LENGTH 20 typedef struct _RIPEMD160_CTX { - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[5]; /*!< intermediate digest state */ - uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ } RIPEMD160_CTX; -void ripemd160_Init(RIPEMD160_CTX *ctx); -void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen); -void ripemd160_Final(RIPEMD160_CTX *ctx, - uint8_t output[RIPEMD160_DIGEST_LENGTH]); -void ripemd160(const uint8_t *msg, uint32_t msg_len, - uint8_t hash[RIPEMD160_DIGEST_LENGTH]); +void ripemd160_Init(RIPEMD160_CTX* ctx); +void ripemd160_Update(RIPEMD160_CTX* ctx, const uint8_t* input, uint32_t ilen); +void ripemd160_Final(RIPEMD160_CTX* ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH]); +void ripemd160(const uint8_t* msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]); #endif diff --git a/crypto/script.c b/crypto/script.c index cbc71b219ca..11173e973bb 100644 --- a/crypto/script.c +++ b/crypto/script.c @@ -24,43 +24,41 @@ #include #include "base58.h" -int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, - int addrsize) { - uint8_t raw[35] = {0}; +int script_output_to_address(const uint8_t* script, int scriptlen, char* addr, int addrsize) { + uint8_t raw[35] = {0}; - // P2PKH - if (scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 && - script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xAC) { - raw[0] = 0x00; - memcpy(raw + 1, script + 3, 20); - return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); - } + // P2PKH + if(scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 && script[2] == 0x14 && + script[23] == 0x88 && script[24] == 0xAC) { + raw[0] = 0x00; + memcpy(raw + 1, script + 3, 20); + return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); + } - // P2SH - if (scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 && - script[22] == 0x87) { - raw[0] = 0x05; - memcpy(raw + 1, script + 2, 20); - return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); - } + // P2SH + if(scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 && script[22] == 0x87) { + raw[0] = 0x05; + memcpy(raw + 1, script + 2, 20); + return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); + } - // P2WPKH - if (scriptlen == 22 && script[0] == 0x00 && script[1] == 0x14) { - raw[0] = 0x06; - raw[1] = 0x00; - raw[2] = 0x00; - memcpy(raw + 3, script + 2, 20); - return base58_encode_check(raw, 3 + 20, HASHER_SHA2D, addr, addrsize); - } + // P2WPKH + if(scriptlen == 22 && script[0] == 0x00 && script[1] == 0x14) { + raw[0] = 0x06; + raw[1] = 0x00; + raw[2] = 0x00; + memcpy(raw + 3, script + 2, 20); + return base58_encode_check(raw, 3 + 20, HASHER_SHA2D, addr, addrsize); + } - // P2WSH - if (scriptlen == 34 && script[0] == 0x00 && script[1] == 0x20) { - raw[0] = 0x0A; - raw[1] = 0x00; - raw[2] = 0x00; - memcpy(raw + 3, script + 2, 32); - return base58_encode_check(raw, 3 + 32, HASHER_SHA2D, addr, addrsize); - } + // P2WSH + if(scriptlen == 34 && script[0] == 0x00 && script[1] == 0x20) { + raw[0] = 0x0A; + raw[1] = 0x00; + raw[2] = 0x00; + memcpy(raw + 3, script + 2, 32); + return base58_encode_check(raw, 3 + 32, HASHER_SHA2D, addr, addrsize); + } - return 0; + return 0; } diff --git a/crypto/script.h b/crypto/script.h index c9cc003b866..585b059fa22 100644 --- a/crypto/script.h +++ b/crypto/script.h @@ -25,7 +25,6 @@ #include -int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, - int addrsize); +int script_output_to_address(const uint8_t* script, int scriptlen, char* addr, int addrsize); #endif diff --git a/crypto/secp256k1.c b/crypto/secp256k1.c index c5502d6b963..d954dd733e0 100644 --- a/crypto/secp256k1.c +++ b/crypto/secp256k1.c @@ -24,25 +24,62 @@ #include "secp256k1.h" const ecdsa_curve secp256k1 = { - /* .prime */ {/*.val =*/{0x1ffffc2f, 0x1ffffff7, 0x1fffffff, 0x1fffffff, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, - 0xffffff}}, + /* .prime */ {/*.val =*/{ + 0x1ffffc2f, + 0x1ffffff7, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0xffffff}}, /* G */ - {/*.x =*/{/*.val =*/{0x16f81798, 0x0f940ad8, 0x138a3656, 0x17f9b65b, - 0x10b07029, 0x114ae743, 0x0eb15681, 0x0fdf3b97, - 0x79be66}}, - /*.y =*/{/*.val =*/{0x1b10d4b8, 0x023e847f, 0x01550667, 0x0f68914d, - 0x108a8fd1, 0x1dfe0708, 0x11957693, 0x0ee4d478, - 0x483ada}}}, + {/*.x =*/{/*.val =*/{ + 0x16f81798, + 0x0f940ad8, + 0x138a3656, + 0x17f9b65b, + 0x10b07029, + 0x114ae743, + 0x0eb15681, + 0x0fdf3b97, + 0x79be66}}, + /*.y =*/{/*.val =*/{ + 0x1b10d4b8, + 0x023e847f, + 0x01550667, + 0x0f68914d, + 0x108a8fd1, + 0x1dfe0708, + 0x11957693, + 0x0ee4d478, + 0x483ada}}}, /* order */ - {/*.val =*/{0x10364141, 0x1e92f466, 0x12280eef, 0x1db9cd5e, 0x1fffebaa, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0xffffff}}, + {/*.val =*/{ + 0x10364141, + 0x1e92f466, + 0x12280eef, + 0x1db9cd5e, + 0x1fffebaa, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0xffffff}}, /* order_half */ - {/*.val =*/{0x081b20a0, 0x1f497a33, 0x09140777, 0x0edce6af, 0x1ffff5d5, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x7fffff}}, + {/*.val =*/{ + 0x081b20a0, + 0x1f497a33, + 0x09140777, + 0x0edce6af, + 0x1ffff5d5, + 0x1fffffff, + 0x1fffffff, + 0x1fffffff, + 0x7fffff}}, /* a */ 0, diff --git a/crypto/segwit_addr.c b/crypto/segwit_addr.c index 446c0d6e639..1dbc1511880 100644 --- a/crypto/segwit_addr.c +++ b/crypto/segwit_addr.c @@ -26,95 +26,94 @@ static uint32_t bech32_polymod_step(uint32_t pre) { uint8_t b = pre >> 25; - return ((pre & 0x1FFFFFF) << 5) ^ - (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ - (-((b >> 1) & 1) & 0x26508e6dUL) ^ - (-((b >> 2) & 1) & 0x1ea119faUL) ^ - (-((b >> 3) & 1) & 0x3d4233ddUL) ^ - (-((b >> 4) & 1) & 0x2a1462b3UL); + return ((pre & 0x1FFFFFF) << 5) ^ (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ + (-((b >> 1) & 1) & 0x26508e6dUL) ^ (-((b >> 2) & 1) & 0x1ea119faUL) ^ + (-((b >> 3) & 1) & 0x3d4233ddUL) ^ (-((b >> 4) & 1) & 0x2a1462b3UL); } static uint32_t bech32_final_constant(bech32_encoding enc) { - if (enc == BECH32_ENCODING_BECH32) return 1; - if (enc == BECH32_ENCODING_BECH32M) return 0x2bc830a3; + if(enc == BECH32_ENCODING_BECH32) return 1; + if(enc == BECH32_ENCODING_BECH32M) return 0x2bc830a3; return 0; } static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; static const int8_t charset_rev[128] = { - -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, - 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, - -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, - 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -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, + -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, -1, 29, + -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, + 6, 4, 2, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, + 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1}; -int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len, bech32_encoding enc) { +int bech32_encode( + char* output, + const char* hrp, + const uint8_t* data, + size_t data_len, + bech32_encoding enc) { uint32_t chk = 1; size_t i = 0; - while (hrp[i] != 0) { + while(hrp[i] != 0) { int ch = hrp[i]; - if (ch < 33 || ch > 126) { + if(ch < 33 || ch > 126) { return 0; } - if (ch >= 'A' && ch <= 'Z') return 0; + if(ch >= 'A' && ch <= 'Z') return 0; chk = bech32_polymod_step(chk) ^ (ch >> 5); ++i; } - if (i + 7 + data_len > 90) return 0; + if(i + 7 + data_len > 90) return 0; chk = bech32_polymod_step(chk); - while (*hrp != 0) { + while(*hrp != 0) { chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f); *(output++) = *(hrp++); } *(output++) = '1'; - for (i = 0; i < data_len; ++i) { - if (*data >> 5) return 0; + for(i = 0; i < data_len; ++i) { + if(*data >> 5) return 0; chk = bech32_polymod_step(chk) ^ (*data); *(output++) = charset[*(data++)]; } - for (i = 0; i < 6; ++i) { + for(i = 0; i < 6; ++i) { chk = bech32_polymod_step(chk); } chk ^= bech32_final_constant(enc); - for (i = 0; i < 6; ++i) { + for(i = 0; i < 6; ++i) { *(output++) = charset[(chk >> ((5 - i) * 5)) & 0x1f]; } *output = 0; return 1; } -bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) { +bech32_encoding bech32_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) { uint32_t chk = 1; size_t i = 0; size_t input_len = strlen(input); size_t hrp_len = 0; int have_lower = 0, have_upper = 0; - if (input_len < 8) { + if(input_len < 8) { return BECH32_ENCODING_NONE; } *data_len = 0; - while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { + while(*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { ++(*data_len); } hrp_len = input_len - (1 + *data_len); - if (1 + *data_len >= input_len || *data_len < 6 || hrp_len > BECH32_MAX_HRP_LEN) { + if(1 + *data_len >= input_len || *data_len < 6 || hrp_len > BECH32_MAX_HRP_LEN) { return BECH32_ENCODING_NONE; } *(data_len) -= 6; - for (i = 0; i < hrp_len; ++i) { + for(i = 0; i < hrp_len; ++i) { int ch = input[i]; - if (ch < 33 || ch > 126) { + if(ch < 33 || ch > 126) { return BECH32_ENCODING_NONE; } - if (ch >= 'a' && ch <= 'z') { + if(ch >= 'a' && ch <= 'z') { have_lower = 1; - } else if (ch >= 'A' && ch <= 'Z') { + } else if(ch >= 'A' && ch <= 'Z') { have_upper = 1; ch = (ch - 'A') + 'a'; } @@ -123,87 +122,104 @@ bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const } hrp[i] = 0; chk = bech32_polymod_step(chk); - for (i = 0; i < hrp_len; ++i) { + for(i = 0; i < hrp_len; ++i) { chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); } ++i; - while (i < input_len) { + while(i < input_len) { int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; - if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; - if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; - if (v == -1) { + if(input[i] >= 'a' && input[i] <= 'z') have_lower = 1; + if(input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; + if(v == -1) { return BECH32_ENCODING_NONE; } chk = bech32_polymod_step(chk) ^ v; - if (i + 6 < input_len) { + if(i + 6 < input_len) { data[i - (1 + hrp_len)] = v; } ++i; } - if (have_lower && have_upper) { + if(have_lower && have_upper) { return BECH32_ENCODING_NONE; } - if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) { + if(chk == bech32_final_constant(BECH32_ENCODING_BECH32)) { return BECH32_ENCODING_BECH32; - } else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) { + } else if(chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) { return BECH32_ENCODING_BECH32M; } else { return BECH32_ENCODING_NONE; } } -static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) { +static int convert_bits( + uint8_t* out, + size_t* outlen, + int outbits, + const uint8_t* in, + size_t inlen, + int inbits, + int pad) { uint32_t val = 0; int bits = 0; uint32_t maxv = (((uint32_t)1) << outbits) - 1; - while (inlen--) { + while(inlen--) { val = (val << inbits) | *(in++); bits += inbits; - while (bits >= outbits) { + while(bits >= outbits) { bits -= outbits; out[(*outlen)++] = (val >> bits) & maxv; } } - if (pad) { - if (bits) { + if(pad) { + if(bits) { out[(*outlen)++] = (val << (outbits - bits)) & maxv; } - } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { + } else if(((val << (outbits - bits)) & maxv) || bits >= inbits) { return 0; } return 1; } -int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { +int segwit_addr_encode( + char* output, + const char* hrp, + int witver, + const uint8_t* witprog, + size_t witprog_len) { uint8_t data[65] = {0}; size_t datalen = 0; bech32_encoding enc = BECH32_ENCODING_BECH32; - if (witver > 16) return 0; - if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; - if (witprog_len < 2 || witprog_len > 40) return 0; - if (witver > 0) enc = BECH32_ENCODING_BECH32M; + if(witver > 16) return 0; + if(witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; + if(witprog_len < 2 || witprog_len > 40) return 0; + if(witver > 0) enc = BECH32_ENCODING_BECH32M; data[0] = witver; convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); ++datalen; return bech32_encode(output, hrp, data, datalen, enc); } -int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { +int segwit_addr_decode( + int* witver, + uint8_t* witdata, + size_t* witdata_len, + const char* hrp, + const char* addr) { uint8_t data[84] = {0}; char hrp_actual[84] = {0}; size_t data_len = 0; - if (strlen(addr) > 90) return 0; + if(strlen(addr) > 90) return 0; bech32_encoding enc = bech32_decode(hrp_actual, data, &data_len, addr); - if (enc == BECH32_ENCODING_NONE) return 0; - if (data_len == 0 || data_len > 65) return 0; - if (strncmp(hrp, hrp_actual, 84) != 0) return 0; - if (data[0] > 16) return 0; - if (data[0] == 0 && enc != BECH32_ENCODING_BECH32) return 0; - if (data[0] > 0 && enc != BECH32_ENCODING_BECH32M) return 0; + if(enc == BECH32_ENCODING_NONE) return 0; + if(data_len == 0 || data_len > 65) return 0; + if(strncmp(hrp, hrp_actual, 84) != 0) return 0; + if(data[0] > 16) return 0; + if(data[0] == 0 && enc != BECH32_ENCODING_BECH32) return 0; + if(data[0] > 0 && enc != BECH32_ENCODING_BECH32M) return 0; *witdata_len = 0; - if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; - if (*witdata_len < 2 || *witdata_len > 40) return 0; - if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; + if(!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; + if(*witdata_len < 2 || *witdata_len > 40) return 0; + if(data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; *witver = data[0]; return 1; } diff --git a/crypto/segwit_addr.h b/crypto/segwit_addr.h index 844874ccfd9..2251e5c473f 100644 --- a/crypto/segwit_addr.h +++ b/crypto/segwit_addr.h @@ -27,7 +27,6 @@ // The maximum length of the Bech32 human-readable part according to BIP-173. #define BECH32_MAX_HRP_LEN 83 - /** Encode a SegWit address * * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be @@ -39,13 +38,7 @@ * prog_len: Number of data bytes in prog. * Returns 1 if successful. */ -int segwit_addr_encode( - char *output, - const char *hrp, - int ver, - const uint8_t *prog, - size_t prog_len -); +int segwit_addr_encode(char* output, const char* hrp, int ver, const uint8_t* prog, size_t prog_len); /** Decode a SegWit address * @@ -60,13 +53,7 @@ int segwit_addr_encode( * addr: Pointer to the null-terminated address. * Returns 1 if successful. */ -int segwit_addr_decode( - int* ver, - uint8_t* prog, - size_t* prog_len, - const char* hrp, - const char* addr -); +int segwit_addr_decode(int* ver, uint8_t* prog, size_t* prog_len, const char* hrp, const char* addr); /** Supported encodings. */ typedef enum { @@ -86,12 +73,11 @@ typedef enum { * Returns 1 if successful. */ int bech32_encode( - char *output, - const char *hrp, - const uint8_t *data, + char* output, + const char* hrp, + const uint8_t* data, size_t data_len, - bech32_encoding enc -); + bech32_encoding enc); /** Decode a Bech32 or Bech32m string * @@ -106,11 +92,6 @@ int bech32_encode( * with the specified encoding standard. BECH32_ENCODING_NONE is returned if * decoding failed. */ -bech32_encoding bech32_decode( - char *hrp, - uint8_t *data, - size_t *data_len, - const char *input -); +bech32_encoding bech32_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input); #endif diff --git a/crypto/sha2.c b/crypto/sha2.c index 42c7efb10ab..85e589c4d60 100644 --- a/crypto/sha2.c +++ b/crypto/sha2.c @@ -54,7 +54,6 @@ * */ - /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: @@ -88,29 +87,30 @@ #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN #endif -typedef uint8_t sha2_byte; /* Exactly 1 byte */ -typedef uint32_t sha2_word32; /* Exactly 4 bytes */ -typedef uint64_t sha2_word64; /* Exactly 8 bytes */ +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ -#define SHA1_SHORT_BLOCK_LENGTH (SHA1_BLOCK_LENGTH - 8) -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) +#define SHA1_SHORT_BLOCK_LENGTH (SHA1_BLOCK_LENGTH - 8) +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ -#define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ -} +#define ADDINC128(w, n) \ + { \ + (w)[0] += (sha2_word64)(n); \ + if((w)[0] < (n)) { \ + (w)[1]++; \ + } \ + } -#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#define MEMCPY_BCOPY(d, s, l) memcpy((d), (s), (l)) /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* @@ -133,32 +133,32 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define SHR(b,x) ((x) >> (b)) +#define SHR(b, x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ -#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +#define ROTR32(b, x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +#define ROTR64(b, x) (((x) >> (b)) | ((x) << (64 - (b)))) /* 32-bit Rotate-left (used in SHA-1): */ -#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) +#define ROTL32(b, x) (((x) << (b)) | ((x) >> (32 - (b)))) /* Two of six logical functions used in SHA-1, SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Function used in SHA-1: */ -#define Parity(x,y,z) ((x) ^ (y) ^ (z)) +#define Parity(x, y, z) ((x) ^ (y) ^ (z)) /* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) -#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) -#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR(3 , (x))) -#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR(10, (x))) +#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) +#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) +#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR(3, (x))) +#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) -#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) -#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) -#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) +#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) +#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) +#define sigma0_512(x) (ROTR64(1, (x)) ^ ROTR64(8, (x)) ^ SHR(7, (x))) +#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR(6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this @@ -167,1127 +167,1086 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ */ static void sha512_Last(SHA512_CTX*); - /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-1: */ -#define K1_0_TO_19 0x5a827999UL -#define K1_20_TO_39 0x6ed9eba1UL -#define K1_40_TO_59 0x8f1bbcdcUL -#define K1_60_TO_79 0xca62c1d6UL +#define K1_0_TO_19 0x5a827999UL +#define K1_20_TO_39 0x6ed9eba1UL +#define K1_40_TO_59 0x8f1bbcdcUL +#define K1_60_TO_79 0xca62c1d6UL /* Initial hash value H for SHA-1: */ -const sha2_word32 sha1_initial_hash_value[SHA1_DIGEST_LENGTH / sizeof(sha2_word32)] = { - 0x67452301UL, - 0xefcdab89UL, - 0x98badcfeUL, - 0x10325476UL, - 0xc3d2e1f0UL -}; +const sha2_word32 sha1_initial_hash_value[SHA1_DIGEST_LENGTH / sizeof(sha2_word32)] = + {0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL}; /* Hash constant words K for SHA-256: */ static const sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, + 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, + 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, + 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, + 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; /* Initial hash value H for SHA-256: */ const sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL -}; + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL}; /* Hash constant words K for SHA-384 and SHA-512: */ static const sha2_word64 K512[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, - 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, - 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, - 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, - 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, - 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, - 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, - 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, - 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, - 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, - 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, - 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, - 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, - 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL}; /* Initial hash value H for SHA-512 */ const sha2_word64 sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL -}; + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL}; /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ -static const char *sha2_hex_digits = "0123456789abcdef"; - +static const char* sha2_hex_digits = "0123456789abcdef"; /*** SHA-1: ***********************************************************/ void sha1_Init(SHA1_CTX* context) { - MEMCPY_BCOPY(context->state, sha1_initial_hash_value, SHA1_DIGEST_LENGTH); - memzero(context->buffer, SHA1_BLOCK_LENGTH); - context->bitcount = 0; + MEMCPY_BCOPY(context->state, sha1_initial_hash_value, SHA1_DIGEST_LENGTH); + memzero(context->buffer, SHA1_BLOCK_LENGTH); + context->bitcount = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-1 round macros: */ -#define ROUND1_0_TO_15(a,b,c,d,e) \ - (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ - K1_0_TO_19 + ( W1[j] = *data++ ); \ - (b) = ROTL32(30, (b)); \ - j++; - -#define ROUND1_16_TO_19(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_20_TO_39(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_40_TO_59(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_60_TO_79(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; +#define ROUND1_0_TO_15(a, b, c, d, e) \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + K1_0_TO_19 + (W1[j] = *data++); \ + (b) = ROTL32(30, (b)); \ + j++; + +#define ROUND1_16_TO_19(a, b, c, d, e) \ + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; \ + (e) = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j & 0x0f] = ROTL32(1, T1)); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_20_TO_39(a, b, c, d, e) \ + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; \ + (e) = ROTL32(5, a) + Parity(b, c, d) + e + K1_20_TO_39 + (W1[j & 0x0f] = ROTL32(1, T1)); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_40_TO_59(a, b, c, d, e) \ + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; \ + (e) = ROTL32(5, a) + Maj(b, c, d) + e + K1_40_TO_59 + (W1[j & 0x0f] = ROTL32(1, T1)); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_60_TO_79(a, b, c, d, e) \ + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; \ + (e) = ROTL32(5, a) + Parity(b, c, d) + e + K1_60_TO_79 + (W1[j & 0x0f] = ROTL32(1, T1)); \ + (b) = ROTL32(30, b); \ + j++; void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; - sha2_word32 T1 = 0; - sha2_word32 W1[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - - j = 0; - - /* Rounds 0 to 15 unrolled: */ - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - - /* Rounds 16 to 19 unrolled: */ - ROUND1_16_TO_19(e,a,b,c,d); - ROUND1_16_TO_19(d,e,a,b,c); - ROUND1_16_TO_19(c,d,e,a,b); - ROUND1_16_TO_19(b,c,d,e,a); - - /* Rounds 20 to 39 unrolled: */ - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - - /* Rounds 40 to 59 unrolled: */ - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - - /* Rounds 60 to 79 unrolled: */ - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - - /* Clean up */ - a = b = c = d = e = T1 = 0; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; + sha2_word32 T1 = 0; + sha2_word32 W1[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + + j = 0; + + /* Rounds 0 to 15 unrolled: */ + ROUND1_0_TO_15(a, b, c, d, e); + ROUND1_0_TO_15(e, a, b, c, d); + ROUND1_0_TO_15(d, e, a, b, c); + ROUND1_0_TO_15(c, d, e, a, b); + ROUND1_0_TO_15(b, c, d, e, a); + ROUND1_0_TO_15(a, b, c, d, e); + ROUND1_0_TO_15(e, a, b, c, d); + ROUND1_0_TO_15(d, e, a, b, c); + ROUND1_0_TO_15(c, d, e, a, b); + ROUND1_0_TO_15(b, c, d, e, a); + ROUND1_0_TO_15(a, b, c, d, e); + ROUND1_0_TO_15(e, a, b, c, d); + ROUND1_0_TO_15(d, e, a, b, c); + ROUND1_0_TO_15(c, d, e, a, b); + ROUND1_0_TO_15(b, c, d, e, a); + ROUND1_0_TO_15(a, b, c, d, e); + + /* Rounds 16 to 19 unrolled: */ + ROUND1_16_TO_19(e, a, b, c, d); + ROUND1_16_TO_19(d, e, a, b, c); + ROUND1_16_TO_19(c, d, e, a, b); + ROUND1_16_TO_19(b, c, d, e, a); + + /* Rounds 20 to 39 unrolled: */ + ROUND1_20_TO_39(a, b, c, d, e); + ROUND1_20_TO_39(e, a, b, c, d); + ROUND1_20_TO_39(d, e, a, b, c); + ROUND1_20_TO_39(c, d, e, a, b); + ROUND1_20_TO_39(b, c, d, e, a); + ROUND1_20_TO_39(a, b, c, d, e); + ROUND1_20_TO_39(e, a, b, c, d); + ROUND1_20_TO_39(d, e, a, b, c); + ROUND1_20_TO_39(c, d, e, a, b); + ROUND1_20_TO_39(b, c, d, e, a); + ROUND1_20_TO_39(a, b, c, d, e); + ROUND1_20_TO_39(e, a, b, c, d); + ROUND1_20_TO_39(d, e, a, b, c); + ROUND1_20_TO_39(c, d, e, a, b); + ROUND1_20_TO_39(b, c, d, e, a); + ROUND1_20_TO_39(a, b, c, d, e); + ROUND1_20_TO_39(e, a, b, c, d); + ROUND1_20_TO_39(d, e, a, b, c); + ROUND1_20_TO_39(c, d, e, a, b); + ROUND1_20_TO_39(b, c, d, e, a); + + /* Rounds 40 to 59 unrolled: */ + ROUND1_40_TO_59(a, b, c, d, e); + ROUND1_40_TO_59(e, a, b, c, d); + ROUND1_40_TO_59(d, e, a, b, c); + ROUND1_40_TO_59(c, d, e, a, b); + ROUND1_40_TO_59(b, c, d, e, a); + ROUND1_40_TO_59(a, b, c, d, e); + ROUND1_40_TO_59(e, a, b, c, d); + ROUND1_40_TO_59(d, e, a, b, c); + ROUND1_40_TO_59(c, d, e, a, b); + ROUND1_40_TO_59(b, c, d, e, a); + ROUND1_40_TO_59(a, b, c, d, e); + ROUND1_40_TO_59(e, a, b, c, d); + ROUND1_40_TO_59(d, e, a, b, c); + ROUND1_40_TO_59(c, d, e, a, b); + ROUND1_40_TO_59(b, c, d, e, a); + ROUND1_40_TO_59(a, b, c, d, e); + ROUND1_40_TO_59(e, a, b, c, d); + ROUND1_40_TO_59(d, e, a, b, c); + ROUND1_40_TO_59(c, d, e, a, b); + ROUND1_40_TO_59(b, c, d, e, a); + + /* Rounds 60 to 79 unrolled: */ + ROUND1_60_TO_79(a, b, c, d, e); + ROUND1_60_TO_79(e, a, b, c, d); + ROUND1_60_TO_79(d, e, a, b, c); + ROUND1_60_TO_79(c, d, e, a, b); + ROUND1_60_TO_79(b, c, d, e, a); + ROUND1_60_TO_79(a, b, c, d, e); + ROUND1_60_TO_79(e, a, b, c, d); + ROUND1_60_TO_79(d, e, a, b, c); + ROUND1_60_TO_79(c, d, e, a, b); + ROUND1_60_TO_79(b, c, d, e, a); + ROUND1_60_TO_79(a, b, c, d, e); + ROUND1_60_TO_79(e, a, b, c, d); + ROUND1_60_TO_79(d, e, a, b, c); + ROUND1_60_TO_79(c, d, e, a, b); + ROUND1_60_TO_79(b, c, d, e, a); + ROUND1_60_TO_79(a, b, c, d, e); + ROUND1_60_TO_79(e, a, b, c, d); + ROUND1_60_TO_79(d, e, a, b, c); + ROUND1_60_TO_79(c, d, e, a, b); + ROUND1_60_TO_79(b, c, d, e, a); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; } -#else /* SHA2_UNROLL_TRANSFORM */ +#else /* SHA2_UNROLL_TRANSFORM */ void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; - sha2_word32 T1 = 0; - sha2_word32 W1[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - j = 0; - do { - T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 16); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 20); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 40); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 60); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 80); - - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - - /* Clean up */ - a = b = c = d = e = T1 = 0; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; + sha2_word32 T1 = 0; + sha2_word32 W1[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + j = 0; + do { + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while(j < 16); + + do { + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j & 0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while(j < 20); + + do { + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; + T1 = ROTL32(5, a) + Parity(b, c, d) + e + K1_20_TO_39 + (W1[j & 0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while(j < 40); + + do { + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; + T1 = ROTL32(5, a) + Maj(b, c, d) + e + K1_40_TO_59 + (W1[j & 0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while(j < 60); + + do { + T1 = W1[(j + 13) & 0x0f] ^ W1[(j + 8) & 0x0f] ^ W1[(j + 2) & 0x0f] ^ W1[j & 0x0f]; + T1 = ROTL32(5, a) + Parity(b, c, d) + e + K1_60_TO_79 + (W1[j & 0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while(j < 80); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ -void sha1_Update(SHA1_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA1_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; +void sha1_Update(SHA1_CTX* context, const sha2_byte* data, size_t len) { + unsigned int freespace = 0, usedspace = 0; + + if(len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; + if(usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA1_BLOCK_LENGTH - usedspace; + + if(len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - sha1_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA1_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA1_BLOCK_LENGTH); + sha1_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while(len >= SHA1_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA1_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - sha1_Transform(context->state, context->buffer, context->state); - context->bitcount += SHA1_BLOCK_LENGTH << 3; - len -= SHA1_BLOCK_LENGTH; - data += SHA1_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; + sha1_Transform(context->state, context->buffer, context->state); + context->bitcount += SHA1_BLOCK_LENGTH << 3; + len -= SHA1_BLOCK_LENGTH; + data += SHA1_BLOCK_LENGTH; + } + if(len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; } void sha1_Final(SHA1_CTX* context, sha2_byte digest[SHA1_DIGEST_LENGTH]) { - unsigned int usedspace = 0; + unsigned int usedspace = 0; - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; + /* If no digest buffer is passed, we don't bother doing this: */ + if(digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; - if (usedspace > SHA1_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA1_BLOCK_LENGTH - usedspace); + if(usedspace > SHA1_SHORT_BLOCK_LENGTH) { + memzero(((uint8_t*)context->buffer) + usedspace, SHA1_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - /* Do second-to-last transform: */ - sha1_Transform(context->state, context->buffer, context->state); + /* Do second-to-last transform: */ + sha1_Transform(context->state, context->buffer, context->state); - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA1_SHORT_BLOCK_LENGTH - usedspace); + /* And prepare the last transform: */ + usedspace = 0; + } + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, SHA1_SHORT_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 14; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - /* Set the bit count: */ - context->buffer[14] = context->bitcount >> 32; - context->buffer[15] = context->bitcount & 0xffffffff; + /* Set the bit count: */ + context->buffer[14] = context->bitcount >> 32; + context->buffer[15] = context->bitcount & 0xffffffff; - /* Final transform: */ - sha1_Transform(context->state, context->buffer, context->state); + /* Final transform: */ + sha1_Transform(context->state, context->buffer, context->state); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 5; j++) { - REVERSE32(context->state[j],context->state[j]); - } + /* Convert FROM host byte order */ + for(int j = 0; j < 5; j++) { + REVERSE32(context->state[j], context->state[j]); + } #endif - MEMCPY_BCOPY(digest, context->state, SHA1_DIGEST_LENGTH); - } + MEMCPY_BCOPY(digest, context->state, SHA1_DIGEST_LENGTH); + } - /* Clean up state data: */ - memzero(context, sizeof(SHA1_CTX)); - usedspace = 0; + /* Clean up state data: */ + memzero(context, sizeof(SHA1_CTX)); + usedspace = 0; } -char *sha1_End(SHA1_CTX* context, char buffer[SHA1_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA1_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha1_Final(context, digest); - - for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA1_CTX)); - } - memzero(digest, SHA1_DIGEST_LENGTH); - return buffer; +char* sha1_End(SHA1_CTX* context, char buffer[SHA1_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA1_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; + + if(buffer != (char*)0) { + sha1_Final(context, digest); + + for(i = 0; i < SHA1_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA1_CTX)); + } + memzero(digest, SHA1_DIGEST_LENGTH); + return buffer; } void sha1_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA1_DIGEST_LENGTH]) { - SHA1_CTX context = {0}; - sha1_Init(&context); - sha1_Update(&context, data, len); - sha1_Final(&context, digest); + SHA1_CTX context = {0}; + sha1_Init(&context); + sha1_Update(&context, data, len); + sha1_Final(&context, digest); } char* sha1_Data(const sha2_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { - SHA1_CTX context = {0}; + SHA1_CTX context = {0}; - sha1_Init(&context); - sha1_Update(&context, data, len); - return sha1_End(&context, digest); + sha1_Init(&context); + sha1_Update(&context, data, len); + return sha1_End(&context, digest); } /*** SHA-256: *********************************************************/ void sha256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - memzero(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; + if(context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + memzero(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; } -void sha256_Init_ex(SHA256_CTX *context, const uint32_t state[8], uint64_t bitcount) { - if (context == (SHA256_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, state, SHA256_DIGEST_LENGTH); - memzero(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = bitcount; +void sha256_Init_ex(SHA256_CTX* context, const uint32_t state[8], uint64_t bitcount) { + if(context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, state, SHA256_DIGEST_LENGTH); + memzero(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = bitcount; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ +#define ROUND256_0_TO_15(a, b, c, d, e, f, g, h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#define ROUND256(a, b, c, d, e, f, g, h) \ + s0 = W256[(j + 1) & 0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j + 14) & 0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word32 T1 = 0; - sha2_word32 W256[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word32 T1 = 0; + sha2_word32 W256[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a, b, c, d, e, f, g, h); + ROUND256_0_TO_15(h, a, b, c, d, e, f, g); + ROUND256_0_TO_15(g, h, a, b, c, d, e, f); + ROUND256_0_TO_15(f, g, h, a, b, c, d, e); + ROUND256_0_TO_15(e, f, g, h, a, b, c, d); + ROUND256_0_TO_15(d, e, f, g, h, a, b, c); + ROUND256_0_TO_15(c, d, e, f, g, h, a, b); + ROUND256_0_TO_15(b, c, d, e, f, g, h, a); + } while(j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a, b, c, d, e, f, g, h); + ROUND256(h, a, b, c, d, e, f, g); + ROUND256(g, h, a, b, c, d, e, f); + ROUND256(f, g, h, a, b, c, d, e); + ROUND256(e, f, g, h, a, b, c, d); + ROUND256(d, e, f, g, h, a, b, c); + ROUND256(c, d, e, f, g, h, a, b); + ROUND256(b, c, d, e, f, g, h, a); + } while(j < 64); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word32 T1 = 0, T2 = 0 , W256[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word32 T1 = 0, T2 = 0, W256[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while(j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j + 1) & 0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j + 14) & 0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while(j < 64); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ -void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; +void sha256_Update(SHA256_CTX* context, const sha2_byte* data, size_t len) { + unsigned int freespace = 0, usedspace = 0; + + if(len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if(usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if(len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - sha256_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); + sha256_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while(len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - sha256_Transform(context->state, context->buffer, context->state); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; + sha256_Transform(context->state, context->buffer, context->state); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if(len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; } void sha256_Final(SHA256_CTX* context, sha2_byte digest[SHA256_DIGEST_LENGTH]) { - unsigned int usedspace = 0; + unsigned int usedspace = 0; - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; + /* If no digest buffer is passed, we don't bother doing this: */ + if(digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; - if (usedspace > SHA256_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA256_BLOCK_LENGTH - usedspace); + if(usedspace > SHA256_SHORT_BLOCK_LENGTH) { + memzero(((uint8_t*)context->buffer) + usedspace, SHA256_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - /* Do second-to-last transform: */ - sha256_Transform(context->state, context->buffer, context->state); + /* Do second-to-last transform: */ + sha256_Transform(context->state, context->buffer, context->state); - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA256_SHORT_BLOCK_LENGTH - usedspace); + /* And prepare the last transform: */ + usedspace = 0; + } + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, SHA256_SHORT_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 14; j++) { + REVERSE32(context->buffer[j], context->buffer[j]); + } #endif - /* Set the bit count: */ - context->buffer[14] = context->bitcount >> 32; - context->buffer[15] = context->bitcount & 0xffffffff; + /* Set the bit count: */ + context->buffer[14] = context->bitcount >> 32; + context->buffer[15] = context->bitcount & 0xffffffff; - /* Final transform: */ - sha256_Transform(context->state, context->buffer, context->state); + /* Final transform: */ + sha256_Transform(context->state, context->buffer, context->state); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - } + /* Convert FROM host byte order */ + for(int j = 0; j < 8; j++) { + REVERSE32(context->state[j], context->state[j]); + } #endif - MEMCPY_BCOPY(digest, context->state, SHA256_DIGEST_LENGTH); - } + MEMCPY_BCOPY(digest, context->state, SHA256_DIGEST_LENGTH); + } - /* Clean up state data: */ - memzero(context, sizeof(SHA256_CTX)); - usedspace = 0; + /* Clean up state data: */ + memzero(context, sizeof(SHA256_CTX)); + usedspace = 0; } -char *sha256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA256_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha256_Final(context, digest); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA256_CTX)); - } - memzero(digest, SHA256_DIGEST_LENGTH); - return buffer; +char* sha256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA256_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; + + if(buffer != (char*)0) { + sha256_Final(context, digest); + + for(i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA256_CTX)); + } + memzero(digest, SHA256_DIGEST_LENGTH); + return buffer; } void sha256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) { - SHA256_CTX context = {0}; - sha256_Init(&context); - sha256_Update(&context, data, len); - sha256_Final(&context, digest); + SHA256_CTX context = {0}; + sha256_Init(&context); + sha256_Update(&context, data, len); + sha256_Final(&context, digest); } char* sha256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context = {0}; + SHA256_CTX context = {0}; - sha256_Init(&context); - sha256_Update(&context, data, len); - return sha256_End(&context, digest); + sha256_Init(&context); + sha256_Update(&context, data, len); + return sha256_End(&context, digest); } - /*** SHA-512: *********************************************************/ void sha512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - memzero(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; + if(context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + memzero(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -#define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ +#define ROUND512_0_TO_15(a, b, c, d, e, f, g, h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#define ROUND512(a, b, c, d, e, f, g, h) \ + s0 = W512[(j + 1) & 0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j + 14) & 0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word64 T1 = 0, W512[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; + sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word64 T1 = 0, W512[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + ROUND512_0_TO_15(a, b, c, d, e, f, g, h); + ROUND512_0_TO_15(h, a, b, c, d, e, f, g); + ROUND512_0_TO_15(g, h, a, b, c, d, e, f); + ROUND512_0_TO_15(f, g, h, a, b, c, d, e); + ROUND512_0_TO_15(e, f, g, h, a, b, c, d); + ROUND512_0_TO_15(d, e, f, g, h, a, b, c); + ROUND512_0_TO_15(c, d, e, f, g, h, a, b); + ROUND512_0_TO_15(b, c, d, e, f, g, h, a); + } while(j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a, b, c, d, e, f, g, h); + ROUND512(h, a, b, c, d, e, f, g); + ROUND512(g, h, a, b, c, d, e, f); + ROUND512(f, g, h, a, b, c, d, e); + ROUND512(e, f, g, h, a, b, c, d); + ROUND512(d, e, f, g, h, a, b, c); + ROUND512(c, d, e, f, g, h, a, b); + ROUND512(b, c, d, e, f, g, h, a); + } while(j < 80); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word64 T1 = 0, T2 = 0, W512[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; + sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; + sha2_word64 T1 = 0, T2 = 0, W512[16] = {0}; + int j = 0; + + /* Initialize registers with the prev. intermediate value */ + a = state_in[0]; + b = state_in[1]; + c = state_in[2]; + d = state_in[3]; + e = state_in[4]; + f = state_in[5]; + g = state_in[6]; + h = state_in[7]; + + j = 0; + do { + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while(j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j + 1) & 0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j + 14) & 0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while(j < 80); + + /* Compute the current intermediate hash value */ + state_out[0] = state_in[0] + a; + state_out[1] = state_in[1] + b; + state_out[2] = state_in[2] + c; + state_out[3] = state_in[3] + d; + state_out[4] = state_in[4] + e; + state_out[5] = state_in[5] + f; + state_out[6] = state_in[6] + g; + state_out[7] = state_in[7] + h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ -void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; +void sha512_Update(SHA512_CTX* context, const sha2_byte* data, size_t len) { + unsigned int freespace = 0, usedspace = 0; + + if(len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if(usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if(len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j], context->buffer[j]); + } #endif - sha512_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); + sha512_Transform(context->state, context->buffer, context->state); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while(len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j], context->buffer[j]); + } #endif - sha512_Transform(context->state, context->buffer, context->state); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; + sha512_Transform(context->state, context->buffer, context->state); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if(len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; } static void sha512_Last(SHA512_CTX* context) { - unsigned int usedspace = 0; + unsigned int usedspace = 0; - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + /* Begin padding with a 1 bit: */ + ((uint8_t*)context->buffer)[usedspace++] = 0x80; - if (usedspace > SHA512_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA512_BLOCK_LENGTH - usedspace); + if(usedspace > SHA512_SHORT_BLOCK_LENGTH) { + memzero(((uint8_t*)context->buffer) + usedspace, SHA512_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 16; j++) { + REVERSE64(context->buffer[j], context->buffer[j]); + } #endif - /* Do second-to-last transform: */ - sha512_Transform(context->state, context->buffer, context->state); + /* Do second-to-last transform: */ + sha512_Transform(context->state, context->buffer, context->state); - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA512_SHORT_BLOCK_LENGTH - usedspace); + /* And prepare the last transform: */ + usedspace = 0; + } + /* Set-up for the last transform: */ + memzero(((uint8_t*)context->buffer) + usedspace, SHA512_SHORT_BLOCK_LENGTH - usedspace); #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } + /* Convert TO host byte order */ + for(int j = 0; j < 14; j++) { + REVERSE64(context->buffer[j], context->buffer[j]); + } #endif - /* Store the length of input data (in bits): */ - context->buffer[14] = context->bitcount[1]; - context->buffer[15] = context->bitcount[0]; + /* Store the length of input data (in bits): */ + context->buffer[14] = context->bitcount[1]; + context->buffer[15] = context->bitcount[0]; - /* Final transform: */ - sha512_Transform(context->state, context->buffer, context->state); + /* Final transform: */ + sha512_Transform(context->state, context->buffer, context->state); } void sha512_Final(SHA512_CTX* context, sha2_byte digest[SHA512_DIGEST_LENGTH]) { - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - sha512_Last(context); + /* If no digest buffer is passed, we don't bother doing this: */ + if(digest != (sha2_byte*)0) { + sha512_Last(context); - /* Save the hash data for output: */ + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - } + /* Convert FROM host byte order */ + for(int j = 0; j < 8; j++) { + REVERSE64(context->state[j], context->state[j]); + } #endif - MEMCPY_BCOPY(digest, context->state, SHA512_DIGEST_LENGTH); - } + MEMCPY_BCOPY(digest, context->state, SHA512_DIGEST_LENGTH); + } - /* Zero out state data */ - memzero(context, sizeof(SHA512_CTX)); + /* Zero out state data */ + memzero(context, sizeof(SHA512_CTX)); } -char *sha512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA512_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha512_Final(context, digest); - - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA512_CTX)); - } - memzero(digest, SHA512_DIGEST_LENGTH); - return buffer; +char* sha512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { + sha2_byte digest[SHA512_DIGEST_LENGTH] = {0}, *d = digest; + int i = 0; + + if(buffer != (char*)0) { + sha512_Final(context, digest); + + for(i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + memzero(context, sizeof(SHA512_CTX)); + } + memzero(digest, SHA512_DIGEST_LENGTH); + return buffer; } void sha512_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA512_DIGEST_LENGTH]) { - SHA512_CTX context = {0}; - sha512_Init(&context); - sha512_Update(&context, data, len); - sha512_Final(&context, digest); + SHA512_CTX context = {0}; + sha512_Init(&context); + sha512_Update(&context, data, len); + sha512_Final(&context, digest); } char* sha512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context = {0}; + SHA512_CTX context = {0}; - sha512_Init(&context); - sha512_Update(&context, data, len); - return sha512_End(&context, digest); + sha512_Init(&context); + sha512_Update(&context, data, len); + return sha512_End(&context, digest); } diff --git a/crypto/sha2.h b/crypto/sha2.h index d310120f4d3..5f7c1f07179 100644 --- a/crypto/sha2.h +++ b/crypto/sha2.h @@ -35,37 +35,37 @@ #include #include "byte_order.h" -#define SHA1_BLOCK_LENGTH 64 -#define SHA1_DIGEST_LENGTH 20 -#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) typedef struct _SHA1_CTX { - uint32_t state[5]; - uint64_t bitcount; - uint32_t buffer[SHA1_BLOCK_LENGTH/sizeof(uint32_t)]; + uint32_t state[5]; + uint64_t bitcount; + uint32_t buffer[SHA1_BLOCK_LENGTH / sizeof(uint32_t)]; } SHA1_CTX; typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint32_t buffer[SHA256_BLOCK_LENGTH/sizeof(uint32_t)]; + uint32_t state[8]; + uint64_t bitcount; + uint32_t buffer[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; } SHA256_CTX; typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint64_t buffer[SHA512_BLOCK_LENGTH/sizeof(uint64_t)]; + uint64_t state[8]; + uint64_t bitcount[2]; + uint64_t buffer[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; } SHA512_CTX; extern const uint32_t sha256_initial_hash_value[8]; extern const uint64_t sha512_initial_hash_value[8]; void sha1_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); -void sha1_Init(SHA1_CTX *); +void sha1_Init(SHA1_CTX*); void sha1_Update(SHA1_CTX*, const uint8_t*, size_t); void sha1_Final(SHA1_CTX*, uint8_t[SHA1_DIGEST_LENGTH]); char* sha1_End(SHA1_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); @@ -73,8 +73,8 @@ void sha1_Raw(const uint8_t*, size_t, uint8_t[SHA1_DIGEST_LENGTH]); char* sha1_Data(const uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); void sha256_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); -void sha256_Init(SHA256_CTX *); -void sha256_Init_ex(SHA256_CTX *, const uint32_t state[8], uint64_t bitcount); +void sha256_Init(SHA256_CTX*); +void sha256_Init_ex(SHA256_CTX*, const uint32_t state[8], uint64_t bitcount); void sha256_Update(SHA256_CTX*, const uint8_t*, size_t); void sha256_Final(SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]); char* sha256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); diff --git a/crypto/sha3.c b/crypto/sha3.c index 8971300c0df..d3a43b6a3f3 100644 --- a/crypto/sha3.c +++ b/crypto/sha3.c @@ -27,31 +27,31 @@ #define I64(x) x##LL #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) #define le2me_64(x) (x) -#define IS_ALIGNED_64(p) (0 == (((uintptr_t)(const void *)(p) & 0x7))) -# define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) +#define IS_ALIGNED_64(p) (0 == (((uintptr_t)(const void*)(p)&0x7))) +#define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) /* constants */ #define NumberOfRounds 24 /* SHA3 (Keccak) constants for 24 rounds */ static uint64_t keccak_round_constants[NumberOfRounds] = { - I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000), - I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009), - I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A), - I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003), - I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A), - I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008) -}; + I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), + I64(0x8000000080008000), I64(0x000000000000808B), I64(0x0000000080000001), + I64(0x8000000080008081), I64(0x8000000000008009), I64(0x000000000000008A), + I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A), + I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), + I64(0x8000000000008003), I64(0x8000000000008002), I64(0x8000000000000080), + I64(0x000000000000800A), I64(0x800000008000000A), I64(0x8000000080008081), + I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)}; /* Initializing a sha3 context for given number of output bits */ -static void keccak_Init(SHA3_CTX *ctx, unsigned bits) -{ - /* NB: The Keccak capacity parameter = bits * 2 */ - unsigned rate = 1600 - bits * 2; - - memzero(ctx, sizeof(SHA3_CTX)); - ctx->block_size = rate / 8; - assert(rate <= 1600 && (rate % 64) == 0); +static void keccak_Init(SHA3_CTX* ctx, unsigned bits) { + /* NB: The Keccak capacity parameter = bits * 2 */ + unsigned rate = 1600 - bits * 2; + + memzero(ctx, sizeof(SHA3_CTX)); + ctx->block_size = rate / 8; + assert(rate <= 1600 && (rate % 64) == 0); } /** @@ -59,9 +59,8 @@ static void keccak_Init(SHA3_CTX *ctx, unsigned bits) * * @param ctx context to initialize */ -void sha3_224_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 224); +void sha3_224_Init(SHA3_CTX* ctx) { + keccak_Init(ctx, 224); } /** @@ -69,9 +68,8 @@ void sha3_224_Init(SHA3_CTX *ctx) * * @param ctx context to initialize */ -void sha3_256_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 256); +void sha3_256_Init(SHA3_CTX* ctx) { + keccak_Init(ctx, 256); } /** @@ -79,9 +77,8 @@ void sha3_256_Init(SHA3_CTX *ctx) * * @param ctx context to initialize */ -void sha3_384_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 384); +void sha3_384_Init(SHA3_CTX* ctx) { + keccak_Init(ctx, 384); } /** @@ -89,132 +86,124 @@ void sha3_384_Init(SHA3_CTX *ctx) * * @param ctx context to initialize */ -void sha3_512_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 512); +void sha3_512_Init(SHA3_CTX* ctx) { + keccak_Init(ctx, 512); } /* Keccak theta() transformation */ -static void keccak_theta(uint64_t *A) -{ - unsigned int x = 0; - uint64_t C[5] = {0}, D[5] = {0}; - - for (x = 0; x < 5; x++) { - C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; - } - D[0] = ROTL64(C[1], 1) ^ C[4]; - D[1] = ROTL64(C[2], 1) ^ C[0]; - D[2] = ROTL64(C[3], 1) ^ C[1]; - D[3] = ROTL64(C[4], 1) ^ C[2]; - D[4] = ROTL64(C[0], 1) ^ C[3]; - - for (x = 0; x < 5; x++) { - A[x] ^= D[x]; - A[x + 5] ^= D[x]; - A[x + 10] ^= D[x]; - A[x + 15] ^= D[x]; - A[x + 20] ^= D[x]; - } +static void keccak_theta(uint64_t* A) { + unsigned int x = 0; + uint64_t C[5] = {0}, D[5] = {0}; + + for(x = 0; x < 5; x++) { + C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; + } + D[0] = ROTL64(C[1], 1) ^ C[4]; + D[1] = ROTL64(C[2], 1) ^ C[0]; + D[2] = ROTL64(C[3], 1) ^ C[1]; + D[3] = ROTL64(C[4], 1) ^ C[2]; + D[4] = ROTL64(C[0], 1) ^ C[3]; + + for(x = 0; x < 5; x++) { + A[x] ^= D[x]; + A[x + 5] ^= D[x]; + A[x + 10] ^= D[x]; + A[x + 15] ^= D[x]; + A[x + 20] ^= D[x]; + } } /* Keccak pi() transformation */ -static void keccak_pi(uint64_t *A) -{ - uint64_t A1 = 0; - A1 = A[1]; - A[ 1] = A[ 6]; - A[ 6] = A[ 9]; - A[ 9] = A[22]; - A[22] = A[14]; - A[14] = A[20]; - A[20] = A[ 2]; - A[ 2] = A[12]; - A[12] = A[13]; - A[13] = A[19]; - A[19] = A[23]; - A[23] = A[15]; - A[15] = A[ 4]; - A[ 4] = A[24]; - A[24] = A[21]; - A[21] = A[ 8]; - A[ 8] = A[16]; - A[16] = A[ 5]; - A[ 5] = A[ 3]; - A[ 3] = A[18]; - A[18] = A[17]; - A[17] = A[11]; - A[11] = A[ 7]; - A[ 7] = A[10]; - A[10] = A1; - /* note: A[ 0] is left as is */ +static void keccak_pi(uint64_t* A) { + uint64_t A1 = 0; + A1 = A[1]; + A[1] = A[6]; + A[6] = A[9]; + A[9] = A[22]; + A[22] = A[14]; + A[14] = A[20]; + A[20] = A[2]; + A[2] = A[12]; + A[12] = A[13]; + A[13] = A[19]; + A[19] = A[23]; + A[23] = A[15]; + A[15] = A[4]; + A[4] = A[24]; + A[24] = A[21]; + A[21] = A[8]; + A[8] = A[16]; + A[16] = A[5]; + A[5] = A[3]; + A[3] = A[18]; + A[18] = A[17]; + A[17] = A[11]; + A[11] = A[7]; + A[7] = A[10]; + A[10] = A1; + /* note: A[ 0] is left as is */ } /* Keccak chi() transformation */ -static void keccak_chi(uint64_t *A) -{ - int i = 0; - for (i = 0; i < 25; i += 5) { - uint64_t A0 = A[0 + i], A1 = A[1 + i]; - A[0 + i] ^= ~A1 & A[2 + i]; - A[1 + i] ^= ~A[2 + i] & A[3 + i]; - A[2 + i] ^= ~A[3 + i] & A[4 + i]; - A[3 + i] ^= ~A[4 + i] & A0; - A[4 + i] ^= ~A0 & A1; - } +static void keccak_chi(uint64_t* A) { + int i = 0; + for(i = 0; i < 25; i += 5) { + uint64_t A0 = A[0 + i], A1 = A[1 + i]; + A[0 + i] ^= ~A1 & A[2 + i]; + A[1 + i] ^= ~A[2 + i] & A[3 + i]; + A[2 + i] ^= ~A[3 + i] & A[4 + i]; + A[3 + i] ^= ~A[4 + i] & A0; + A[4 + i] ^= ~A0 & A1; + } } -static void sha3_permutation(uint64_t *state) -{ +static void sha3_permutation(uint64_t* state) { #if BYTE_ORDER == BIG_ENDIAN - int i; - for (i = 0; i < 25; i++) - { - REVERSE64(state[i], state[i]); - } + int i; + for(i = 0; i < 25; i++) { + REVERSE64(state[i], state[i]); + } #endif - int round = 0; - for (round = 0; round < NumberOfRounds; round++) - { - keccak_theta(state); - - /* apply Keccak rho() transformation */ - state[ 1] = ROTL64(state[ 1], 1); - state[ 2] = ROTL64(state[ 2], 62); - state[ 3] = ROTL64(state[ 3], 28); - state[ 4] = ROTL64(state[ 4], 27); - state[ 5] = ROTL64(state[ 5], 36); - state[ 6] = ROTL64(state[ 6], 44); - state[ 7] = ROTL64(state[ 7], 6); - state[ 8] = ROTL64(state[ 8], 55); - state[ 9] = ROTL64(state[ 9], 20); - state[10] = ROTL64(state[10], 3); - state[11] = ROTL64(state[11], 10); - state[12] = ROTL64(state[12], 43); - state[13] = ROTL64(state[13], 25); - state[14] = ROTL64(state[14], 39); - state[15] = ROTL64(state[15], 41); - state[16] = ROTL64(state[16], 45); - state[17] = ROTL64(state[17], 15); - state[18] = ROTL64(state[18], 21); - state[19] = ROTL64(state[19], 8); - state[20] = ROTL64(state[20], 18); - state[21] = ROTL64(state[21], 2); - state[22] = ROTL64(state[22], 61); - state[23] = ROTL64(state[23], 56); - state[24] = ROTL64(state[24], 14); - - keccak_pi(state); - keccak_chi(state); - - /* apply iota(state, round) */ - *state ^= keccak_round_constants[round]; - } + int round = 0; + for(round = 0; round < NumberOfRounds; round++) { + keccak_theta(state); + + /* apply Keccak rho() transformation */ + state[1] = ROTL64(state[1], 1); + state[2] = ROTL64(state[2], 62); + state[3] = ROTL64(state[3], 28); + state[4] = ROTL64(state[4], 27); + state[5] = ROTL64(state[5], 36); + state[6] = ROTL64(state[6], 44); + state[7] = ROTL64(state[7], 6); + state[8] = ROTL64(state[8], 55); + state[9] = ROTL64(state[9], 20); + state[10] = ROTL64(state[10], 3); + state[11] = ROTL64(state[11], 10); + state[12] = ROTL64(state[12], 43); + state[13] = ROTL64(state[13], 25); + state[14] = ROTL64(state[14], 39); + state[15] = ROTL64(state[15], 41); + state[16] = ROTL64(state[16], 45); + state[17] = ROTL64(state[17], 15); + state[18] = ROTL64(state[18], 21); + state[19] = ROTL64(state[19], 8); + state[20] = ROTL64(state[20], 18); + state[21] = ROTL64(state[21], 2); + state[22] = ROTL64(state[22], 61); + state[23] = ROTL64(state[23], 56); + state[24] = ROTL64(state[24], 14); + + keccak_pi(state); + keccak_chi(state); + + /* apply iota(state, round) */ + *state ^= keccak_round_constants[round]; + } #if BYTE_ORDER == BIG_ENDIAN - for (i = 0; i < 25; i++) - { - REVERSE64(state[i], state[i]); - } + for(i = 0; i < 25; i++) { + REVERSE64(state[i], state[i]); + } #endif } @@ -225,50 +214,49 @@ static void sha3_permutation(uint64_t *state) * @param block the message block to process * @param block_size the size of the processed block in bytes */ -static void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) -{ - /* expanded loop */ - hash[ 0] ^= le2me_64(block[ 0]); - hash[ 1] ^= le2me_64(block[ 1]); - hash[ 2] ^= le2me_64(block[ 2]); - hash[ 3] ^= le2me_64(block[ 3]); - hash[ 4] ^= le2me_64(block[ 4]); - hash[ 5] ^= le2me_64(block[ 5]); - hash[ 6] ^= le2me_64(block[ 6]); - hash[ 7] ^= le2me_64(block[ 7]); - hash[ 8] ^= le2me_64(block[ 8]); - /* if not sha3-512 */ - if (block_size > 72) { - hash[ 9] ^= le2me_64(block[ 9]); - hash[10] ^= le2me_64(block[10]); - hash[11] ^= le2me_64(block[11]); - hash[12] ^= le2me_64(block[12]); - /* if not sha3-384 */ - if (block_size > 104) { - hash[13] ^= le2me_64(block[13]); - hash[14] ^= le2me_64(block[14]); - hash[15] ^= le2me_64(block[15]); - hash[16] ^= le2me_64(block[16]); - /* if not sha3-256 */ - if (block_size > 136) { - hash[17] ^= le2me_64(block[17]); +static void sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size) { + /* expanded loop */ + hash[0] ^= le2me_64(block[0]); + hash[1] ^= le2me_64(block[1]); + hash[2] ^= le2me_64(block[2]); + hash[3] ^= le2me_64(block[3]); + hash[4] ^= le2me_64(block[4]); + hash[5] ^= le2me_64(block[5]); + hash[6] ^= le2me_64(block[6]); + hash[7] ^= le2me_64(block[7]); + hash[8] ^= le2me_64(block[8]); + /* if not sha3-512 */ + if(block_size > 72) { + hash[9] ^= le2me_64(block[9]); + hash[10] ^= le2me_64(block[10]); + hash[11] ^= le2me_64(block[11]); + hash[12] ^= le2me_64(block[12]); + /* if not sha3-384 */ + if(block_size > 104) { + hash[13] ^= le2me_64(block[13]); + hash[14] ^= le2me_64(block[14]); + hash[15] ^= le2me_64(block[15]); + hash[16] ^= le2me_64(block[16]); + /* if not sha3-256 */ + if(block_size > 136) { + hash[17] ^= le2me_64(block[17]); #ifdef FULL_SHA3_FAMILY_SUPPORT - /* if not sha3-224 */ - if (block_size > 144) { - hash[18] ^= le2me_64(block[18]); - hash[19] ^= le2me_64(block[19]); - hash[20] ^= le2me_64(block[20]); - hash[21] ^= le2me_64(block[21]); - hash[22] ^= le2me_64(block[22]); - hash[23] ^= le2me_64(block[23]); - hash[24] ^= le2me_64(block[24]); - } + /* if not sha3-224 */ + if(block_size > 144) { + hash[18] ^= le2me_64(block[18]); + hash[19] ^= le2me_64(block[19]); + hash[20] ^= le2me_64(block[20]); + hash[21] ^= le2me_64(block[21]); + hash[22] ^= le2me_64(block[22]); + hash[23] ^= le2me_64(block[23]); + hash[24] ^= le2me_64(block[24]); + } #endif - } - } - } - /* make a permutation of the hash */ - sha3_permutation(hash); + } + } + } + /* make a permutation of the hash */ + sha3_permutation(hash); } #define SHA3_FINALIZED 0x80000000 @@ -281,45 +269,44 @@ static void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t * @param msg message chunk * @param size length of the message chunk */ -void sha3_Update(SHA3_CTX *ctx, const unsigned char *msg, size_t size) -{ - if (size == 0) return; - - size_t idx = (size_t)ctx->rest; - size_t block_size = (size_t)ctx->block_size; - - if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */ - ctx->rest = (unsigned)((ctx->rest + size) % block_size); - - /* fill partial block */ - if (idx) { - size_t left = block_size - idx; - memcpy((char*)ctx->message + idx, msg, (size < left ? size : left)); - if (size < left) return; - - /* process partial block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - msg += left; - size -= left; - } - while (size >= block_size) { - uint64_t *aligned_message_block = NULL; - if (IS_ALIGNED_64(msg)) { - /* the most common case is processing of an already aligned message +void sha3_Update(SHA3_CTX* ctx, const unsigned char* msg, size_t size) { + if(size == 0) return; + + size_t idx = (size_t)ctx->rest; + size_t block_size = (size_t)ctx->block_size; + + if(ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */ + ctx->rest = (unsigned)((ctx->rest + size) % block_size); + + /* fill partial block */ + if(idx) { + size_t left = block_size - idx; + memcpy((char*)ctx->message + idx, msg, (size < left ? size : left)); + if(size < left) return; + + /* process partial block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + msg += left; + size -= left; + } + while(size >= block_size) { + uint64_t* aligned_message_block = NULL; + if(IS_ALIGNED_64(msg)) { + /* the most common case is processing of an already aligned message without copying it */ - aligned_message_block = (uint64_t*)(void*)msg; - } else { - memcpy(ctx->message, msg, block_size); - aligned_message_block = ctx->message; - } - - sha3_process_block(ctx->hash, aligned_message_block, block_size); - msg += block_size; - size -= block_size; - } - if (size) { - memcpy(ctx->message, msg, size); /* save leftovers */ - } + aligned_message_block = (uint64_t*)(void*)msg; + } else { + memcpy(ctx->message, msg, block_size); + aligned_message_block = ctx->message; + } + + sha3_process_block(ctx->hash, aligned_message_block, block_size); + msg += block_size; + size -= block_size; + } + if(size) { + memcpy(ctx->message, msg, size); /* save leftovers */ + } } /** @@ -328,26 +315,24 @@ void sha3_Update(SHA3_CTX *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void sha3_Final(SHA3_CTX *ctx, unsigned char* result) -{ - size_t digest_length = 100 - ctx->block_size / 2; - const size_t block_size = ctx->block_size; - - if (!(ctx->rest & SHA3_FINALIZED)) - { - /* clear the rest of the data queue */ - memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); - ((char*)ctx->message)[ctx->rest] |= 0x06; - ((char*)ctx->message)[block_size - 1] |= 0x80; - - /* process final block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ - } - - assert(block_size > digest_length); - if (result) me64_to_le_str(result, ctx->hash, digest_length); - memzero(ctx, sizeof(SHA3_CTX)); +void sha3_Final(SHA3_CTX* ctx, unsigned char* result) { + size_t digest_length = 100 - ctx->block_size / 2; + const size_t block_size = ctx->block_size; + + if(!(ctx->rest & SHA3_FINALIZED)) { + /* clear the rest of the data queue */ + memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); + ((char*)ctx->message)[ctx->rest] |= 0x06; + ((char*)ctx->message)[block_size - 1] |= 0x80; + + /* process final block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ + } + + assert(block_size > digest_length); + if(result) me64_to_le_str(result, ctx->hash, digest_length); + memzero(ctx, sizeof(SHA3_CTX)); } #if USE_KECCAK @@ -357,57 +342,51 @@ void sha3_Final(SHA3_CTX *ctx, unsigned char* result) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void keccak_Final(SHA3_CTX *ctx, unsigned char* result) -{ - size_t digest_length = 100 - ctx->block_size / 2; - const size_t block_size = ctx->block_size; - - if (!(ctx->rest & SHA3_FINALIZED)) - { - /* clear the rest of the data queue */ - memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); - ((char*)ctx->message)[ctx->rest] |= 0x01; - ((char*)ctx->message)[block_size - 1] |= 0x80; - - /* process final block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ - } - - assert(block_size > digest_length); - if (result) me64_to_le_str(result, ctx->hash, digest_length); - memzero(ctx, sizeof(SHA3_CTX)); +void keccak_Final(SHA3_CTX* ctx, unsigned char* result) { + size_t digest_length = 100 - ctx->block_size / 2; + const size_t block_size = ctx->block_size; + + if(!(ctx->rest & SHA3_FINALIZED)) { + /* clear the rest of the data queue */ + memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); + ((char*)ctx->message)[ctx->rest] |= 0x01; + ((char*)ctx->message)[block_size - 1] |= 0x80; + + /* process final block */ + sha3_process_block(ctx->hash, ctx->message, block_size); + ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ + } + + assert(block_size > digest_length); + if(result) me64_to_le_str(result, ctx->hash, digest_length); + memzero(ctx, sizeof(SHA3_CTX)); } -void keccak_256(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - keccak_256_Init(&ctx); - keccak_Update(&ctx, data, len); - keccak_Final(&ctx, digest); +void keccak_256(const unsigned char* data, size_t len, unsigned char* digest) { + SHA3_CTX ctx = {0}; + keccak_256_Init(&ctx); + keccak_Update(&ctx, data, len); + keccak_Final(&ctx, digest); } -void keccak_512(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - keccak_512_Init(&ctx); - keccak_Update(&ctx, data, len); - keccak_Final(&ctx, digest); +void keccak_512(const unsigned char* data, size_t len, unsigned char* digest) { + SHA3_CTX ctx = {0}; + keccak_512_Init(&ctx); + keccak_Update(&ctx, data, len); + keccak_Final(&ctx, digest); } #endif /* USE_KECCAK */ -void sha3_256(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - sha3_256_Init(&ctx); - sha3_Update(&ctx, data, len); - sha3_Final(&ctx, digest); +void sha3_256(const unsigned char* data, size_t len, unsigned char* digest) { + SHA3_CTX ctx = {0}; + sha3_256_Init(&ctx); + sha3_Update(&ctx, data, len); + sha3_Final(&ctx, digest); } -void sha3_512(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - sha3_512_Init(&ctx); - sha3_Update(&ctx, data, len); - sha3_Final(&ctx, digest); +void sha3_512(const unsigned char* data, size_t len, unsigned char* digest) { + SHA3_CTX ctx = {0}; + sha3_512_Init(&ctx); + sha3_Update(&ctx, data, len); + sha3_Final(&ctx, digest); } diff --git a/crypto/sha3.h b/crypto/sha3.h index 367369d4d79..01818a4fed0 100644 --- a/crypto/sha3.h +++ b/crypto/sha3.h @@ -27,46 +27,45 @@ extern "C" { #endif -#define sha3_224_hash_size 28 -#define sha3_256_hash_size 32 -#define sha3_384_hash_size 48 -#define sha3_512_hash_size 64 +#define sha3_224_hash_size 28 +#define sha3_256_hash_size 32 +#define sha3_384_hash_size 48 +#define sha3_512_hash_size 64 #define sha3_max_permutation_size 25 #define sha3_max_rate_in_qwords 24 -#define SHA3_224_BLOCK_LENGTH 144 -#define SHA3_256_BLOCK_LENGTH 136 -#define SHA3_384_BLOCK_LENGTH 104 -#define SHA3_512_BLOCK_LENGTH 72 +#define SHA3_224_BLOCK_LENGTH 144 +#define SHA3_256_BLOCK_LENGTH 136 +#define SHA3_384_BLOCK_LENGTH 104 +#define SHA3_512_BLOCK_LENGTH 72 -#define SHA3_224_DIGEST_LENGTH sha3_224_hash_size -#define SHA3_256_DIGEST_LENGTH sha3_256_hash_size -#define SHA3_384_DIGEST_LENGTH sha3_384_hash_size -#define SHA3_512_DIGEST_LENGTH sha3_512_hash_size +#define SHA3_224_DIGEST_LENGTH sha3_224_hash_size +#define SHA3_256_DIGEST_LENGTH sha3_256_hash_size +#define SHA3_384_DIGEST_LENGTH sha3_384_hash_size +#define SHA3_512_DIGEST_LENGTH sha3_512_hash_size /** * SHA3 Algorithm context. */ -typedef struct SHA3_CTX -{ - /* 1600 bits algorithm hashing state */ - uint64_t hash[sha3_max_permutation_size]; - /* 1536-bit buffer for leftovers */ - uint64_t message[sha3_max_rate_in_qwords]; - /* count of bytes in the message[] buffer */ - unsigned rest; - /* size of a message block processed at once */ - unsigned block_size; +typedef struct SHA3_CTX { + /* 1600 bits algorithm hashing state */ + uint64_t hash[sha3_max_permutation_size]; + /* 1536-bit buffer for leftovers */ + uint64_t message[sha3_max_rate_in_qwords]; + /* count of bytes in the message[] buffer */ + unsigned rest; + /* size of a message block processed at once */ + unsigned block_size; } SHA3_CTX; /* methods for calculating the hash function */ -void sha3_224_Init(SHA3_CTX *ctx); -void sha3_256_Init(SHA3_CTX *ctx); -void sha3_384_Init(SHA3_CTX *ctx); -void sha3_512_Init(SHA3_CTX *ctx); -void sha3_Update(SHA3_CTX *ctx, const unsigned char* msg, size_t size); -void sha3_Final(SHA3_CTX *ctx, unsigned char* result); +void sha3_224_Init(SHA3_CTX* ctx); +void sha3_256_Init(SHA3_CTX* ctx); +void sha3_384_Init(SHA3_CTX* ctx); +void sha3_512_Init(SHA3_CTX* ctx); +void sha3_Update(SHA3_CTX* ctx, const unsigned char* msg, size_t size); +void sha3_Final(SHA3_CTX* ctx, unsigned char* result); #if USE_KECCAK #define keccak_224_Init sha3_224_Init @@ -74,7 +73,7 @@ void sha3_Final(SHA3_CTX *ctx, unsigned char* result); #define keccak_384_Init sha3_384_Init #define keccak_512_Init sha3_512_Init #define keccak_Update sha3_Update -void keccak_Final(SHA3_CTX *ctx, unsigned char* result); +void keccak_Final(SHA3_CTX* ctx, unsigned char* result); void keccak_256(const unsigned char* data, size_t len, unsigned char* digest); void keccak_512(const unsigned char* data, size_t len, unsigned char* digest); #endif diff --git a/crypto/shamir.c b/crypto/shamir.c index 82b5e29a291..037af99cc45 100644 --- a/crypto/shamir.c +++ b/crypto/shamir.c @@ -40,45 +40,45 @@ #include #include "memzero.h" -static void bitslice(uint32_t r[8], const uint8_t *x, size_t len) { - size_t bit_idx = 0, arr_idx = 0; - uint32_t cur = 0; +static void bitslice(uint32_t r[8], const uint8_t* x, size_t len) { + size_t bit_idx = 0, arr_idx = 0; + uint32_t cur = 0; - memset(r, 0, sizeof(uint32_t[8])); - for (arr_idx = 0; arr_idx < len; arr_idx++) { - cur = (uint32_t)x[arr_idx]; - for (bit_idx = 0; bit_idx < 8; bit_idx++) { - r[bit_idx] |= ((cur >> bit_idx) & 1) << arr_idx; + memset(r, 0, sizeof(uint32_t[8])); + for(arr_idx = 0; arr_idx < len; arr_idx++) { + cur = (uint32_t)x[arr_idx]; + for(bit_idx = 0; bit_idx < 8; bit_idx++) { + r[bit_idx] |= ((cur >> bit_idx) & 1) << arr_idx; + } } - } } -static void unbitslice(uint8_t *r, const uint32_t x[8], size_t len) { - size_t bit_idx = 0, arr_idx = 0; - uint32_t cur = 0; +static void unbitslice(uint8_t* r, const uint32_t x[8], size_t len) { + size_t bit_idx = 0, arr_idx = 0; + uint32_t cur = 0; - memset(r, 0, sizeof(uint8_t) * len); - for (bit_idx = 0; bit_idx < 8; bit_idx++) { - cur = (uint32_t)x[bit_idx]; - for (arr_idx = 0; arr_idx < len; arr_idx++) { - r[arr_idx] |= ((cur >> arr_idx) & 1) << bit_idx; + memset(r, 0, sizeof(uint8_t) * len); + for(bit_idx = 0; bit_idx < 8; bit_idx++) { + cur = (uint32_t)x[bit_idx]; + for(arr_idx = 0; arr_idx < len; arr_idx++) { + r[arr_idx] |= ((cur >> arr_idx) & 1) << bit_idx; + } } - } } static void bitslice_setall(uint32_t r[8], const uint8_t x) { - size_t idx = 0; - for (idx = 0; idx < 8; idx++) { - r[idx] = -((x >> idx) & 1); - } + size_t idx = 0; + for(idx = 0; idx < 8; idx++) { + r[idx] = -((x >> idx) & 1); + } } /* * Add (XOR) `r` with `x` and store the result in `r`. */ static void gf256_add(uint32_t r[8], const uint32_t x[8]) { - size_t idx = 0; - for (idx = 0; idx < 8; idx++) r[idx] ^= x[idx]; + size_t idx = 0; + for(idx = 0; idx < 8; idx++) r[idx] ^= x[idx]; } /* @@ -88,7 +88,7 @@ static void gf256_add(uint32_t r[8], const uint32_t x[8]) { * use `gf256_square` instead. */ static void gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8]) { - /* This function implements Russian Peasant multiplication on two + /* This function implements Russian Peasant multiplication on two * bitsliced polynomials. * * I personally think that these kinds of long lists of operations @@ -97,239 +97,242 @@ static void gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8]) { * However, some compilers seem to fail in optimizing these kinds of * loops. So we will just have to do this by hand. */ - uint32_t a2[8] = {0}; - memcpy(a2, a, sizeof(uint32_t[8])); + uint32_t a2[8] = {0}; + memcpy(a2, a, sizeof(uint32_t[8])); - r[0] = a2[0] & b[0]; /* add (assignment, because r is 0) */ - r[1] = a2[1] & b[0]; - r[2] = a2[2] & b[0]; - r[3] = a2[3] & b[0]; - r[4] = a2[4] & b[0]; - r[5] = a2[5] & b[0]; - r[6] = a2[6] & b[0]; - r[7] = a2[7] & b[0]; - a2[0] ^= a2[7]; /* reduce */ - a2[2] ^= a2[7]; - a2[3] ^= a2[7]; + r[0] = a2[0] & b[0]; /* add (assignment, because r is 0) */ + r[1] = a2[1] & b[0]; + r[2] = a2[2] & b[0]; + r[3] = a2[3] & b[0]; + r[4] = a2[4] & b[0]; + r[5] = a2[5] & b[0]; + r[6] = a2[6] & b[0]; + r[7] = a2[7] & b[0]; + a2[0] ^= a2[7]; /* reduce */ + a2[2] ^= a2[7]; + a2[3] ^= a2[7]; - r[0] ^= a2[7] & b[1]; /* add */ - r[1] ^= a2[0] & b[1]; - r[2] ^= a2[1] & b[1]; - r[3] ^= a2[2] & b[1]; - r[4] ^= a2[3] & b[1]; - r[5] ^= a2[4] & b[1]; - r[6] ^= a2[5] & b[1]; - r[7] ^= a2[6] & b[1]; - a2[7] ^= a2[6]; /* reduce */ - a2[1] ^= a2[6]; - a2[2] ^= a2[6]; + r[0] ^= a2[7] & b[1]; /* add */ + r[1] ^= a2[0] & b[1]; + r[2] ^= a2[1] & b[1]; + r[3] ^= a2[2] & b[1]; + r[4] ^= a2[3] & b[1]; + r[5] ^= a2[4] & b[1]; + r[6] ^= a2[5] & b[1]; + r[7] ^= a2[6] & b[1]; + a2[7] ^= a2[6]; /* reduce */ + a2[1] ^= a2[6]; + a2[2] ^= a2[6]; - r[0] ^= a2[6] & b[2]; /* add */ - r[1] ^= a2[7] & b[2]; - r[2] ^= a2[0] & b[2]; - r[3] ^= a2[1] & b[2]; - r[4] ^= a2[2] & b[2]; - r[5] ^= a2[3] & b[2]; - r[6] ^= a2[4] & b[2]; - r[7] ^= a2[5] & b[2]; - a2[6] ^= a2[5]; /* reduce */ - a2[0] ^= a2[5]; - a2[1] ^= a2[5]; + r[0] ^= a2[6] & b[2]; /* add */ + r[1] ^= a2[7] & b[2]; + r[2] ^= a2[0] & b[2]; + r[3] ^= a2[1] & b[2]; + r[4] ^= a2[2] & b[2]; + r[5] ^= a2[3] & b[2]; + r[6] ^= a2[4] & b[2]; + r[7] ^= a2[5] & b[2]; + a2[6] ^= a2[5]; /* reduce */ + a2[0] ^= a2[5]; + a2[1] ^= a2[5]; - r[0] ^= a2[5] & b[3]; /* add */ - r[1] ^= a2[6] & b[3]; - r[2] ^= a2[7] & b[3]; - r[3] ^= a2[0] & b[3]; - r[4] ^= a2[1] & b[3]; - r[5] ^= a2[2] & b[3]; - r[6] ^= a2[3] & b[3]; - r[7] ^= a2[4] & b[3]; - a2[5] ^= a2[4]; /* reduce */ - a2[7] ^= a2[4]; - a2[0] ^= a2[4]; + r[0] ^= a2[5] & b[3]; /* add */ + r[1] ^= a2[6] & b[3]; + r[2] ^= a2[7] & b[3]; + r[3] ^= a2[0] & b[3]; + r[4] ^= a2[1] & b[3]; + r[5] ^= a2[2] & b[3]; + r[6] ^= a2[3] & b[3]; + r[7] ^= a2[4] & b[3]; + a2[5] ^= a2[4]; /* reduce */ + a2[7] ^= a2[4]; + a2[0] ^= a2[4]; - r[0] ^= a2[4] & b[4]; /* add */ - r[1] ^= a2[5] & b[4]; - r[2] ^= a2[6] & b[4]; - r[3] ^= a2[7] & b[4]; - r[4] ^= a2[0] & b[4]; - r[5] ^= a2[1] & b[4]; - r[6] ^= a2[2] & b[4]; - r[7] ^= a2[3] & b[4]; - a2[4] ^= a2[3]; /* reduce */ - a2[6] ^= a2[3]; - a2[7] ^= a2[3]; + r[0] ^= a2[4] & b[4]; /* add */ + r[1] ^= a2[5] & b[4]; + r[2] ^= a2[6] & b[4]; + r[3] ^= a2[7] & b[4]; + r[4] ^= a2[0] & b[4]; + r[5] ^= a2[1] & b[4]; + r[6] ^= a2[2] & b[4]; + r[7] ^= a2[3] & b[4]; + a2[4] ^= a2[3]; /* reduce */ + a2[6] ^= a2[3]; + a2[7] ^= a2[3]; - r[0] ^= a2[3] & b[5]; /* add */ - r[1] ^= a2[4] & b[5]; - r[2] ^= a2[5] & b[5]; - r[3] ^= a2[6] & b[5]; - r[4] ^= a2[7] & b[5]; - r[5] ^= a2[0] & b[5]; - r[6] ^= a2[1] & b[5]; - r[7] ^= a2[2] & b[5]; - a2[3] ^= a2[2]; /* reduce */ - a2[5] ^= a2[2]; - a2[6] ^= a2[2]; + r[0] ^= a2[3] & b[5]; /* add */ + r[1] ^= a2[4] & b[5]; + r[2] ^= a2[5] & b[5]; + r[3] ^= a2[6] & b[5]; + r[4] ^= a2[7] & b[5]; + r[5] ^= a2[0] & b[5]; + r[6] ^= a2[1] & b[5]; + r[7] ^= a2[2] & b[5]; + a2[3] ^= a2[2]; /* reduce */ + a2[5] ^= a2[2]; + a2[6] ^= a2[2]; - r[0] ^= a2[2] & b[6]; /* add */ - r[1] ^= a2[3] & b[6]; - r[2] ^= a2[4] & b[6]; - r[3] ^= a2[5] & b[6]; - r[4] ^= a2[6] & b[6]; - r[5] ^= a2[7] & b[6]; - r[6] ^= a2[0] & b[6]; - r[7] ^= a2[1] & b[6]; - a2[2] ^= a2[1]; /* reduce */ - a2[4] ^= a2[1]; - a2[5] ^= a2[1]; + r[0] ^= a2[2] & b[6]; /* add */ + r[1] ^= a2[3] & b[6]; + r[2] ^= a2[4] & b[6]; + r[3] ^= a2[5] & b[6]; + r[4] ^= a2[6] & b[6]; + r[5] ^= a2[7] & b[6]; + r[6] ^= a2[0] & b[6]; + r[7] ^= a2[1] & b[6]; + a2[2] ^= a2[1]; /* reduce */ + a2[4] ^= a2[1]; + a2[5] ^= a2[1]; - r[0] ^= a2[1] & b[7]; /* add */ - r[1] ^= a2[2] & b[7]; - r[2] ^= a2[3] & b[7]; - r[3] ^= a2[4] & b[7]; - r[4] ^= a2[5] & b[7]; - r[5] ^= a2[6] & b[7]; - r[6] ^= a2[7] & b[7]; - r[7] ^= a2[0] & b[7]; + r[0] ^= a2[1] & b[7]; /* add */ + r[1] ^= a2[2] & b[7]; + r[2] ^= a2[3] & b[7]; + r[3] ^= a2[4] & b[7]; + r[4] ^= a2[5] & b[7]; + r[5] ^= a2[6] & b[7]; + r[6] ^= a2[7] & b[7]; + r[7] ^= a2[0] & b[7]; - memzero(a2, sizeof(a2)); + memzero(a2, sizeof(a2)); } /* * Square `x` in GF(2^8) and write the result to `r`. `r` and `x` may overlap. */ static void gf256_square(uint32_t r[8], const uint32_t x[8]) { - uint32_t r8 = 0, r10 = 0, r12 = 0, r14 = 0; - /* Use the Freshman's Dream rule to square the polynomial + uint32_t r8 = 0, r10 = 0, r12 = 0, r14 = 0; + /* Use the Freshman's Dream rule to square the polynomial * Assignments are done from 7 downto 0, because this allows the user * to execute this function in-place (e.g. `gf256_square(r, r);`). */ - r14 = x[7]; - r12 = x[6]; - r10 = x[5]; - r8 = x[4]; - r[6] = x[3]; - r[4] = x[2]; - r[2] = x[1]; - r[0] = x[0]; + r14 = x[7]; + r12 = x[6]; + r10 = x[5]; + r8 = x[4]; + r[6] = x[3]; + r[4] = x[2]; + r[2] = x[1]; + r[0] = x[0]; - /* Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8 */ - r[7] = r14; /* r[7] was 0 */ - r[6] ^= r14; - r10 ^= r14; - /* Skip, because r13 is always 0 */ - r[4] ^= r12; - r[5] = r12; /* r[5] was 0 */ - r[7] ^= r12; - r8 ^= r12; - /* Skip, because r11 is always 0 */ - r[2] ^= r10; - r[3] = r10; /* r[3] was 0 */ - r[5] ^= r10; - r[6] ^= r10; - r[1] = r14; /* r[1] was 0 */ - r[2] ^= r14; /* Substitute r9 by r14 because they will always be equal*/ - r[4] ^= r14; - r[5] ^= r14; - r[0] ^= r8; - r[1] ^= r8; - r[3] ^= r8; - r[4] ^= r8; + /* Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8 */ + r[7] = r14; /* r[7] was 0 */ + r[6] ^= r14; + r10 ^= r14; + /* Skip, because r13 is always 0 */ + r[4] ^= r12; + r[5] = r12; /* r[5] was 0 */ + r[7] ^= r12; + r8 ^= r12; + /* Skip, because r11 is always 0 */ + r[2] ^= r10; + r[3] = r10; /* r[3] was 0 */ + r[5] ^= r10; + r[6] ^= r10; + r[1] = r14; /* r[1] was 0 */ + r[2] ^= r14; /* Substitute r9 by r14 because they will always be equal*/ + r[4] ^= r14; + r[5] ^= r14; + r[0] ^= r8; + r[1] ^= r8; + r[3] ^= r8; + r[4] ^= r8; } /* * Invert `x` in GF(2^8) and write the result to `r` */ static void gf256_inv(uint32_t r[8], uint32_t x[8]) { - uint32_t y[8] = {0}, z[8] = {0}; + uint32_t y[8] = {0}, z[8] = {0}; - gf256_square(y, x); // y = x^2 - gf256_square(y, y); // y = x^4 - gf256_square(r, y); // r = x^8 - gf256_mul(z, r, x); // z = x^9 - gf256_square(r, r); // r = x^16 - gf256_mul(r, r, z); // r = x^25 - gf256_square(r, r); // r = x^50 - gf256_square(z, r); // z = x^100 - gf256_square(z, z); // z = x^200 - gf256_mul(r, r, z); // r = x^250 - gf256_mul(r, r, y); // r = x^254 + gf256_square(y, x); // y = x^2 + gf256_square(y, y); // y = x^4 + gf256_square(r, y); // r = x^8 + gf256_mul(z, r, x); // z = x^9 + gf256_square(r, r); // r = x^16 + gf256_mul(r, r, z); // r = x^25 + gf256_square(r, r); // r = x^50 + gf256_square(z, r); // z = x^100 + gf256_square(z, z); // z = x^200 + gf256_mul(r, r, z); // r = x^250 + gf256_mul(r, r, y); // r = x^254 - memzero(y, sizeof(y)); - memzero(z, sizeof(z)); + memzero(y, sizeof(y)); + memzero(z, sizeof(z)); } -bool shamir_interpolate(uint8_t *result, uint8_t result_index, - const uint8_t *share_indices, - const uint8_t **share_values, uint8_t share_count, - size_t len) { - size_t i = 0, j = 0; - uint32_t x[8] = {0}; - uint32_t xs[share_count][8]; - memset(xs, 0, sizeof(xs)); - uint32_t ys[share_count][8]; - memset(ys, 0, sizeof(ys)); - uint32_t num[8] = {~0}; /* num is the numerator (=1) */ - uint32_t denom[8] = {0}; - uint32_t tmp[8] = {0}; - uint32_t secret[8] = {0}; - bool ret = true; +bool shamir_interpolate( + uint8_t* result, + uint8_t result_index, + const uint8_t* share_indices, + const uint8_t** share_values, + uint8_t share_count, + size_t len) { + size_t i = 0, j = 0; + uint32_t x[8] = {0}; + uint32_t xs[share_count][8]; + memset(xs, 0, sizeof(xs)); + uint32_t ys[share_count][8]; + memset(ys, 0, sizeof(ys)); + uint32_t num[8] = {~0}; /* num is the numerator (=1) */ + uint32_t denom[8] = {0}; + uint32_t tmp[8] = {0}; + uint32_t secret[8] = {0}; + bool ret = true; - if (len > SHAMIR_MAX_LEN) return false; + if(len > SHAMIR_MAX_LEN) return false; - /* Collect the x and y values */ - for (i = 0; i < share_count; i++) { - bitslice_setall(xs[i], share_indices[i]); - bitslice(ys[i], share_values[i], len); - } - bitslice_setall(x, result_index); + /* Collect the x and y values */ + for(i = 0; i < share_count; i++) { + bitslice_setall(xs[i], share_indices[i]); + bitslice(ys[i], share_values[i], len); + } + bitslice_setall(x, result_index); - for (i = 0; i < share_count; i++) { - memcpy(tmp, x, sizeof(uint32_t[8])); - gf256_add(tmp, xs[i]); - gf256_mul(num, num, tmp); - } + for(i = 0; i < share_count; i++) { + memcpy(tmp, x, sizeof(uint32_t[8])); + gf256_add(tmp, xs[i]); + gf256_mul(num, num, tmp); + } - /* Use Lagrange basis polynomials to calculate the secret coefficient */ - for (i = 0; i < share_count; i++) { - /* The code below assumes that none of the share_indices are equal to + /* Use Lagrange basis polynomials to calculate the secret coefficient */ + for(i = 0; i < share_count; i++) { + /* The code below assumes that none of the share_indices are equal to * result_index. We need to treat that as a special case. */ - if (share_indices[i] != result_index) { - memcpy(denom, x, sizeof(denom)); - gf256_add(denom, xs[i]); - } else { - bitslice_setall(denom, 1); - gf256_add(secret, ys[i]); + if(share_indices[i] != result_index) { + memcpy(denom, x, sizeof(denom)); + gf256_add(denom, xs[i]); + } else { + bitslice_setall(denom, 1); + gf256_add(secret, ys[i]); + } + for(j = 0; j < share_count; j++) { + if(i == j) continue; + memcpy(tmp, xs[i], sizeof(uint32_t[8])); + gf256_add(tmp, xs[j]); + gf256_mul(denom, denom, tmp); + } + if((denom[0] | denom[1] | denom[2] | denom[3] | denom[4] | denom[5] | denom[6] | + denom[7]) == 0) { + /* The share_indices are not unique. */ + ret = false; + break; + } + gf256_inv(tmp, denom); /* inverted denominator */ + gf256_mul(tmp, tmp, num); /* basis polynomial */ + gf256_mul(tmp, tmp, ys[i]); /* scaled coefficient */ + gf256_add(secret, tmp); } - for (j = 0; j < share_count; j++) { - if (i == j) continue; - memcpy(tmp, xs[i], sizeof(uint32_t[8])); - gf256_add(tmp, xs[j]); - gf256_mul(denom, denom, tmp); - } - if ((denom[0] | denom[1] | denom[2] | denom[3] | denom[4] | denom[5] | - denom[6] | denom[7]) == 0) { - /* The share_indices are not unique. */ - ret = false; - break; - } - gf256_inv(tmp, denom); /* inverted denominator */ - gf256_mul(tmp, tmp, num); /* basis polynomial */ - gf256_mul(tmp, tmp, ys[i]); /* scaled coefficient */ - gf256_add(secret, tmp); - } - if (ret == true) { - unbitslice(result, secret, len); - } + if(ret == true) { + unbitslice(result, secret, len); + } - memzero(x, sizeof(x)); - memzero(xs, sizeof(xs)); - memzero(ys, sizeof(ys)); - memzero(num, sizeof(num)); - memzero(denom, sizeof(denom)); - memzero(tmp, sizeof(tmp)); - memzero(secret, sizeof(secret)); - return ret; + memzero(x, sizeof(x)); + memzero(xs, sizeof(xs)); + memzero(ys, sizeof(ys)); + memzero(num, sizeof(num)); + memzero(denom, sizeof(denom)); + memzero(tmp, sizeof(tmp)); + memzero(secret, sizeof(secret)); + return ret; } diff --git a/crypto/shamir.h b/crypto/shamir.h index ef04a30636a..2250fc67205 100644 --- a/crypto/shamir.h +++ b/crypto/shamir.h @@ -62,9 +62,12 @@ * This function treats `shares_values`, `share_indices` and `result` as secret * values. `share_count` is treated as a public value (for performance reasons). */ -bool shamir_interpolate(uint8_t *result, uint8_t result_index, - const uint8_t *share_indices, - const uint8_t **share_values, uint8_t share_count, - size_t len); +bool shamir_interpolate( + uint8_t* result, + uint8_t result_index, + const uint8_t* share_indices, + const uint8_t** share_values, + uint8_t share_count, + size_t len); #endif /* __SHAMIR_H__ */ diff --git a/crypto/slip39.c b/crypto/slip39.c index 2dd39fa4a04..268d0f37ee4 100644 --- a/crypto/slip39.c +++ b/crypto/slip39.c @@ -31,11 +31,11 @@ * Returns word at position `index`. */ const char* get_word(uint16_t index) { - if (index >= WORDS_COUNT) { - return NULL; - } + if(index >= WORDS_COUNT) { + return NULL; + } - return slip39_wordlist[index]; + return slip39_wordlist[index]; } /** @@ -43,23 +43,23 @@ const char* get_word(uint16_t index) { * Returns true on success and stores result in `index`. */ bool word_index(uint16_t* index, const char* word, uint8_t word_length) { - uint16_t lo = 0; - uint16_t hi = WORDS_COUNT; - uint16_t mid = 0; - - while ((hi - lo) > 1) { - mid = (hi + lo) / 2; - if (strncmp(slip39_wordlist[mid], word, word_length) > 0) { - hi = mid; - } else { - lo = mid; + uint16_t lo = 0; + uint16_t hi = WORDS_COUNT; + uint16_t mid = 0; + + while((hi - lo) > 1) { + mid = (hi + lo) / 2; + if(strncmp(slip39_wordlist[mid], word, word_length) > 0) { + hi = mid; + } else { + lo = mid; + } + } + if(strncmp(slip39_wordlist[lo], word, word_length) != 0) { + return false; } - } - if (strncmp(slip39_wordlist[lo], word, word_length) != 0) { - return false; - } - *index = lo; - return true; + *index = lo; + return true; } /** @@ -68,23 +68,23 @@ bool word_index(uint16_t* index, const char* word, uint8_t word_length) { * sequence. */ static uint16_t find_sequence(uint16_t sequence) { - if (sequence <= words_button_seq[0].sequence) { - return 0; - } - - uint16_t lo = 0; - uint16_t hi = WORDS_COUNT; - - while (hi - lo > 1) { - uint16_t mid = (hi + lo) / 2; - if (words_button_seq[mid].sequence >= sequence) { - hi = mid; - } else { - lo = mid; + if(sequence <= words_button_seq[0].sequence) { + return 0; + } + + uint16_t lo = 0; + uint16_t hi = WORDS_COUNT; + + while(hi - lo > 1) { + uint16_t mid = (hi + lo) / 2; + if(words_button_seq[mid].sequence >= sequence) { + hi = mid; + } else { + lo = mid; + } } - } - return hi; + return hi; } /** @@ -92,23 +92,22 @@ static uint16_t find_sequence(uint16_t sequence) { * found. */ const char* button_sequence_to_word(uint16_t sequence) { - if (sequence == 0) { - return slip39_wordlist[words_button_seq[0].index]; - } - - uint16_t multiplier = 1; - while (sequence < 1000) { - sequence *= 10; - multiplier *= 10; - } - - uint16_t i = find_sequence(sequence); - if (i >= WORDS_COUNT || - words_button_seq[i].sequence - sequence >= multiplier) { - return NULL; - } - - return slip39_wordlist[words_button_seq[i].index]; + if(sequence == 0) { + return slip39_wordlist[words_button_seq[0].index]; + } + + uint16_t multiplier = 1; + while(sequence < 1000) { + sequence *= 10; + multiplier *= 10; + } + + uint16_t i = find_sequence(sequence); + if(i >= WORDS_COUNT || words_button_seq[i].sequence - sequence >= multiplier) { + return NULL; + } + + return slip39_wordlist[words_button_seq[i].index]; } /** @@ -121,31 +120,31 @@ const char* button_sequence_to_word(uint16_t sequence) { * pressed. */ uint16_t slip39_word_completion_mask(uint16_t prefix) { - if (prefix >= 1000) { - // Four char prefix -> the mask is zero. - return 0; - } - - // Determine the range of sequences [min, max), which have the given prefix. - uint16_t min = prefix; - uint16_t max = prefix + 1; - uint16_t divider = 1; - while (max <= 1000) { - min *= 10; - max *= 10; - divider *= 10; - } - divider /= 10; - - // Determine the range we will be searching in words_button_seq[]. - min = find_sequence(min); - max = find_sequence(max); - - uint16_t bitmap = 0; - for (uint16_t i = min; i < max; ++i) { - uint8_t digit = (words_button_seq[i].sequence / divider) % 10; - bitmap |= 1 << (digit - 1); - } - - return bitmap; + if(prefix >= 1000) { + // Four char prefix -> the mask is zero. + return 0; + } + + // Determine the range of sequences [min, max), which have the given prefix. + uint16_t min = prefix; + uint16_t max = prefix + 1; + uint16_t divider = 1; + while(max <= 1000) { + min *= 10; + max *= 10; + divider *= 10; + } + divider /= 10; + + // Determine the range we will be searching in words_button_seq[]. + min = find_sequence(min); + max = find_sequence(max); + + uint16_t bitmap = 0; + for(uint16_t i = min; i < max; ++i) { + uint8_t digit = (words_button_seq[i].sequence / divider) % 10; + bitmap |= 1 << (digit - 1); + } + + return bitmap; } diff --git a/crypto/slip39_wordlist.h b/crypto/slip39_wordlist.h index 3464aae9412..17d4edeedb8 100644 --- a/crypto/slip39_wordlist.h +++ b/crypto/slip39_wordlist.h @@ -30,177 +30,134 @@ #define WORDS_COUNT 1024 static const char* const slip39_wordlist[WORDS_COUNT] = { - "academic", "acid", "acne", "acquire", "acrobat", "activity", - "actress", "adapt", "adequate", "adjust", "admit", "adorn", - "adult", "advance", "advocate", "afraid", "again", "agency", - "agree", "aide", "aircraft", "airline", "airport", "ajar", - "alarm", "album", "alcohol", "alien", "alive", "alpha", - "already", "alto", "aluminum", "always", "amazing", "ambition", - "amount", "amuse", "analysis", "anatomy", "ancestor", "ancient", - "angel", "angry", "animal", "answer", "antenna", "anxiety", - "apart", "aquatic", "arcade", "arena", "argue", "armed", - "artist", "artwork", "aspect", "auction", "august", "aunt", - "average", "aviation", "avoid", "award", "away", "axis", - "axle", "beam", "beard", "beaver", "become", "bedroom", - "behavior", "being", "believe", "belong", "benefit", "best", - "beyond", "bike", "biology", "birthday", "bishop", "black", - "blanket", "blessing", "blimp", "blind", "blue", "body", - "bolt", "boring", "born", "both", "boundary", "bracelet", - "branch", "brave", "breathe", "briefing", "broken", "brother", - "browser", "bucket", "budget", "building", "bulb", "bulge", - "bumpy", "bundle", "burden", "burning", "busy", "buyer", - "cage", "calcium", "camera", "campus", "canyon", "capacity", - "capital", "capture", "carbon", "cards", "careful", "cargo", - "carpet", "carve", "category", "cause", "ceiling", "center", - "ceramic", "champion", "change", "charity", "check", "chemical", - "chest", "chew", "chubby", "cinema", "civil", "class", - "clay", "cleanup", "client", "climate", "clinic", "clock", - "clogs", "closet", "clothes", "club", "cluster", "coal", - "coastal", "coding", "column", "company", "corner", "costume", - "counter", "course", "cover", "cowboy", "cradle", "craft", - "crazy", "credit", "cricket", "criminal", "crisis", "critical", - "crowd", "crucial", "crunch", "crush", "crystal", "cubic", - "cultural", "curious", "curly", "custody", "cylinder", "daisy", - "damage", "dance", "darkness", "database", "daughter", "deadline", - "deal", "debris", "debut", "decent", "decision", "declare", - "decorate", "decrease", "deliver", "demand", "density", "deny", - "depart", "depend", "depict", "deploy", "describe", "desert", - "desire", "desktop", "destroy", "detailed", "detect", "device", - "devote", "diagnose", "dictate", "diet", "dilemma", "diminish", - "dining", "diploma", "disaster", "discuss", "disease", "dish", - "dismiss", "display", "distance", "dive", "divorce", "document", - "domain", "domestic", "dominant", "dough", "downtown", "dragon", - "dramatic", "dream", "dress", "drift", "drink", "drove", - "drug", "dryer", "duckling", "duke", "duration", "dwarf", - "dynamic", "early", "earth", "easel", "easy", "echo", - "eclipse", "ecology", "edge", "editor", "educate", "either", - "elbow", "elder", "election", "elegant", "element", "elephant", - "elevator", "elite", "else", "email", "emerald", "emission", - "emperor", "emphasis", "employer", "empty", "ending", "endless", - "endorse", "enemy", "energy", "enforce", "engage", "enjoy", - "enlarge", "entrance", "envelope", "envy", "epidemic", "episode", - "equation", "equip", "eraser", "erode", "escape", "estate", - "estimate", "evaluate", "evening", "evidence", "evil", "evoke", - "exact", "example", "exceed", "exchange", "exclude", "excuse", - "execute", "exercise", "exhaust", "exotic", "expand", "expect", - "explain", "express", "extend", "extra", "eyebrow", "facility", - "fact", "failure", "faint", "fake", "false", "family", - "famous", "fancy", "fangs", "fantasy", "fatal", "fatigue", - "favorite", "fawn", "fiber", "fiction", "filter", "finance", - "findings", "finger", "firefly", "firm", "fiscal", "fishing", - "fitness", "flame", "flash", "flavor", "flea", "flexible", - "flip", "float", "floral", "fluff", "focus", "forbid", - "force", "forecast", "forget", "formal", "fortune", "forward", - "founder", "fraction", "fragment", "frequent", "freshman", "friar", - "fridge", "friendly", "frost", "froth", "frozen", "fumes", - "funding", "furl", "fused", "galaxy", "game", "garbage", - "garden", "garlic", "gasoline", "gather", "general", "genius", - "genre", "genuine", "geology", "gesture", "glad", "glance", - "glasses", "glen", "glimpse", "goat", "golden", "graduate", - "grant", "grasp", "gravity", "gray", "greatest", "grief", - "grill", "grin", "grocery", "gross", "group", "grownup", - "grumpy", "guard", "guest", "guilt", "guitar", "gums", - "hairy", "hamster", "hand", "hanger", "harvest", "have", - "havoc", "hawk", "hazard", "headset", "health", "hearing", - "heat", "helpful", "herald", "herd", "hesitate", "hobo", - "holiday", "holy", "home", "hormone", "hospital", "hour", - "huge", "human", "humidity", "hunting", "husband", "hush", - "husky", "hybrid", "idea", "identify", "idle", "image", - "impact", "imply", "improve", "impulse", "include", "income", - "increase", "index", "indicate", "industry", "infant", "inform", - "inherit", "injury", "inmate", "insect", "inside", "install", - "intend", "intimate", "invasion", "involve", "iris", "island", - "isolate", "item", "ivory", "jacket", "jerky", "jewelry", - "join", "judicial", "juice", "jump", "junction", "junior", - "junk", "jury", "justice", "kernel", "keyboard", "kidney", - "kind", "kitchen", "knife", "knit", "laden", "ladle", - "ladybug", "lair", "lamp", "language", "large", "laser", - "laundry", "lawsuit", "leader", "leaf", "learn", "leaves", - "lecture", "legal", "legend", "legs", "lend", "length", - "level", "liberty", "library", "license", "lift", "likely", - "lilac", "lily", "lips", "liquid", "listen", "literary", - "living", "lizard", "loan", "lobe", "location", "losing", - "loud", "loyalty", "luck", "lunar", "lunch", "lungs", - "luxury", "lying", "lyrics", "machine", "magazine", "maiden", - "mailman", "main", "makeup", "making", "mama", "manager", - "mandate", "mansion", "manual", "marathon", "march", "market", - "marvel", "mason", "material", "math", "maximum", "mayor", - "meaning", "medal", "medical", "member", "memory", "mental", - "merchant", "merit", "method", "metric", "midst", "mild", - "military", "mineral", "minister", "miracle", "mixed", "mixture", - "mobile", "modern", "modify", "moisture", "moment", "morning", - "mortgage", "mother", "mountain", "mouse", "move", "much", - "mule", "multiple", "muscle", "museum", "music", "mustang", - "nail", "national", "necklace", "negative", "nervous", "network", - "news", "nuclear", "numb", "numerous", "nylon", "oasis", - "obesity", "object", "observe", "obtain", "ocean", "often", - "olympic", "omit", "oral", "orange", "orbit", "order", - "ordinary", "organize", "ounce", "oven", "overall", "owner", - "paces", "pacific", "package", "paid", "painting", "pajamas", - "pancake", "pants", "papa", "paper", "parcel", "parking", - "party", "patent", "patrol", "payment", "payroll", "peaceful", - "peanut", "peasant", "pecan", "penalty", "pencil", "percent", - "perfect", "permit", "petition", "phantom", "pharmacy", "photo", - "phrase", "physics", "pickup", "picture", "piece", "pile", - "pink", "pipeline", "pistol", "pitch", "plains", "plan", - "plastic", "platform", "playoff", "pleasure", "plot", "plunge", - "practice", "prayer", "preach", "predator", "pregnant", "premium", - "prepare", "presence", "prevent", "priest", "primary", "priority", - "prisoner", "privacy", "prize", "problem", "process", "profile", - "program", "promise", "prospect", "provide", "prune", "public", - "pulse", "pumps", "punish", "puny", "pupal", "purchase", - "purple", "python", "quantity", "quarter", "quick", "quiet", - "race", "racism", "radar", "railroad", "rainbow", "raisin", - "random", "ranked", "rapids", "raspy", "reaction", "realize", - "rebound", "rebuild", "recall", "receiver", "recover", "regret", - "regular", "reject", "relate", "remember", "remind", "remove", - "render", "repair", "repeat", "replace", "require", "rescue", - "research", "resident", "response", "result", "retailer", "retreat", - "reunion", "revenue", "review", "reward", "rhyme", "rhythm", - "rich", "rival", "river", "robin", "rocky", "romantic", - "romp", "roster", "round", "royal", "ruin", "ruler", - "rumor", "sack", "safari", "salary", "salon", "salt", - "satisfy", "satoshi", "saver", "says", "scandal", "scared", - "scatter", "scene", "scholar", "science", "scout", "scramble", - "screw", "script", "scroll", "seafood", "season", "secret", - "security", "segment", "senior", "shadow", "shaft", "shame", - "shaped", "sharp", "shelter", "sheriff", "short", "should", - "shrimp", "sidewalk", "silent", "silver", "similar", "simple", - "single", "sister", "skin", "skunk", "slap", "slavery", - "sled", "slice", "slim", "slow", "slush", "smart", - "smear", "smell", "smirk", "smith", "smoking", "smug", - "snake", "snapshot", "sniff", "society", "software", "soldier", - "solution", "soul", "source", "space", "spark", "speak", - "species", "spelling", "spend", "spew", "spider", "spill", - "spine", "spirit", "spit", "spray", "sprinkle", "square", - "squeeze", "stadium", "staff", "standard", "starting", "station", - "stay", "steady", "step", "stick", "stilt", "story", - "strategy", "strike", "style", "subject", "submit", "sugar", - "suitable", "sunlight", "superior", "surface", "surprise", "survive", - "sweater", "swimming", "swing", "switch", "symbolic", "sympathy", - "syndrome", "system", "tackle", "tactics", "tadpole", "talent", - "task", "taste", "taught", "taxi", "teacher", "teammate", - "teaspoon", "temple", "tenant", "tendency", "tension", "terminal", - "testify", "texture", "thank", "that", "theater", "theory", - "therapy", "thorn", "threaten", "thumb", "thunder", "ticket", - "tidy", "timber", "timely", "ting", "tofu", "together", - "tolerate", "total", "toxic", "tracks", "traffic", "training", - "transfer", "trash", "traveler", "treat", "trend", "trial", - "tricycle", "trip", "triumph", "trouble", "true", "trust", - "twice", "twin", "type", "typical", "ugly", "ultimate", - "umbrella", "uncover", "undergo", "unfair", "unfold", "unhappy", - "union", "universe", "unkind", "unknown", "unusual", "unwrap", - "upgrade", "upstairs", "username", "usher", "usual", "valid", - "valuable", "vampire", "vanish", "various", "vegan", "velvet", - "venture", "verdict", "verify", "very", "veteran", "vexed", - "victim", "video", "view", "vintage", "violence", "viral", - "visitor", "visual", "vitamins", "vocal", "voice", "volume", - "voter", "voting", "walnut", "warmth", "warn", "watch", - "wavy", "wealthy", "weapon", "webcam", "welcome", "welfare", - "western", "width", "wildlife", "window", "wine", "wireless", - "wisdom", "withdraw", "wits", "wolf", "woman", "work", - "worthy", "wrap", "wrist", "writing", "wrote", "year", - "yelp", "yield", "yoga", "zero", + "academic", "acid", "acne", "acquire", "acrobat", "activity", "actress", "adapt", + "adequate", "adjust", "admit", "adorn", "adult", "advance", "advocate", "afraid", + "again", "agency", "agree", "aide", "aircraft", "airline", "airport", "ajar", + "alarm", "album", "alcohol", "alien", "alive", "alpha", "already", "alto", + "aluminum", "always", "amazing", "ambition", "amount", "amuse", "analysis", "anatomy", + "ancestor", "ancient", "angel", "angry", "animal", "answer", "antenna", "anxiety", + "apart", "aquatic", "arcade", "arena", "argue", "armed", "artist", "artwork", + "aspect", "auction", "august", "aunt", "average", "aviation", "avoid", "award", + "away", "axis", "axle", "beam", "beard", "beaver", "become", "bedroom", + "behavior", "being", "believe", "belong", "benefit", "best", "beyond", "bike", + "biology", "birthday", "bishop", "black", "blanket", "blessing", "blimp", "blind", + "blue", "body", "bolt", "boring", "born", "both", "boundary", "bracelet", + "branch", "brave", "breathe", "briefing", "broken", "brother", "browser", "bucket", + "budget", "building", "bulb", "bulge", "bumpy", "bundle", "burden", "burning", + "busy", "buyer", "cage", "calcium", "camera", "campus", "canyon", "capacity", + "capital", "capture", "carbon", "cards", "careful", "cargo", "carpet", "carve", + "category", "cause", "ceiling", "center", "ceramic", "champion", "change", "charity", + "check", "chemical", "chest", "chew", "chubby", "cinema", "civil", "class", + "clay", "cleanup", "client", "climate", "clinic", "clock", "clogs", "closet", + "clothes", "club", "cluster", "coal", "coastal", "coding", "column", "company", + "corner", "costume", "counter", "course", "cover", "cowboy", "cradle", "craft", + "crazy", "credit", "cricket", "criminal", "crisis", "critical", "crowd", "crucial", + "crunch", "crush", "crystal", "cubic", "cultural", "curious", "curly", "custody", + "cylinder", "daisy", "damage", "dance", "darkness", "database", "daughter", "deadline", + "deal", "debris", "debut", "decent", "decision", "declare", "decorate", "decrease", + "deliver", "demand", "density", "deny", "depart", "depend", "depict", "deploy", + "describe", "desert", "desire", "desktop", "destroy", "detailed", "detect", "device", + "devote", "diagnose", "dictate", "diet", "dilemma", "diminish", "dining", "diploma", + "disaster", "discuss", "disease", "dish", "dismiss", "display", "distance", "dive", + "divorce", "document", "domain", "domestic", "dominant", "dough", "downtown", "dragon", + "dramatic", "dream", "dress", "drift", "drink", "drove", "drug", "dryer", + "duckling", "duke", "duration", "dwarf", "dynamic", "early", "earth", "easel", + "easy", "echo", "eclipse", "ecology", "edge", "editor", "educate", "either", + "elbow", "elder", "election", "elegant", "element", "elephant", "elevator", "elite", + "else", "email", "emerald", "emission", "emperor", "emphasis", "employer", "empty", + "ending", "endless", "endorse", "enemy", "energy", "enforce", "engage", "enjoy", + "enlarge", "entrance", "envelope", "envy", "epidemic", "episode", "equation", "equip", + "eraser", "erode", "escape", "estate", "estimate", "evaluate", "evening", "evidence", + "evil", "evoke", "exact", "example", "exceed", "exchange", "exclude", "excuse", + "execute", "exercise", "exhaust", "exotic", "expand", "expect", "explain", "express", + "extend", "extra", "eyebrow", "facility", "fact", "failure", "faint", "fake", + "false", "family", "famous", "fancy", "fangs", "fantasy", "fatal", "fatigue", + "favorite", "fawn", "fiber", "fiction", "filter", "finance", "findings", "finger", + "firefly", "firm", "fiscal", "fishing", "fitness", "flame", "flash", "flavor", + "flea", "flexible", "flip", "float", "floral", "fluff", "focus", "forbid", + "force", "forecast", "forget", "formal", "fortune", "forward", "founder", "fraction", + "fragment", "frequent", "freshman", "friar", "fridge", "friendly", "frost", "froth", + "frozen", "fumes", "funding", "furl", "fused", "galaxy", "game", "garbage", + "garden", "garlic", "gasoline", "gather", "general", "genius", "genre", "genuine", + "geology", "gesture", "glad", "glance", "glasses", "glen", "glimpse", "goat", + "golden", "graduate", "grant", "grasp", "gravity", "gray", "greatest", "grief", + "grill", "grin", "grocery", "gross", "group", "grownup", "grumpy", "guard", + "guest", "guilt", "guitar", "gums", "hairy", "hamster", "hand", "hanger", + "harvest", "have", "havoc", "hawk", "hazard", "headset", "health", "hearing", + "heat", "helpful", "herald", "herd", "hesitate", "hobo", "holiday", "holy", + "home", "hormone", "hospital", "hour", "huge", "human", "humidity", "hunting", + "husband", "hush", "husky", "hybrid", "idea", "identify", "idle", "image", + "impact", "imply", "improve", "impulse", "include", "income", "increase", "index", + "indicate", "industry", "infant", "inform", "inherit", "injury", "inmate", "insect", + "inside", "install", "intend", "intimate", "invasion", "involve", "iris", "island", + "isolate", "item", "ivory", "jacket", "jerky", "jewelry", "join", "judicial", + "juice", "jump", "junction", "junior", "junk", "jury", "justice", "kernel", + "keyboard", "kidney", "kind", "kitchen", "knife", "knit", "laden", "ladle", + "ladybug", "lair", "lamp", "language", "large", "laser", "laundry", "lawsuit", + "leader", "leaf", "learn", "leaves", "lecture", "legal", "legend", "legs", + "lend", "length", "level", "liberty", "library", "license", "lift", "likely", + "lilac", "lily", "lips", "liquid", "listen", "literary", "living", "lizard", + "loan", "lobe", "location", "losing", "loud", "loyalty", "luck", "lunar", + "lunch", "lungs", "luxury", "lying", "lyrics", "machine", "magazine", "maiden", + "mailman", "main", "makeup", "making", "mama", "manager", "mandate", "mansion", + "manual", "marathon", "march", "market", "marvel", "mason", "material", "math", + "maximum", "mayor", "meaning", "medal", "medical", "member", "memory", "mental", + "merchant", "merit", "method", "metric", "midst", "mild", "military", "mineral", + "minister", "miracle", "mixed", "mixture", "mobile", "modern", "modify", "moisture", + "moment", "morning", "mortgage", "mother", "mountain", "mouse", "move", "much", + "mule", "multiple", "muscle", "museum", "music", "mustang", "nail", "national", + "necklace", "negative", "nervous", "network", "news", "nuclear", "numb", "numerous", + "nylon", "oasis", "obesity", "object", "observe", "obtain", "ocean", "often", + "olympic", "omit", "oral", "orange", "orbit", "order", "ordinary", "organize", + "ounce", "oven", "overall", "owner", "paces", "pacific", "package", "paid", + "painting", "pajamas", "pancake", "pants", "papa", "paper", "parcel", "parking", + "party", "patent", "patrol", "payment", "payroll", "peaceful", "peanut", "peasant", + "pecan", "penalty", "pencil", "percent", "perfect", "permit", "petition", "phantom", + "pharmacy", "photo", "phrase", "physics", "pickup", "picture", "piece", "pile", + "pink", "pipeline", "pistol", "pitch", "plains", "plan", "plastic", "platform", + "playoff", "pleasure", "plot", "plunge", "practice", "prayer", "preach", "predator", + "pregnant", "premium", "prepare", "presence", "prevent", "priest", "primary", "priority", + "prisoner", "privacy", "prize", "problem", "process", "profile", "program", "promise", + "prospect", "provide", "prune", "public", "pulse", "pumps", "punish", "puny", + "pupal", "purchase", "purple", "python", "quantity", "quarter", "quick", "quiet", + "race", "racism", "radar", "railroad", "rainbow", "raisin", "random", "ranked", + "rapids", "raspy", "reaction", "realize", "rebound", "rebuild", "recall", "receiver", + "recover", "regret", "regular", "reject", "relate", "remember", "remind", "remove", + "render", "repair", "repeat", "replace", "require", "rescue", "research", "resident", + "response", "result", "retailer", "retreat", "reunion", "revenue", "review", "reward", + "rhyme", "rhythm", "rich", "rival", "river", "robin", "rocky", "romantic", + "romp", "roster", "round", "royal", "ruin", "ruler", "rumor", "sack", + "safari", "salary", "salon", "salt", "satisfy", "satoshi", "saver", "says", + "scandal", "scared", "scatter", "scene", "scholar", "science", "scout", "scramble", + "screw", "script", "scroll", "seafood", "season", "secret", "security", "segment", + "senior", "shadow", "shaft", "shame", "shaped", "sharp", "shelter", "sheriff", + "short", "should", "shrimp", "sidewalk", "silent", "silver", "similar", "simple", + "single", "sister", "skin", "skunk", "slap", "slavery", "sled", "slice", + "slim", "slow", "slush", "smart", "smear", "smell", "smirk", "smith", + "smoking", "smug", "snake", "snapshot", "sniff", "society", "software", "soldier", + "solution", "soul", "source", "space", "spark", "speak", "species", "spelling", + "spend", "spew", "spider", "spill", "spine", "spirit", "spit", "spray", + "sprinkle", "square", "squeeze", "stadium", "staff", "standard", "starting", "station", + "stay", "steady", "step", "stick", "stilt", "story", "strategy", "strike", + "style", "subject", "submit", "sugar", "suitable", "sunlight", "superior", "surface", + "surprise", "survive", "sweater", "swimming", "swing", "switch", "symbolic", "sympathy", + "syndrome", "system", "tackle", "tactics", "tadpole", "talent", "task", "taste", + "taught", "taxi", "teacher", "teammate", "teaspoon", "temple", "tenant", "tendency", + "tension", "terminal", "testify", "texture", "thank", "that", "theater", "theory", + "therapy", "thorn", "threaten", "thumb", "thunder", "ticket", "tidy", "timber", + "timely", "ting", "tofu", "together", "tolerate", "total", "toxic", "tracks", + "traffic", "training", "transfer", "trash", "traveler", "treat", "trend", "trial", + "tricycle", "trip", "triumph", "trouble", "true", "trust", "twice", "twin", + "type", "typical", "ugly", "ultimate", "umbrella", "uncover", "undergo", "unfair", + "unfold", "unhappy", "union", "universe", "unkind", "unknown", "unusual", "unwrap", + "upgrade", "upstairs", "username", "usher", "usual", "valid", "valuable", "vampire", + "vanish", "various", "vegan", "velvet", "venture", "verdict", "verify", "very", + "veteran", "vexed", "victim", "video", "view", "vintage", "violence", "viral", + "visitor", "visual", "vitamins", "vocal", "voice", "volume", "voter", "voting", + "walnut", "warmth", "warn", "watch", "wavy", "wealthy", "weapon", "webcam", + "welcome", "welfare", "western", "width", "wildlife", "window", "wine", "wireless", + "wisdom", "withdraw", "wits", "wolf", "woman", "work", "worthy", "wrap", + "wrist", "writing", "wrote", "year", "yelp", "yield", "yoga", "zero", }; /** @@ -214,1033 +171,1033 @@ static const char* const slip39_wordlist[WORDS_COUNT] = { * Each word is uniquely defined by four buttons. */ static const struct { - uint16_t sequence; - uint16_t index; + uint16_t sequence; + uint16_t index; } words_button_seq[WORDS_COUNT] = { - {1212, 0}, // academic - {1216, 7}, // adapt - {1236, 8}, // adequate - {1242, 1}, // acid - {1248, 9}, // adjust - {1254, 10}, // admit - {1263, 2}, // acne - {1267, 11}, // adorn - {1268, 3}, // acquire - {1276, 4}, // acrobat - {1281, 13}, // advance - {1284, 5}, // activity - {1285, 12}, // adult - {1286, 14}, // advocate - {1287, 6}, // actress - {1315, 67}, // beam - {1317, 68}, // beard - {1318, 69}, // beaver - {1326, 70}, // become - {1327, 71}, // bedroom - {1341, 72}, // behavior - {1346, 73}, // being - {1354, 74}, // believe - {1356, 75}, // belong - {1363, 76}, // benefit - {1371, 15}, // afraid - {1378, 77}, // best - {1396, 78}, // beyond - {1414, 16}, // again - {1417, 23}, // ajar - {1423, 19}, // aide - {1436, 17}, // agency - {1453, 79}, // bike - {1465, 80}, // biology - {1472, 20}, // aircraft - {1473, 18}, // agree - {1474, 82}, // bishop - {1475, 21}, // airline - {1476, 22}, // airport - {1478, 81}, // birthday - {1512, 83}, // black - {1514, 35}, // ambition - {1516, 84}, // blanket - {1517, 24}, // alarm - {1518, 25}, // album - {1519, 34}, // amazing - {1526, 26}, // alcohol - {1537, 85}, // blessing - {1543, 27}, // alien - {1545, 86}, // blimp - {1546, 87}, // blind - {1548, 28}, // alive - {1564, 29}, // alpha - {1568, 36}, // amount - {1573, 30}, // already - {1583, 88}, // blue - {1585, 32}, // aluminum - {1586, 31}, // alto - {1587, 37}, // amuse - {1591, 33}, // always - {1615, 38}, // analysis - {1617, 48}, // apart - {1618, 39}, // anatomy - {1623, 40}, // ancestor - {1624, 41}, // ancient - {1629, 89}, // body - {1643, 42}, // angel - {1645, 44}, // animal - {1647, 43}, // angry - {1658, 90}, // bolt - {1674, 91}, // boring - {1676, 92}, // born - {1679, 45}, // answer - {1681, 49}, // aquatic - {1683, 46}, // antenna - {1684, 93}, // both - {1686, 94}, // boundary - {1694, 47}, // anxiety - {1712, 95}, // bracelet - {1716, 96}, // branch - {1718, 97}, // brave - {1721, 50}, // arcade - {1731, 98}, // breathe - {1736, 51}, // arena - {1743, 99}, // briefing - {1748, 52}, // argue - {1753, 53}, // armed - {1763, 56}, // aspect - {1765, 100}, // broken - {1768, 101}, // brother - {1769, 102}, // browser - {1784, 54}, // artist - {1789, 55}, // artwork - {1824, 104}, // budget - {1825, 103}, // bucket - {1828, 57}, // auction - {1837, 60}, // average - {1841, 61}, // aviation - {1845, 105}, // building - {1848, 58}, // august - {1851, 106}, // bulb - {1854, 107}, // bulge - {1856, 108}, // bumpy - {1862, 109}, // bundle - {1864, 62}, // avoid - {1868, 59}, // aunt - {1872, 110}, // burden - {1876, 111}, // burning - {1879, 112}, // busy - {1893, 113}, // buyer - {1917, 63}, // award - {1919, 64}, // away - {1947, 65}, // axis - {1953, 66}, // axle - {2143, 114}, // cage - {2147, 185}, // daisy - {2151, 186}, // damage - {2152, 115}, // calcium - {2153, 116}, // camera - {2156, 117}, // campus - {2161, 119}, // capacity - {2162, 187}, // dance - {2164, 120}, // capital - {2168, 121}, // capture - {2169, 118}, // canyon - {2171, 122}, // carbon - {2172, 123}, // cards - {2173, 124}, // careful - {2174, 125}, // cargo - {2175, 188}, // darkness - {2176, 126}, // carpet - {2178, 127}, // carve - {2181, 189}, // database - {2183, 128}, // category - {2184, 190}, // daughter - {2187, 129}, // cause - {2312, 191}, // deadline - {2315, 192}, // deal - {2317, 193}, // debris - {2318, 194}, // debut - {2323, 195}, // decent - {2324, 196}, // decision - {2325, 197}, // declare - {2326, 198}, // decorate - {2327, 199}, // decrease - {2345, 130}, // ceiling - {2351, 201}, // demand - {2354, 200}, // deliver - {2361, 204}, // depart - {2363, 205}, // depend - {2364, 206}, // depict - {2365, 207}, // deploy - {2367, 202}, // density - {2368, 131}, // center - {2369, 203}, // deny - {2371, 132}, // ceramic - {2372, 208}, // describe - {2373, 209}, // desert - {2374, 210}, // desire - {2375, 211}, // desktop - {2378, 212}, // destroy - {2381, 213}, // detailed - {2383, 214}, // detect - {2384, 215}, // device - {2386, 216}, // devote - {2414, 217}, // diagnose - {2415, 133}, // champion - {2416, 134}, // change - {2417, 135}, // charity - {2428, 218}, // dictate - {2432, 136}, // check - {2435, 137}, // chemical - {2437, 138}, // chest - {2438, 219}, // diet - {2439, 139}, // chew - {2453, 220}, // dilemma - {2454, 221}, // diminish - {2463, 141}, // cinema - {2464, 222}, // dining - {2465, 223}, // diploma - {2471, 224}, // disaster - {2472, 225}, // discuss - {2473, 226}, // disease - {2474, 227}, // dish - {2475, 228}, // dismiss - {2476, 229}, // display - {2478, 230}, // distance - {2481, 140}, // chubby - {2483, 231}, // dive - {2484, 142}, // civil - {2486, 232}, // divorce - {2517, 143}, // class - {2519, 144}, // clay - {2531, 145}, // cleanup - {2543, 146}, // client - {2545, 147}, // climate - {2546, 148}, // clinic - {2562, 149}, // clock - {2564, 150}, // clogs - {2567, 151}, // closet - {2568, 152}, // clothes - {2581, 153}, // club - {2587, 154}, // cluster - {2615, 155}, // coal - {2617, 156}, // coastal - {2624, 157}, // coding - {2628, 233}, // document - {2651, 234}, // domain - {2653, 235}, // domestic - {2654, 236}, // dominant - {2656, 159}, // company - {2658, 158}, // column - {2676, 160}, // corner - {2678, 161}, // costume - {2683, 164}, // cover - {2684, 237}, // dough - {2686, 162}, // counter - {2687, 163}, // course - {2691, 165}, // cowboy - {2696, 238}, // downtown - {2712, 166}, // cradle - {2713, 167}, // craft - {2714, 239}, // dragon - {2715, 240}, // dramatic - {2719, 168}, // crazy - {2731, 241}, // dream - {2732, 169}, // credit - {2737, 242}, // dress - {2742, 170}, // cricket - {2743, 243}, // drift - {2745, 171}, // criminal - {2746, 244}, // drink - {2747, 172}, // crisis - {2748, 173}, // critical - {2768, 245}, // drove - {2769, 174}, // crowd - {2782, 175}, // crucial - {2784, 246}, // drug - {2786, 176}, // crunch - {2787, 177}, // crush - {2793, 247}, // dryer - {2797, 178}, // crystal - {2814, 179}, // cubic - {2825, 248}, // duckling - {2853, 249}, // duke - {2858, 180}, // cultural - {2871, 250}, // duration - {2874, 181}, // curious - {2875, 182}, // curly - {2878, 183}, // custody - {2917, 251}, // dwarf - {2954, 184}, // cylinder - {2961, 252}, // dynamic - {3124, 323}, // facility - {3128, 324}, // fact - {3145, 325}, // failure - {3146, 326}, // faint - {3153, 327}, // fake - {3154, 329}, // family - {3156, 330}, // famous - {3157, 328}, // false - {3162, 331}, // fancy - {3164, 332}, // fangs - {3168, 333}, // fantasy - {3173, 255}, // easel - {3175, 253}, // early - {3178, 254}, // earth - {3179, 256}, // easy - {3181, 334}, // fatal - {3184, 335}, // fatigue - {3186, 336}, // favorite - {3196, 337}, // fawn - {3243, 260}, // edge - {3246, 257}, // echo - {3248, 261}, // editor - {3254, 258}, // eclipse - {3265, 259}, // ecology - {3282, 262}, // educate - {3413, 338}, // fiber - {3428, 339}, // fiction - {3458, 340}, // filter - {3461, 341}, // finance - {3462, 342}, // findings - {3464, 343}, // finger - {3472, 346}, // fiscal - {3473, 344}, // firefly - {3474, 347}, // fishing - {3475, 345}, // firm - {3484, 263}, // either - {3486, 348}, // fitness - {3514, 273}, // email - {3515, 349}, // flame - {3516, 264}, // elbow - {3517, 350}, // flash - {3518, 351}, // flavor - {3523, 265}, // elder - {3531, 352}, // flea - {3532, 266}, // election - {3534, 267}, // elegant - {3535, 268}, // element - {3536, 269}, // elephant - {3537, 274}, // emerald - {3538, 270}, // elevator - {3539, 353}, // flexible - {3546, 354}, // flip - {3547, 275}, // emission - {3548, 271}, // elite - {3561, 355}, // float - {3563, 276}, // emperor - {3564, 277}, // emphasis - {3565, 278}, // employer - {3567, 356}, // floral - {3568, 279}, // empty - {3573, 272}, // else - {3583, 357}, // fluff - {3624, 280}, // ending - {3625, 281}, // endless - {3626, 282}, // endorse - {3628, 358}, // focus - {3635, 283}, // enemy - {3636, 285}, // enforce - {3637, 284}, // energy - {3641, 286}, // engage - {3642, 292}, // epidemic - {3646, 287}, // enjoy - {3647, 293}, // episode - {3651, 288}, // enlarge - {3671, 359}, // forbid - {3672, 360}, // force - {3673, 361}, // forecast - {3674, 362}, // forget - {3675, 363}, // formal - {3678, 364}, // fortune - {3679, 365}, // forward - {3681, 294}, // equation - {3683, 290}, // envelope - {3684, 295}, // equip - {3686, 366}, // founder - {3687, 289}, // entrance - {3689, 291}, // envy - {3712, 367}, // fraction - {3714, 368}, // fragment - {3717, 296}, // eraser - {3721, 298}, // escape - {3736, 369}, // frequent - {3737, 370}, // freshman - {3741, 371}, // friar - {3742, 372}, // fridge - {3743, 373}, // friendly - {3762, 297}, // erode - {3767, 374}, // frost - {3768, 375}, // froth - {3769, 376}, // frozen - {3781, 299}, // estate - {3784, 300}, // estimate - {3815, 301}, // evaluate - {3836, 302}, // evening - {3842, 303}, // evidence - {3845, 304}, // evil - {3853, 377}, // fumes - {3862, 378}, // funding - {3865, 305}, // evoke - {3873, 380}, // fused - {3875, 379}, // furl - {3912, 306}, // exact - {3915, 307}, // example - {3923, 308}, // exceed - {3924, 309}, // exchange - {3925, 310}, // exclude - {3928, 311}, // excuse - {3931, 322}, // eyebrow - {3932, 312}, // execute - {3937, 313}, // exercise - {3941, 314}, // exhaust - {3961, 316}, // expand - {3963, 317}, // expect - {3965, 318}, // explain - {3967, 319}, // express - {3968, 315}, // exotic - {3983, 320}, // extend - {3987, 321}, // extra - {4125, 483}, // jacket - {4147, 420}, // hairy - {4151, 381}, // galaxy - {4153, 382}, // game - {4157, 421}, // hamster - {4162, 422}, // hand - {4164, 423}, // hanger - {4171, 383}, // garbage - {4172, 384}, // garden - {4175, 385}, // garlic - {4176, 386}, // gasoline - {4178, 424}, // harvest - {4183, 425}, // have - {4184, 387}, // gather - {4186, 426}, // havoc - {4191, 428}, // hazard - {4195, 427}, // hawk - {4231, 452}, // idea - {4236, 453}, // identify - {4253, 454}, // idle - {4312, 429}, // headset - {4315, 430}, // health - {4317, 431}, // hearing - {4318, 432}, // heat - {4356, 433}, // helpful - {4363, 388}, // general - {4364, 389}, // genius - {4365, 392}, // geology - {4367, 390}, // genre - {4368, 391}, // genuine - {4371, 434}, // herald - {4372, 435}, // herd - {4374, 436}, // hesitate - {4375, 484}, // jerky - {4378, 393}, // gesture - {4393, 485}, // jewelry - {4512, 394}, // glad - {4514, 455}, // image - {4516, 395}, // glance - {4517, 396}, // glasses - {4536, 397}, // glen - {4545, 398}, // glimpse - {4561, 456}, // impact - {4565, 457}, // imply - {4567, 458}, // improve - {4568, 459}, // impulse - {4616, 437}, // hobo - {4618, 399}, // goat - {4623, 463}, // index - {4624, 464}, // indicate - {4625, 460}, // include - {4626, 461}, // income - {4627, 462}, // increase - {4628, 465}, // industry - {4631, 466}, // infant - {4636, 467}, // inform - {4643, 468}, // inherit - {4646, 486}, // join - {4648, 469}, // injury - {4651, 470}, // inmate - {4652, 400}, // golden - {4653, 440}, // home - {4654, 438}, // holiday - {4659, 439}, // holy - {4673, 471}, // insect - {4674, 472}, // inside - {4675, 441}, // hormone - {4676, 442}, // hospital - {4678, 473}, // install - {4681, 476}, // invasion - {4683, 474}, // intend - {4684, 475}, // intimate - {4686, 477}, // involve - {4687, 443}, // hour - {4712, 401}, // graduate - {4716, 402}, // grant - {4717, 403}, // grasp - {4718, 404}, // gravity - {4719, 405}, // gray - {4731, 406}, // greatest - {4743, 407}, // grief - {4745, 408}, // grill - {4746, 409}, // grin - {4747, 478}, // iris - {4751, 479}, // island - {4762, 410}, // grocery - {4765, 480}, // isolate - {4767, 411}, // gross - {4768, 412}, // group - {4769, 413}, // grownup - {4785, 414}, // grumpy - {4817, 415}, // guard - {4824, 487}, // judicial - {4835, 481}, // item - {4837, 416}, // guest - {4842, 488}, // juice - {4843, 444}, // huge - {4845, 417}, // guilt - {4848, 418}, // guitar - {4851, 445}, // human - {4854, 446}, // humidity - {4856, 489}, // jump - {4857, 419}, // gums - {4862, 490}, // junction - {4864, 491}, // junior - {4865, 492}, // junk - {4867, 482}, // ivory - {4868, 447}, // hunting - {4871, 448}, // husband - {4874, 449}, // hush - {4875, 450}, // husky - {4878, 494}, // justice - {4879, 493}, // jury - {4917, 451}, // hybrid - {5123, 502}, // laden - {5124, 549}, // machine - {5125, 503}, // ladle - {5129, 504}, // ladybug - {5141, 550}, // magazine - {5142, 551}, // maiden - {5145, 552}, // mailman - {5146, 553}, // main - {5147, 505}, // lair - {5151, 556}, // mama - {5153, 554}, // makeup - {5154, 555}, // making - {5156, 506}, // lamp - {5161, 557}, // manager - {5162, 558}, // mandate - {5164, 507}, // language - {5167, 559}, // mansion - {5168, 560}, // manual - {5171, 561}, // marathon - {5172, 562}, // march - {5173, 509}, // laser - {5174, 508}, // large - {5175, 563}, // market - {5176, 565}, // mason - {5178, 564}, // marvel - {5183, 566}, // material - {5184, 567}, // math - {5186, 510}, // laundry - {5194, 568}, // maximum - {5196, 569}, // mayor - {5197, 511}, // lawsuit - {5312, 512}, // leader - {5313, 513}, // leaf - {5316, 570}, // meaning - {5317, 514}, // learn - {5318, 515}, // leaves - {5321, 571}, // medal - {5324, 572}, // medical - {5328, 516}, // lecture - {5341, 517}, // legal - {5343, 518}, // legend - {5347, 519}, // legs - {5351, 573}, // member - {5356, 574}, // memory - {5362, 520}, // lend - {5364, 521}, // length - {5368, 575}, // mental - {5372, 576}, // merchant - {5374, 577}, // merit - {5376, 495}, // kernel - {5383, 522}, // level - {5384, 578}, // method - {5387, 579}, // metric - {5391, 496}, // keyboard - {5413, 523}, // liberty - {5417, 524}, // library - {5423, 525}, // license - {5426, 497}, // kidney - {5427, 580}, // midst - {5438, 526}, // lift - {5451, 528}, // lilac - {5452, 581}, // mild - {5453, 527}, // likely - {5454, 582}, // military - {5459, 529}, // lily - {5462, 498}, // kind - {5463, 583}, // mineral - {5464, 584}, // minister - {5467, 530}, // lips - {5468, 531}, // liquid - {5471, 585}, // miracle - {5478, 532}, // listen - {5482, 499}, // kitchen - {5483, 533}, // literary - {5484, 534}, // living - {5491, 535}, // lizard - {5493, 586}, // mixed - {5498, 587}, // mixture - {5613, 537}, // lobe - {5614, 588}, // mobile - {5616, 536}, // loan - {5621, 538}, // location - {5623, 589}, // modern - {5624, 590}, // modify - {5643, 500}, // knife - {5647, 591}, // moisture - {5648, 501}, // knit - {5653, 592}, // moment - {5674, 539}, // losing - {5676, 593}, // morning - {5678, 594}, // mortgage - {5682, 540}, // loud - {5683, 598}, // move - {5684, 595}, // mother - {5686, 596}, // mountain - {5687, 597}, // mouse - {5691, 541}, // loyalty - {5824, 599}, // much - {5825, 542}, // luck - {5853, 600}, // mule - {5858, 601}, // multiple - {5861, 543}, // lunar - {5862, 544}, // lunch - {5864, 545}, // lungs - {5872, 602}, // muscle - {5873, 603}, // museum - {5874, 604}, // music - {5878, 605}, // mustang - {5898, 546}, // luxury - {5946, 547}, // lying - {5974, 548}, // lyrics - {6123, 636}, // paces - {6124, 637}, // pacific - {6125, 638}, // package - {6137, 618}, // obesity - {6141, 641}, // pajamas - {6142, 639}, // paid - {6143, 619}, // object - {6145, 606}, // nail - {6146, 640}, // painting - {6161, 644}, // papa - {6162, 642}, // pancake - {6163, 645}, // paper - {6168, 643}, // pants - {6172, 646}, // parcel - {6173, 620}, // observe - {6174, 617}, // oasis - {6175, 647}, // parking - {6178, 648}, // party - {6181, 621}, // obtain - {6183, 649}, // patent - {6184, 607}, // national - {6187, 650}, // patrol - {6195, 651}, // payment - {6197, 652}, // payroll - {6231, 622}, // ocean - {6312, 653}, // peaceful - {6316, 654}, // peanut - {6317, 655}, // peasant - {6321, 656}, // pecan - {6325, 608}, // necklace - {6341, 609}, // negative - {6361, 657}, // penalty - {6362, 658}, // pencil - {6372, 659}, // percent - {6373, 660}, // perfect - {6375, 661}, // permit - {6378, 610}, // nervous - {6383, 623}, // often - {6384, 662}, // petition - {6389, 611}, // network - {6397, 612}, // news - {6416, 663}, // phantom - {6417, 664}, // pharmacy - {6425, 668}, // pickup - {6428, 669}, // picture - {6432, 670}, // piece - {6453, 671}, // pile - {6463, 673}, // pipeline - {6465, 672}, // pink - {6468, 665}, // photo - {6471, 666}, // phrase - {6478, 674}, // pistol - {6482, 675}, // pitch - {6497, 667}, // physics - {6514, 676}, // plains - {6516, 677}, // plan - {6517, 678}, // plastic - {6518, 679}, // platform - {6519, 680}, // playoff - {6531, 681}, // pleasure - {6548, 625}, // omit - {6568, 682}, // plot - {6586, 683}, // plunge - {6595, 624}, // olympic - {6712, 684}, // practice - {6714, 628}, // orbit - {6715, 626}, // oral - {6716, 627}, // orange - {6719, 685}, // prayer - {6723, 629}, // order - {6724, 630}, // ordinary - {6731, 686}, // preach - {6732, 687}, // predator - {6734, 688}, // pregnant - {6735, 689}, // premium - {6736, 690}, // prepare - {6737, 691}, // presence - {6738, 692}, // prevent - {6741, 631}, // organize - {6743, 693}, // priest - {6745, 694}, // primary - {6746, 695}, // priority - {6747, 696}, // prisoner - {6748, 697}, // privacy - {6749, 698}, // prize - {6761, 699}, // problem - {6762, 700}, // process - {6763, 701}, // profile - {6764, 702}, // program - {6765, 703}, // promise - {6767, 704}, // prospect - {6768, 705}, // provide - {6786, 706}, // prune - {6815, 707}, // public - {6816, 716}, // quantity - {6817, 717}, // quarter - {6825, 613}, // nuclear - {6836, 633}, // oven - {6837, 634}, // overall - {6842, 718}, // quick - {6843, 719}, // quiet - {6851, 614}, // numb - {6853, 615}, // numerous - {6856, 709}, // pumps - {6857, 708}, // pulse - {6861, 712}, // pupal - {6862, 632}, // ounce - {6864, 710}, // punish - {6869, 711}, // puny - {6872, 713}, // purchase - {6876, 714}, // purple - {6956, 616}, // nylon - {6963, 635}, // owner - {6984, 715}, // python - {7121, 722}, // radar - {7123, 720}, // race - {7124, 721}, // racism - {7125, 775}, // sack - {7131, 776}, // safari - {7145, 723}, // railroad - {7146, 724}, // rainbow - {7147, 725}, // raisin - {7151, 777}, // salary - {7156, 778}, // salon - {7158, 779}, // salt - {7162, 726}, // random - {7164, 728}, // rapids - {7165, 727}, // ranked - {7176, 729}, // raspy - {7183, 782}, // saver - {7184, 780}, // satisfy - {7186, 781}, // satoshi - {7197, 783}, // says - {7216, 784}, // scandal - {7217, 785}, // scared - {7218, 786}, // scatter - {7236, 787}, // scene - {7243, 789}, // science - {7246, 788}, // scholar - {7268, 790}, // scout - {7271, 791}, // scramble - {7273, 792}, // screw - {7274, 793}, // script - {7276, 794}, // scroll - {7312, 730}, // reaction - {7313, 795}, // seafood - {7315, 731}, // realize - {7316, 732}, // rebound - {7317, 796}, // season - {7318, 733}, // rebuild - {7321, 734}, // recall - {7323, 735}, // receiver - {7326, 736}, // recover - {7327, 797}, // secret - {7328, 798}, // security - {7343, 739}, // reject - {7345, 799}, // segment - {7347, 737}, // regret - {7348, 738}, // regular - {7351, 740}, // relate - {7353, 741}, // remember - {7354, 742}, // remind - {7356, 743}, // remove - {7361, 745}, // repair - {7362, 744}, // render - {7363, 746}, // repeat - {7364, 800}, // senior - {7365, 747}, // replace - {7368, 748}, // require - {7372, 749}, // rescue - {7373, 750}, // research - {7374, 751}, // resident - {7376, 752}, // response - {7378, 753}, // result - {7381, 754}, // retailer - {7383, 757}, // revenue - {7384, 758}, // review - {7386, 756}, // reunion - {7387, 755}, // retreat - {7391, 759}, // reward - {7412, 801}, // shadow - {7413, 802}, // shaft - {7415, 803}, // shame - {7416, 804}, // shaped - {7417, 805}, // sharp - {7423, 811}, // sidewalk - {7424, 762}, // rich - {7435, 806}, // shelter - {7437, 807}, // sheriff - {7453, 812}, // silent - {7454, 814}, // similar - {7456, 815}, // simple - {7458, 813}, // silver - {7464, 816}, // single - {7467, 808}, // short - {7468, 809}, // should - {7474, 810}, // shrimp - {7478, 817}, // sister - {7481, 763}, // rival - {7483, 764}, // river - {7495, 760}, // rhyme - {7498, 761}, // rhythm - {7516, 820}, // slap - {7517, 827}, // smart - {7518, 821}, // slavery - {7531, 828}, // smear - {7532, 822}, // sled - {7535, 829}, // smell - {7542, 823}, // slice - {7545, 824}, // slim - {7546, 818}, // skin - {7547, 830}, // smirk - {7548, 831}, // smith - {7565, 832}, // smoking - {7569, 825}, // slow - {7584, 833}, // smug - {7586, 819}, // skunk - {7587, 826}, // slush - {7612, 843}, // space - {7614, 765}, // robin - {7615, 834}, // snake - {7616, 835}, // snapshot - {7617, 844}, // spark - {7624, 837}, // society - {7625, 766}, // rocky - {7631, 845}, // speak - {7632, 846}, // species - {7635, 847}, // spelling - {7636, 848}, // spend - {7638, 838}, // software - {7639, 849}, // spew - {7642, 850}, // spider - {7643, 836}, // sniff - {7645, 851}, // spill - {7646, 852}, // spine - {7647, 853}, // spirit - {7648, 854}, // spit - {7651, 767}, // romantic - {7652, 839}, // soldier - {7656, 768}, // romp - {7658, 840}, // solution - {7671, 855}, // spray - {7674, 856}, // sprinkle - {7678, 769}, // roster - {7681, 857}, // square - {7683, 858}, // squeeze - {7685, 841}, // soul - {7686, 770}, // round - {7687, 842}, // source - {7691, 771}, // royal - {7812, 859}, // stadium - {7813, 860}, // staff - {7814, 873}, // subject - {7815, 874}, // submit - {7816, 861}, // standard - {7817, 862}, // starting - {7818, 863}, // station - {7819, 864}, // stay - {7831, 865}, // steady - {7836, 866}, // step - {7841, 875}, // sugar - {7842, 867}, // stick - {7845, 868}, // stilt - {7846, 772}, // ruin - {7848, 876}, // suitable - {7853, 773}, // ruler - {7856, 774}, // rumor - {7863, 878}, // superior - {7865, 877}, // sunlight - {7867, 869}, // story - {7871, 870}, // strategy - {7873, 879}, // surface - {7874, 871}, // strike - {7876, 880}, // surprise - {7878, 881}, // survive - {7895, 872}, // style - {7931, 882}, // sweater - {7945, 883}, // swimming - {7946, 884}, // swing - {7948, 885}, // switch - {7951, 886}, // symbolic - {7956, 887}, // sympathy - {7962, 888}, // syndrome - {7978, 889}, // system - {8125, 890}, // tackle - {8126, 892}, // tadpole - {8128, 891}, // tactics - {8153, 893}, // talent - {8154, 965}, // valid - {8156, 967}, // vampire - {8158, 966}, // valuable - {8164, 968}, // vanish - {8174, 969}, // various - {8175, 894}, // task - {8178, 895}, // taste - {8184, 896}, // taught - {8194, 897}, // taxi - {8312, 898}, // teacher - {8315, 899}, // teammate - {8317, 900}, // teaspoon - {8341, 970}, // vegan - {8356, 901}, // temple - {8358, 971}, // velvet - {8361, 902}, // tenant - {8362, 903}, // tendency - {8367, 904}, // tension - {8368, 972}, // venture - {8372, 973}, // verdict - {8374, 974}, // verify - {8375, 905}, // terminal - {8378, 906}, // testify - {8379, 975}, // very - {8383, 976}, // veteran - {8393, 977}, // vexed - {8398, 907}, // texture - {8416, 908}, // thank - {8418, 909}, // that - {8423, 979}, // video - {8425, 917}, // ticket - {8428, 978}, // victim - {8429, 918}, // tidy - {8431, 910}, // theater - {8436, 911}, // theory - {8437, 912}, // therapy - {8439, 980}, // view - {8451, 919}, // timber - {8453, 920}, // timely - {8459, 946}, // ugly - {8464, 921}, // ting - {8465, 982}, // violence - {8467, 913}, // thorn - {8468, 981}, // vintage - {8471, 983}, // viral - {8473, 914}, // threaten - {8474, 984}, // visitor - {8478, 985}, // visual - {8481, 986}, // vitamins - {8485, 915}, // thumb - {8486, 916}, // thunder - {8517, 948}, // umbrella - {8584, 947}, // ultimate - {8621, 987}, // vocal - {8623, 950}, // undergo - {8626, 949}, // uncover - {8631, 951}, // unfair - {8636, 952}, // unfold - {8638, 922}, // tofu - {8641, 953}, // unhappy - {8642, 988}, // voice - {8643, 923}, // together - {8646, 954}, // union - {8647, 960}, // upgrade - {8648, 955}, // universe - {8653, 924}, // tolerate - {8654, 956}, // unkind - {8656, 957}, // unknown - {8658, 989}, // volume - {8678, 961}, // upstairs - {8681, 925}, // total - {8683, 990}, // voter - {8684, 991}, // voting - {8687, 958}, // unusual - {8694, 926}, // toxic - {8697, 959}, // unwrap - {8712, 927}, // tracks - {8713, 928}, // traffic - {8714, 929}, // training - {8716, 930}, // transfer - {8717, 931}, // trash - {8718, 932}, // traveler - {8731, 933}, // treat - {8736, 934}, // trend - {8737, 962}, // username - {8741, 935}, // trial - {8742, 936}, // tricycle - {8743, 963}, // usher - {8746, 937}, // trip - {8748, 938}, // triumph - {8768, 939}, // trouble - {8781, 964}, // usual - {8783, 940}, // true - {8787, 941}, // trust - {8942, 942}, // twice - {8946, 943}, // twin - {8963, 944}, // type - {8964, 945}, // typical - {9156, 992}, // walnut - {9175, 993}, // warmth - {9176, 994}, // warn - {9182, 995}, // watch - {9189, 996}, // wavy - {9312, 999}, // webcam - {9315, 997}, // wealthy - {9316, 998}, // weapon - {9317, 1019}, // year - {9352, 1000}, // welcome - {9353, 1001}, // welfare - {9356, 1020}, // yelp - {9376, 1023}, // zero - {9378, 1002}, // western - {9428, 1003}, // width - {9435, 1021}, // yield - {9452, 1004}, // wildlife - {9462, 1005}, // window - {9463, 1006}, // wine - {9472, 1008}, // wisdom - {9473, 1007}, // wireless - {9484, 1009}, // withdraw - {9487, 1010}, // wits - {9641, 1022}, // yoga - {9651, 1012}, // woman - {9653, 1011}, // wolf - {9675, 1013}, // work - {9678, 1014}, // worthy - {9716, 1015}, // wrap - {9747, 1016}, // wrist - {9748, 1017}, // writing - {9768, 1018}, // wrote + {1212, 0}, // academic + {1216, 7}, // adapt + {1236, 8}, // adequate + {1242, 1}, // acid + {1248, 9}, // adjust + {1254, 10}, // admit + {1263, 2}, // acne + {1267, 11}, // adorn + {1268, 3}, // acquire + {1276, 4}, // acrobat + {1281, 13}, // advance + {1284, 5}, // activity + {1285, 12}, // adult + {1286, 14}, // advocate + {1287, 6}, // actress + {1315, 67}, // beam + {1317, 68}, // beard + {1318, 69}, // beaver + {1326, 70}, // become + {1327, 71}, // bedroom + {1341, 72}, // behavior + {1346, 73}, // being + {1354, 74}, // believe + {1356, 75}, // belong + {1363, 76}, // benefit + {1371, 15}, // afraid + {1378, 77}, // best + {1396, 78}, // beyond + {1414, 16}, // again + {1417, 23}, // ajar + {1423, 19}, // aide + {1436, 17}, // agency + {1453, 79}, // bike + {1465, 80}, // biology + {1472, 20}, // aircraft + {1473, 18}, // agree + {1474, 82}, // bishop + {1475, 21}, // airline + {1476, 22}, // airport + {1478, 81}, // birthday + {1512, 83}, // black + {1514, 35}, // ambition + {1516, 84}, // blanket + {1517, 24}, // alarm + {1518, 25}, // album + {1519, 34}, // amazing + {1526, 26}, // alcohol + {1537, 85}, // blessing + {1543, 27}, // alien + {1545, 86}, // blimp + {1546, 87}, // blind + {1548, 28}, // alive + {1564, 29}, // alpha + {1568, 36}, // amount + {1573, 30}, // already + {1583, 88}, // blue + {1585, 32}, // aluminum + {1586, 31}, // alto + {1587, 37}, // amuse + {1591, 33}, // always + {1615, 38}, // analysis + {1617, 48}, // apart + {1618, 39}, // anatomy + {1623, 40}, // ancestor + {1624, 41}, // ancient + {1629, 89}, // body + {1643, 42}, // angel + {1645, 44}, // animal + {1647, 43}, // angry + {1658, 90}, // bolt + {1674, 91}, // boring + {1676, 92}, // born + {1679, 45}, // answer + {1681, 49}, // aquatic + {1683, 46}, // antenna + {1684, 93}, // both + {1686, 94}, // boundary + {1694, 47}, // anxiety + {1712, 95}, // bracelet + {1716, 96}, // branch + {1718, 97}, // brave + {1721, 50}, // arcade + {1731, 98}, // breathe + {1736, 51}, // arena + {1743, 99}, // briefing + {1748, 52}, // argue + {1753, 53}, // armed + {1763, 56}, // aspect + {1765, 100}, // broken + {1768, 101}, // brother + {1769, 102}, // browser + {1784, 54}, // artist + {1789, 55}, // artwork + {1824, 104}, // budget + {1825, 103}, // bucket + {1828, 57}, // auction + {1837, 60}, // average + {1841, 61}, // aviation + {1845, 105}, // building + {1848, 58}, // august + {1851, 106}, // bulb + {1854, 107}, // bulge + {1856, 108}, // bumpy + {1862, 109}, // bundle + {1864, 62}, // avoid + {1868, 59}, // aunt + {1872, 110}, // burden + {1876, 111}, // burning + {1879, 112}, // busy + {1893, 113}, // buyer + {1917, 63}, // award + {1919, 64}, // away + {1947, 65}, // axis + {1953, 66}, // axle + {2143, 114}, // cage + {2147, 185}, // daisy + {2151, 186}, // damage + {2152, 115}, // calcium + {2153, 116}, // camera + {2156, 117}, // campus + {2161, 119}, // capacity + {2162, 187}, // dance + {2164, 120}, // capital + {2168, 121}, // capture + {2169, 118}, // canyon + {2171, 122}, // carbon + {2172, 123}, // cards + {2173, 124}, // careful + {2174, 125}, // cargo + {2175, 188}, // darkness + {2176, 126}, // carpet + {2178, 127}, // carve + {2181, 189}, // database + {2183, 128}, // category + {2184, 190}, // daughter + {2187, 129}, // cause + {2312, 191}, // deadline + {2315, 192}, // deal + {2317, 193}, // debris + {2318, 194}, // debut + {2323, 195}, // decent + {2324, 196}, // decision + {2325, 197}, // declare + {2326, 198}, // decorate + {2327, 199}, // decrease + {2345, 130}, // ceiling + {2351, 201}, // demand + {2354, 200}, // deliver + {2361, 204}, // depart + {2363, 205}, // depend + {2364, 206}, // depict + {2365, 207}, // deploy + {2367, 202}, // density + {2368, 131}, // center + {2369, 203}, // deny + {2371, 132}, // ceramic + {2372, 208}, // describe + {2373, 209}, // desert + {2374, 210}, // desire + {2375, 211}, // desktop + {2378, 212}, // destroy + {2381, 213}, // detailed + {2383, 214}, // detect + {2384, 215}, // device + {2386, 216}, // devote + {2414, 217}, // diagnose + {2415, 133}, // champion + {2416, 134}, // change + {2417, 135}, // charity + {2428, 218}, // dictate + {2432, 136}, // check + {2435, 137}, // chemical + {2437, 138}, // chest + {2438, 219}, // diet + {2439, 139}, // chew + {2453, 220}, // dilemma + {2454, 221}, // diminish + {2463, 141}, // cinema + {2464, 222}, // dining + {2465, 223}, // diploma + {2471, 224}, // disaster + {2472, 225}, // discuss + {2473, 226}, // disease + {2474, 227}, // dish + {2475, 228}, // dismiss + {2476, 229}, // display + {2478, 230}, // distance + {2481, 140}, // chubby + {2483, 231}, // dive + {2484, 142}, // civil + {2486, 232}, // divorce + {2517, 143}, // class + {2519, 144}, // clay + {2531, 145}, // cleanup + {2543, 146}, // client + {2545, 147}, // climate + {2546, 148}, // clinic + {2562, 149}, // clock + {2564, 150}, // clogs + {2567, 151}, // closet + {2568, 152}, // clothes + {2581, 153}, // club + {2587, 154}, // cluster + {2615, 155}, // coal + {2617, 156}, // coastal + {2624, 157}, // coding + {2628, 233}, // document + {2651, 234}, // domain + {2653, 235}, // domestic + {2654, 236}, // dominant + {2656, 159}, // company + {2658, 158}, // column + {2676, 160}, // corner + {2678, 161}, // costume + {2683, 164}, // cover + {2684, 237}, // dough + {2686, 162}, // counter + {2687, 163}, // course + {2691, 165}, // cowboy + {2696, 238}, // downtown + {2712, 166}, // cradle + {2713, 167}, // craft + {2714, 239}, // dragon + {2715, 240}, // dramatic + {2719, 168}, // crazy + {2731, 241}, // dream + {2732, 169}, // credit + {2737, 242}, // dress + {2742, 170}, // cricket + {2743, 243}, // drift + {2745, 171}, // criminal + {2746, 244}, // drink + {2747, 172}, // crisis + {2748, 173}, // critical + {2768, 245}, // drove + {2769, 174}, // crowd + {2782, 175}, // crucial + {2784, 246}, // drug + {2786, 176}, // crunch + {2787, 177}, // crush + {2793, 247}, // dryer + {2797, 178}, // crystal + {2814, 179}, // cubic + {2825, 248}, // duckling + {2853, 249}, // duke + {2858, 180}, // cultural + {2871, 250}, // duration + {2874, 181}, // curious + {2875, 182}, // curly + {2878, 183}, // custody + {2917, 251}, // dwarf + {2954, 184}, // cylinder + {2961, 252}, // dynamic + {3124, 323}, // facility + {3128, 324}, // fact + {3145, 325}, // failure + {3146, 326}, // faint + {3153, 327}, // fake + {3154, 329}, // family + {3156, 330}, // famous + {3157, 328}, // false + {3162, 331}, // fancy + {3164, 332}, // fangs + {3168, 333}, // fantasy + {3173, 255}, // easel + {3175, 253}, // early + {3178, 254}, // earth + {3179, 256}, // easy + {3181, 334}, // fatal + {3184, 335}, // fatigue + {3186, 336}, // favorite + {3196, 337}, // fawn + {3243, 260}, // edge + {3246, 257}, // echo + {3248, 261}, // editor + {3254, 258}, // eclipse + {3265, 259}, // ecology + {3282, 262}, // educate + {3413, 338}, // fiber + {3428, 339}, // fiction + {3458, 340}, // filter + {3461, 341}, // finance + {3462, 342}, // findings + {3464, 343}, // finger + {3472, 346}, // fiscal + {3473, 344}, // firefly + {3474, 347}, // fishing + {3475, 345}, // firm + {3484, 263}, // either + {3486, 348}, // fitness + {3514, 273}, // email + {3515, 349}, // flame + {3516, 264}, // elbow + {3517, 350}, // flash + {3518, 351}, // flavor + {3523, 265}, // elder + {3531, 352}, // flea + {3532, 266}, // election + {3534, 267}, // elegant + {3535, 268}, // element + {3536, 269}, // elephant + {3537, 274}, // emerald + {3538, 270}, // elevator + {3539, 353}, // flexible + {3546, 354}, // flip + {3547, 275}, // emission + {3548, 271}, // elite + {3561, 355}, // float + {3563, 276}, // emperor + {3564, 277}, // emphasis + {3565, 278}, // employer + {3567, 356}, // floral + {3568, 279}, // empty + {3573, 272}, // else + {3583, 357}, // fluff + {3624, 280}, // ending + {3625, 281}, // endless + {3626, 282}, // endorse + {3628, 358}, // focus + {3635, 283}, // enemy + {3636, 285}, // enforce + {3637, 284}, // energy + {3641, 286}, // engage + {3642, 292}, // epidemic + {3646, 287}, // enjoy + {3647, 293}, // episode + {3651, 288}, // enlarge + {3671, 359}, // forbid + {3672, 360}, // force + {3673, 361}, // forecast + {3674, 362}, // forget + {3675, 363}, // formal + {3678, 364}, // fortune + {3679, 365}, // forward + {3681, 294}, // equation + {3683, 290}, // envelope + {3684, 295}, // equip + {3686, 366}, // founder + {3687, 289}, // entrance + {3689, 291}, // envy + {3712, 367}, // fraction + {3714, 368}, // fragment + {3717, 296}, // eraser + {3721, 298}, // escape + {3736, 369}, // frequent + {3737, 370}, // freshman + {3741, 371}, // friar + {3742, 372}, // fridge + {3743, 373}, // friendly + {3762, 297}, // erode + {3767, 374}, // frost + {3768, 375}, // froth + {3769, 376}, // frozen + {3781, 299}, // estate + {3784, 300}, // estimate + {3815, 301}, // evaluate + {3836, 302}, // evening + {3842, 303}, // evidence + {3845, 304}, // evil + {3853, 377}, // fumes + {3862, 378}, // funding + {3865, 305}, // evoke + {3873, 380}, // fused + {3875, 379}, // furl + {3912, 306}, // exact + {3915, 307}, // example + {3923, 308}, // exceed + {3924, 309}, // exchange + {3925, 310}, // exclude + {3928, 311}, // excuse + {3931, 322}, // eyebrow + {3932, 312}, // execute + {3937, 313}, // exercise + {3941, 314}, // exhaust + {3961, 316}, // expand + {3963, 317}, // expect + {3965, 318}, // explain + {3967, 319}, // express + {3968, 315}, // exotic + {3983, 320}, // extend + {3987, 321}, // extra + {4125, 483}, // jacket + {4147, 420}, // hairy + {4151, 381}, // galaxy + {4153, 382}, // game + {4157, 421}, // hamster + {4162, 422}, // hand + {4164, 423}, // hanger + {4171, 383}, // garbage + {4172, 384}, // garden + {4175, 385}, // garlic + {4176, 386}, // gasoline + {4178, 424}, // harvest + {4183, 425}, // have + {4184, 387}, // gather + {4186, 426}, // havoc + {4191, 428}, // hazard + {4195, 427}, // hawk + {4231, 452}, // idea + {4236, 453}, // identify + {4253, 454}, // idle + {4312, 429}, // headset + {4315, 430}, // health + {4317, 431}, // hearing + {4318, 432}, // heat + {4356, 433}, // helpful + {4363, 388}, // general + {4364, 389}, // genius + {4365, 392}, // geology + {4367, 390}, // genre + {4368, 391}, // genuine + {4371, 434}, // herald + {4372, 435}, // herd + {4374, 436}, // hesitate + {4375, 484}, // jerky + {4378, 393}, // gesture + {4393, 485}, // jewelry + {4512, 394}, // glad + {4514, 455}, // image + {4516, 395}, // glance + {4517, 396}, // glasses + {4536, 397}, // glen + {4545, 398}, // glimpse + {4561, 456}, // impact + {4565, 457}, // imply + {4567, 458}, // improve + {4568, 459}, // impulse + {4616, 437}, // hobo + {4618, 399}, // goat + {4623, 463}, // index + {4624, 464}, // indicate + {4625, 460}, // include + {4626, 461}, // income + {4627, 462}, // increase + {4628, 465}, // industry + {4631, 466}, // infant + {4636, 467}, // inform + {4643, 468}, // inherit + {4646, 486}, // join + {4648, 469}, // injury + {4651, 470}, // inmate + {4652, 400}, // golden + {4653, 440}, // home + {4654, 438}, // holiday + {4659, 439}, // holy + {4673, 471}, // insect + {4674, 472}, // inside + {4675, 441}, // hormone + {4676, 442}, // hospital + {4678, 473}, // install + {4681, 476}, // invasion + {4683, 474}, // intend + {4684, 475}, // intimate + {4686, 477}, // involve + {4687, 443}, // hour + {4712, 401}, // graduate + {4716, 402}, // grant + {4717, 403}, // grasp + {4718, 404}, // gravity + {4719, 405}, // gray + {4731, 406}, // greatest + {4743, 407}, // grief + {4745, 408}, // grill + {4746, 409}, // grin + {4747, 478}, // iris + {4751, 479}, // island + {4762, 410}, // grocery + {4765, 480}, // isolate + {4767, 411}, // gross + {4768, 412}, // group + {4769, 413}, // grownup + {4785, 414}, // grumpy + {4817, 415}, // guard + {4824, 487}, // judicial + {4835, 481}, // item + {4837, 416}, // guest + {4842, 488}, // juice + {4843, 444}, // huge + {4845, 417}, // guilt + {4848, 418}, // guitar + {4851, 445}, // human + {4854, 446}, // humidity + {4856, 489}, // jump + {4857, 419}, // gums + {4862, 490}, // junction + {4864, 491}, // junior + {4865, 492}, // junk + {4867, 482}, // ivory + {4868, 447}, // hunting + {4871, 448}, // husband + {4874, 449}, // hush + {4875, 450}, // husky + {4878, 494}, // justice + {4879, 493}, // jury + {4917, 451}, // hybrid + {5123, 502}, // laden + {5124, 549}, // machine + {5125, 503}, // ladle + {5129, 504}, // ladybug + {5141, 550}, // magazine + {5142, 551}, // maiden + {5145, 552}, // mailman + {5146, 553}, // main + {5147, 505}, // lair + {5151, 556}, // mama + {5153, 554}, // makeup + {5154, 555}, // making + {5156, 506}, // lamp + {5161, 557}, // manager + {5162, 558}, // mandate + {5164, 507}, // language + {5167, 559}, // mansion + {5168, 560}, // manual + {5171, 561}, // marathon + {5172, 562}, // march + {5173, 509}, // laser + {5174, 508}, // large + {5175, 563}, // market + {5176, 565}, // mason + {5178, 564}, // marvel + {5183, 566}, // material + {5184, 567}, // math + {5186, 510}, // laundry + {5194, 568}, // maximum + {5196, 569}, // mayor + {5197, 511}, // lawsuit + {5312, 512}, // leader + {5313, 513}, // leaf + {5316, 570}, // meaning + {5317, 514}, // learn + {5318, 515}, // leaves + {5321, 571}, // medal + {5324, 572}, // medical + {5328, 516}, // lecture + {5341, 517}, // legal + {5343, 518}, // legend + {5347, 519}, // legs + {5351, 573}, // member + {5356, 574}, // memory + {5362, 520}, // lend + {5364, 521}, // length + {5368, 575}, // mental + {5372, 576}, // merchant + {5374, 577}, // merit + {5376, 495}, // kernel + {5383, 522}, // level + {5384, 578}, // method + {5387, 579}, // metric + {5391, 496}, // keyboard + {5413, 523}, // liberty + {5417, 524}, // library + {5423, 525}, // license + {5426, 497}, // kidney + {5427, 580}, // midst + {5438, 526}, // lift + {5451, 528}, // lilac + {5452, 581}, // mild + {5453, 527}, // likely + {5454, 582}, // military + {5459, 529}, // lily + {5462, 498}, // kind + {5463, 583}, // mineral + {5464, 584}, // minister + {5467, 530}, // lips + {5468, 531}, // liquid + {5471, 585}, // miracle + {5478, 532}, // listen + {5482, 499}, // kitchen + {5483, 533}, // literary + {5484, 534}, // living + {5491, 535}, // lizard + {5493, 586}, // mixed + {5498, 587}, // mixture + {5613, 537}, // lobe + {5614, 588}, // mobile + {5616, 536}, // loan + {5621, 538}, // location + {5623, 589}, // modern + {5624, 590}, // modify + {5643, 500}, // knife + {5647, 591}, // moisture + {5648, 501}, // knit + {5653, 592}, // moment + {5674, 539}, // losing + {5676, 593}, // morning + {5678, 594}, // mortgage + {5682, 540}, // loud + {5683, 598}, // move + {5684, 595}, // mother + {5686, 596}, // mountain + {5687, 597}, // mouse + {5691, 541}, // loyalty + {5824, 599}, // much + {5825, 542}, // luck + {5853, 600}, // mule + {5858, 601}, // multiple + {5861, 543}, // lunar + {5862, 544}, // lunch + {5864, 545}, // lungs + {5872, 602}, // muscle + {5873, 603}, // museum + {5874, 604}, // music + {5878, 605}, // mustang + {5898, 546}, // luxury + {5946, 547}, // lying + {5974, 548}, // lyrics + {6123, 636}, // paces + {6124, 637}, // pacific + {6125, 638}, // package + {6137, 618}, // obesity + {6141, 641}, // pajamas + {6142, 639}, // paid + {6143, 619}, // object + {6145, 606}, // nail + {6146, 640}, // painting + {6161, 644}, // papa + {6162, 642}, // pancake + {6163, 645}, // paper + {6168, 643}, // pants + {6172, 646}, // parcel + {6173, 620}, // observe + {6174, 617}, // oasis + {6175, 647}, // parking + {6178, 648}, // party + {6181, 621}, // obtain + {6183, 649}, // patent + {6184, 607}, // national + {6187, 650}, // patrol + {6195, 651}, // payment + {6197, 652}, // payroll + {6231, 622}, // ocean + {6312, 653}, // peaceful + {6316, 654}, // peanut + {6317, 655}, // peasant + {6321, 656}, // pecan + {6325, 608}, // necklace + {6341, 609}, // negative + {6361, 657}, // penalty + {6362, 658}, // pencil + {6372, 659}, // percent + {6373, 660}, // perfect + {6375, 661}, // permit + {6378, 610}, // nervous + {6383, 623}, // often + {6384, 662}, // petition + {6389, 611}, // network + {6397, 612}, // news + {6416, 663}, // phantom + {6417, 664}, // pharmacy + {6425, 668}, // pickup + {6428, 669}, // picture + {6432, 670}, // piece + {6453, 671}, // pile + {6463, 673}, // pipeline + {6465, 672}, // pink + {6468, 665}, // photo + {6471, 666}, // phrase + {6478, 674}, // pistol + {6482, 675}, // pitch + {6497, 667}, // physics + {6514, 676}, // plains + {6516, 677}, // plan + {6517, 678}, // plastic + {6518, 679}, // platform + {6519, 680}, // playoff + {6531, 681}, // pleasure + {6548, 625}, // omit + {6568, 682}, // plot + {6586, 683}, // plunge + {6595, 624}, // olympic + {6712, 684}, // practice + {6714, 628}, // orbit + {6715, 626}, // oral + {6716, 627}, // orange + {6719, 685}, // prayer + {6723, 629}, // order + {6724, 630}, // ordinary + {6731, 686}, // preach + {6732, 687}, // predator + {6734, 688}, // pregnant + {6735, 689}, // premium + {6736, 690}, // prepare + {6737, 691}, // presence + {6738, 692}, // prevent + {6741, 631}, // organize + {6743, 693}, // priest + {6745, 694}, // primary + {6746, 695}, // priority + {6747, 696}, // prisoner + {6748, 697}, // privacy + {6749, 698}, // prize + {6761, 699}, // problem + {6762, 700}, // process + {6763, 701}, // profile + {6764, 702}, // program + {6765, 703}, // promise + {6767, 704}, // prospect + {6768, 705}, // provide + {6786, 706}, // prune + {6815, 707}, // public + {6816, 716}, // quantity + {6817, 717}, // quarter + {6825, 613}, // nuclear + {6836, 633}, // oven + {6837, 634}, // overall + {6842, 718}, // quick + {6843, 719}, // quiet + {6851, 614}, // numb + {6853, 615}, // numerous + {6856, 709}, // pumps + {6857, 708}, // pulse + {6861, 712}, // pupal + {6862, 632}, // ounce + {6864, 710}, // punish + {6869, 711}, // puny + {6872, 713}, // purchase + {6876, 714}, // purple + {6956, 616}, // nylon + {6963, 635}, // owner + {6984, 715}, // python + {7121, 722}, // radar + {7123, 720}, // race + {7124, 721}, // racism + {7125, 775}, // sack + {7131, 776}, // safari + {7145, 723}, // railroad + {7146, 724}, // rainbow + {7147, 725}, // raisin + {7151, 777}, // salary + {7156, 778}, // salon + {7158, 779}, // salt + {7162, 726}, // random + {7164, 728}, // rapids + {7165, 727}, // ranked + {7176, 729}, // raspy + {7183, 782}, // saver + {7184, 780}, // satisfy + {7186, 781}, // satoshi + {7197, 783}, // says + {7216, 784}, // scandal + {7217, 785}, // scared + {7218, 786}, // scatter + {7236, 787}, // scene + {7243, 789}, // science + {7246, 788}, // scholar + {7268, 790}, // scout + {7271, 791}, // scramble + {7273, 792}, // screw + {7274, 793}, // script + {7276, 794}, // scroll + {7312, 730}, // reaction + {7313, 795}, // seafood + {7315, 731}, // realize + {7316, 732}, // rebound + {7317, 796}, // season + {7318, 733}, // rebuild + {7321, 734}, // recall + {7323, 735}, // receiver + {7326, 736}, // recover + {7327, 797}, // secret + {7328, 798}, // security + {7343, 739}, // reject + {7345, 799}, // segment + {7347, 737}, // regret + {7348, 738}, // regular + {7351, 740}, // relate + {7353, 741}, // remember + {7354, 742}, // remind + {7356, 743}, // remove + {7361, 745}, // repair + {7362, 744}, // render + {7363, 746}, // repeat + {7364, 800}, // senior + {7365, 747}, // replace + {7368, 748}, // require + {7372, 749}, // rescue + {7373, 750}, // research + {7374, 751}, // resident + {7376, 752}, // response + {7378, 753}, // result + {7381, 754}, // retailer + {7383, 757}, // revenue + {7384, 758}, // review + {7386, 756}, // reunion + {7387, 755}, // retreat + {7391, 759}, // reward + {7412, 801}, // shadow + {7413, 802}, // shaft + {7415, 803}, // shame + {7416, 804}, // shaped + {7417, 805}, // sharp + {7423, 811}, // sidewalk + {7424, 762}, // rich + {7435, 806}, // shelter + {7437, 807}, // sheriff + {7453, 812}, // silent + {7454, 814}, // similar + {7456, 815}, // simple + {7458, 813}, // silver + {7464, 816}, // single + {7467, 808}, // short + {7468, 809}, // should + {7474, 810}, // shrimp + {7478, 817}, // sister + {7481, 763}, // rival + {7483, 764}, // river + {7495, 760}, // rhyme + {7498, 761}, // rhythm + {7516, 820}, // slap + {7517, 827}, // smart + {7518, 821}, // slavery + {7531, 828}, // smear + {7532, 822}, // sled + {7535, 829}, // smell + {7542, 823}, // slice + {7545, 824}, // slim + {7546, 818}, // skin + {7547, 830}, // smirk + {7548, 831}, // smith + {7565, 832}, // smoking + {7569, 825}, // slow + {7584, 833}, // smug + {7586, 819}, // skunk + {7587, 826}, // slush + {7612, 843}, // space + {7614, 765}, // robin + {7615, 834}, // snake + {7616, 835}, // snapshot + {7617, 844}, // spark + {7624, 837}, // society + {7625, 766}, // rocky + {7631, 845}, // speak + {7632, 846}, // species + {7635, 847}, // spelling + {7636, 848}, // spend + {7638, 838}, // software + {7639, 849}, // spew + {7642, 850}, // spider + {7643, 836}, // sniff + {7645, 851}, // spill + {7646, 852}, // spine + {7647, 853}, // spirit + {7648, 854}, // spit + {7651, 767}, // romantic + {7652, 839}, // soldier + {7656, 768}, // romp + {7658, 840}, // solution + {7671, 855}, // spray + {7674, 856}, // sprinkle + {7678, 769}, // roster + {7681, 857}, // square + {7683, 858}, // squeeze + {7685, 841}, // soul + {7686, 770}, // round + {7687, 842}, // source + {7691, 771}, // royal + {7812, 859}, // stadium + {7813, 860}, // staff + {7814, 873}, // subject + {7815, 874}, // submit + {7816, 861}, // standard + {7817, 862}, // starting + {7818, 863}, // station + {7819, 864}, // stay + {7831, 865}, // steady + {7836, 866}, // step + {7841, 875}, // sugar + {7842, 867}, // stick + {7845, 868}, // stilt + {7846, 772}, // ruin + {7848, 876}, // suitable + {7853, 773}, // ruler + {7856, 774}, // rumor + {7863, 878}, // superior + {7865, 877}, // sunlight + {7867, 869}, // story + {7871, 870}, // strategy + {7873, 879}, // surface + {7874, 871}, // strike + {7876, 880}, // surprise + {7878, 881}, // survive + {7895, 872}, // style + {7931, 882}, // sweater + {7945, 883}, // swimming + {7946, 884}, // swing + {7948, 885}, // switch + {7951, 886}, // symbolic + {7956, 887}, // sympathy + {7962, 888}, // syndrome + {7978, 889}, // system + {8125, 890}, // tackle + {8126, 892}, // tadpole + {8128, 891}, // tactics + {8153, 893}, // talent + {8154, 965}, // valid + {8156, 967}, // vampire + {8158, 966}, // valuable + {8164, 968}, // vanish + {8174, 969}, // various + {8175, 894}, // task + {8178, 895}, // taste + {8184, 896}, // taught + {8194, 897}, // taxi + {8312, 898}, // teacher + {8315, 899}, // teammate + {8317, 900}, // teaspoon + {8341, 970}, // vegan + {8356, 901}, // temple + {8358, 971}, // velvet + {8361, 902}, // tenant + {8362, 903}, // tendency + {8367, 904}, // tension + {8368, 972}, // venture + {8372, 973}, // verdict + {8374, 974}, // verify + {8375, 905}, // terminal + {8378, 906}, // testify + {8379, 975}, // very + {8383, 976}, // veteran + {8393, 977}, // vexed + {8398, 907}, // texture + {8416, 908}, // thank + {8418, 909}, // that + {8423, 979}, // video + {8425, 917}, // ticket + {8428, 978}, // victim + {8429, 918}, // tidy + {8431, 910}, // theater + {8436, 911}, // theory + {8437, 912}, // therapy + {8439, 980}, // view + {8451, 919}, // timber + {8453, 920}, // timely + {8459, 946}, // ugly + {8464, 921}, // ting + {8465, 982}, // violence + {8467, 913}, // thorn + {8468, 981}, // vintage + {8471, 983}, // viral + {8473, 914}, // threaten + {8474, 984}, // visitor + {8478, 985}, // visual + {8481, 986}, // vitamins + {8485, 915}, // thumb + {8486, 916}, // thunder + {8517, 948}, // umbrella + {8584, 947}, // ultimate + {8621, 987}, // vocal + {8623, 950}, // undergo + {8626, 949}, // uncover + {8631, 951}, // unfair + {8636, 952}, // unfold + {8638, 922}, // tofu + {8641, 953}, // unhappy + {8642, 988}, // voice + {8643, 923}, // together + {8646, 954}, // union + {8647, 960}, // upgrade + {8648, 955}, // universe + {8653, 924}, // tolerate + {8654, 956}, // unkind + {8656, 957}, // unknown + {8658, 989}, // volume + {8678, 961}, // upstairs + {8681, 925}, // total + {8683, 990}, // voter + {8684, 991}, // voting + {8687, 958}, // unusual + {8694, 926}, // toxic + {8697, 959}, // unwrap + {8712, 927}, // tracks + {8713, 928}, // traffic + {8714, 929}, // training + {8716, 930}, // transfer + {8717, 931}, // trash + {8718, 932}, // traveler + {8731, 933}, // treat + {8736, 934}, // trend + {8737, 962}, // username + {8741, 935}, // trial + {8742, 936}, // tricycle + {8743, 963}, // usher + {8746, 937}, // trip + {8748, 938}, // triumph + {8768, 939}, // trouble + {8781, 964}, // usual + {8783, 940}, // true + {8787, 941}, // trust + {8942, 942}, // twice + {8946, 943}, // twin + {8963, 944}, // type + {8964, 945}, // typical + {9156, 992}, // walnut + {9175, 993}, // warmth + {9176, 994}, // warn + {9182, 995}, // watch + {9189, 996}, // wavy + {9312, 999}, // webcam + {9315, 997}, // wealthy + {9316, 998}, // weapon + {9317, 1019}, // year + {9352, 1000}, // welcome + {9353, 1001}, // welfare + {9356, 1020}, // yelp + {9376, 1023}, // zero + {9378, 1002}, // western + {9428, 1003}, // width + {9435, 1021}, // yield + {9452, 1004}, // wildlife + {9462, 1005}, // window + {9463, 1006}, // wine + {9472, 1008}, // wisdom + {9473, 1007}, // wireless + {9484, 1009}, // withdraw + {9487, 1010}, // wits + {9641, 1022}, // yoga + {9651, 1012}, // woman + {9653, 1011}, // wolf + {9675, 1013}, // work + {9678, 1014}, // worthy + {9716, 1015}, // wrap + {9747, 1016}, // wrist + {9748, 1017}, // writing + {9768, 1018}, // wrote }; #endif diff --git a/flipbip.c b/flipbip.c index 5b164929e0d..c9aee49f948 100644 --- a/flipbip.c +++ b/flipbip.c @@ -23,7 +23,7 @@ FlipBip* flipbip_app_alloc() { FlipBip* app = malloc(sizeof(FlipBip)); app->gui = furi_record_open(RECORD_GUI); app->notification = furi_record_open(RECORD_NOTIFICATION); - + //Turn backlight on, believe me this makes testing your app easier notification_message(app->notification, &sequence_display_backlight_on); @@ -33,8 +33,10 @@ FlipBip* flipbip_app_alloc() { app->scene_manager = scene_manager_alloc(&flipbip_scene_handlers, app); view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_navigation_event_callback(app->view_dispatcher, flipbip_navigation_event_callback); - view_dispatcher_set_tick_event_callback(app->view_dispatcher, flipbip_tick_event_callback, 100); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, flipbip_navigation_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, flipbip_tick_event_callback, 100); view_dispatcher_set_custom_event_callback(app->view_dispatcher, flipbip_custom_event_callback); app->submenu = submenu_alloc(); @@ -45,13 +47,21 @@ FlipBip* flipbip_app_alloc() { app->bip44_coin = 0; // 0 (BTC) app->overwrite_saved_seed = 0; - view_dispatcher_add_view(app->view_dispatcher, FlipBipViewIdMenu, submenu_get_view(app->submenu)); + view_dispatcher_add_view( + app->view_dispatcher, FlipBipViewIdMenu, submenu_get_view(app->submenu)); app->flipbip_startscreen = flipbip_startscreen_alloc(); - view_dispatcher_add_view(app->view_dispatcher, FlipBipViewIdStartscreen, flipbip_startscreen_get_view(app->flipbip_startscreen)); + view_dispatcher_add_view( + app->view_dispatcher, + FlipBipViewIdStartscreen, + flipbip_startscreen_get_view(app->flipbip_startscreen)); app->flipbip_scene_1 = flipbip_scene_1_alloc(); - view_dispatcher_add_view(app->view_dispatcher, FlipBipViewIdScene1, flipbip_scene_1_get_view(app->flipbip_scene_1)); + view_dispatcher_add_view( + app->view_dispatcher, FlipBipViewIdScene1, flipbip_scene_1_get_view(app->flipbip_scene_1)); app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view(app->view_dispatcher, FlipBipViewIdSettings, variable_item_list_get_view(app->variable_item_list)); + view_dispatcher_add_view( + app->view_dispatcher, + FlipBipViewIdSettings, + variable_item_list_get_view(app->variable_item_list)); //End Scene Additions @@ -60,7 +70,7 @@ FlipBip* flipbip_app_alloc() { void flipbip_app_free(FlipBip* app) { furi_assert(app); - + // Scene manager scene_manager_free(app->scene_manager); @@ -73,7 +83,7 @@ void flipbip_app_free(FlipBip* app) { view_dispatcher_free(app->view_dispatcher); furi_record_close(RECORD_GUI); - + app->gui = NULL; app->notification = NULL; @@ -84,27 +94,25 @@ void flipbip_app_free(FlipBip* app) { int32_t flipbip_app(void* p) { UNUSED(p); FlipBip* app = flipbip_app_alloc(); - + // Disabled because causes exit on customer firmwares such as RM /*if(!furi_hal_region_is_provisioned()) { flipbip_app_free(app); return 1; }*/ - + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - scene_manager_next_scene(app->scene_manager, FlipBipSceneStartscreen); //Start with start screen + + scene_manager_next_scene( + app->scene_manager, FlipBipSceneStartscreen); //Start with start screen //scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); //if you want to directly start with Menu furi_hal_power_suppress_charge_enter(); view_dispatcher_run(app->view_dispatcher); - + furi_hal_power_suppress_charge_exit(); flipbip_app_free(app); return 0; } - - - diff --git a/flipbip.h b/flipbip.h index 3a239a855e9..2d020b38c75 100644 --- a/flipbip.h +++ b/flipbip.h @@ -23,7 +23,7 @@ typedef struct { VariableItemList* variable_item_list; FlipBipStartscreen* flipbip_startscreen; FlipBipScene1* flipbip_scene_1; - int haptic; + int haptic; int led; int bip39_strength; int bip44_coin; diff --git a/helpers/flipbip_file.c b/helpers/flipbip_file.c index 97d0ca02729..a6913255e7e 100644 --- a/helpers/flipbip_file.c +++ b/helpers/flipbip_file.c @@ -34,7 +34,7 @@ bool flipbip_load_settings(char* settings, bool key_file) { path = FLIPBIP_DAT_PATH; } - Storage *fs_api = furi_record_open(RECORD_STORAGE); + Storage* fs_api = furi_record_open(RECORD_STORAGE); File* settings_file = storage_file_alloc(fs_api); if(storage_file_open(settings_file, path, FSAM_READ, FSOM_OPEN_EXISTING)) { @@ -58,8 +58,7 @@ bool flipbip_load_settings(char* settings, bool key_file) { if(!strlen(settings) == 0) { Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo layout_file_info; - FS_Error file_check_err = storage_common_stat( - fs_api, path, &layout_file_info); + FS_Error file_check_err = storage_common_stat(fs_api, path, &layout_file_info); furi_record_close(RECORD_STORAGE); if(file_check_err != FSE_OK) { memzero(settings, strlen(settings)); @@ -121,10 +120,7 @@ bool flipbip_save_settings(const char* settings, bool key_file, bool append) { File* settings_file = storage_file_alloc(fs_api); if(storage_file_open(settings_file, path, FSAM_WRITE, open_mode)) { - storage_file_write( - settings_file, - settings, - strlen(settings)); + storage_file_write(settings_file, settings, strlen(settings)); storage_file_write(settings_file, "\n", 1); ret = true; } @@ -133,10 +129,7 @@ bool flipbip_save_settings(const char* settings, bool key_file, bool append) { File* settings_file_bak = storage_file_alloc(fs_api); if(storage_file_open(settings_file_bak, path_bak, FSAM_WRITE, open_mode)) { - storage_file_write( - settings_file_bak, - settings, - strlen(settings)); + storage_file_write(settings_file_bak, settings, strlen(settings)); storage_file_write(settings_file_bak, "\n", 1); } storage_file_close(settings_file_bak); @@ -149,16 +142,17 @@ bool flipbip_save_settings(const char* settings, bool key_file, bool append) { bool flipbip_load_settings_secure(char* settings) { const size_t dlen = FILE_HLEN + FILE_SLEN + 1; - + // allocate memory for key/data - char *data = malloc(dlen); + char* data = malloc(dlen); memzero(data, dlen); // load k2 from file - if (!flipbip_load_settings(data, true)) return false; + if(!flipbip_load_settings(data, true)) return false; // check header - if (data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] || data[3] != FILE_HSTR[3]) { + if(data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] || + data[3] != FILE_HSTR[3]) { memzero(data, dlen); free(data); return false; @@ -169,7 +163,7 @@ bool flipbip_load_settings_secure(char* settings) { // prepare k1 uint8_t k1[64]; flipbip_xtob(FILE_K1, k1, strlen(FILE_K1) / 2); - + // load k2 from file buffer (secured by k1) flipbip_cipher(k1, strlen(FILE_K1) / 2, data, data, FILE_KLEN); uint8_t k2[128]; @@ -180,10 +174,11 @@ bool flipbip_load_settings_secure(char* settings) { data -= FILE_HLEN; // load data from file - if (!flipbip_load_settings(data, false)) return false; + if(!flipbip_load_settings(data, false)) return false; // check header - if (data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] || data[3] != FILE_HSTR[3]) { + if(data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] || + data[3] != FILE_HSTR[3]) { memzero(data, dlen); free(data); memzero(k1, strlen(FILE_K1) / 2); @@ -202,7 +197,7 @@ bool flipbip_load_settings_secure(char* settings) { // seek <-- header data -= FILE_HLEN; - + // clear memory memzero(data, dlen); free(data); @@ -217,12 +212,12 @@ bool flipbip_save_settings_secure(const char* settings) { // cap settings to 256 bytes size_t len = strlen(settings); - if (len > (FILE_SLEN / 2)) len = FILE_SLEN / 2; - + if(len > (FILE_SLEN / 2)) len = FILE_SLEN / 2; + // allocate memory for key/data - char *data = malloc(dlen); + char* data = malloc(dlen); memzero(data, dlen); - + // write header strncpy(data, FILE_HSTR, FILE_HLEN); // seek --> header @@ -231,13 +226,13 @@ bool flipbip_save_settings_secure(const char* settings) { // prepare k1 uint8_t k1[64]; flipbip_xtob(FILE_K1, k1, strlen(FILE_K1) / 2); - + // generate k2 uint8_t k2[128]; random_buffer(k2, FILE_KLEN / 2); // write k2 to file buffer (secured by k1) - for (size_t i = 0; i < (FILE_KLEN / 2); i++) { + for(size_t i = 0; i < (FILE_KLEN / 2); i++) { flipbip_btox(k2[i], data + (i * 2)); } flipbip_cipher(k1, strlen(FILE_K1) / 2, data, data, FILE_KLEN); @@ -252,7 +247,7 @@ bool flipbip_save_settings_secure(const char* settings) { memzero(data, FILE_KLEN); // write settings to file buffer (secured by k2) - for (size_t i = 0; i < len; i++) { + for(size_t i = 0; i < len; i++) { flipbip_btox((uint8_t)settings[i], data + (i * 2)); } flipbip_cipher(k2, FILE_KLEN / 2, data, data, FILE_SLEN); diff --git a/helpers/flipbip_file.h b/helpers/flipbip_file.h index bf1c078f3b2..8440a26b196 100644 --- a/helpers/flipbip_file.h +++ b/helpers/flipbip_file.h @@ -2,7 +2,7 @@ bool flipbip_has_settings(bool key_file); bool flipbip_load_settings(char* settings, bool key_file); -bool flipbip_save_settings(const char* settings, bool key_file , bool append); +bool flipbip_save_settings(const char* settings, bool key_file, bool append); bool flipbip_load_settings_secure(char* settings); bool flipbip_save_settings_secure(const char* settings); \ No newline at end of file diff --git a/helpers/flipbip_haptic.c b/helpers/flipbip_haptic.c index 95f34f0afcf..c5608efa565 100644 --- a/helpers/flipbip_haptic.c +++ b/helpers/flipbip_haptic.c @@ -1,10 +1,9 @@ #include "flipbip_haptic.h" #include "../flipbip.h" - void flipbip_play_happy_bump(void* context) { FlipBip* app = context; - if (app->haptic != 1) { + if(app->haptic != 1) { return; } notification_message(app->notification, &sequence_set_vibro_on); @@ -14,7 +13,7 @@ void flipbip_play_happy_bump(void* context) { void flipbip_play_bad_bump(void* context) { FlipBip* app = context; - if (app->haptic != 1) { + if(app->haptic != 1) { return; } notification_message(app->notification, &sequence_set_vibro_on); @@ -24,10 +23,10 @@ void flipbip_play_bad_bump(void* context) { void flipbip_play_long_bump(void* context) { FlipBip* app = context; - if (app->haptic != 1) { + if(app->haptic != 1) { return; } - for (int i = 0; i < 4; i++) { + for(int i = 0; i < 4; i++) { notification_message(app->notification, &sequence_set_vibro_on); furi_thread_flags_wait(0, FuriFlagWaitAny, 50); notification_message(app->notification, &sequence_reset_vibro); diff --git a/helpers/flipbip_haptic.h b/helpers/flipbip_haptic.h index a02e80c5757..cab1d3a6329 100644 --- a/helpers/flipbip_haptic.h +++ b/helpers/flipbip_haptic.h @@ -5,4 +5,3 @@ void flipbip_play_happy_bump(void* context); void flipbip_play_bad_bump(void* context); void flipbip_play_long_bump(void* context); - diff --git a/helpers/flipbip_led.c b/helpers/flipbip_led.c index 147f22146ac..7a6fd1778a0 100644 --- a/helpers/flipbip_led.c +++ b/helpers/flipbip_led.c @@ -1,11 +1,9 @@ #include "flipbip_led.h" #include "../flipbip.h" - - void flipbip_led_set_rgb(void* context, int red, int green, int blue) { FlipBip* app = context; - if (app->led != 1) { + if(app->led != 1) { return; } NotificationMessage notification_led_message_1; @@ -26,7 +24,8 @@ void flipbip_led_set_rgb(void* context, int red, int green, int blue) { NULL, }; notification_message(app->notification, ¬ification_sequence); - furi_thread_flags_wait(0, FuriFlagWaitAny, 10); //Delay, prevent removal from RAM before LED value set + furi_thread_flags_wait( + 0, FuriFlagWaitAny, 10); //Delay, prevent removal from RAM before LED value set } void flipbip_led_reset(void* context) { @@ -34,6 +33,7 @@ void flipbip_led_reset(void* context) { notification_message(app->notification, &sequence_reset_red); notification_message(app->notification, &sequence_reset_green); notification_message(app->notification, &sequence_reset_blue); - - furi_thread_flags_wait(0, FuriFlagWaitAny, 300); //Delay, prevent removal from RAM before LED value set + + furi_thread_flags_wait( + 0, FuriFlagWaitAny, 300); //Delay, prevent removal from RAM before LED value set } diff --git a/helpers/flipbip_led.h b/helpers/flipbip_led.h index 1a641e59461..ba662d26a98 100644 --- a/helpers/flipbip_led.h +++ b/helpers/flipbip_led.h @@ -3,4 +3,3 @@ void flipbip_led_set_rgb(void* context, int red, int green, int blue); void flipbip_led_reset(void* context); - diff --git a/helpers/flipbip_speaker.c b/helpers/flipbip_speaker.c index aa1f69bab93..f7ae2193b9d 100644 --- a/helpers/flipbip_speaker.c +++ b/helpers/flipbip_speaker.c @@ -12,7 +12,7 @@ // if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { // furi_hal_speaker_start(NOTE_INPUT, volume); // } - + // } // void flipbip_stop_all_sound(void* context) { diff --git a/helpers/flipbip_string.c b/helpers/flipbip_string.c index 5c95ecf5327..2238a6e9fc2 100644 --- a/helpers/flipbip_string.c +++ b/helpers/flipbip_string.c @@ -34,103 +34,94 @@ #include "../crypto/memzero.h" #include "../crypto/rc4.h" -char * -flipbip_strtok(char *s, const char *delim) -{ - static char *last; - return flipbip_strtok_r(s, delim, &last); +char* flipbip_strtok(char* s, const char* delim) { + static char* last; + return flipbip_strtok_r(s, delim, &last); } -char * -flipbip_strtok_r(char *s, const char *delim, char **last) -{ - char *spanp; - int c, sc; - char *tok; - if (s == NULL && (s = *last) == NULL) - return (NULL); - /* +char* flipbip_strtok_r(char* s, const char* delim, char** last) { + char* spanp; + int c, sc; + char* tok; + if(s == NULL && (s = *last) == NULL) return (NULL); + /* * Skip (span) leading delimiters (s += strspn(s, delim), sort of). */ cont: - c = *s++; - for (spanp = (char *)delim; (sc = *spanp++) != 0;) { - if (c == sc) - goto cont; - } - if (c == 0) { /* no non-delimiter characters */ - *last = NULL; - return (NULL); - } - tok = s - 1; - /* + c = *s++; + for(spanp = (char*)delim; (sc = *spanp++) != 0;) { + if(c == sc) goto cont; + } + if(c == 0) { /* no non-delimiter characters */ + *last = NULL; + return (NULL); + } + tok = s - 1; + /* * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). * Note that delim must have one NUL; we stop if we see that, too. */ - for (;;) { - c = *s++; - spanp = (char *)delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *last = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ + for(;;) { + c = *s++; + spanp = (char*)delim; + do { + if((sc = *spanp++) == c) { + if(c == 0) + s = NULL; + else + s[-1] = 0; + *last = s; + return (tok); + } + } while(sc != 0); + } + /* NOTREACHED */ } -void -flipbip_btox(const unsigned char in, char *str) -{ +void flipbip_btox(const unsigned char in, char* str) { unsigned char n; unsigned char i = in; - + str += 2; *str = '\0'; - - for (n = 2; n != 0; --n) { + + for(n = 2; n != 0; --n) { *--str = "0123456789abcdef"[i & 0x0F]; i >>= 4; } } -void -flipbip_xtob(const char *str, unsigned char *out, int out_len) -{ +void flipbip_xtob(const char* str, unsigned char* out, int out_len) { int len = strlen(str) / 2; - if (len > out_len) len = out_len; - for (int i = 0; i < len; i++) { + if(len > out_len) len = out_len; + for(int i = 0; i < len; i++) { char c = 0; - if (str[i * 2] >= '0' && str[i * 2] <= '9') - c += (str[i * 2] - '0') << 4; - if ((str[i * 2] & ~0x20) >= 'A' && (str[i * 2] & ~0x20) <= 'F') + if(str[i * 2] >= '0' && str[i * 2] <= '9') c += (str[i * 2] - '0') << 4; + if((str[i * 2] & ~0x20) >= 'A' && (str[i * 2] & ~0x20) <= 'F') c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; - if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') - c += (str[i * 2 + 1] - '0'); - if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') + if(str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') c += (str[i * 2 + 1] - '0'); + if((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); out[i] = c; } } -void -flipbip_cipher(const unsigned char* key_in, const unsigned int key_len, const char* in, char* out, const unsigned int io_len) -{ - if (io_len > 512) return; +void flipbip_cipher( + const unsigned char* key_in, + const unsigned int key_len, + const char* in, + char* out, + const unsigned int io_len) { + if(io_len > 512) return; RC4_CTX ctx; uint8_t buf[256]; memzero(buf, 256); - + flipbip_xtob(in, buf, io_len / 2); rc4_init(&ctx, key_in, key_len); rc4_encrypt(&ctx, buf, 256); - for (size_t i = 0; i < (io_len / 2); i++) { + for(size_t i = 0; i < (io_len / 2); i++) { flipbip_btox(buf[i], out + i * 2); } diff --git a/helpers/flipbip_string.h b/helpers/flipbip_string.h index 282e2be3bc8..edeb3f99021 100644 --- a/helpers/flipbip_string.h +++ b/helpers/flipbip_string.h @@ -1,7 +1,12 @@ -char * flipbip_strtok(char *s, const char *delim); -char * flipbip_strtok_r(char *s, const char *delim, char **last); +char* flipbip_strtok(char* s, const char* delim); +char* flipbip_strtok_r(char* s, const char* delim, char** last); -void flipbip_btox(const unsigned char i, char *str); -void flipbip_xtob(const char *str, unsigned char *out, int out_len); +void flipbip_btox(const unsigned char i, char* str); +void flipbip_xtob(const char* str, unsigned char* out, int out_len); -void flipbip_cipher(const unsigned char* key_in, const unsigned int key_len, const char* in, char* out, const unsigned int io_len); \ No newline at end of file +void flipbip_cipher( + const unsigned char* key_in, + const unsigned int key_len, + const char* in, + char* out, + const unsigned int io_len); \ No newline at end of file diff --git a/scenes/flipbip_scene_menu.c b/scenes/flipbip_scene_menu.c index e58cc473ae1..6309f7c63c4 100644 --- a/scenes/flipbip_scene_menu.c +++ b/scenes/flipbip_scene_menu.c @@ -17,14 +17,31 @@ void flipbip_scene_menu_on_enter(void* context) { FlipBip* app = context; if(flipbip_has_settings(true) && flipbip_has_settings(false)) { - submenu_add_item(app->submenu, "View saved BTC wallet", SubmenuIndexScene1BTC, flipbip_scene_menu_submenu_callback, app); - submenu_add_item(app->submenu, "View saved ETH wallet", SubmenuIndexScene1ETH, flipbip_scene_menu_submenu_callback, app); + submenu_add_item( + app->submenu, + "View saved BTC wallet", + SubmenuIndexScene1BTC, + flipbip_scene_menu_submenu_callback, + app); + submenu_add_item( + app->submenu, + "View saved ETH wallet", + SubmenuIndexScene1ETH, + flipbip_scene_menu_submenu_callback, + app); } - submenu_add_item(app->submenu, "Generate new wallet", SubmenuIndexScene1New, flipbip_scene_menu_submenu_callback, app); - - submenu_add_item(app->submenu, "Settings", SubmenuIndexSettings, flipbip_scene_menu_submenu_callback, app); + submenu_add_item( + app->submenu, + "Generate new wallet", + SubmenuIndexScene1New, + flipbip_scene_menu_submenu_callback, + app); - submenu_set_selected_item(app->submenu, scene_manager_get_scene_state(app->scene_manager, FlipBipSceneMenu)); + submenu_add_item( + app->submenu, "Settings", SubmenuIndexSettings, flipbip_scene_menu_submenu_callback, app); + + submenu_set_selected_item( + app->submenu, scene_manager_get_scene_state(app->scene_manager, FlipBipSceneMenu)); view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu); } @@ -45,20 +62,20 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1BTC); scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); return true; - } else if (event.event == SubmenuIndexScene1ETH) { + } else if(event.event == SubmenuIndexScene1ETH) { app->overwrite_saved_seed = 0; app->bip44_coin = FlipBipCoinETH60; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ETH); scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); return true; - } else if (event.event == SubmenuIndexScene1New) { + } else if(event.event == SubmenuIndexScene1New) { app->overwrite_saved_seed = 1; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1New); scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); return true; - } else if (event.event == SubmenuIndexSettings) { + } else if(event.event == SubmenuIndexSettings) { scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexSettings); scene_manager_next_scene(app->scene_manager, FlipBipSceneSettings); diff --git a/scenes/flipbip_scene_scene_1.c b/scenes/flipbip_scene_scene_1.c index d57487bbaa4..6f4064cd40f 100644 --- a/scenes/flipbip_scene_scene_1.c +++ b/scenes/flipbip_scene_scene_1.c @@ -18,29 +18,29 @@ void flipbip_scene_scene_1_on_enter(void* context) { bool flipbip_scene_scene_1_on_event(void* context, SceneManagerEvent event) { FlipBip* app = context; bool consumed = false; - + if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case FlipBipCustomEventScene1Left: - case FlipBipCustomEventScene1Right: - break; - case FlipBipCustomEventScene1Up: - case FlipBipCustomEventScene1Down: - break; - case FlipBipCustomEventScene1Back: - notification_message(app->notification, &sequence_reset_red); - notification_message(app->notification, &sequence_reset_green); - notification_message(app->notification, &sequence_reset_blue); - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, FlipBipSceneMenu)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - consumed = true; - break; + case FlipBipCustomEventScene1Left: + case FlipBipCustomEventScene1Right: + break; + case FlipBipCustomEventScene1Up: + case FlipBipCustomEventScene1Down: + break; + case FlipBipCustomEventScene1Back: + notification_message(app->notification, &sequence_reset_red); + notification_message(app->notification, &sequence_reset_green); + notification_message(app->notification, &sequence_reset_blue); + if(!scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, FlipBipSceneMenu)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + break; } } - + return consumed; } diff --git a/scenes/flipbip_scene_settings.c b/scenes/flipbip_scene_settings.c index 000914c4e15..50ae1593ca6 100644 --- a/scenes/flipbip_scene_settings.c +++ b/scenes/flipbip_scene_settings.c @@ -86,11 +86,7 @@ void flipbip_scene_settings_on_enter(void* context) { // BIP39 strength item = variable_item_list_add( - app->variable_item_list, - "BIP39 Words:", - 3, - flipbip_scene_settings_set_bip39_strength, - app); + app->variable_item_list, "BIP39 Words:", 3, flipbip_scene_settings_set_bip39_strength, app); value_index = value_index_uint32(app->bip39_strength, bip39_strength_value, 3); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, bip39_strength_text[value_index]); @@ -108,26 +104,18 @@ void flipbip_scene_settings_on_enter(void* context) { // Vibro on/off item = variable_item_list_add( - app->variable_item_list, - "Vibro/Haptic:", - 2, - flipbip_scene_settings_set_haptic, - app); + app->variable_item_list, "Vibro/Haptic:", 2, flipbip_scene_settings_set_haptic, app); value_index = value_index_uint32(app->haptic, haptic_value, 2); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, haptic_text[value_index]); // LED Effects on/off item = variable_item_list_add( - app->variable_item_list, - "LED FX:", - 2, - flipbip_scene_settings_set_led, - app); + app->variable_item_list, "LED FX:", 2, flipbip_scene_settings_set_led, app); value_index = value_index_uint32(app->led, led_value, 2); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, led_text[value_index]); - + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings); } @@ -136,7 +124,6 @@ bool flipbip_scene_settings_on_event(void* context, SceneManagerEvent event) { UNUSED(app); bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - } return consumed; } diff --git a/scenes/flipbip_scene_startscreen.c b/scenes/flipbip_scene_startscreen.c index bf3d76de8b5..a9cb8ba5fce 100644 --- a/scenes/flipbip_scene_startscreen.c +++ b/scenes/flipbip_scene_startscreen.c @@ -11,40 +11,41 @@ void flipbip_scene_startscreen_callback(FlipBipCustomEvent event, void* context) void flipbip_scene_startscreen_on_enter(void* context) { furi_assert(context); FlipBip* app = context; - flipbip_startscreen_set_callback(app->flipbip_startscreen, flipbip_scene_startscreen_callback, app); + flipbip_startscreen_set_callback( + app->flipbip_startscreen, flipbip_scene_startscreen_callback, app); view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdStartscreen); } bool flipbip_scene_startscreen_on_event(void* context, SceneManagerEvent event) { FlipBip* app = context; bool consumed = false; - + if(event.type == SceneManagerEventTypeCustom) { switch(event.event) { - case FlipBipCustomEventStartscreenLeft: - case FlipBipCustomEventStartscreenRight: - break; - case FlipBipCustomEventStartscreenUp: - case FlipBipCustomEventStartscreenDown: - break; - case FlipBipCustomEventStartscreenOk: - scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); - consumed = true; - break; - case FlipBipCustomEventStartscreenBack: - notification_message(app->notification, &sequence_reset_red); - notification_message(app->notification, &sequence_reset_green); - notification_message(app->notification, &sequence_reset_blue); - if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, FlipBipSceneStartscreen)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - consumed = true; - break; + case FlipBipCustomEventStartscreenLeft: + case FlipBipCustomEventStartscreenRight: + break; + case FlipBipCustomEventStartscreenUp: + case FlipBipCustomEventStartscreenDown: + break; + case FlipBipCustomEventStartscreenOk: + scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); + consumed = true; + break; + case FlipBipCustomEventStartscreenBack: + notification_message(app->notification, &sequence_reset_red); + notification_message(app->notification, &sequence_reset_green); + notification_message(app->notification, &sequence_reset_blue); + if(!scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, FlipBipSceneStartscreen)) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + } + consumed = true; + break; } } - + return consumed; } diff --git a/views/flipbip_scene_1.c b/views/flipbip_scene_1.c index 2d4169f3385..10540896930 100644 --- a/views/flipbip_scene_1.c +++ b/views/flipbip_scene_1.c @@ -24,7 +24,6 @@ struct FlipBipScene1 { void* context; }; - typedef struct { int page; int strength; @@ -61,18 +60,24 @@ void flipbip_scene_1_set_callback( static void flipbip_scene_1_draw_generic(const char* text, size_t line_len) { // Split the text into parts - for (size_t si = 1; si <= 6; si++) { - char *ptr = NULL; - - if (si == 1) ptr = s_disp_text1; - else if (si == 2) ptr = s_disp_text2; - else if (si == 3) ptr = s_disp_text3; - else if (si == 4) ptr = s_disp_text4; - else if (si == 5) ptr = s_disp_text5; - else if (si == 6) ptr = s_disp_text6; - + for(size_t si = 1; si <= 6; si++) { + char* ptr = NULL; + + if(si == 1) + ptr = s_disp_text1; + else if(si == 2) + ptr = s_disp_text2; + else if(si == 3) + ptr = s_disp_text3; + else if(si == 4) + ptr = s_disp_text4; + else if(si == 5) + ptr = s_disp_text5; + else if(si == 6) + ptr = s_disp_text6; + memzero(ptr, 30 + 1); - if (line_len > 30) { + if(line_len > 30) { strncpy(ptr, text + ((si - 1) * 30), 30); } else { strncpy(ptr, text + ((si - 1) * line_len), line_len); @@ -82,35 +87,40 @@ static void flipbip_scene_1_draw_generic(const char* text, size_t line_len) { static void flipbip_scene_1_draw_mnemonic(const char* mnemonic) { // Delineate sections of the mnemonic every 4 words - char *mnemonic_working = malloc(strlen(mnemonic) + 1); + char* mnemonic_working = malloc(strlen(mnemonic) + 1); strcpy(mnemonic_working, mnemonic); int word = 0; - for (size_t i = 0; i < strlen(mnemonic_working); i++) { - if (mnemonic_working[i] == ' ') { + for(size_t i = 0; i < strlen(mnemonic_working); i++) { + if(mnemonic_working[i] == ' ') { word++; - if (word % 4 == 0) { + if(word % 4 == 0) { mnemonic_working[i] = ','; } - } + } } // Split the mnemonic into parts - char *mnemonic_part = flipbip_strtok(mnemonic_working, ","); + char* mnemonic_part = flipbip_strtok(mnemonic_working, ","); int mi = 0; - while(mnemonic_part != NULL) - { - char *ptr = NULL; + while(mnemonic_part != NULL) { + char* ptr = NULL; mi++; - - if (mi == 1) ptr = s_disp_text1; - else if (mi == 2) ptr = s_disp_text2; - else if (mi == 3) ptr = s_disp_text3; - else if (mi == 4) ptr = s_disp_text4; - else if (mi == 5) ptr = s_disp_text5; - else if (mi == 6) ptr = s_disp_text6; + + if(mi == 1) + ptr = s_disp_text1; + else if(mi == 2) + ptr = s_disp_text2; + else if(mi == 3) + ptr = s_disp_text3; + else if(mi == 4) + ptr = s_disp_text4; + else if(mi == 5) + ptr = s_disp_text5; + else if(mi == 6) + ptr = s_disp_text6; memzero(ptr, 30 + 1); - if (strlen(mnemonic_part) > 30) { + if(strlen(mnemonic_part) > 30) { strncpy(ptr, mnemonic_part, 30); } else { strncpy(ptr, mnemonic_part, strlen(mnemonic_part)); @@ -125,12 +135,12 @@ static void flipbip_scene_1_draw_mnemonic(const char* mnemonic) { } static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) { - char *seed_working = malloc(64 * 2 + 1); + char* seed_working = malloc(64 * 2 + 1); // Convert the seed to a hex string - for (size_t i = 0; i < 64; i++) { + for(size_t i = 0; i < 64; i++) { flipbip_btox(model->seed[i], seed_working + (i * 2)); } - + flipbip_scene_1_draw_generic(seed_working, 22); // Free the working seed memory @@ -138,41 +148,43 @@ static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) { free(seed_working); } -static void flipbip_scene_1_draw_address(const HDNode* node, uint32_t addr_type, uint32_t addr_index) { +static void + flipbip_scene_1_draw_address(const HDNode* node, uint32_t addr_type, uint32_t addr_index) { s_busy = true; - + // buffer for key serialization const size_t buflen = 128; char buf[128 + 1]; - HDNode *addr_node = malloc(sizeof(HDNode)); + HDNode* addr_node = malloc(sizeof(HDNode)); memcpy(addr_node, node, sizeof(HDNode)); hdnode_private_ckd(addr_node, addr_index); hdnode_fill_public_key(addr_node); - if (addr_type == 0) { // BTC + if(addr_type == 0) { // BTC // BTC style address const char addr_version = 0x00; //const char wif_version = 0x80; - ecdsa_get_address(addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen); + ecdsa_get_address( + addr_node->public_key, addr_version, HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen); - char *address = malloc(buflen + 1); + char* address = malloc(buflen + 1); strncpy(address, buf, buflen); flipbip_scene_1_draw_generic(address, 12); memzero(address, buflen + 1); free(address); - //ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen); + //ecdsa_get_wif(addr_node->private_key, wif_version, HASHER_SHA2D, buf, buflen); //char *wif = malloc(buflen + 1); //strncpy(wif, buf, buflen); - } else if (addr_type == 60) { // ETH + } else if(addr_type == 60) { // ETH // ETH style address - hdnode_get_ethereum_pubkeyhash(addr_node, (uint8_t *)buf); - char *address = malloc(42 + 1); + hdnode_get_ethereum_pubkeyhash(addr_node, (uint8_t*)buf); + char* address = malloc(42 + 1); memcpy(address, "0x", 2); // Convert the hash to a hex string - for (size_t i = 0; i < 20; i++) { + for(size_t i = 0; i < 20; i++) { flipbip_btox(buf[i], address + 2 + (i * 2)); } flipbip_scene_1_draw_generic(address, 12); @@ -199,56 +211,46 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { //UNUSED(model); canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); - + flipbip_scene_1_clear_text(); - if (model->page == 1) { - const char* info = "-Scroll pages with up/down-" + if(model->page == 1) { + const char* info = "-Scroll pages with up/down-" "p1,2) Mnemonic/Seed " "p3) xprv Root Key " "p4,5) xprv/xpub Accnt Keys" "p6,7) xprv/xpub Extnd Keys" "p8+) Receive Addresses "; flipbip_scene_1_draw_generic(info, 27); - } - else if (model->page == 2) { + } else if(model->page == 2) { flipbip_scene_1_draw_mnemonic(model->mnemonic); - } - else if (model->page == 3) { + } else if(model->page == 3) { flipbip_scene_1_draw_seed(model); - } - else if (model->page == 4) { + } else if(model->page == 4) { flipbip_scene_1_draw_generic(model->xprv_root, 20); - } - else if (model->page == 5) { + } else if(model->page == 5) { flipbip_scene_1_draw_generic(model->xprv_account, 20); - } - else if (model->page == 6) { + } else if(model->page == 6) { flipbip_scene_1_draw_generic(model->xpub_account, 20); - } - else if (model->page == 7) { + } else if(model->page == 7) { flipbip_scene_1_draw_generic(model->xprv_extended, 20); - } - else if (model->page == 8) { + } else if(model->page == 8) { flipbip_scene_1_draw_generic(model->xpub_extended, 20); - } - else if (model->page >= 9 && model->page <= 13) { + } else if(model->page >= 9 && model->page <= 13) { flipbip_scene_1_draw_address(model->node, model->coin, model->page - 9); } - if (model->page == 0) { + if(model->page == 0) { canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 1, 10, "Loading..."); canvas_draw_str(canvas, 6, 30, "m/44'/x'/0'/0"); - } else if (model->page >= 9 && model->page <= 13) { + } else if(model->page >= 9 && model->page <= 13) { canvas_set_font(canvas, FontSecondary); - const char * receive_text; - if (model->coin == 0) { // BTC + const char* receive_text; + if(model->coin == 0) { // BTC receive_text = "BTC receive address:"; - } - else if (model->coin == 60) { // ETH + } else if(model->coin == 60) { // ETH receive_text = "ETH receive address:"; - } - else { + } else { receive_text = "Receive address:"; } canvas_draw_str_aligned(canvas, 1, 2, AlignLeft, AlignTop, receive_text); @@ -257,8 +259,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { canvas_draw_str(canvas, 6, 34, s_disp_text2); canvas_draw_str(canvas, 6, 46, s_disp_text3); canvas_draw_str(canvas, 6, 58, s_disp_text4); - } - else { + } else { canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned(canvas, 1, 2, AlignLeft, AlignTop, s_disp_text1); canvas_draw_str_aligned(canvas, 1, 12, AlignLeft, AlignTop, s_disp_text2); @@ -267,43 +268,45 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { canvas_draw_str_aligned(canvas, 1, 42, AlignLeft, AlignTop, s_disp_text5); canvas_draw_str_aligned(canvas, 1, 52, AlignLeft, AlignTop, s_disp_text6); } - } -static int flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int strength, const uint32_t coin, const bool overwrite) { - +static int flipbip_scene_1_model_init( + FlipBipScene1Model* const model, + const int strength, + const uint32_t coin, + const bool overwrite) { model->page = 0; model->mnemonic_only = false; model->strength = strength; model->coin = coin; model->overwrite = overwrite; - + // Allocate memory for mnemonic char* mnemonic = malloc(256); memzero(mnemonic, 256); // Check if the mnemonic key & data is already saved in persistent storage, or overwrite is true - if (overwrite || (!flipbip_has_settings(true) && !flipbip_has_settings(false))) { + if(overwrite || (!flipbip_has_settings(true) && !flipbip_has_settings(false))) { // Generate a random mnemonic using trezor-crypto const char* mnemonic_gen = mnemonic_generate(strength); // Save the mnemonic to persistent storage - if (!flipbip_save_settings_secure(mnemonic_gen)) return 1; // 1 = save error + if(!flipbip_save_settings_secure(mnemonic_gen)) return 1; // 1 = save error // Clear the generated mnemonic from memory mnemonic_clear(); model->mnemonic_only = true; } - + // Load the mnemonic from persistent storage - if (!flipbip_load_settings_secure(mnemonic)) return 2; // 2 = load error + if(!flipbip_load_settings_secure(mnemonic)) return 2; // 2 = load error model->mnemonic = mnemonic; // Check if the mnemonic is valid - if (mnemonic_check(model->mnemonic) == 0) return 3; // 3 = mnemonic check error + if(mnemonic_check(model->mnemonic) == 0) return 3; // 3 = mnemonic check error // if we are only generating the mnemonic, return - if (model->mnemonic_only) { + if(model->mnemonic_only) { return -1; // -1 = mnemonic only, return from parent } - + // test mnemonic //model->mnemonic = "wealth budget salt video delay obey neutral tail sure soda hold rubber joy movie boat raccoon tornado noise off inmate payment patch group topple"; @@ -311,7 +314,7 @@ static int flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int mnemonic_to_seed(model->mnemonic, "", model->seed, 0); // Generate a BIP32 root HD node from the mnemonic - HDNode *root = malloc(sizeof(HDNode)); + HDNode* root = malloc(sizeof(HDNode)); hdnode_from_seed(model->seed, 64, SECP256K1_NAME, root); // m/44'/0'/0'/0 or m/44'/60'/0'/0 @@ -320,7 +323,7 @@ static int flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int //const uint32_t coin = 60; // ETH const uint32_t account = 0; const uint32_t change = 0; - + // constants for BTC / ETH const uint32_t version_public = 0x0488b21e; const uint32_t version_private = 0x0488ade4; @@ -330,53 +333,53 @@ static int flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int // "xpub_magic_segwit_native": 78792518, // "xpub_magic_multisig_segwit_p2sh": 43365439, // "xpub_magic_multisig_segwit_native": 44728019, - + // buffer for key serialization const size_t buflen = 128; char buf[128 + 1]; - + // root uint32_t fingerprint = 0; - hdnode_serialize_private(root, fingerprint, version_private, buf, buflen); - char *xprv_root = malloc(buflen + 1); + hdnode_serialize_private(root, fingerprint, version_private, buf, buflen); + char* xprv_root = malloc(buflen + 1); strncpy(xprv_root, buf, buflen); model->xprv_root = xprv_root; - - HDNode *node = root; - + + HDNode* node = root; + // purpose m/44' fingerprint = hdnode_fingerprint(node); hdnode_private_ckd_prime(node, purpose); // purpose - + // coin m/44'/0' or m/44'/60' fingerprint = hdnode_fingerprint(node); hdnode_private_ckd_prime(node, model->coin); // coin - + // account m/44'/0'/0' or m/44'/60'/0' fingerprint = hdnode_fingerprint(node); hdnode_private_ckd_prime(node, account); // account - - hdnode_serialize_private(node, fingerprint, version_private, buf, buflen); - char *xprv_acc = malloc(buflen + 1); + + hdnode_serialize_private(node, fingerprint, version_private, buf, buflen); + char* xprv_acc = malloc(buflen + 1); strncpy(xprv_acc, buf, buflen); model->xprv_account = xprv_acc; - - hdnode_serialize_public(node, fingerprint, version_public, buf, buflen); - char *xpub_acc = malloc(buflen + 1); + + hdnode_serialize_public(node, fingerprint, version_public, buf, buflen); + char* xpub_acc = malloc(buflen + 1); strncpy(xpub_acc, buf, buflen); model->xpub_account = xpub_acc; - + // external/internal (change) m/44'/0'/0'/0 or m/44'/60'/0'/0 fingerprint = hdnode_fingerprint(node); hdnode_private_ckd(node, change); // external/internal (change) - - hdnode_serialize_private(node, fingerprint, version_private, buf, buflen); - char *xprv_ext = malloc(buflen + 1); + + hdnode_serialize_private(node, fingerprint, version_private, buf, buflen); + char* xprv_ext = malloc(buflen + 1); strncpy(xprv_ext, buf, buflen); model->xprv_extended = xprv_ext; - - hdnode_serialize_public(node, fingerprint, version_public, buf, buflen); - char *xpub_ext = malloc(buflen + 1); + + hdnode_serialize_public(node, fingerprint, version_public, buf, buflen); + char* xpub_ext = malloc(buflen + 1); strncpy(xpub_ext, buf, buflen); model->xpub_extended = xpub_ext; @@ -394,57 +397,57 @@ static int flipbip_scene_1_model_init(FlipBipScene1Model* const model, const int } bool flipbip_scene_1_input(InputEvent* event, void* context) { - furi_assert(context); + furi_assert(context); FlipBipScene1* instance = context; // Ignore input if busy - if (s_busy) { + if(s_busy) { return false; } - if (event->type == InputTypeRelease) { + if(event->type == InputTypeRelease) { switch(event->key) { - case InputKeyBack: - with_view_model( - instance->view, - FlipBipScene1Model * model, - { - UNUSED(model); - instance->callback(FlipBipCustomEventScene1Back, instance->context); - }, - true); - break; - case InputKeyRight: - case InputKeyDown: - case InputKeyOk: - with_view_model( - instance->view, - FlipBipScene1Model* model, - { - //UNUSED(model); - model->page = (model->page + 1) % 14; - if (model->page == 0) { - model->page = 1; - } - }, - true); - break; - case InputKeyLeft: - case InputKeyUp: - with_view_model( - instance->view, - FlipBipScene1Model* model, - { - //UNUSED(model); - model->page = (model->page - 1) % 14; - if (model->page == 0) { - model->page = 13; - } - }, - true); - break; - case InputKeyMAX: - break; + case InputKeyBack: + with_view_model( + instance->view, + FlipBipScene1Model * model, + { + UNUSED(model); + instance->callback(FlipBipCustomEventScene1Back, instance->context); + }, + true); + break; + case InputKeyRight: + case InputKeyDown: + case InputKeyOk: + with_view_model( + instance->view, + FlipBipScene1Model * model, + { + //UNUSED(model); + model->page = (model->page + 1) % 14; + if(model->page == 0) { + model->page = 1; + } + }, + true); + break; + case InputKeyLeft: + case InputKeyUp: + with_view_model( + instance->view, + FlipBipScene1Model * model, + { + //UNUSED(model); + model->page = (model->page - 1) % 14; + if(model->page == 0) { + model->page = 13; + } + }, + true); + break; + case InputKeyMAX: + break; } } return true; @@ -463,7 +466,7 @@ void flipbip_scene_1_exit(void* context) { model->coin = 0; memzero(model->seed, 64); // if mnemonic_only is true, then we don't need to free the data here - if (!model->mnemonic_only) { + if(!model->mnemonic_only) { memzero((void*)model->mnemonic, strlen(model->mnemonic)); free((void*)model->mnemonic); memzero((void*)model->node, sizeof(HDNode)); @@ -480,8 +483,7 @@ void flipbip_scene_1_exit(void* context) { free((void*)model->xpub_extended); } }, - true - ); + true); flipbip_scene_1_clear_text(); } @@ -491,17 +493,19 @@ void flipbip_scene_1_enter(void* context) { FlipBipScene1* instance = (FlipBipScene1*)context; FlipBip* app = instance->context; - + // BIP39 Strength setting int strength_setting = app->bip39_strength; int strength = 256; // FlipBipStrength256 // 24 words (256 bit) - if (strength_setting == FlipBipStrength128) strength = 128; // 12 words (128 bit) - else if (strength_setting == FlipBipStrength192) strength = 192; // 18 words (192 bit) - + if(strength_setting == FlipBipStrength128) + strength = 128; // 12 words (128 bit) + else if(strength_setting == FlipBipStrength192) + strength = 192; // 18 words (192 bit) + // BIP44 Coin setting int coin_setting = app->bip44_coin; uint32_t coin = 0; //FlipBipCoinBTC0 // BTC (0) - if (coin_setting == FlipBipCoinETH60) coin = 60; // ETH (60) + if(coin_setting == FlipBipCoinETH60) coin = 60; // ETH (60) // Overwrite the saved seed with a new one setting bool overwrite = app->overwrite_saved_seed != 0; @@ -518,19 +522,19 @@ void flipbip_scene_1_enter(void* context) { const int status = flipbip_scene_1_model_init(model, strength, coin, overwrite); // nonzero status, free the mnemonic - if (status != 0) { + if(status != 0) { memzero((void*)model->mnemonic, strlen(model->mnemonic)); free((void*)model->mnemonic); } // if error, set the error message - if (status == 1) { + if(status == 1) { model->mnemonic = "ERROR:,Save error"; model->page = 2; - } else if (status == 2) { + } else if(status == 2) { model->mnemonic = "ERROR:,Load error"; model->page = 2; - } else if (status == 3) { + } else if(status == 3) { model->mnemonic = "ERROR:,Mnemonic check failed"; model->page = 2; } @@ -538,12 +542,11 @@ void flipbip_scene_1_enter(void* context) { s_busy = false; // if overwrite is set and mnemonic generated, return from scene immediately - if (status == -1) { + if(status == -1) { instance->callback(FlipBipCustomEventScene1Back, instance->context); } }, - true - ); + true); } FlipBipScene1* flipbip_scene_1_alloc() { @@ -555,7 +558,7 @@ FlipBipScene1* flipbip_scene_1_alloc() { view_set_input_callback(instance->view, flipbip_scene_1_input); view_set_enter_callback(instance->view, flipbip_scene_1_enter); view_set_exit_callback(instance->view, flipbip_scene_1_exit); - + return instance; } @@ -563,12 +566,7 @@ void flipbip_scene_1_free(FlipBipScene1* instance) { furi_assert(instance); with_view_model( - instance->view, - FlipBipScene1Model * model, - { - UNUSED(model); - }, - true); + instance->view, FlipBipScene1Model * model, { UNUSED(model); }, true); flipbip_scene_1_clear_text(); @@ -580,4 +578,3 @@ View* flipbip_scene_1_get_view(FlipBipScene1* instance) { furi_assert(instance); return instance->view; } - diff --git a/views/flipbip_startscreen.c b/views/flipbip_startscreen.c index 2cbc62d44a8..f18d5944cce 100644 --- a/views/flipbip_startscreen.c +++ b/views/flipbip_startscreen.c @@ -11,7 +11,6 @@ struct FlipBipStartscreen { void* context; }; - typedef struct { int some_value; } FlipBipStartscreenModel; @@ -30,7 +29,7 @@ void flipbip_startscreen_draw(Canvas* canvas, FlipBipStartscreenModel* model) { UNUSED(model); canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); - + canvas_draw_icon(canvas, 1, 33, &I_Auth_62x31); canvas_set_font(canvas, FontPrimary); @@ -39,8 +38,8 @@ void flipbip_startscreen_draw(Canvas* canvas, FlipBipStartscreenModel* model) { canvas_set_font(canvas, FontSecondary); //canvas_draw_str(canvas, 30, 23, "Crypto tools for Flipper"); canvas_draw_str(canvas, 23, 22, "Crypto toolkit for Flipper"); - - elements_button_right(canvas, "Start"); + + elements_button_right(canvas, "Start"); } static void flipbip_startscreen_model_init(FlipBipStartscreenModel* const model) { @@ -48,36 +47,36 @@ static void flipbip_startscreen_model_init(FlipBipStartscreenModel* const model) } bool flipbip_startscreen_input(InputEvent* event, void* context) { - furi_assert(context); + furi_assert(context); FlipBipStartscreen* instance = context; - if (event->type == InputTypeRelease) { + if(event->type == InputTypeRelease) { switch(event->key) { - case InputKeyBack: - with_view_model( - instance->view, - FlipBipStartscreenModel * model, - { - UNUSED(model); - instance->callback(FlipBipCustomEventStartscreenBack, instance->context); - }, - true); - break; - case InputKeyLeft: - case InputKeyRight: - case InputKeyUp: - case InputKeyDown: - case InputKeyOk: - with_view_model( - instance->view, - FlipBipStartscreenModel* model, - { - UNUSED(model); - instance->callback(FlipBipCustomEventStartscreenOk, instance->context); - }, - true); - break; - case InputKeyMAX: - break; + case InputKeyBack: + with_view_model( + instance->view, + FlipBipStartscreenModel * model, + { + UNUSED(model); + instance->callback(FlipBipCustomEventStartscreenBack, instance->context); + }, + true); + break; + case InputKeyLeft: + case InputKeyRight: + case InputKeyUp: + case InputKeyDown: + case InputKeyOk: + with_view_model( + instance->view, + FlipBipStartscreenModel * model, + { + UNUSED(model); + instance->callback(FlipBipCustomEventStartscreenOk, instance->context); + }, + true); + break; + case InputKeyMAX: + break; } } return true; @@ -93,11 +92,8 @@ void flipbip_startscreen_enter(void* context) { with_view_model( instance->view, FlipBipStartscreenModel * model, - { - flipbip_startscreen_model_init(model); - }, - true - ); + { flipbip_startscreen_model_init(model); }, + true); } FlipBipStartscreen* flipbip_startscreen_alloc() { @@ -113,12 +109,9 @@ FlipBipStartscreen* flipbip_startscreen_alloc() { with_view_model( instance->view, FlipBipStartscreenModel * model, - { - flipbip_startscreen_model_init(model); - }, - true - ); - + { flipbip_startscreen_model_init(model); }, + true); + return instance; } @@ -126,12 +119,7 @@ void flipbip_startscreen_free(FlipBipStartscreen* instance) { furi_assert(instance); with_view_model( - instance->view, - FlipBipStartscreenModel * model, - { - UNUSED(model); - }, - true); + instance->view, FlipBipStartscreenModel * model, { UNUSED(model); }, true); view_free(instance->view); free(instance); } @@ -140,4 +128,3 @@ View* flipbip_startscreen_get_view(FlipBipStartscreen* instance) { furi_assert(instance); return instance->view; } -