mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-21 02:26:10 +00:00
MONOREPO MERGE trezor-crypto
This commit is contained in:
commit
4e0d813269
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -23,3 +23,6 @@
|
||||
[submodule "common/defs/ethereum/tokens"]
|
||||
path = common/defs/ethereum/tokens
|
||||
url = https://github.com/ethereum-lists/tokens.git
|
||||
[submodule "crypto/tests/wycheproof"]
|
||||
path = crypto/tests/wycheproof
|
||||
url = https://github.com/google/wycheproof
|
||||
|
2
crypto/.clang-format
Normal file
2
crypto/.clang-format
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
BasedOnStyle: Google
|
14
crypto/.gitignore
vendored
Normal file
14
crypto/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
.cache/
|
||||
.vscode/
|
||||
_attic/
|
||||
*.o
|
||||
*.d
|
||||
*.exe
|
||||
*~
|
||||
tests/aestst
|
||||
tests/test_openssl
|
||||
tests/test_speed
|
||||
tests/test_check
|
||||
tests/libtrezor-crypto.so
|
||||
*.os
|
||||
*.pyc
|
3
crypto/.gitmodules
vendored
Normal file
3
crypto/.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "tests/wycheproof"]
|
||||
path = tests/wycheproof
|
||||
url = https://github.com/google/wycheproof
|
38
crypto/.travis.yml
Normal file
38
crypto/.travis.yml
Normal file
@ -0,0 +1,38 @@
|
||||
sudo: false
|
||||
dist: trusty
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- check
|
||||
- libssl-dev
|
||||
- python3-pip
|
||||
- valgrind
|
||||
|
||||
env:
|
||||
global:
|
||||
- PYTHON=python3
|
||||
|
||||
install:
|
||||
- $PYTHON -m pip install --user pytest ecdsa curve25519-donna pyasn1
|
||||
|
||||
script:
|
||||
- make
|
||||
- ./tests/aestst
|
||||
- ./tests/test_check
|
||||
- CK_TIMEOUT_MULTIPLIER=20 valgrind -q --error-exitcode=1 ./tests/test_check
|
||||
- ./tests/test_openssl 1000
|
||||
- ITERS=10 $PYTHON -m pytest tests/
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- http://ci-bot.satoshilabs.com:5000/travis
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: always
|
2
crypto/AUTHORS
Normal file
2
crypto/AUTHORS
Normal file
@ -0,0 +1,2 @@
|
||||
Tomas Dzetkulic <dzetkulic@gmail.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
15
crypto/CONTRIBUTORS
Normal file
15
crypto/CONTRIBUTORS
Normal file
@ -0,0 +1,15 @@
|
||||
Tomas Dzetkulic <dzetkulic@gmail.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Jochen Hoenicke <hoenicke@gmail.com>
|
||||
Dustin Laurence <dustin@laurences.net>
|
||||
Ondrej Mikle <ondrej.mikle@nic.cz>
|
||||
Roman Zeyde <roman.zeyde@gmail.com>
|
||||
Alex Beregszaszi <alex@rtfs.hu>
|
||||
netanelkl <netanel.keidar@gmail.com>
|
||||
Jan Pochyla <jpochyla@gmail.com>
|
||||
Ondrej Mikle <ondrej.mikle@gmail.com>
|
||||
Josh Billings <jdb6167@rit.edu>
|
||||
Adam Mackler <AdamMackler@gmail.com>
|
||||
Oleg Andreev <oleganza@gmail.com>
|
||||
mog <mog@rush.rldn.net>
|
||||
John Dvorak <johndvorak26@gmail.com>
|
22
crypto/LICENSE
Normal file
22
crypto/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Tomas Dzetkulic
|
||||
Copyright (c) 2013 Pavol Rusnak
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
110
crypto/Makefile
Normal file
110
crypto/Makefile
Normal file
@ -0,0 +1,110 @@
|
||||
CC ?= gcc
|
||||
|
||||
OPTFLAGS ?= -O3 -g
|
||||
|
||||
CFLAGS += $(OPTFLAGS) \
|
||||
-std=gnu99 \
|
||||
-W \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wimplicit-function-declaration \
|
||||
-Wredundant-decls \
|
||||
-Wstrict-prototypes \
|
||||
-Wundef \
|
||||
-Wshadow \
|
||||
-Wpointer-arith \
|
||||
-Wformat \
|
||||
-Wreturn-type \
|
||||
-Wsign-compare \
|
||||
-Wmultichar \
|
||||
-Wformat-nonliteral \
|
||||
-Winit-self \
|
||||
-Wuninitialized \
|
||||
-Wformat-security \
|
||||
-Werror
|
||||
|
||||
VALGRIND ?= 1
|
||||
|
||||
CFLAGS += -I.
|
||||
CFLAGS += -DVALGRIND=$(VALGRIND)
|
||||
CFLAGS += -DUSE_ETHEREUM=1
|
||||
CFLAGS += -DUSE_GRAPHENE=1
|
||||
CFLAGS += -DUSE_KECCAK=1
|
||||
CFLAGS += -DUSE_MONERO=1
|
||||
CFLAGS += -DUSE_NEM=1
|
||||
CFLAGS += -DUSE_CARDANO=1
|
||||
CFLAGS += $(shell pkg-config --cflags openssl)
|
||||
|
||||
# disable certain optimizations and features when small footprint is required
|
||||
ifdef SMALL
|
||||
CFLAGS += -DUSE_PRECOMPUTED_CP=0
|
||||
endif
|
||||
|
||||
SRCS = bignum.c ecdsa.c curves.c secp256k1.c nist256p1.c rand.c hmac.c bip32.c bip39.c pbkdf2.c base58.c base32.c
|
||||
SRCS += address.c
|
||||
SRCS += script.c
|
||||
SRCS += ripemd160.c
|
||||
SRCS += sha2.c
|
||||
SRCS += sha3.c
|
||||
SRCS += hasher.c
|
||||
SRCS += aes/aescrypt.c aes/aeskey.c aes/aestab.c aes/aes_modes.c
|
||||
SRCS += ed25519-donna/curve25519-donna-32bit.c ed25519-donna/curve25519-donna-helpers.c ed25519-donna/modm-donna-32bit.c
|
||||
SRCS += ed25519-donna/ed25519-donna-basepoint-table.c ed25519-donna/ed25519-donna-32bit-tables.c ed25519-donna/ed25519-donna-impl-base.c
|
||||
SRCS += ed25519-donna/ed25519.c ed25519-donna/curve25519-donna-scalarmult-base.c ed25519-donna/ed25519-sha3.c ed25519-donna/ed25519-keccak.c
|
||||
SRCS += monero/base58.c
|
||||
SRCS += monero/serialize.c
|
||||
SRCS += monero/xmr.c
|
||||
SRCS += monero/range_proof.c
|
||||
SRCS += blake256.c
|
||||
SRCS += blake2b.c blake2s.c
|
||||
SRCS += groestl.c
|
||||
SRCS += chacha20poly1305/chacha20poly1305.c chacha20poly1305/chacha_merged.c chacha20poly1305/poly1305-donna.c chacha20poly1305/rfc7539.c
|
||||
SRCS += rc4.c
|
||||
SRCS += nem.c
|
||||
SRCS += segwit_addr.c cash_addr.c
|
||||
SRCS += memzero.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
TESTLIBS = $(shell pkg-config --libs check) -lpthread -lm
|
||||
TESTSSLLIBS = $(shell pkg-config --libs openssl)
|
||||
|
||||
all: tools tests
|
||||
|
||||
%.o: %.c %.h options.h
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
tests: tests/test_check tests/test_openssl tests/test_speed tests/libtrezor-crypto.so tests/aestst
|
||||
|
||||
tests/aestst: aes/aestst.o aes/aescrypt.o aes/aeskey.o aes/aestab.o
|
||||
$(CC) $^ -o $@
|
||||
|
||||
tests/test_check.o: tests/test_check_cardano.h tests/test_check_monero.h tests/test_check_cashaddr.h tests/test_check_segwit.h
|
||||
|
||||
tests/test_check: tests/test_check.o $(OBJS)
|
||||
$(CC) tests/test_check.o $(OBJS) $(TESTLIBS) -o tests/test_check
|
||||
|
||||
tests/test_speed: tests/test_speed.o $(OBJS)
|
||||
$(CC) tests/test_speed.o $(OBJS) -o tests/test_speed
|
||||
|
||||
tests/test_openssl: tests/test_openssl.o $(OBJS)
|
||||
$(CC) tests/test_openssl.o $(OBJS) $(TESTSSLLIBS) -o tests/test_openssl
|
||||
|
||||
tests/libtrezor-crypto.so: $(SRCS)
|
||||
$(CC) $(CFLAGS) -DAES_128 -DAES_192 -fPIC -shared $(SRCS) -o tests/libtrezor-crypto.so
|
||||
|
||||
tools: tools/xpubaddrgen tools/mktable tools/bip39bruteforce
|
||||
|
||||
tools/xpubaddrgen: tools/xpubaddrgen.o $(OBJS)
|
||||
$(CC) tools/xpubaddrgen.o $(OBJS) -o tools/xpubaddrgen
|
||||
|
||||
tools/mktable: tools/mktable.o $(OBJS)
|
||||
$(CC) tools/mktable.o $(OBJS) -o tools/mktable
|
||||
|
||||
tools/bip39bruteforce: tools/bip39bruteforce.o $(OBJS)
|
||||
$(CC) tools/bip39bruteforce.o $(OBJS) -o tools/bip39bruteforce
|
||||
|
||||
clean:
|
||||
rm -f *.o aes/*.o chacha20poly1305/*.o ed25519-donna/*.o
|
||||
rm -f 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
|
44
crypto/README.md
Normal file
44
crypto/README.md
Normal file
@ -0,0 +1,44 @@
|
||||
# trezor-crypto
|
||||
|
||||
[](https://travis-ci.org/trezor/trezor-crypto) [](https://gitter.im/trezor/community)
|
||||
|
||||
Heavily optimized cryptography algorithms for embedded devices.
|
||||
|
||||
These include:
|
||||
- AES/Rijndael encryption/decryption
|
||||
- Big Number (256 bit) Arithmetics
|
||||
- BIP32 Hierarchical Deterministic Wallets
|
||||
- BIP39 Mnemonic code
|
||||
- ECDSA signing/verifying (supports secp256k1 and nist256p1 curves,
|
||||
uses RFC6979 for deterministic signatures)
|
||||
- ECDSA public key derivation
|
||||
- Base32 (RFC4648 and custom alphabets)
|
||||
- Base58 address representation
|
||||
- Ed25519 signing/verifying (also SHA3 and Keccak variants)
|
||||
- ECDH using secp256k1, nist256p1 and Curve25519
|
||||
- HMAC-SHA256 and HMAC-SHA512
|
||||
- PBKDF2
|
||||
- RIPEMD-160
|
||||
- SHA1
|
||||
- SHA2-256/SHA2-512
|
||||
- SHA3/Keccak
|
||||
- BLAKE2s/BLAKE2b
|
||||
- Chacha20-Poly1305
|
||||
- unit tests (using Check - check.sf.net; in test_check.c)
|
||||
- tests against OpenSSL (in test_openssl.c)
|
||||
- integrated Wycheproof tests
|
||||
|
||||
Distibuted under MIT License.
|
||||
|
||||
## Some parts of the library come from external sources:
|
||||
|
||||
- AES: https://github.com/BrianGladman/aes
|
||||
- Base58: https://github.com/luke-jr/libbase58
|
||||
- BLAKE2s/BLAKE2b: https://github.com/BLAKE2/BLAKE2
|
||||
- RIPEMD-160: https://github.com/ARMmbed/mbedtls
|
||||
- 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
|
||||
- Chacha20: https://github.com/wg/c20p1305
|
||||
- Poly1305: https://github.com/floodyberry/poly1305-donna
|
91
crypto/address.c
Normal file
91
crypto/address.c
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2016 Daira Hopwood
|
||||
* Copyright (c) 2016 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "address.h"
|
||||
#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;
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
#if USE_ETHEREUM
|
||||
#include "sha3.h"
|
||||
|
||||
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
|
||||
uint32_t chain_id) {
|
||||
const char *hex = "0123456789abcdef";
|
||||
for (int i = 0; i < 20; i++) {
|
||||
address[i * 2] = hex[(addr[i] >> 4) & 0xF];
|
||||
address[i * 2 + 1] = hex[addr[i] & 0xF];
|
||||
}
|
||||
address[40] = 0;
|
||||
|
||||
SHA3_CTX ctx;
|
||||
uint8_t hash[32];
|
||||
keccak_256_Init(&ctx);
|
||||
if (rskip60) {
|
||||
char prefix[16];
|
||||
int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false,
|
||||
prefix, sizeof(prefix));
|
||||
keccak_Update(&ctx, (const uint8_t *)prefix, prefix_size);
|
||||
}
|
||||
keccak_Update(&ctx, (const uint8_t *)address, 40);
|
||||
keccak_Final(&ctx, hash);
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (hash[i] & 0x80 && address[i * 2] >= 'a' && address[i * 2] <= 'f') {
|
||||
address[i * 2] -= 0x20;
|
||||
}
|
||||
if (hash[i] & 0x08 && address[i * 2 + 1] >= 'a' &&
|
||||
address[i * 2 + 1] <= 'f') {
|
||||
address[i * 2 + 1] -= 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
40
crypto/address.h
Normal file
40
crypto/address.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2016 Daira Hopwood
|
||||
* Copyright (c) 2016 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ADDRESS_H__
|
||||
#define __ADDRESS_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#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);
|
||||
#if USE_ETHEREUM
|
||||
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
|
||||
uint32_t chain_id);
|
||||
#endif
|
||||
|
||||
#endif
|
226
crypto/aes/aes.h
Normal file
226
crypto/aes/aes.h
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 02/08/2018
|
||||
|
||||
This file contains the definitions required to use AES in C. See aesopt.h
|
||||
for optimisation details.
|
||||
*/
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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"
|
||||
{
|
||||
#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_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
|
||||
#endif
|
||||
|
||||
/* The following must also be set in assembler files if being used */
|
||||
|
||||
#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 */
|
||||
|
||||
/* 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
|
||||
#else
|
||||
#define KS_LENGTH 44
|
||||
#endif
|
||||
|
||||
#define AES_RETURN INT_RETURN
|
||||
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* 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;
|
||||
uint8_t b[4];
|
||||
} aes_inf;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# 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)))
|
||||
#else
|
||||
#define ALIGNED_(x)
|
||||
#endif
|
||||
|
||||
typedef struct ALIGNED_(16)
|
||||
{ uint32_t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_encrypt_ctx;
|
||||
|
||||
typedef struct ALIGNED_(16)
|
||||
{ uint32_t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_decrypt_ctx;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( default : 4324 )
|
||||
#endif
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
/* tables are being used */
|
||||
|
||||
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_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]);
|
||||
#endif
|
||||
|
||||
#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]);
|
||||
#endif
|
||||
|
||||
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_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]);
|
||||
#endif
|
||||
|
||||
#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]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
/* long messages incrementally provided that the context AND the iv */
|
||||
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||
/* each individual call within a series of incremental calls must */
|
||||
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB needs no reset and CBC can be reset without setting */
|
||||
/* a new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* without setting the key, aes_mode_reset() must be called and the */
|
||||
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||
/* this has to be reset if a new operation with the same IV as the */
|
||||
/* previous one is required (or decryption follows encryption with */
|
||||
/* the same IV array). */
|
||||
|
||||
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_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_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]);
|
||||
|
||||
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]);
|
||||
|
||||
void aes_ctr_cbuf_inc(unsigned char *cbuf);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
957
crypto/aes/aes_modes.c
Normal file
957
crypto/aes/aes_modes.c
Normal file
@ -0,0 +1,957 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
These subroutines implement multiple block AES modes for ECB, CBC, CFB,
|
||||
OFB and CTR encryption, The code provides support for the VIA Advanced
|
||||
Cryptography Engine (ACE).
|
||||
|
||||
NOTE: In the following subroutines, the AES contexts (ctx) must be
|
||||
16 byte aligned if VIA ACE is being used
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined( AES_MODES )
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
/* some machines so this define can be commented out if necessary */
|
||||
|
||||
#define FAST_BUFFER_OPERATIONS
|
||||
|
||||
#define lp32(x) ((uint32_t*)(x))
|
||||
|
||||
#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_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_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;
|
||||
|
||||
/* NOTE: These control word macros must only be used after */
|
||||
/* a key has been set up because they depend on key size */
|
||||
/* See the VIA ACE documentation for key type information */
|
||||
/* and aes_via_ace.h for non-default NEH_KEY_TYPE values */
|
||||
|
||||
#ifndef NEH_KEY_TYPE
|
||||
# define NEH_KEY_TYPE NEH_HYBRID
|
||||
#endif
|
||||
|
||||
#if NEH_KEY_TYPE == NEH_LOAD
|
||||
#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])
|
||||
#elif NEH_KEY_TYPE == NEH_HYBRID
|
||||
#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
|
||||
|
||||
#else
|
||||
|
||||
#define aligned_array(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
|
||||
|
||||
#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; \
|
||||
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];
|
||||
uint32_t i, count_eq = 0, count_neq = 0;
|
||||
|
||||
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);
|
||||
|
||||
if(qh == qf)
|
||||
++count_eq;
|
||||
else if(qh == qf + n)
|
||||
++count_neq;
|
||||
else
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( 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);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
|
||||
|
||||
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
|
||||
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
nb -= m;
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( 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);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
|
||||
|
||||
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
|
||||
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
nb -= m;
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( 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 ))
|
||||
{
|
||||
via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
|
||||
|
||||
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
|
||||
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
nb -= m;
|
||||
}
|
||||
}
|
||||
|
||||
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--)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
memcpy(obuf, iv, AES_BLOCK_SIZE);
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
#endif
|
||||
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];
|
||||
int nb = len >> AES_BLOCK_SIZE_P2;
|
||||
|
||||
if(len & (AES_BLOCK_SIZE - 1))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( 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 ))
|
||||
{
|
||||
via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp);
|
||||
}
|
||||
else
|
||||
{ aligned_auto(uint8_t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
while(nb)
|
||||
{
|
||||
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
|
||||
|
||||
ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
|
||||
op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
nb -= m;
|
||||
}
|
||||
}
|
||||
|
||||
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--)
|
||||
{
|
||||
memcpy(tmp, ibuf, AES_BLOCK_SIZE);
|
||||
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];
|
||||
lp32(obuf)[3] ^= lp32(iv)[3];
|
||||
memcpy(iv, tmp, AES_BLOCK_SIZE);
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
else
|
||||
# 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];
|
||||
memcpy(iv, tmp, AES_BLOCK_SIZE);
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
|
||||
if(b_pos) /* complete any partial block */
|
||||
{
|
||||
while(b_pos < AES_BLOCK_SIZE && cnt < len)
|
||||
{
|
||||
*obuf++ = (iv[b_pos++] ^= *ibuf++);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( iv, 16 )) /* ensure an aligned iv */
|
||||
{
|
||||
ivp = liv;
|
||||
memcpy(liv, iv, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
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);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
cnt += m * 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)
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
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;
|
||||
}
|
||||
else
|
||||
# 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];
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += 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 && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
*obuf++ = (iv[b_pos++] ^= *ibuf++);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
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;
|
||||
|
||||
if(b_pos) /* complete any partial block */
|
||||
{ uint8_t t;
|
||||
|
||||
while(b_pos < AES_BLOCK_SIZE && cnt < len)
|
||||
{
|
||||
t = *ibuf++;
|
||||
*obuf++ = t ^ iv[b_pos];
|
||||
iv[b_pos++] = t;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( iv, 16 )) /* ensure an aligned iv */
|
||||
{
|
||||
ivp = liv;
|
||||
memcpy(liv, iv, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
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);
|
||||
uint8_t *ip, *op;
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
memcpy(obuf, buf, m * AES_BLOCK_SIZE);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
cnt += m * 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;
|
||||
|
||||
assert(b_pos == 0);
|
||||
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;
|
||||
}
|
||||
else
|
||||
# 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;
|
||||
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;
|
||||
t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t;
|
||||
t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t;
|
||||
t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t;
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
cnt += AES_BLOCK_SIZE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
while(cnt < len)
|
||||
{ uint8_t t;
|
||||
|
||||
if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(cnt < len && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
t = *ibuf++;
|
||||
*obuf++ = t ^ iv[b_pos];
|
||||
iv[b_pos++] = t;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
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;
|
||||
|
||||
if(b_pos) /* complete any partial block */
|
||||
{
|
||||
while(b_pos < AES_BLOCK_SIZE && cnt < len)
|
||||
{
|
||||
*obuf++ = iv[b_pos++] ^ *ibuf++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
|
||||
{
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
|
||||
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( iv, 16 )) /* ensure an aligned iv */
|
||||
{
|
||||
ivp = liv;
|
||||
memcpy(liv, iv, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
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, *op;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ibuf += m * AES_BLOCK_SIZE;
|
||||
obuf += m * AES_BLOCK_SIZE;
|
||||
cnt += m * 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)
|
||||
{
|
||||
assert(b_pos == 0);
|
||||
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;
|
||||
}
|
||||
else
|
||||
# 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];
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += 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 && b_pos < AES_BLOCK_SIZE)
|
||||
{
|
||||
*obuf++ = iv[b_pos++] ^ *ibuf++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
|
||||
}
|
||||
|
||||
ctx->inf.b[2] = (uint8_t)b_pos;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#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, blen, b_pos = (int)(ctx->inf.b[2]);
|
||||
|
||||
#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;
|
||||
#else
|
||||
uint8_t buf[BFR_LENGTH];
|
||||
#endif
|
||||
|
||||
if(b_pos)
|
||||
{
|
||||
memcpy(buf, cbuf, AES_BLOCK_SIZE);
|
||||
if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while(b_pos < AES_BLOCK_SIZE && len)
|
||||
{
|
||||
*obuf++ = *ibuf++ ^ buf[b_pos++];
|
||||
--len;
|
||||
}
|
||||
|
||||
if(len)
|
||||
ctr_inc(cbuf), b_pos = 0;
|
||||
}
|
||||
|
||||
while(len)
|
||||
{
|
||||
blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
|
||||
|
||||
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 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
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
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];
|
||||
lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3];
|
||||
i += AES_BLOCK_SIZE;
|
||||
ip += AES_BLOCK_SIZE;
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
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];
|
||||
i += AES_BLOCK_SIZE;
|
||||
ip += AES_BLOCK_SIZE;
|
||||
ibuf += AES_BLOCK_SIZE;
|
||||
obuf += AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int i = AES_BLOCK_SIZE - 1;
|
||||
while (i >= 0) {
|
||||
cbuf[i]++;
|
||||
if (cbuf[i]) return; // if there was no overflow
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
307
crypto/aes/aescrypt.c
Normal file
307
crypto/aes/aescrypt.c
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.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
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
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))
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#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
|
||||
#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 )
|
||||
|
||||
/* 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 )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
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)))
|
||||
|
||||
#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))
|
||||
#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))
|
||||
#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)))
|
||||
#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))
|
||||
#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))
|
||||
#else
|
||||
#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;
|
||||
#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;
|
||||
|
||||
kp = cx->ks;
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
//-fallthrough
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#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);
|
||||
#else
|
||||
{ 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);
|
||||
}
|
||||
#endif
|
||||
kp += N_COLS;
|
||||
round(fwd_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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 )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
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)))
|
||||
|
||||
#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))
|
||||
#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))
|
||||
#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)))
|
||||
#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))
|
||||
#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))
|
||||
#else
|
||||
#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 */
|
||||
/* order that is used for encrytpion (where the 1st decryption */
|
||||
/* round key is at the high end ot the schedule) or with a key */
|
||||
/* schedule that has been reversed to put the 1st decryption */
|
||||
/* round key at the low end of the schedule in memory (when */
|
||||
/* AES_REV_DKS is defined) */
|
||||
|
||||
#ifdef AES_REV_DKS
|
||||
#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)
|
||||
#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 )
|
||||
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||
#endif
|
||||
const uint32_t *kp;
|
||||
|
||||
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)
|
||||
|
||||
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
|
||||
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));
|
||||
//-fallthrough
|
||||
case 12 * AES_BLOCK_SIZE:
|
||||
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));
|
||||
//-fallthrough
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#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);
|
||||
round(inv_rnd, b0, b1, kp);
|
||||
}
|
||||
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)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp = rnd_key(1);
|
||||
round(inv_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
560
crypto/aes/aeskey.c
Normal file
560
crypto/aes/aeskey.c
Normal file
@ -0,0 +1,560 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.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
|
||||
#endif
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
# include "aes_via_ace.h"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length can be specified in bytes, with legal values of 16, 24
|
||||
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||
values correspond with Nk values of 4, 6 and 8 respectively.
|
||||
|
||||
The following macros implement a single cycle in the key
|
||||
schedule generation process. The number of cycles needed
|
||||
for each cx->n_col and nk value is:
|
||||
|
||||
nk = 4 5 6 7 8
|
||||
------------------------------
|
||||
cx->n_col = 4 10 9 8 7 7
|
||||
cx->n_col = 5 14 11 10 9 9
|
||||
cx->n_col = 6 19 15 12 11 11
|
||||
cx->n_col = 7 21 19 16 13 14
|
||||
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
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & ENC_KEYING_IN_C)
|
||||
|
||||
#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]; \
|
||||
}
|
||||
|
||||
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);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
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, 8);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 9; ++i)
|
||||
ke4(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
ke4(cx->ks, 9);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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 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];
|
||||
|
||||
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);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
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, 6);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 7; ++i)
|
||||
ke6(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef6(cx->ks, 7);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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 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];
|
||||
|
||||
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);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||
cx->ks[6] = ss[6] = word_in(key, 6);
|
||||
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);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 6; ++i)
|
||||
ke8(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef8(cx->ks, 6);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#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))
|
||||
#else
|
||||
#define v(n,i) (i)
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES
|
||||
#define ff(x) (x)
|
||||
#else
|
||||
#define ff(x) inv_mcol(x)
|
||||
#if defined( dec_imvars )
|
||||
#define d_vars dec_imvars
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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]; \
|
||||
}
|
||||
|
||||
#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 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]; \
|
||||
}
|
||||
|
||||
#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 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]; \
|
||||
}
|
||||
|
||||
#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;
|
||||
#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);
|
||||
|
||||
#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);
|
||||
#else
|
||||
{ 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]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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 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 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]; \
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#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);
|
||||
#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;
|
||||
|
||||
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]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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 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 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]; \
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#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);
|
||||
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);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 14 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#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_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
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
784
crypto/aes/aesopt.h
Normal file
784
crypto/aes/aesopt.h
Normal file
@ -0,0 +1,784 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the compilation options for AES (Rijndael) and code
|
||||
that is common across encryption, key scheduling and table generation.
|
||||
|
||||
OPERATION
|
||||
|
||||
These source code files implement the AES algorithm Rijndael designed by
|
||||
Joan Daemen and Vincent Rijmen. This version is designed for the standard
|
||||
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
|
||||
and 32 bytes).
|
||||
|
||||
This version is designed for flexibility and speed using operations on
|
||||
32-bit words rather than operations on bytes. It can be compiled with
|
||||
either big or little endian internal byte order but is faster when the
|
||||
native byte order for the processor is used.
|
||||
|
||||
THE CIPHER INTERFACE
|
||||
|
||||
The cipher interface is implemented as an array of bytes in which lower
|
||||
AES bit sequence indexes map to higher numeric significance within bytes.
|
||||
|
||||
uint8_t (an unsigned 8-bit type)
|
||||
uint32_t (an unsigned 32-bit type)
|
||||
struct aes_encrypt_ctx (structure for the cipher encryption context)
|
||||
struct aes_decrypt_ctx (structure for the cipher decryption context)
|
||||
AES_RETURN the function return type
|
||||
|
||||
C subroutine calls:
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
|
||||
you call aes_init() before AES is used so that the tables are initialised.
|
||||
|
||||
C++ aes class subroutines:
|
||||
|
||||
Class AESencrypt for encryption
|
||||
|
||||
Constructors:
|
||||
AESencrypt(void)
|
||||
AESencrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||
|
||||
Class AESdecrypt for encryption
|
||||
Constructors:
|
||||
AESdecrypt(void)
|
||||
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
|
||||
*/
|
||||
|
||||
#if !defined( _AESOPT_H )
|
||||
#define _AESOPT_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
#include "aescpp.h"
|
||||
#else
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
/* PLATFORM SPECIFIC INCLUDES */
|
||||
|
||||
#define IS_BIG_ENDIAN 4321
|
||||
#define IS_LITTLE_ENDIAN 1234
|
||||
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
/* CONFIGURATION - THE USE OF DEFINES
|
||||
|
||||
Later in this section there are a number of defines that control the
|
||||
operation of the code. In each section, the purpose of each define is
|
||||
explained so that the relevant form can be included or excluded by
|
||||
setting either 1's or 0's respectively on the branches of the related
|
||||
#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 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 --- */
|
||||
|
||||
/* 1. BYTE ORDER WITHIN 32 BIT WORDS
|
||||
|
||||
The fundamental data processing units in Rijndael are 8-bit bytes. The
|
||||
input, output and key input are all enumerated arrays of bytes in which
|
||||
bytes are numbered starting at zero and increasing to one less than the
|
||||
number of bytes in the array in question. This enumeration is only used
|
||||
for naming bytes and does not imply any adjacency or order relationship
|
||||
from one byte to another. When these inputs and outputs are considered
|
||||
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
|
||||
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
|
||||
In this implementation bits are numbered from 0 to 7 starting at the
|
||||
numerically least significant end of each byte (bit n represents 2^n).
|
||||
|
||||
However, Rijndael can be implemented more efficiently using 32-bit
|
||||
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
|
||||
into word[n]. While in principle these bytes can be assembled into words
|
||||
in any positions, this implementation only supports the two formats in
|
||||
which bytes in adjacent positions within words also have adjacent byte
|
||||
numbers. This order is called big-endian if the lowest numbered bytes
|
||||
in words have the highest numeric significance and little-endian if the
|
||||
opposite applies.
|
||||
|
||||
This code can work in either order irrespective of the order used by the
|
||||
machine on which it runs. Normally the internal byte order will be set
|
||||
to the order of the processor on which the code is to be run but this
|
||||
define can be used to reverse this in special situations
|
||||
|
||||
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
|
||||
This define will hence be redefined later (in section 4) if necessary
|
||||
*/
|
||||
|
||||
#if 1
|
||||
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# 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
|
||||
#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
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the Intel AESNI is required
|
||||
If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used
|
||||
if it is detected (both present and enabled).
|
||||
|
||||
AESNI uses a decryption key schedule with the first decryption
|
||||
round key at the high end of the key scedule with the following
|
||||
round keys at lower positions in memory. So AES_REV_DKS must NOT
|
||||
be defined when AESNI will be used. Although it is unlikely that
|
||||
assembler code will be used with an AESNI build, if it is then
|
||||
AES_REV_DKS must NOT be defined when the assembler files are
|
||||
built (the definition of USE_INTEL_AES_IF_PRESENT in the assembler
|
||||
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
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the VIA ACE is required. This uses
|
||||
inline assembler instructions and is only implemented for the Microsoft,
|
||||
Intel and GCC compilers. If VIA ACE is known to be present, then defining
|
||||
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
|
||||
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
|
||||
it is detected (both present and enabled) but the normal AES code will
|
||||
also be present.
|
||||
|
||||
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
|
||||
aligned; other input/output buffers do not need to be 16 byte aligned
|
||||
but there are very large performance gains if this can be arranged.
|
||||
VIA ACE also requires the decryption key schedule to be in reverse
|
||||
order (which later checks below ensure).
|
||||
|
||||
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
|
||||
#endif
|
||||
|
||||
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
|
||||
# define ASSUME_VIA_ACE_PRESENT
|
||||
# endif
|
||||
|
||||
/* 3. ASSEMBLER SUPPORT
|
||||
|
||||
This define (which can be on the command line) enables the use of the
|
||||
assembler code routines for encryption, decryption and key scheduling
|
||||
as follows:
|
||||
|
||||
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption, decryption and key scheduling
|
||||
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
|
||||
Change one 'if 0' below to 'if 1' to select the version or define
|
||||
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
|
||||
#endif
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
/* 4. FAST INPUT/OUTPUT OPERATIONS.
|
||||
|
||||
On some machines it is possible to improve speed by transferring the
|
||||
bytes in the input and output arrays to and from the internal 32-bit
|
||||
variables by addressing these arrays as if they are arrays of 32-bit
|
||||
words. On some machines this will always be possible but there may
|
||||
be a large performance penalty if the byte arrays are not aligned on
|
||||
the normal word boundaries. On other machines this technique will
|
||||
lead to memory access errors when such 32-bit word accesses are not
|
||||
properly aligned. The option SAFE_IO avoids such problems but will
|
||||
often be slower on those machines that support misaligned access
|
||||
(especially so if care is taken to align the input and output byte
|
||||
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
|
||||
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
|
||||
#endif
|
||||
|
||||
/* 5. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion cycles through a number of rounds
|
||||
that can be implemented either in a loop or by expanding the code into a
|
||||
long sequence of instructions, the latter producing a larger program but
|
||||
one that will often be much faster. The latter is called loop unrolling.
|
||||
There are also potential speed advantages in expanding two iterations in
|
||||
a loop with half the number of iterations, which is called partial loop
|
||||
unrolling. The following options allow partial or full loop unrolling
|
||||
to be set independently for encryption and decryption
|
||||
*/
|
||||
#if 1
|
||||
# define ENC_UNROLL FULL
|
||||
#elif 0
|
||||
# define ENC_UNROLL PARTIAL
|
||||
#else
|
||||
# define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_UNROLL FULL
|
||||
#elif 0
|
||||
# define DEC_UNROLL PARTIAL
|
||||
#else
|
||||
# define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define ENC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
/* 6. FAST FINITE FIELD OPERATIONS
|
||||
|
||||
If this section is included, tables are used to provide faster finite
|
||||
field arithmetic (this has no effect if STATIC_TABLES is defined).
|
||||
*/
|
||||
#if 1
|
||||
# define FF_TABLES
|
||||
#endif
|
||||
|
||||
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||
|
||||
The internal state of Rijndael is stored in a number of local 32-bit
|
||||
word varaibles which can be defined either as an array or as individual
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
# define ARRAYS
|
||||
#endif
|
||||
|
||||
/* 8. FIXED OR DYNAMIC TABLES
|
||||
|
||||
When this section is included the tables used by the code are compiled
|
||||
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
|
||||
#endif
|
||||
|
||||
/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
|
||||
|
||||
In some systems it is better to mask longer values to extract bytes
|
||||
rather than using a cast. This option allows this choice.
|
||||
*/
|
||||
#if 0
|
||||
# define to_byte(x) ((uint8_t)(x))
|
||||
#else
|
||||
# define to_byte(x) ((x) & 0xff)
|
||||
#endif
|
||||
|
||||
/* 10. TABLE ALIGNMENT
|
||||
|
||||
On some sytsems speed will be improved by aligning the AES large lookup
|
||||
tables on particular boundaries. This define should be set to a power of
|
||||
two giving the desired alignment. It can be left undefined if alignment
|
||||
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||
*/
|
||||
|
||||
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# define TABLE_ALIGN 32
|
||||
#endif
|
||||
|
||||
/* 11. REDUCE CODE AND TABLE SIZE
|
||||
|
||||
This replaces some expanded macros with function calls if AES_ASM_V2 or
|
||||
AES_ASM_V2C are defined
|
||||
*/
|
||||
|
||||
#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
|
||||
# define REDUCE_CODE_SIZE
|
||||
#endif
|
||||
|
||||
/* 12. TABLE OPTIONS
|
||||
|
||||
This cipher proceeds by repeating in a number of cycles known as 'rounds'
|
||||
which are implemented by a round function which can optionally be speeded
|
||||
up using tables. The basic tables are each 256 32-bit words, with either
|
||||
one or four tables being required for each round function depending on
|
||||
how much speed is required. The encryption and decryption round functions
|
||||
are different and the last encryption and decrytpion round functions are
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
1. Normal encryption and decryption rounds can each use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
2. The last encryption and decryption rounds can also use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
|
||||
Include or exclude the appropriate definitions below to set the number
|
||||
of tables used by this implementation.
|
||||
*/
|
||||
|
||||
#if 1 /* set tables for the normal encryption round */
|
||||
# define ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last encryption round */
|
||||
# define LAST_ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the normal decryption round */
|
||||
# define DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last decryption round */
|
||||
# define LAST_DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
/* The decryption key schedule can be speeded up with tables in the same
|
||||
way that the round functions can. Include or exclude the following
|
||||
defines to set this requirement.
|
||||
*/
|
||||
#if 1
|
||||
# define KEY_SCHED FOUR_TABLES
|
||||
#elif 0
|
||||
# define KEY_SCHED ONE_TABLE
|
||||
#else
|
||||
# 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
|
||||
#endif
|
||||
|
||||
#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
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
/* In this implementation the columns of the state array are each held in
|
||||
32-bit words. The state array can be held in various ways: in an array
|
||||
of words, in a number of individual word variables or in a number of
|
||||
processor registers. The following define maps a variable name x and
|
||||
a column number c to the way the state array variable is to be held.
|
||||
The first define below maps the state into an array x[c] whereas the
|
||||
second form maps the state into a number of individual variables x0,
|
||||
x1, etc. Another form could map individual state colums to machine
|
||||
register names.
|
||||
*/
|
||||
|
||||
#if defined( ARRAYS )
|
||||
# define s(x,c) x[c]
|
||||
#else
|
||||
# define s(x,c) x##c
|
||||
#endif
|
||||
|
||||
/* This implementation provides subroutines for encryption, decryption
|
||||
and for setting the three key lengths (separately) for encryption
|
||||
and decryption. Since not all functions are needed, masks are set
|
||||
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 )
|
||||
#else
|
||||
# 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 )
|
||||
#else
|
||||
# define DFUNCS_IN_C 0
|
||||
#endif
|
||||
|
||||
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
|
||||
|
||||
/* END OF CONFIGURATION OPTIONS */
|
||||
|
||||
#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
|
||||
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
|
||||
# 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
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && 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
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && 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
|
||||
#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))
|
||||
#endif
|
||||
|
||||
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||
higher index positions with wrap around into low positions
|
||||
ups(x,n): moves bytes by n positions to higher index positions in
|
||||
words but without wrap around
|
||||
bval(x,n): extracts a byte from a word
|
||||
|
||||
WARNING: The definitions given here are intended only for use with
|
||||
unsigned variables and with shift counts that are compile
|
||||
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))
|
||||
#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))
|
||||
#endif
|
||||
|
||||
/* the finite field modular polynomial and elements */
|
||||
|
||||
#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))
|
||||
|
||||
/* The following defines provide alternative definitions of gf_mulx that might
|
||||
give improved performance if a fast 32-bit multiply is not available. Note
|
||||
that a temporary variable u needs to be defined where gf_mulx is used.
|
||||
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define gf_c4 (0x01010101 * BPOLY)
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
|
||||
*/
|
||||
|
||||
/* 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
|
||||
#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 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 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( 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))
|
||||
#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)
|
||||
#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)
|
||||
#else
|
||||
# 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
|
||||
#endif
|
||||
|
||||
#endif
|
418
crypto/aes/aestab.c
Normal file
418
crypto/aes/aestab.c
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#define DO_TABLES
|
||||
|
||||
#include "aes.h"
|
||||
#include "aesopt.h"
|
||||
|
||||
#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))
|
||||
|
||||
#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))
|
||||
|
||||
#else
|
||||
|
||||
#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
|
||||
#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
|
||||
#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
|
||||
#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
|
||||
#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
|
||||
#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
|
||||
|
||||
#endif
|
||||
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(STATIC_TABLES)
|
||||
|
||||
/* implemented in case of wrong call for fixed tables */
|
||||
|
||||
AES_RETURN aes_init(void)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* Generate the tables for the dynamic table option */
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0)
|
||||
|
||||
#else
|
||||
|
||||
/* It will generally be sensible to use tables to compute finite
|
||||
field multiplies and inverses but where memory is scarse this
|
||||
code might sometimes be better. But it only has effect during
|
||||
initialisation so its pretty unimportant in overall terms.
|
||||
*/
|
||||
|
||||
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||
set in x with x in the range 1 < x < 0x00000200. This form is
|
||||
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));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
return (r + 1) >> 1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
if(x < 2)
|
||||
return x;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
if(n1)
|
||||
while(n2 >= n1) /* divide polynomial p2 by p1 */
|
||||
{
|
||||
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 */
|
||||
}
|
||||
else
|
||||
return v1;
|
||||
|
||||
if(n2) /* repeat with values swapped */
|
||||
while(n1 >= n2)
|
||||
{
|
||||
n1 /= n2;
|
||||
p1 ^= p2 * n1;
|
||||
v1 ^= v2 * n1;
|
||||
n1 = hibit(p1);
|
||||
}
|
||||
else
|
||||
return v2;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
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;
|
||||
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;
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
uint8_t pow[512], log[256];
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
|
||||
#else
|
||||
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);
|
||||
w = f2(w);
|
||||
}
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#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) */
|
||||
#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);
|
||||
#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 */
|
||||
#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);
|
||||
#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;
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#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;
|
||||
#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);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
init = 1;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Automatic code initialisation (suggested by by Henrik S. Gaßmann)
|
||||
based on code provided by Joe Lowe and placed in the public domain at:
|
||||
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#pragma section(".CRT$XCU", read)
|
||||
|
||||
__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)
|
||||
{
|
||||
aes_init();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#pragma message( "dynamic tables must be initialised manually on your system" )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
173
crypto/aes/aestab.h
Normal file
173
crypto/aes/aestab.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the code for declaring the tables needed to implement
|
||||
AES. The file aesopt.h is assumed to be included before this header file.
|
||||
If there are no global variables, the definitions here can be used to put
|
||||
the AES tables in a structure so that a pointer can then be added to the
|
||||
AES context to pass them to the AES routines that need them. If this
|
||||
facility is used, the calling program has to ensure that this pointer is
|
||||
managed appropriately. In particular, the value of the t_dec(in,it) item
|
||||
in the table structure must be set to zero in order to ensure that the
|
||||
tables are initialised. In practice the three code sequences in aeskey.c
|
||||
that control the calls to aes_init() and the aes_init() routine itself will
|
||||
have to be changed for a specific implementation. If global variables are
|
||||
available it will generally be preferable to use them with the precomputed
|
||||
STATIC_TABLES option that uses static global tables.
|
||||
|
||||
The following defines can be used to control the way the tables
|
||||
are defined, initialised and used in embedded environments that
|
||||
require special features for these purposes
|
||||
|
||||
the 't_dec' construction is used to declare fixed table arrays
|
||||
the 't_set' construction is used to set fixed table values
|
||||
the 't_use' construction is used to access fixed table values
|
||||
|
||||
256 byte tables:
|
||||
|
||||
t_xxx(s,box) => forward S box
|
||||
t_xxx(i,box) => inverse S box
|
||||
|
||||
256 32-bit word OR 4 x 256 32-bit word tables:
|
||||
|
||||
t_xxx(f,n) => forward normal round
|
||||
t_xxx(f,l) => forward last round
|
||||
t_xxx(i,n) => inverse normal round
|
||||
t_xxx(i,l) => inverse last round
|
||||
t_xxx(l,s) => key schedule table
|
||||
t_xxx(i,m) => key schedule table
|
||||
|
||||
Other variables and tables:
|
||||
|
||||
t_xxx(r,c) => the rcon table
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
#if defined(STATIC_TABLES)
|
||||
# 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
|
||||
#else
|
||||
# define CONST
|
||||
#endif
|
||||
|
||||
#if defined(DO_TABLES)
|
||||
# define EXTERN
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(TABLE_ALIGN)
|
||||
#define ALIGN __declspec(align(TABLE_ALIGN))
|
||||
#else
|
||||
#define ALIGN
|
||||
#endif
|
||||
|
||||
#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
|
||||
# define XP_DIR __cdecl
|
||||
#else
|
||||
# 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);
|
||||
#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];
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#if defined( LS1_SET )
|
||||
#if defined( FL1_SET )
|
||||
#undef LS1_SET
|
||||
#else
|
||||
d_1(uint32_t, t_dec(l,s), sb_data, w0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
178
crypto/aes/aestst.c
Normal file
178
crypto/aes/aestst.c
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
// Correct Output (for variable block size - AES_BLOCK_SIZE undefined):
|
||||
|
||||
// lengths: block = 16 bytes, key = 16 bytes
|
||||
// key = 2b7e151628aed2a6abf7158809cf4f3c
|
||||
// input = 3243f6a8885a308d313198a2e0370734
|
||||
// encrypt = 3925841d02dc09fbdc118597196a0b32
|
||||
// decrypt = 3243f6a8885a308d313198a2e0370734
|
||||
|
||||
// lengths: block = 16 bytes, key = 24 bytes
|
||||
// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da5
|
||||
// input = 3243f6a8885a308d313198a2e0370734
|
||||
// encrypt = f9fb29aefc384a250340d833b87ebc00
|
||||
// decrypt = 3243f6a8885a308d313198a2e0370734
|
||||
|
||||
// lengths: block = 16 bytes, key = 32 bytes
|
||||
// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe
|
||||
// input = 3243f6a8885a308d313198a2e0370734
|
||||
// encrypt = 1a6e6c2c662e7da6501ffb62bc9e93f3
|
||||
// decrypt = 3243f6a8885a308d313198a2e0370734
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aes.h"
|
||||
#include "aestst.h"
|
||||
|
||||
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;
|
||||
|
||||
printf("\n%s", m);
|
||||
|
||||
for(i = 0; i < n; ++i)
|
||||
printf("%02x", v[i]);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
void cycles(volatile uint64_t *rtn)
|
||||
{
|
||||
#if defined( _MSCVER )
|
||||
__asm // read the Pentium Time Stamp Counter
|
||||
{ cpuid
|
||||
rdtsc
|
||||
mov ecx,rtn
|
||||
mov [ecx],eax
|
||||
mov [ecx+4],edx
|
||||
cpuid
|
||||
}
|
||||
#elif defined( __GNUC__ )
|
||||
__asm__ __volatile__("rdtsc": "=A" (*rtn));
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{ unsigned char out[32], ret[32], err = 0;
|
||||
f_ectx alge[1];
|
||||
f_dctx algd[1];
|
||||
|
||||
aes_init();
|
||||
|
||||
message("\nRun tests for the AES algorithm");
|
||||
|
||||
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);
|
||||
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; }
|
||||
f_dec_key128(algd, exh);
|
||||
do_dec(algd, out, ret, 1);
|
||||
oblk("// decrypt = ", ret, 16);
|
||||
if(memcmp(ret, pih, 16)) { message (" error"); err += 2; }
|
||||
#endif
|
||||
|
||||
#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; }
|
||||
f_dec_key192(algd, exh);
|
||||
do_dec(algd, out, ret, 1);
|
||||
oblk("// decrypt = ", ret, 16);
|
||||
if(memcmp(ret, pih, 16)) { message (" error"); err += 8; }
|
||||
#endif
|
||||
|
||||
#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; }
|
||||
f_dec_key256(algd, exh);
|
||||
do_dec(algd, out, ret, 1);
|
||||
oblk("// decrypt = ", ret, 16);
|
||||
if(memcmp(ret, pih, 16)) { message (" error"); err += 32; }
|
||||
#endif
|
||||
|
||||
if(!err)
|
||||
message("\n\nThese values are all correct\n\n");
|
||||
else
|
||||
message("\n\nSome values are in error\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
85
crypto/aes/aestst.h
Normal file
85
crypto/aes/aestst.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
// The following definitions are required for testing only, They are not needed
|
||||
// for AES (Rijndael) implementation. They are used to allow C, C++ and DLL
|
||||
// data access and subroutine calls to be expressed in the same form in the
|
||||
// testing code.
|
||||
|
||||
#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_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 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 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)
|
||||
#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)
|
||||
#endif
|
||||
|
||||
#endif
|
240
crypto/base32.c
Normal file
240
crypto/base32.c
Normal file
@ -0,0 +1,240 @@
|
||||
/**
|
||||
* Copyright (c) 2017 Saleem Rashid
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, E1PRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "base32.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
const char *BASE32_ALPHABET_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789";
|
||||
|
||||
static inline void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out);
|
||||
static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out,
|
||||
const char *alphabet);
|
||||
static inline void base32_8to5_raw(const uint8_t *in, uint8_t length,
|
||||
uint8_t *out);
|
||||
|
||||
static inline int base32_encode_character(uint8_t decoded,
|
||||
const char *alphabet);
|
||||
static inline int base32_decode_character(char encoded, const char *alphabet);
|
||||
|
||||
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen,
|
||||
const char *alphabet) {
|
||||
size_t length = base32_encoded_length(inlen);
|
||||
if (outlen <= length) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base32_encode_unsafe(in, inlen, (uint8_t *)out);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
int ret = base32_encode_character(out[i], alphabet);
|
||||
|
||||
if (ret == -1) {
|
||||
return false;
|
||||
} else {
|
||||
out[i] = ret;
|
||||
}
|
||||
}
|
||||
|
||||
out[length] = '\0';
|
||||
return &out[length];
|
||||
}
|
||||
|
||||
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out,
|
||||
size_t outlen, const char *alphabet) {
|
||||
size_t length = base32_decoded_length(inlen);
|
||||
if (outlen < length) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!base32_decode_unsafe((uint8_t *)in, inlen, (uint8_t *)out, alphabet)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &out[length];
|
||||
}
|
||||
|
||||
void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out) {
|
||||
uint8_t remainder = inlen % 5;
|
||||
size_t limit = inlen - remainder;
|
||||
|
||||
size_t i, j;
|
||||
for (i = 0, j = 0; i < limit; i += 5, j += 8) {
|
||||
base32_5to8(&in[i], 5, &out[j]);
|
||||
}
|
||||
|
||||
if (remainder) base32_5to8(&in[i], remainder, &out[j]);
|
||||
}
|
||||
|
||||
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out,
|
||||
const char *alphabet) {
|
||||
uint8_t remainder = inlen % 8;
|
||||
size_t limit = inlen - remainder;
|
||||
|
||||
size_t i, j;
|
||||
for (i = 0, j = 0; i < limit; i += 8, j += 5) {
|
||||
if (!base32_8to5(&in[i], 8, &out[j], alphabet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (remainder && !base32_8to5(&in[i], remainder, &out[j], alphabet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t base32_encoded_length(size_t inlen) {
|
||||
uint8_t remainder = inlen % 5;
|
||||
|
||||
return (inlen / 5) * 8 + (remainder * 8 + 4) / 5;
|
||||
}
|
||||
|
||||
size_t base32_decoded_length(size_t inlen) {
|
||||
uint8_t remainder = inlen % 8;
|
||||
|
||||
return (inlen / 8) * 5 + (remainder * 5) / 8;
|
||||
}
|
||||
|
||||
void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out) {
|
||||
if (length >= 1) {
|
||||
out[0] = (in[0] >> 3);
|
||||
out[1] = (in[0] & 7) << 2;
|
||||
}
|
||||
|
||||
if (length >= 2) {
|
||||
out[1] |= (in[1] >> 6);
|
||||
out[2] = (in[1] >> 1) & 31;
|
||||
out[3] = (in[1] & 1) << 4;
|
||||
}
|
||||
|
||||
if (length >= 3) {
|
||||
out[3] |= (in[2] >> 4);
|
||||
out[4] = (in[2] & 15) << 1;
|
||||
}
|
||||
|
||||
if (length >= 4) {
|
||||
out[4] |= (in[3] >> 7);
|
||||
out[5] = (in[3] >> 2) & 31;
|
||||
out[6] = (in[3] & 3) << 3;
|
||||
}
|
||||
|
||||
if (length >= 5) {
|
||||
out[6] |= (in[4] >> 5);
|
||||
out[7] = (in[4] & 31);
|
||||
}
|
||||
}
|
||||
|
||||
bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out,
|
||||
const char *alphabet) {
|
||||
if (length == 1 || length == 3 || length == 6 || length > 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (alphabet) {
|
||||
uint8_t decoded[length];
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
int ret = base32_decode_character(in[i], alphabet);
|
||||
|
||||
if (ret == -1) {
|
||||
return false;
|
||||
} else {
|
||||
decoded[i] = ret;
|
||||
}
|
||||
}
|
||||
|
||||
base32_8to5_raw(decoded, length, out);
|
||||
} else {
|
||||
base32_8to5_raw(in, length, out);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out) {
|
||||
if (length >= 2) {
|
||||
out[0] = (in[0] << 3);
|
||||
out[0] |= (in[1] >> 2);
|
||||
}
|
||||
|
||||
if (length >= 4) {
|
||||
out[1] = (in[1] & 3) << 6;
|
||||
out[1] |= (in[2] << 1);
|
||||
out[1] |= (in[3] >> 4);
|
||||
}
|
||||
|
||||
if (length >= 5) {
|
||||
out[2] = (in[3] & 15) << 4;
|
||||
out[2] |= (in[4] >> 1);
|
||||
}
|
||||
|
||||
if (length >= 7) {
|
||||
out[3] = (in[4] & 1) << 7;
|
||||
out[3] |= (in[5] << 2);
|
||||
out[3] |= (in[6] >> 3);
|
||||
}
|
||||
|
||||
if (length >= 8) {
|
||||
out[4] = (in[6] & 7) << 5;
|
||||
out[4] |= (in[7] & 31);
|
||||
}
|
||||
}
|
||||
|
||||
int base32_encode_character(uint8_t decoded, const char *alphabet) {
|
||||
if (decoded >> 5) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (alphabet == BASE32_ALPHABET_RFC4648) {
|
||||
if (decoded < 26) {
|
||||
return 'A' + decoded;
|
||||
} else {
|
||||
return '2' - 26 + decoded;
|
||||
}
|
||||
}
|
||||
|
||||
return alphabet[decoded];
|
||||
}
|
||||
|
||||
int base32_decode_character(char encoded, const char *alphabet) {
|
||||
if (alphabet == BASE32_ALPHABET_RFC4648) {
|
||||
if (encoded >= 'A' && encoded <= 'Z') {
|
||||
return encoded - 'A';
|
||||
} else if (encoded >= 'a' && encoded <= 'z') {
|
||||
return encoded - 'a';
|
||||
} else if (encoded >= '2' && encoded <= '7') {
|
||||
return encoded - '2' + 26;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *occurrence = strchr(alphabet, encoded);
|
||||
|
||||
if (occurrence) {
|
||||
return occurrence - alphabet;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
44
crypto/base32.h
Normal file
44
crypto/base32.h
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2017 Saleem Rashid
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BASE32_H__
|
||||
#define __BASE32_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern const char *BASE32_ALPHABET_RFC4648;
|
||||
|
||||
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen,
|
||||
const char *alphabet);
|
||||
void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out);
|
||||
|
||||
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out,
|
||||
size_t outlen, const char *alphabet);
|
||||
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out,
|
||||
const char *alphabet);
|
||||
|
||||
size_t base32_encoded_length(size_t inlen);
|
||||
size_t base32_decoded_length(size_t inlen);
|
||||
|
||||
#endif
|
268
crypto/base58.c
Normal file
268
crypto/base58.c
Normal file
@ -0,0 +1,268 @@
|
||||
/**
|
||||
* Copyright (c) 2012-2014 Luke Dashjr
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "base58.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "memzero.h"
|
||||
#include "ripemd160.h"
|
||||
#include "sha2.h"
|
||||
|
||||
const char b58digits_ordered[] =
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
const int8_t b58digits_map[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18,
|
||||
19, 20, 21, -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1,
|
||||
-1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
bool b58tobin(void *bin, size_t *binszp, const char *b58) {
|
||||
size_t binsz = *binszp;
|
||||
|
||||
if (binsz == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned char *b58u = (const unsigned char *)b58;
|
||||
unsigned char *binu = bin;
|
||||
size_t outisz = (binsz + 3) / 4;
|
||||
uint32_t outi[outisz];
|
||||
uint64_t t;
|
||||
uint32_t c;
|
||||
size_t i, j;
|
||||
uint8_t bytesleft = binsz % 4;
|
||||
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
|
||||
unsigned zerocount = 0;
|
||||
size_t b58sz;
|
||||
|
||||
b58sz = strlen(b58);
|
||||
|
||||
memzero(outi, sizeof(outi));
|
||||
|
||||
// Leading zeros, just count
|
||||
for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount;
|
||||
|
||||
for (; i < b58sz; ++i) {
|
||||
if (b58u[i] & 0x80)
|
||||
// High-bit set on invalid digit
|
||||
return false;
|
||||
if (b58digits_map[b58u[i]] == -1)
|
||||
// Invalid base58 digit
|
||||
return false;
|
||||
c = (unsigned)b58digits_map[b58u[i]];
|
||||
for (j = outisz; j--;) {
|
||||
t = ((uint64_t)outi[j]) * 58 + c;
|
||||
c = (t & 0x3f00000000) >> 32;
|
||||
outi[j] = t & 0xffffffff;
|
||||
}
|
||||
if (c)
|
||||
// Output number too big (carry to the next int32)
|
||||
return false;
|
||||
if (outi[0] & zeromask)
|
||||
// Output number too big (last int32 filled too far)
|
||||
return false;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
switch (bytesleft) {
|
||||
case 3:
|
||||
*(binu++) = (outi[0] & 0xff0000) >> 16;
|
||||
//-fallthrough
|
||||
case 2:
|
||||
*(binu++) = (outi[0] & 0xff00) >> 8;
|
||||
//-fallthrough
|
||||
case 1:
|
||||
*(binu++) = (outi[0] & 0xff);
|
||||
++j;
|
||||
//-fallthrough
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (; j < outisz; ++j) {
|
||||
*(binu++) = (outi[j] >> 0x18) & 0xff;
|
||||
*(binu++) = (outi[j] >> 0x10) & 0xff;
|
||||
*(binu++) = (outi[j] >> 8) & 0xff;
|
||||
*(binu++) = (outi[j] >> 0) & 0xff;
|
||||
}
|
||||
|
||||
// Count canonical base58 byte count
|
||||
binu = bin;
|
||||
for (i = 0; i < binsz; ++i) {
|
||||
if (binu[i]) {
|
||||
if (zerocount > i) {
|
||||
/* result too large */
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
--*binszp;
|
||||
}
|
||||
*binszp += zerocount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int b58check(const void *bin, size_t binsz, HasherType hasher_type,
|
||||
const char *base58str) {
|
||||
unsigned char buf[32];
|
||||
const uint8_t *binc = bin;
|
||||
unsigned i;
|
||||
if (binsz < 4) return -4;
|
||||
hasher_Raw(hasher_type, bin, binsz - 4, buf);
|
||||
if (memcmp(&binc[binsz - 4], buf, 4)) return -1;
|
||||
|
||||
// Check number of zeros is correct AFTER verifying checksum (to avoid
|
||||
// possibility of accessing base58str beyond the end)
|
||||
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) {
|
||||
} // Just finding the end of zeros, nothing to do in loop
|
||||
if (binc[i] == '\0' || base58str[i] == '1') return -3;
|
||||
|
||||
return binc[0];
|
||||
}
|
||||
|
||||
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) {
|
||||
const uint8_t *bin = data;
|
||||
int carry;
|
||||
ssize_t i, j, high, zcount = 0;
|
||||
size_t size;
|
||||
|
||||
while (zcount < (ssize_t)binsz && !bin[zcount]) ++zcount;
|
||||
|
||||
size = (binsz - zcount) * 138 / 100 + 1;
|
||||
uint8_t buf[size];
|
||||
memzero(buf, size);
|
||||
|
||||
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
|
||||
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
|
||||
carry += 256 * buf[j];
|
||||
buf[j] = carry % 58;
|
||||
carry /= 58;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
|
||||
;
|
||||
|
||||
if (*b58sz <= zcount + size - j) {
|
||||
*b58sz = zcount + size - j + 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zcount) memset(b58, '1', zcount);
|
||||
for (i = zcount; j < (ssize_t)size; ++i, ++j)
|
||||
b58[i] = b58digits_ordered[buf[j]];
|
||||
b58[i] = '\0';
|
||||
*b58sz = i + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int base58_encode_check(const uint8_t *data, int datalen,
|
||||
HasherType hasher_type, char *str, int strsize) {
|
||||
if (datalen > 128) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t buf[datalen + 32];
|
||||
uint8_t *hash = buf + datalen;
|
||||
memcpy(buf, data, datalen);
|
||||
hasher_Raw(hasher_type, data, datalen, hash);
|
||||
size_t res = strsize;
|
||||
bool success = b58enc(str, &res, buf, datalen + 4);
|
||||
memzero(buf, sizeof(buf));
|
||||
return success ? res : 0;
|
||||
}
|
||||
|
||||
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data,
|
||||
int datalen) {
|
||||
if (datalen > 128) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t d[datalen + 4];
|
||||
size_t res = datalen + 4;
|
||||
if (b58tobin(d, &res, str) != true) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t *nd = d + datalen + 4 - res;
|
||||
if (b58check(nd, res, hasher_type, str) < 0) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(data, nd, res - 4);
|
||||
return res - 4;
|
||||
}
|
||||
|
||||
#if USE_GRAPHENE
|
||||
int b58gphcheck(const void *bin, size_t binsz, const char *base58str) {
|
||||
unsigned char buf[32];
|
||||
const uint8_t *binc = bin;
|
||||
unsigned i;
|
||||
if (binsz < 4) return -4;
|
||||
ripemd160(bin, binsz - 4, buf); // No double SHA256, but a single RIPEMD160
|
||||
if (memcmp(&binc[binsz - 4], buf, 4)) return -1;
|
||||
|
||||
// Check number of zeros is correct AFTER verifying checksum (to avoid
|
||||
// possibility of accessing base58str beyond the end)
|
||||
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) {
|
||||
} // Just finding the end of zeros, nothing to do in loop
|
||||
if (binc[i] == '\0' || base58str[i] == '1') return -3;
|
||||
|
||||
return binc[0];
|
||||
}
|
||||
|
||||
int base58gph_encode_check(const uint8_t *data, int datalen, char *str,
|
||||
int strsize) {
|
||||
if (datalen > 128) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t buf[datalen + 32];
|
||||
uint8_t *hash = buf + datalen;
|
||||
memcpy(buf, data, datalen);
|
||||
ripemd160(data, datalen, hash); // No double SHA256, but a single RIPEMD160
|
||||
size_t res = strsize;
|
||||
bool success = b58enc(str, &res, buf, datalen + 4);
|
||||
memzero(buf, sizeof(buf));
|
||||
return success ? res : 0;
|
||||
}
|
||||
|
||||
int base58gph_decode_check(const char *str, uint8_t *data, int datalen) {
|
||||
if (datalen > 128) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t d[datalen + 4];
|
||||
size_t res = datalen + 4;
|
||||
if (b58tobin(d, &res, str) != true) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t *nd = d + datalen + 4 - res;
|
||||
if (b58gphcheck(nd, res, str) < 0) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(data, nd, res - 4);
|
||||
return res - 4;
|
||||
}
|
||||
#endif
|
53
crypto/base58.h
Normal file
53
crypto/base58.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BASE58_H__
|
||||
#define __BASE58_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hasher.h"
|
||||
#include "options.h"
|
||||
|
||||
extern const char b58digits_ordered[];
|
||||
extern const int8_t b58digits_map[];
|
||||
|
||||
int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type,
|
||||
char *str, int strsize);
|
||||
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data,
|
||||
int datalen);
|
||||
|
||||
// Private
|
||||
bool b58tobin(void *bin, size_t *binszp, const char *b58);
|
||||
int b58check(const void *bin, size_t binsz, HasherType hasher_type,
|
||||
const char *base58str);
|
||||
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz);
|
||||
|
||||
#if USE_GRAPHENE
|
||||
int base58gph_encode_check(const uint8_t *data, int datalen, char *str,
|
||||
int strsize);
|
||||
int base58gph_decode_check(const char *str, uint8_t *data, int datalen);
|
||||
int b58gphcheck(const void *bin, size_t binsz, const char *base58str);
|
||||
#endif
|
||||
|
||||
#endif
|
1068
crypto/bignum.c
Normal file
1068
crypto/bignum.c
Normal file
File diff suppressed because it is too large
Load Diff
168
crypto/bignum.h
Normal file
168
crypto/bignum.h
Normal file
@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
* Copyright (c) 2016 Alex Beregszaszi
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BIGNUM_H__
|
||||
#define __BIGNUM_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "options.h"
|
||||
|
||||
// bignum256 are 256 bits stored as 8*30 bit + 1*16 bit
|
||||
// val[0] are lowest 30 bits, val[8] highest 16 bits
|
||||
typedef struct {
|
||||
uint32_t val[9];
|
||||
} bignum256;
|
||||
|
||||
// read 4 big endian bytes into uint32
|
||||
uint32_t read_be(const uint8_t *data);
|
||||
|
||||
// write 4 big endian bytes
|
||||
void write_be(uint8_t *data, uint32_t x);
|
||||
|
||||
// read 4 little endian bytes into uint32
|
||||
uint32_t read_le(const uint8_t *data);
|
||||
|
||||
// write 4 little endian bytes
|
||||
void write_le(uint8_t *data, uint32_t 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);
|
||||
|
||||
static inline uint32_t bn_write_uint32(const bignum256 *in_number) {
|
||||
return in_number->val[0] | (in_number->val[1] << 30);
|
||||
}
|
||||
|
||||
static inline uint64_t bn_write_uint64(const bignum256 *in_number) {
|
||||
uint64_t tmp;
|
||||
tmp = in_number->val[2];
|
||||
tmp <<= 30;
|
||||
tmp |= in_number->val[1];
|
||||
tmp <<= 30;
|
||||
tmp |= in_number->val[0];
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// copies number a to b
|
||||
static inline void bn_copy(const bignum256 *a, bignum256 *b) { *b = *a; }
|
||||
|
||||
int bn_bitcount(const bignum256 *a);
|
||||
|
||||
unsigned int bn_digitcount(const bignum256 *a);
|
||||
|
||||
void bn_zero(bignum256 *a);
|
||||
|
||||
int bn_is_zero(const bignum256 *a);
|
||||
|
||||
void bn_one(bignum256 *a);
|
||||
|
||||
static inline int bn_is_even(const bignum256 *a) {
|
||||
return (a->val[0] & 1) == 0;
|
||||
}
|
||||
|
||||
static inline int bn_is_odd(const bignum256 *a) { return (a->val[0] & 1) == 1; }
|
||||
|
||||
int bn_is_less(const bignum256 *a, const bignum256 *b);
|
||||
|
||||
int bn_is_equal(const bignum256 *a, const bignum256 *b);
|
||||
|
||||
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase,
|
||||
const bignum256 *falsecase);
|
||||
|
||||
void bn_lshift(bignum256 *a);
|
||||
|
||||
void bn_rshift(bignum256 *a);
|
||||
|
||||
void bn_setbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
void bn_clearbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
uint32_t bn_testbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c);
|
||||
|
||||
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_sqrt(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_inverse(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_normalize(bignum256 *a);
|
||||
|
||||
void bn_add(bignum256 *a, const bignum256 *b);
|
||||
|
||||
void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime);
|
||||
|
||||
void bn_addi(bignum256 *a, uint32_t b);
|
||||
|
||||
void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime);
|
||||
|
||||
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res,
|
||||
const bignum256 *prime);
|
||||
|
||||
void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res);
|
||||
|
||||
void bn_divmod58(bignum256 *a, uint32_t *r);
|
||||
|
||||
void bn_divmod1000(bignum256 *a, uint32_t *r);
|
||||
|
||||
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix,
|
||||
unsigned int decimals, int exponent, bool trailing, char *out,
|
||||
size_t outlen);
|
||||
|
||||
static inline size_t bn_format_uint64(uint64_t amount, const char *prefix,
|
||||
const char *suffix, unsigned int decimals,
|
||||
int exponent, bool trailing, char *out,
|
||||
size_t outlen) {
|
||||
bignum256 amnt;
|
||||
bn_read_uint64(amount, &amnt);
|
||||
|
||||
return bn_format(&amnt, prefix, suffix, decimals, exponent, trailing, out,
|
||||
outlen);
|
||||
}
|
||||
|
||||
#if USE_BN_PRINT
|
||||
void bn_print(const bignum256 *a);
|
||||
void bn_print_raw(const bignum256 *a);
|
||||
#endif
|
||||
|
||||
#endif
|
887
crypto/bip32.c
Normal file
887
crypto/bip32.c
Normal file
@ -0,0 +1,887 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2016 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2016 Pavol Rusnak
|
||||
* Copyright (c) 2015-2016 Jochen Hoenicke
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "address.h"
|
||||
#include "aes/aes.h"
|
||||
#include "base58.h"
|
||||
#include "bignum.h"
|
||||
#include "bip32.h"
|
||||
#include "curves.h"
|
||||
#include "ecdsa.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"
|
||||
#endif
|
||||
#if USE_NEM
|
||||
#include "nem.h"
|
||||
#endif
|
||||
#if USE_CARDANO
|
||||
#include "pbkdf2.h"
|
||||
#endif
|
||||
#include "memzero.h"
|
||||
|
||||
const curve_info ed25519_info = {
|
||||
.bip32_name = "ed25519 seed",
|
||||
.params = NULL,
|
||||
.hasher_base58 = HASHER_SHA2D,
|
||||
.hasher_sign = HASHER_SHA2D,
|
||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||
.hasher_script = HASHER_SHA2,
|
||||
};
|
||||
|
||||
const curve_info ed25519_cardano_info = {
|
||||
.bip32_name = "ed25519 cardano seed",
|
||||
.params = NULL,
|
||||
.hasher_base58 = HASHER_SHA2D,
|
||||
.hasher_sign = HASHER_SHA2D,
|
||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||
.hasher_script = HASHER_SHA2,
|
||||
};
|
||||
|
||||
const curve_info ed25519_sha3_info = {
|
||||
.bip32_name = "ed25519-sha3 seed",
|
||||
.params = NULL,
|
||||
.hasher_base58 = HASHER_SHA2D,
|
||||
.hasher_sign = HASHER_SHA2D,
|
||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||
.hasher_script = HASHER_SHA2,
|
||||
};
|
||||
|
||||
#if USE_KECCAK
|
||||
const curve_info ed25519_keccak_info = {
|
||||
.bip32_name = "ed25519-keccak seed",
|
||||
.params = NULL,
|
||||
.hasher_base58 = HASHER_SHA2D,
|
||||
.hasher_sign = HASHER_SHA2D,
|
||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||
.hasher_script = HASHER_SHA2,
|
||||
};
|
||||
#endif
|
||||
|
||||
const curve_info curve25519_info = {
|
||||
.bip32_name = "curve25519 seed",
|
||||
.params = NULL,
|
||||
.hasher_base58 = HASHER_SHA2D,
|
||||
.hasher_sign = HASHER_SHA2D,
|
||||
.hasher_pubkey = HASHER_SHA2_RIPEMD,
|
||||
.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_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;
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
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];
|
||||
uint32_t 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(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 (i & 0x80000000) { // private derivation
|
||||
data[0] = 0;
|
||||
memcpy(data + 1, inout->private_key, 32);
|
||||
} else { // public derivation
|
||||
if (!inout->curve->params) {
|
||||
return 0;
|
||||
}
|
||||
hdnode_fill_public_key(inout);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if USE_CARDANO
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
|
||||
// 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
|
||||
hdnode_fill_public_key(inout);
|
||||
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;
|
||||
}
|
||||
|
||||
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len,
|
||||
const uint8_t *seed, int seed_len, HDNode *out) {
|
||||
static CONFIDENTIAL uint8_t secret[96];
|
||||
pbkdf2_hmac_sha512(pass, pass_len, seed, seed_len, 4096, secret, 96);
|
||||
|
||||
secret[0] &= 248;
|
||||
secret[31] &= 31;
|
||||
secret[31] |= 64;
|
||||
|
||||
memzero(out, sizeof(HDNode));
|
||||
out->depth = 0;
|
||||
out->child_num = 0;
|
||||
out->curve = get_curve_by_name(ED25519_CARDANO_NAME);
|
||||
|
||||
memcpy(out->private_key, secret, 32);
|
||||
memcpy(out->private_key_extension, secret + 32, 32);
|
||||
|
||||
out->public_key[0] = 0;
|
||||
hdnode_fill_public_key(out);
|
||||
|
||||
memcpy(out->chain_code, secret + 64, 32);
|
||||
memzero(secret, sizeof(secret));
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
||||
const uint8_t *parent_chain_code, uint32_t i,
|
||||
curve_point *child, uint8_t *child_chain_code) {
|
||||
uint8_t data[1 + 32 + 4];
|
||||
uint8_t I[32 + 32];
|
||||
bignum256 c;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
int hdnode_public_ckd(HDNode *inout, uint32_t i) {
|
||||
curve_point parent, child;
|
||||
|
||||
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];
|
||||
curve_point b;
|
||||
|
||||
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
|
||||
static bool private_ckd_cache_root_set = false;
|
||||
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;
|
||||
} private_ckd_cache[BIP32_CACHE_SIZE];
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// else derive parent
|
||||
if (!found) {
|
||||
size_t k;
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) {
|
||||
hdnode_fill_public_key(node);
|
||||
ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey,
|
||||
addr_raw);
|
||||
}
|
||||
|
||||
void hdnode_get_address(HDNode *node, uint32_t version, char *addr,
|
||||
int addrsize) {
|
||||
hdnode_fill_public_key(node);
|
||||
ecdsa_get_address(node->public_key, version, node->curve->hasher_pubkey,
|
||||
node->curve->hasher_base58, addr, addrsize);
|
||||
}
|
||||
|
||||
void hdnode_fill_public_key(HDNode *node) {
|
||||
if (node->public_key[0] != 0) return;
|
||||
|
||||
#if USE_BIP32_25519_CURVES
|
||||
if (node->curve->params) {
|
||||
ecdsa_get_public_key33(node->curve->params, node->private_key,
|
||||
node->public_key);
|
||||
} 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);
|
||||
#endif
|
||||
} 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->private_key_extension,
|
||||
node->public_key + 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
ecdsa_get_public_key33(node->curve->params, node->private_key,
|
||||
node->public_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_ETHEREUM
|
||||
int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) {
|
||||
uint8_t buf[65];
|
||||
SHA3_CTX ctx;
|
||||
|
||||
/* get uncompressed public key */
|
||||
ecdsa_get_public_key65(node->curve->params, node->private_key, 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);
|
||||
|
||||
/* result are the least significant 160 bits */
|
||||
memcpy(pubkeyhash, buf + 12, 20);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
hdnode_fill_public_key(node);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
shared_key[i] = mul[i] ^ salt[i];
|
||||
}
|
||||
|
||||
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];
|
||||
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];
|
||||
memcpy(iv, iv_immut, AES_BLOCK_SIZE);
|
||||
|
||||
uint8_t shared_key[SHA3_256_DIGEST_LENGTH];
|
||||
if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
aes_encrypt_ctx ctx;
|
||||
|
||||
int ret = aes_encrypt_key256(shared_key, &ctx);
|
||||
memzero(shared_key, sizeof(shared_key));
|
||||
|
||||
if (ret != 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;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
aes_decrypt_ctx ctx;
|
||||
|
||||
int ret = aes_decrypt_key256(shared_key, &ctx);
|
||||
memzero(shared_key, sizeof(shared_key));
|
||||
|
||||
if (ret != EXIT_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aes_cbc_decrypt(payload, buffer, size, iv, &ctx) != EXIT_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 {
|
||||
hdnode_fill_public_key(node);
|
||||
if (node->curve == &ed25519_info) {
|
||||
ed25519_sign(msg, msg_len, node->private_key, node->public_key + 1, sig);
|
||||
} else if (node->curve == &ed25519_sha3_info) {
|
||||
ed25519_sign_sha3(msg, msg_len, node->private_key, node->public_key + 1,
|
||||
sig);
|
||||
#if USE_KECCAK
|
||||
} else if (node->curve == &ed25519_keccak_info) {
|
||||
ed25519_sign_keccak(msg, msg_len, node->private_key, node->public_key + 1,
|
||||
sig);
|
||||
#endif
|
||||
}
|
||||
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_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
|
||||
}
|
||||
}
|
||||
|
||||
static int hdnode_serialize(const HDNode *node, uint32_t fingerprint,
|
||||
uint32_t version, char use_public, char *str,
|
||||
int strsize) {
|
||||
uint8_t node_data[78];
|
||||
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_public) {
|
||||
memcpy(node_data + 45, node->public_key, 33);
|
||||
} else {
|
||||
node_data[45] = 0;
|
||||
memcpy(node_data + 46, node->private_key, 32);
|
||||
}
|
||||
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, 1, 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, 0, str, strsize);
|
||||
}
|
||||
|
||||
// check for validity of curve point in case of public data not performed
|
||||
int hdnode_deserialize(const char *str, uint32_t version_public,
|
||||
uint32_t version_private, const char *curve,
|
||||
HDNode *node, uint32_t *fingerprint) {
|
||||
uint8_t node_data[78];
|
||||
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 version = read_be(node_data);
|
||||
if (version == version_public) {
|
||||
memzero(node->private_key, sizeof(node->private_key));
|
||||
memcpy(node->public_key, node_data + 45, 33);
|
||||
} else if (version == version_private) { // private node
|
||||
if (node_data[45]) { // invalid data
|
||||
return -2;
|
||||
}
|
||||
memcpy(node->private_key, node_data + 46, 32);
|
||||
memzero(node->public_key, sizeof(node->public_key));
|
||||
} else {
|
||||
return -3; // invalid version
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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 (strcmp(curve_name, ED25519_CARDANO_NAME) == 0) {
|
||||
return &ed25519_cardano_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;
|
||||
}
|
||||
#endif
|
||||
if (strcmp(curve_name, CURVE25519_NAME) == 0) {
|
||||
return &curve25519_info;
|
||||
}
|
||||
return 0;
|
||||
}
|
144
crypto/bip32.h
Normal file
144
crypto/bip32.h
Normal file
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BIP32_H__
|
||||
#define __BIP32_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "ecdsa.h"
|
||||
#include "ed25519-donna/ed25519.h"
|
||||
#include "options.h"
|
||||
|
||||
typedef struct {
|
||||
const char *bip32_name; // string for generating BIP32 xprv from seed
|
||||
const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519
|
||||
|
||||
HasherType hasher_base58;
|
||||
HasherType hasher_sign;
|
||||
HasherType hasher_pubkey;
|
||||
HasherType hasher_script;
|
||||
} curve_info;
|
||||
|
||||
typedef struct {
|
||||
uint32_t depth;
|
||||
uint32_t child_num;
|
||||
uint8_t chain_code[32];
|
||||
|
||||
uint8_t private_key[32];
|
||||
uint8_t private_key_extension[32];
|
||||
|
||||
uint8_t public_key[33];
|
||||
const curve_info *curve;
|
||||
} HDNode;
|
||||
|
||||
int hdnode_from_xpub(uint32_t depth, uint32_t child_num,
|
||||
const uint8_t *chain_code, const uint8_t *public_key,
|
||||
const char *curve, HDNode *out);
|
||||
|
||||
int hdnode_from_xprv(uint32_t depth, uint32_t child_num,
|
||||
const uint8_t *chain_code, const uint8_t *private_key,
|
||||
const char *curve, HDNode *out);
|
||||
|
||||
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
|
||||
HDNode *out);
|
||||
|
||||
#define hdnode_private_ckd_prime(X, I) \
|
||||
hdnode_private_ckd((X), ((I) | 0x80000000))
|
||||
|
||||
int hdnode_private_ckd(HDNode *inout, uint32_t i);
|
||||
|
||||
#if USE_CARDANO
|
||||
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i);
|
||||
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len,
|
||||
const uint8_t *seed, int seed_len, HDNode *out);
|
||||
#endif
|
||||
|
||||
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
|
||||
const uint8_t *parent_chain_code, uint32_t i,
|
||||
curve_point *child, uint8_t *child_chain_code);
|
||||
|
||||
int hdnode_public_ckd(HDNode *inout, uint32_t i);
|
||||
|
||||
void hdnode_public_ckd_address_optimized(const curve_point *pub,
|
||||
const uint8_t *chain_code, uint32_t i,
|
||||
uint32_t version,
|
||||
HasherType hasher_pubkey,
|
||||
HasherType hasher_base58, char *addr,
|
||||
int addrsize, int addrformat);
|
||||
|
||||
#if USE_BIP32_CACHE
|
||||
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
|
||||
uint32_t *fingerprint);
|
||||
#endif
|
||||
|
||||
uint32_t hdnode_fingerprint(HDNode *node);
|
||||
|
||||
void hdnode_fill_public_key(HDNode *node);
|
||||
|
||||
#if USE_ETHEREUM
|
||||
int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash);
|
||||
#endif
|
||||
|
||||
#if USE_NEM
|
||||
int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address);
|
||||
int hdnode_get_nem_shared_key(const HDNode *node,
|
||||
const ed25519_public_key peer_public_key,
|
||||
const uint8_t *salt, ed25519_public_key mul,
|
||||
uint8_t *shared_key);
|
||||
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key,
|
||||
const uint8_t *iv, const uint8_t *salt,
|
||||
const uint8_t *payload, size_t size, uint8_t *buffer);
|
||||
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key,
|
||||
uint8_t *iv, const uint8_t *salt, const uint8_t *payload,
|
||||
size_t size, uint8_t *buffer);
|
||||
#endif
|
||||
|
||||
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len,
|
||||
HasherType hasher_sign, uint8_t *sig, uint8_t *pby,
|
||||
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
|
||||
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig,
|
||||
uint8_t *pby,
|
||||
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
|
||||
|
||||
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key,
|
||||
uint8_t *session_key, int *result_size);
|
||||
|
||||
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint,
|
||||
uint32_t version, char *str, int strsize);
|
||||
|
||||
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint,
|
||||
uint32_t version, char *str, int strsize);
|
||||
|
||||
int hdnode_deserialize(const char *str, uint32_t version_public,
|
||||
uint32_t version_private, const char *curve,
|
||||
HDNode *node, uint32_t *fingerprint);
|
||||
|
||||
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw);
|
||||
void hdnode_get_address(HDNode *node, uint32_t version, char *addr,
|
||||
int addrsize);
|
||||
|
||||
const curve_info *get_curve_by_name(const char *curve_name);
|
||||
|
||||
#endif
|
231
crypto/bip39.c
Normal file
231
crypto/bip39.c
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bip39.h"
|
||||
#include "bip39_english.h"
|
||||
#include "hmac.h"
|
||||
#include "memzero.h"
|
||||
#include "options.h"
|
||||
#include "pbkdf2.h"
|
||||
#include "rand.h"
|
||||
#include "sha2.h"
|
||||
|
||||
#if USE_BIP39_CACHE
|
||||
|
||||
static int bip39_cache_index = 0;
|
||||
|
||||
static CONFIDENTIAL struct {
|
||||
bool set;
|
||||
char mnemonic[256];
|
||||
char passphrase[64];
|
||||
uint8_t seed[512 / 8];
|
||||
} bip39_cache[BIP39_CACHE_SIZE];
|
||||
|
||||
#endif
|
||||
|
||||
const char *mnemonic_generate(int strength) {
|
||||
if (strength % 32 || strength < 128 || strength > 256) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t data[32];
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t bits[32 + 1];
|
||||
|
||||
sha256_Raw(data, len, bits);
|
||||
// checksum
|
||||
bits[len] = bits[0];
|
||||
// data
|
||||
memcpy(bits, data, len);
|
||||
|
||||
int mlen = len * 3 / 4;
|
||||
|
||||
int i, j, idx;
|
||||
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, wordlist[idx]);
|
||||
p += strlen(wordlist[idx]);
|
||||
*p = (i < mlen - 1) ? ' ' : 0;
|
||||
p++;
|
||||
}
|
||||
memzero(bits, sizeof(bits));
|
||||
|
||||
return mnemo;
|
||||
}
|
||||
|
||||
void mnemonic_clear(void) { memzero(mnemo, sizeof(mnemo)); }
|
||||
|
||||
int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy) {
|
||||
if (!mnemonic) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t i = 0, n = 0;
|
||||
|
||||
while (mnemonic[i]) {
|
||||
if (mnemonic[i] == ' ') {
|
||||
n++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
n++;
|
||||
|
||||
// check number of words
|
||||
if (n != 12 && n != 18 && n != 24) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char current_word[10];
|
||||
uint32_t j, k, ki, bi = 0;
|
||||
uint8_t bits[32 + 1];
|
||||
|
||||
memzero(bits, sizeof(bits));
|
||||
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++;
|
||||
}
|
||||
k = 0;
|
||||
for (;;) {
|
||||
if (!wordlist[k]) { // word not found
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(current_word, wordlist[k]) == 0) { // word found on index k
|
||||
for (ki = 0; ki < 11; ki++) {
|
||||
if (k & (1 << (10 - ki))) {
|
||||
bits[bi / 8] |= 1 << (7 - (bi % 8));
|
||||
}
|
||||
bi++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
if (bi != n * 11) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(entropy, bits, sizeof(bits));
|
||||
return n * 11;
|
||||
}
|
||||
|
||||
int mnemonic_check(const char *mnemonic) {
|
||||
uint8_t bits[32 + 1];
|
||||
int seed_len = mnemonic_to_entropy(mnemonic, bits);
|
||||
if (seed_len != (12 * 11) && seed_len != (18 * 11) && seed_len != (24 * 11)) {
|
||||
return 0;
|
||||
}
|
||||
int words = seed_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;
|
||||
}
|
||||
|
||||
// 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 = strnlen(passphrase, 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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
uint8_t salt[8 + 256];
|
||||
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));
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *const *mnemonic_wordlist(void) { return wordlist; }
|
47
crypto/bip39.h
Normal file
47
crypto/bip39.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __BIP39_H__
|
||||
#define __BIP39_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIP39_PBKDF2_ROUNDS 2048
|
||||
|
||||
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_to_entropy(const char *mnemonic, uint8_t *entropy);
|
||||
|
||||
// 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));
|
||||
|
||||
const char *const *mnemonic_wordlist(void);
|
||||
|
||||
#endif
|
367
crypto/bip39_english.h
Normal file
367
crypto/bip39_english.h
Normal file
@ -0,0 +1,367 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
static const char* const wordlist[] = {
|
||||
"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", 0,
|
||||
};
|
235
crypto/blake256.c
Normal file
235
crypto/blake256.c
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
BLAKE reference C implementation
|
||||
|
||||
Copyright (c) 2012 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#include "blake256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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], m[16], i;
|
||||
#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];
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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 + ( int )inlen;
|
||||
}
|
||||
else S->buflen = 0;
|
||||
}
|
||||
|
||||
|
||||
void blake256_Final( BLAKE256_CTX *S, uint8_t *out )
|
||||
{
|
||||
uint8_t msglen[8], 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] -= 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;
|
||||
}
|
||||
|
||||
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;
|
||||
blake256_Init( &S );
|
||||
blake256_Update( &S, in, inlen );
|
||||
blake256_Final( &S, out );
|
||||
}
|
53
crypto/blake256.h
Normal file
53
crypto/blake256.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2014-2017, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
#ifndef __BLAKE256_H__
|
||||
#define __BLAKE256_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define BLAKE256_DIGEST_LENGTH 32
|
||||
#define BLAKE256_BLOCK_LENGTH 64
|
||||
|
||||
typedef struct {
|
||||
uint32_t h[8], s[4], t[2];
|
||||
size_t buflen;
|
||||
uint8_t nullt;
|
||||
uint8_t buf[64];
|
||||
} BLAKE256_CTX;
|
||||
|
||||
void blake256_Init(BLAKE256_CTX *);
|
||||
void blake256_Update(BLAKE256_CTX *, const uint8_t *, size_t);
|
||||
void blake256_Final(BLAKE256_CTX *, uint8_t *);
|
||||
|
||||
void blake256(const uint8_t *, size_t, uint8_t *);
|
||||
|
||||
#endif /* __BLAKE256_H__ */
|
25
crypto/blake2_common.h
Normal file
25
crypto/blake2_common.h
Normal file
@ -0,0 +1,25 @@
|
||||
static inline uint32_t load32(const void *src) {
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline uint64_t load64(const void *src) {
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline void store16(void *dst, uint16_t w) { memcpy(dst, &w, sizeof w); }
|
||||
|
||||
static inline void store32(void *dst, uint32_t w) { memcpy(dst, &w, sizeof w); }
|
||||
|
||||
static inline void store64(void *dst, uint64_t w) { memcpy(dst, &w, sizeof w); }
|
||||
|
||||
static inline uint32_t rotr32(const uint32_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (32 - c));
|
||||
}
|
||||
|
||||
static inline uint64_t rotr64(const uint64_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (64 - c));
|
||||
}
|
324
crypto/blake2b.c
Normal file
324
crypto/blake2b.c
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "blake2b.h"
|
||||
#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 */
|
||||
} __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;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
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 );
|
||||
|
||||
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_init0( blake2b_state *S )
|
||||
{
|
||||
size_t i;
|
||||
memzero( S, sizeof( blake2b_state ) );
|
||||
|
||||
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;
|
||||
|
||||
blake2b_init0( S );
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* Sequential blake2b initialization */
|
||||
int blake2b_Init( blake2b_state *S, size_t outlen )
|
||||
{
|
||||
blake2b_param P[1];
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
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];
|
||||
uint64_t v[16];
|
||||
size_t i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
memcpy( S->buf + S->buflen, in, inlen );
|
||||
S->buflen += inlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b_Final( blake2b_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
size_t i;
|
||||
|
||||
if( out == NULL || outlen < S->outlen )
|
||||
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 );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
41
crypto/blake2b.h
Normal file
41
crypto/blake2b.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef __BLAKE2B_H__
|
||||
#define __BLAKE2B_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
typedef struct __blake2b_state
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
#define BLAKE2B_CTX blake2b_state
|
||||
#define BLAKE2B_BLOCK_LENGTH BLAKE2B_BLOCKBYTES
|
||||
#define BLAKE2B_DIGEST_LENGTH BLAKE2B_OUTBYTES
|
||||
#define BLAKE2B_KEY_LENGTH BLAKE2B_KEYBYTES
|
||||
|
||||
int blake2b_Init(blake2b_state *S, size_t outlen);
|
||||
int blake2b_InitKey(blake2b_state *S, size_t outlen, const void *key, size_t keylen);
|
||||
int blake2b_InitPersonal(blake2b_state *S, size_t outlen, const void *personal, size_t personal_len);
|
||||
int blake2b_Update(blake2b_state *S, const void *pin, size_t inlen);
|
||||
int blake2b_Final(blake2b_state *S, void *out, size_t outlen);
|
||||
|
||||
int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen);
|
||||
int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen);
|
||||
|
||||
#endif
|
318
crypto/blake2s.c
Normal file
318
crypto/blake2s.c
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "blake2s.h"
|
||||
#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 */
|
||||
/* uint8_t reserved[0]; */
|
||||
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 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;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
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 );
|
||||
|
||||
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_init0( blake2s_state *S )
|
||||
{
|
||||
size_t i;
|
||||
memzero( S, sizeof( blake2s_state ) );
|
||||
|
||||
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;
|
||||
|
||||
blake2s_init0( S );
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load32( &p[i * 4] );
|
||||
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Sequential blake2s initialization */
|
||||
int blake2s_Init( blake2s_state *S, size_t outlen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
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];
|
||||
uint32_t v[16];
|
||||
size_t i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
memcpy( S->buf + S->buflen, in, inlen );
|
||||
S->buflen += inlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_Final( blake2s_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
|
||||
size_t i;
|
||||
|
||||
if( out == NULL || outlen < S->outlen )
|
||||
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 );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
41
crypto/blake2s.h
Normal file
41
crypto/blake2s.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef __BLAKE2S_H__
|
||||
#define __BLAKE2S_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
typedef struct __blake2s_state
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[BLAKE2S_BLOCKBYTES];
|
||||
uint32_t buflen;
|
||||
uint8_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2s_state;
|
||||
|
||||
#define BLAKE2S_CTX blake2s_state
|
||||
#define BLAKE2S_BLOCK_LENGTH BLAKE2S_BLOCKBYTES
|
||||
#define BLAKE2S_DIGEST_LENGTH BLAKE2S_OUTBYTES
|
||||
#define BLAKE2S_KEY_LENGTH BLAKE2S_KEYBYTES
|
||||
|
||||
int blake2s_Init(blake2s_state *S, size_t outlen);
|
||||
int blake2s_InitKey(blake2s_state *S, size_t outlen, const void *key, size_t keylen);
|
||||
int blake2s_InitPersonal(blake2s_state *S, size_t outlen, const void *personal, size_t personal_len);
|
||||
int blake2s_Update(blake2s_state *S, const void *pin, size_t inlen);
|
||||
int blake2s_Final(blake2s_state *S, void *out, size_t outlen);
|
||||
|
||||
int blake2s(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen);
|
||||
int blake2s_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen);
|
||||
|
||||
#endif
|
189
crypto/cash_addr.c
Normal file
189
crypto/cash_addr.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* Copyright (c) 2017 Jochen Hoenicke
|
||||
* based on code Copyright (c) 2017 Peter Wuille
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cash_addr.h"
|
||||
|
||||
#define MAX_CASHADDR_SIZE 129
|
||||
#define MAX_BASE32_SIZE 104
|
||||
#define MAX_DATA_SIZE 65
|
||||
#define MAX_HRP_SIZE 20
|
||||
#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);
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) {
|
||||
uint64_t chk = 1;
|
||||
size_t i;
|
||||
size_t input_len = strlen(input);
|
||||
size_t hrp_len;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (pad) {
|
||||
if (bits) {
|
||||
out[(*outlen)++] = (val << (outbits - bits)) & maxv;
|
||||
}
|
||||
} else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
|
||||
return 0;
|
||||
}
|
||||
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];
|
||||
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];
|
||||
char hrp_actual[MAX_HRP_SIZE + 1];
|
||||
size_t data_len;
|
||||
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;
|
||||
}
|
77
crypto/cash_addr.h
Normal file
77
crypto/cash_addr.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* Copyright (c) 2017 Jochen Hoenicke, Pieter Wuille
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _CASH_ADDR_H_
|
||||
#define _CASH_ADDR_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Encode a Cashaddr address
|
||||
*
|
||||
* Out: output: Pointer to a buffer of size 105 + strlen(hrp) that will be
|
||||
* updated to contain the null-terminated address.
|
||||
* In: hrp: Pointer to the null-terminated human readable part to use
|
||||
* (chain/network specific).
|
||||
* prog: Data bytes for the hash (between 21 and 65 bytes).
|
||||
* 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);
|
||||
|
||||
/** Decode a CashAddr address
|
||||
*
|
||||
* Out: prog: Pointer to a buffer of size 65 that will be updated to
|
||||
* contain the witness program bytes.
|
||||
* prog_len: Pointer to a size_t that will be updated to contain the
|
||||
* length of bytes in prog. hrp: Pointer to the null-terminated human
|
||||
* 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);
|
||||
|
||||
/** Encode a Cash string
|
||||
*
|
||||
* Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that
|
||||
* will be updated to contain the null-terminated Cash string.
|
||||
* In: hrp : Pointer to the null-terminated human readable part.
|
||||
* data : Pointer to an array of 5-bit values.
|
||||
* 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);
|
||||
|
||||
/** Decode a Cash string
|
||||
*
|
||||
* Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be
|
||||
* updated to contain the null-terminated human readable part.
|
||||
* data: Pointer to a buffer of size strlen(input) - 8 that will
|
||||
* hold the encoded 5-bit data values.
|
||||
* data_len: Pointer to a size_t that will be updated to be the number
|
||||
* of entries in 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);
|
||||
|
||||
#endif
|
60
crypto/chacha20poly1305/chacha20poly1305.c
Normal file
60
crypto/chacha20poly1305/chacha20poly1305.c
Normal file
@ -0,0 +1,60 @@
|
||||
// Implementations of the XChaCha20 + Poly1305 and ChaCha20 + Poly1305
|
||||
// AEAD constructions with a goal of simplicity and correctness rather
|
||||
// than performance.
|
||||
|
||||
#include "chacha20poly1305.h"
|
||||
#include "ecrypt-portable.h"
|
||||
|
||||
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]) {
|
||||
unsigned char subkey[32] = {0};
|
||||
unsigned char block0[64] = {0};
|
||||
ECRYPT_ctx tmp;
|
||||
|
||||
// Generate the Chacha20 key by applying HChaCha20 to the
|
||||
// original key and the first 16 bytes of the nonce.
|
||||
ECRYPT_keysetup(&tmp, key, 256, 16);
|
||||
tmp.input[12] = U8TO32_LITTLE(nonce + 0);
|
||||
tmp.input[13] = U8TO32_LITTLE(nonce + 4);
|
||||
tmp.input[14] = U8TO32_LITTLE(nonce + 8);
|
||||
tmp.input[15] = U8TO32_LITTLE(nonce + 12);
|
||||
hchacha20(&tmp, subkey);
|
||||
|
||||
// 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);
|
||||
|
||||
// Encrypt 64 bytes of zeros and use the first 32 bytes
|
||||
// as the Poly1305 key.
|
||||
ECRYPT_encrypt_bytes(&ctx->chacha20, block0, block0, 64);
|
||||
poly1305_init(&ctx->poly1305, block0);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
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) {
|
||||
poly1305_update(&ctx->poly1305, in, n);
|
||||
}
|
||||
|
||||
// Compute NaCl secretbox-style Poly1305 MAC.
|
||||
void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16]) {
|
||||
poly1305_finish(&ctx->poly1305, mac);
|
||||
}
|
19
crypto/chacha20poly1305/chacha20poly1305.h
Normal file
19
crypto/chacha20poly1305/chacha20poly1305.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef CHACHA20POLY1305_H
|
||||
#define CHACHA20POLY1305_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ecrypt-sync.h"
|
||||
#include "poly1305-donna.h"
|
||||
|
||||
typedef struct {
|
||||
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]);
|
||||
|
||||
#endif // CHACHA20POLY1305_H
|
246
crypto/chacha20poly1305/chacha_merged.c
Normal file
246
crypto/chacha20poly1305/chacha_merged.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
chacha-merged.c version 20080118
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes)
|
||||
{
|
||||
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||
u8 *ctarget = 0;
|
||||
u8 tmp[64];
|
||||
int i;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
int i;
|
||||
|
||||
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);
|
||||
}
|
316
crypto/chacha20poly1305/ecrypt-config.h
Normal file
316
crypto/chacha20poly1305/ecrypt-config.h
Normal file
@ -0,0 +1,316 @@
|
||||
/* ecrypt-config.h */
|
||||
|
||||
/* *** Normally, it should not be necessary to edit this file. *** */
|
||||
|
||||
#ifndef ECRYPT_CONFIG
|
||||
#define ECRYPT_CONFIG
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Guess the endianness of the target architecture. */
|
||||
|
||||
/*
|
||||
* The LITTLE endian machines:
|
||||
*/
|
||||
#if defined(__ultrix) /* Older MIPS */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__alpha) /* Alpha */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__i386) /* x86 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(__x86_64) /* x86_64 (gcc) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#elif defined(_M_IX86) /* x86 (MSC, Borland) */
|
||||
#define ECRYPT_LITTLE_ENDIAN
|
||||
#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
|
||||
|
||||
/*
|
||||
* The BIG endian machines:
|
||||
*/
|
||||
#elif defined(__sparc) /* Newer Sparc's */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
#elif defined(__powerpc__) /* PowerPC */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
#elif defined(__ppc__) /* PowerPC */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
#elif defined(__hppa) /* HP-PA */
|
||||
#define ECRYPT_BIG_ENDIAN
|
||||
|
||||
/*
|
||||
* Finally machines with UNKNOWN endianness:
|
||||
*/
|
||||
#elif defined (_AIX) /* RS6000 */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__aux) /* 68K */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__dgux) /* 88K (but P6 in latest boxes) */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#elif defined(__sgi) /* Newer MIPS */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#else /* Any other processor */
|
||||
#define ECRYPT_UNKNOWN
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit
|
||||
* integers.
|
||||
*
|
||||
* 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), or to allow compiler-specific extensions.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/* --- check char --- */
|
||||
|
||||
#if (UCHAR_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T char
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (UCHAR_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T char
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T char
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T char
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check short --- */
|
||||
|
||||
#if (USHRT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T short
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (USHRT_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T short
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T short
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T short
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check int --- */
|
||||
|
||||
#if (UINT_MAX / 0xFU > 0xFU)
|
||||
#ifndef I8T
|
||||
#define I8T int
|
||||
#define U8C(v) (v##U)
|
||||
|
||||
#if (ULONG_MAX == 0xFFU)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFU > 0xFFU)
|
||||
#ifndef I16T
|
||||
#define I16T int
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFU > 0xFFFFU)
|
||||
#ifndef I32T
|
||||
#define I32T int
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU)
|
||||
#ifndef I64T
|
||||
#define I64T int
|
||||
#define U64C(v) (v##U)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long --- */
|
||||
|
||||
#if (ULONG_MAX / 0xFUL > 0xFUL)
|
||||
#ifndef I8T
|
||||
#define I8T long
|
||||
#define U8C(v) (v##UL)
|
||||
|
||||
#if (ULONG_MAX == 0xFFUL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFUL > 0xFFUL)
|
||||
#ifndef I16T
|
||||
#define I16T long
|
||||
#define U16C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL)
|
||||
#ifndef I32T
|
||||
#define I32T long
|
||||
#define U32C(v) (v##UL)
|
||||
#endif
|
||||
|
||||
#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL)
|
||||
#ifndef I64T
|
||||
#define I64T long
|
||||
#define U64C(v) (v##UL)
|
||||
#define ECRYPT_NATIVE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* --- check long long --- */
|
||||
|
||||
#ifdef ULLONG_MAX
|
||||
|
||||
#if (ULLONG_MAX / 0xFULL > 0xFULL)
|
||||
#ifndef I8T
|
||||
#define I8T long long
|
||||
#define U8C(v) (v##ULL)
|
||||
|
||||
#if (ULLONG_MAX == 0xFFULL)
|
||||
#define ECRYPT_I8T_IS_BYTE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFULL > 0xFFULL)
|
||||
#ifndef I16T
|
||||
#define I16T long long
|
||||
#define U16C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL)
|
||||
#ifndef I32T
|
||||
#define I32T long long
|
||||
#define U32C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL)
|
||||
#ifndef I64T
|
||||
#define I64T long long
|
||||
#define U64C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* --- check __int64 --- */
|
||||
|
||||
#if !defined(__STDC__) && defined(_UI64_MAX)
|
||||
|
||||
#ifndef I64T
|
||||
#define I64T __int64
|
||||
#define U64C(v) (v##ui64)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* --- if platform doesn't announce anything, use most common choices --- */
|
||||
|
||||
#ifndef I8T
|
||||
#define I8T char
|
||||
#define U8C(v) (v##U)
|
||||
#endif
|
||||
#ifndef I16T
|
||||
#define I16T short
|
||||
#define U16C(v) (v##U)
|
||||
#endif
|
||||
#ifndef I32T
|
||||
#define I32T int
|
||||
#define U32C(v) (v##U)
|
||||
#endif
|
||||
#ifndef I64T
|
||||
#define I64T long long
|
||||
#define U64C(v) (v##ULL)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* find the largest type on this platform (used for alignment) */
|
||||
|
||||
#if defined(__SSE__) || (defined(_MSC_VER) && (_MSC_VER >= 1300))
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#define MAXT __m128
|
||||
|
||||
#elif defined(__MMX__)
|
||||
|
||||
#include <mmintrin.h>
|
||||
#define MAXT __m64
|
||||
|
||||
#elif defined(__ALTIVEC__)
|
||||
|
||||
#define MAXT __vector int
|
||||
|
||||
#else
|
||||
|
||||
#define MAXT long
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
49
crypto/chacha20poly1305/ecrypt-machine.h
Normal file
49
crypto/chacha20poly1305/ecrypt-machine.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* ecrypt-machine.h */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT))
|
||||
|
||||
#define ECRYPT_MACHINE_ROT
|
||||
|
||||
#if (defined(WIN32) && defined(_MSC_VER))
|
||||
|
||||
#undef ROTL32
|
||||
#undef ROTR32
|
||||
#undef ROTL64
|
||||
#undef ROTR64
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma intrinsic(_lrotl) /* compile rotations "inline" */
|
||||
#pragma intrinsic(_lrotr)
|
||||
|
||||
#define ROTL32(v, n) _lrotl(v, n)
|
||||
#define ROTR32(v, n) _lrotr(v, n)
|
||||
#define ROTL64(v, n) _rotl64(v, n)
|
||||
#define ROTR64(v, n) _rotr64(v, n)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP))
|
||||
|
||||
#define ECRYPT_MACHINE_SWAP
|
||||
|
||||
/*
|
||||
* If you want to overwrite the default swap macros, put it here. And so on.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
275
crypto/chacha20poly1305/ecrypt-portable.h
Normal file
275
crypto/chacha20poly1305/ecrypt-portable.h
Normal file
@ -0,0 +1,275 @@
|
||||
/* 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
|
281
crypto/chacha20poly1305/ecrypt-sync.h
Normal file
281
crypto/chacha20poly1305/ecrypt-sync.h
Normal file
@ -0,0 +1,281 @@
|
||||
#define ECRYPT_VARIANT 1
|
||||
#define ECRYPT_API
|
||||
/* ecrypt-sync.h */
|
||||
|
||||
/*
|
||||
* Header file for synchronous stream ciphers without authentication
|
||||
* mechanism.
|
||||
*
|
||||
* *** Please only edit parts marked with "[edit]". ***
|
||||
*/
|
||||
|
||||
#ifndef ECRYPT_SYNC
|
||||
#define ECRYPT_SYNC
|
||||
|
||||
#include "ecrypt-types.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Cipher parameters */
|
||||
|
||||
/*
|
||||
* The name of your cipher.
|
||||
*/
|
||||
#define ECRYPT_NAME "ChaCha20"
|
||||
#define ECRYPT_PROFILE "_____"
|
||||
|
||||
/*
|
||||
* Specify which key and IV sizes are supported by your cipher. A user
|
||||
* should be able to enumerate the supported sizes by running the
|
||||
* following code:
|
||||
*
|
||||
* for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i)
|
||||
* {
|
||||
* keysize = ECRYPT_KEYSIZE(i);
|
||||
*
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* All sizes are in bits.
|
||||
*/
|
||||
|
||||
#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] */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Data structures */
|
||||
|
||||
/*
|
||||
* ECRYPT_ctx is the structure containing the representation of the
|
||||
* internal state of your cipher.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 input[16]; /* could be compressed */
|
||||
/*
|
||||
* [edit]
|
||||
*
|
||||
* Put here all state variable needed during the encryption process.
|
||||
*/
|
||||
} ECRYPT_ctx;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Mandatory functions */
|
||||
|
||||
/*
|
||||
* Key and message independent initialization. This function will be
|
||||
* called once when the program starts (e.g., to build expanded S-box
|
||||
* tables).
|
||||
*/
|
||||
void ECRYPT_init(void);
|
||||
|
||||
/*
|
||||
* Key setup. It is the user's responsibility to select the values of
|
||||
* keysize and ivsize from the set of supported values specified
|
||||
* above.
|
||||
*/
|
||||
void ECRYPT_keysetup(
|
||||
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
|
||||
* allowed to call ECRYPT_ivsetup() different times in order to
|
||||
* encrypt/decrypt different messages with the same key but different
|
||||
* IV's.
|
||||
*/
|
||||
void ECRYPT_ivsetup(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* iv);
|
||||
|
||||
/*
|
||||
* Encryption/decryption of arbitrary length messages.
|
||||
*
|
||||
* For efficiency reasons, the API provides two types of
|
||||
* encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function
|
||||
* (declared here) encrypts byte strings of arbitrary length, while
|
||||
* the ECRYPT_encrypt_blocks() function (defined later) only accepts
|
||||
* lengths which are multiples of ECRYPT_BLOCKLENGTH.
|
||||
*
|
||||
* The user is allowed to make multiple calls to
|
||||
* ECRYPT_encrypt_blocks() to incrementally encrypt a long message,
|
||||
* but he is NOT allowed to make additional encryption calls once he
|
||||
* has called ECRYPT_encrypt_bytes() (unless he starts a new message
|
||||
* of course). For example, this sequence of calls is acceptable:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
*
|
||||
* The following sequence is not:
|
||||
*
|
||||
* ECRYPT_keysetup();
|
||||
* ECRYPT_ivsetup();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
* ECRYPT_encrypt_bytes();
|
||||
* ECRYPT_encrypt_blocks();
|
||||
*/
|
||||
|
||||
void ECRYPT_encrypt_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. */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional features */
|
||||
|
||||
/*
|
||||
* For testing purposes it can sometimes be useful to have a function
|
||||
* which immediately generates keystream without having to provide it
|
||||
* with a zero plaintext. If your cipher cannot provide this function
|
||||
* (e.g., because it is not strictly a synchronous cipher), please
|
||||
* reset the ECRYPT_GENERATES_KEYSTREAM flag.
|
||||
*/
|
||||
|
||||
#define ECRYPT_GENERATES_KEYSTREAM
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_bytes(
|
||||
ECRYPT_ctx* ctx,
|
||||
u8* keystream,
|
||||
u32 length); /* Length of keystream in bytes. */
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Optional optimizations */
|
||||
|
||||
/*
|
||||
* By default, the functions in this section are implemented using
|
||||
* calls to functions declared above. However, you might want to
|
||||
* implement them differently for performance reasons.
|
||||
*/
|
||||
|
||||
/*
|
||||
* All-in-one encryption/decryption of (short) packets.
|
||||
*
|
||||
* The default definitions of these functions can be found in
|
||||
* "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] */
|
||||
|
||||
void ECRYPT_encrypt_packet(
|
||||
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);
|
||||
|
||||
/*
|
||||
* Encryption/decryption of blocks.
|
||||
*
|
||||
* By default, these functions are defined as macros. If you want to
|
||||
* provide a different implementation, please undef the
|
||||
* ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions
|
||||
* declared below.
|
||||
*/
|
||||
|
||||
#define ECRYPT_BLOCKLENGTH 64 /* [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_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)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
void ECRYPT_encrypt_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. */
|
||||
|
||||
#ifdef ECRYPT_GENERATES_KEYSTREAM
|
||||
|
||||
void ECRYPT_keystream_blocks(
|
||||
ECRYPT_ctx* ctx,
|
||||
const u8* keystream,
|
||||
u32 blocks); /* Keystream length in blocks. */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If your cipher can be implemented in different ways, you can use
|
||||
* the ECRYPT_VARIANT parameter to allow the user to choose between
|
||||
* them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please
|
||||
* only use this possibility if you really think it could make a
|
||||
* significant difference and keep the number of variants
|
||||
* (ECRYPT_MAXVARIANT) as small as possible (definitely not more than
|
||||
* 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] */
|
||||
|
||||
#ifndef ECRYPT_VARIANT
|
||||
#define ECRYPT_VARIANT 1
|
||||
#endif
|
||||
|
||||
#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT)
|
||||
#error this variant does not exist
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
53
crypto/chacha20poly1305/ecrypt-types.h
Normal file
53
crypto/chacha20poly1305/ecrypt-types.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* ecrypt-types.h */
|
||||
|
||||
/*
|
||||
* *** Please do not edit this file. ***
|
||||
*
|
||||
* The default macros can be overridden for specific architectures by
|
||||
* editing 'ecrypt-machine.h'.
|
||||
*/
|
||||
|
||||
#ifndef ECRYPT_TYPES
|
||||
#define ECRYPT_TYPES
|
||||
|
||||
#include "ecrypt-config.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The following types are defined (if available):
|
||||
*
|
||||
* u8: unsigned integer type, at least 8 bits
|
||||
* u16: unsigned integer type, at least 16 bits
|
||||
* u32: unsigned integer type, at least 32 bits
|
||||
* u64: unsigned integer type, at least 64 bits
|
||||
*
|
||||
* 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
|
||||
* compilers, it might be necessary to switch from ISO C90 mode to ISO
|
||||
* C99 mode (e.g., gcc -std=c99).
|
||||
*/
|
||||
|
||||
#ifdef I8T
|
||||
typedef signed I8T s8;
|
||||
typedef unsigned I8T u8;
|
||||
#endif
|
||||
|
||||
#ifdef I16T
|
||||
typedef signed I16T s16;
|
||||
typedef unsigned I16T u16;
|
||||
#endif
|
||||
|
||||
#ifdef I32T
|
||||
typedef signed I32T s32;
|
||||
typedef unsigned I32T u32;
|
||||
#endif
|
||||
|
||||
#ifdef I64T
|
||||
typedef signed I64T s64;
|
||||
typedef unsigned I64T u64;
|
||||
#endif
|
||||
|
||||
#endif
|
219
crypto/chacha20poly1305/poly1305-donna-32.h
Normal file
219
crypto/chacha20poly1305/poly1305-donna-32.h
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
179
crypto/chacha20poly1305/poly1305-donna.c
Normal file
179
crypto/chacha20poly1305/poly1305-donna.c
Normal file
@ -0,0 +1,179 @@
|
||||
#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;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
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;
|
||||
poly1305_context total_ctx;
|
||||
unsigned char all_key[32];
|
||||
unsigned char all_msg[256];
|
||||
unsigned char mac[16];
|
||||
size_t i, j;
|
||||
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;
|
||||
}
|
20
crypto/chacha20poly1305/poly1305-donna.h
Normal file
20
crypto/chacha20poly1305/poly1305-donna.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef POLY1305_DONNA_H
|
||||
#define POLY1305_DONNA_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
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 */
|
||||
|
48
crypto/chacha20poly1305/rfc7539.c
Normal file
48
crypto/chacha20poly1305/rfc7539.c
Normal file
@ -0,0 +1,48 @@
|
||||
// Implementation of the ChaCha20 + Poly1305 AEAD construction
|
||||
// as described in RFC 7539.
|
||||
|
||||
#include <string.h>
|
||||
#include "rfc7539.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]) {
|
||||
unsigned char block0[64] = {0};
|
||||
|
||||
ECRYPT_keysetup(&ctx->chacha20, key, 256, 16);
|
||||
ctx->chacha20.input[12] = 0;
|
||||
ctx->chacha20.input[13] = U8TO32_LITTLE(nonce + 0);
|
||||
ctx->chacha20.input[14] = U8TO32_LITTLE(nonce + 4);
|
||||
ctx->chacha20.input[15] = U8TO32_LITTLE(nonce + 8);
|
||||
|
||||
// Encrypt 64 bytes of zeros and use the first 32 bytes
|
||||
// as the Poly1305 key.
|
||||
ECRYPT_encrypt_bytes(&ctx->chacha20, block0, block0, 64);
|
||||
poly1305_init(&ctx->poly1305, block0);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
uint8_t padding[16] = {0};
|
||||
poly1305_update(&ctx->poly1305, in, n);
|
||||
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]) {
|
||||
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);
|
||||
poly1305_update(&ctx->poly1305, lengths, 16);
|
||||
|
||||
poly1305_finish(&ctx->poly1305, mac);
|
||||
}
|
10
crypto/chacha20poly1305/rfc7539.h
Normal file
10
crypto/chacha20poly1305/rfc7539.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef RFC7539_H
|
||||
#define RFC7539_H
|
||||
|
||||
#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]);
|
||||
|
||||
#endif // RFC7539_H
|
30
crypto/check_mem.h
Normal file
30
crypto/check_mem.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CHECK_MEM_H
|
||||
#define CHECK_MEM_H
|
||||
|
||||
#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_eq(X, Y, L) _ck_assert_mem(X, Y, L, ==)
|
||||
#define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, Y, L, !=)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
36
crypto/curves.c
Normal file
36
crypto/curves.c
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2016 Jochen Hoenicke
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "curves.h"
|
||||
|
||||
const char SECP256K1_NAME[] = "secp256k1";
|
||||
const char SECP256K1_DECRED_NAME[] = "secp256k1-decred";
|
||||
const char SECP256K1_GROESTL_NAME[] = "secp256k1-groestl";
|
||||
const char SECP256K1_SMART_NAME[] = "secp256k1-smart";
|
||||
const char NIST256P1_NAME[] = "nist256p1";
|
||||
const char ED25519_NAME[] = "ed25519";
|
||||
const char ED25519_CARDANO_NAME[] = "ed25519 cardano seed";
|
||||
const char ED25519_SHA3_NAME[] = "ed25519-sha3";
|
||||
#if USE_KECCAK
|
||||
const char ED25519_KECCAK_NAME[] = "ed25519-keccak";
|
||||
#endif
|
||||
const char CURVE25519_NAME[] = "curve25519";
|
41
crypto/curves.h
Normal file
41
crypto/curves.h
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2016 Jochen Hoenicke
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __CURVES_H__
|
||||
#define __CURVES_H__
|
||||
|
||||
#include "options.h"
|
||||
|
||||
extern const char SECP256K1_NAME[];
|
||||
extern const char SECP256K1_DECRED_NAME[];
|
||||
extern const char SECP256K1_GROESTL_NAME[];
|
||||
extern const char SECP256K1_SMART_NAME[];
|
||||
extern const char NIST256P1_NAME[];
|
||||
extern const char ED25519_NAME[];
|
||||
extern const char ED25519_CARDANO_NAME[];
|
||||
extern const char ED25519_SHA3_NAME[];
|
||||
#if USE_KECCAK
|
||||
extern const char ED25519_KECCAK_NAME[];
|
||||
#endif
|
||||
extern const char CURVE25519_NAME[];
|
||||
|
||||
#endif
|
1190
crypto/ecdsa.c
Normal file
1190
crypto/ecdsa.c
Normal file
File diff suppressed because it is too large
Load Diff
126
crypto/ecdsa.h
Normal file
126
crypto/ecdsa.h
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __ECDSA_H__
|
||||
#define __ECDSA_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bignum.h"
|
||||
#include "hasher.h"
|
||||
#include "options.h"
|
||||
|
||||
// curve point x and y
|
||||
typedef struct {
|
||||
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
|
||||
|
||||
#if USE_PRECOMPUTED_CP
|
||||
const curve_point cp[64][8];
|
||||
#endif
|
||||
|
||||
} ecdsa_curve;
|
||||
|
||||
// 4 byte prefix + 40 byte data (segwit)
|
||||
// 1 byte prefix + 64 byte data (cashaddr)
|
||||
#define MAX_ADDR_RAW_SIZE 65
|
||||
// bottle neck is cashaddr
|
||||
// segwit is at most 90 characters plus NUL separator
|
||||
// cashaddr: human readable prefix + 1 separator + 104 data + 8 checksum + 1 NUL
|
||||
// we choose 130 as maximum (including NUL character)
|
||||
#define MAX_ADDR_SIZE 130
|
||||
// 4 byte prefix + 32 byte privkey + 1 byte compressed marker
|
||||
#define MAX_WIF_RAW_SIZE (4 + 32 + 1)
|
||||
// (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);
|
||||
void 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);
|
||||
void 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 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]));
|
||||
void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
|
||||
uint8_t *pub_key);
|
||||
void 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);
|
||||
|
||||
#endif
|
183
crypto/ed25519-donna/README.md
Normal file
183
crypto/ed25519-donna/README.md
Normal file
@ -0,0 +1,183 @@
|
||||
[ed25519](http://ed25519.cr.yp.to/) is an
|
||||
[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA),
|
||||
developed by [Dan Bernstein](http://cr.yp.to/djb.html),
|
||||
[Niels Duif](http://www.nielsduif.nl/),
|
||||
[Tanja Lange](http://hyperelliptic.org/tanja),
|
||||
[Peter Schwabe](http://www.cryptojedi.org/users/peter/),
|
||||
and [Bo-Yin Yang](http://www.iis.sinica.edu.tw/pages/byyang/).
|
||||
|
||||
This project provides performant, portable 32-bit & 64-bit implementations. All implementations are
|
||||
of course constant time in regard to secret data.
|
||||
|
||||
#### Performance
|
||||
|
||||
SSE2 code and benches have not been updated yet. I will do those next.
|
||||
|
||||
Compilers versions are gcc 4.6.3, icc 13.1.1, clang 3.4-1~exp1.
|
||||
|
||||
Batch verification time (in parentheses) is the average time per 1 verification in a batch of 64 signatures. Counts are in thousands of cycles.
|
||||
|
||||
Note that SSE2 performance may be less impressive on AMD & older CPUs with slower SSE ops!
|
||||
|
||||
Visual Studio performance for `ge25519_scalarmult_base_niels` will lag behind a bit until optimized assembler versions of `ge25519_scalarmult_base_choose_niels`
|
||||
are made.
|
||||
|
||||
##### E5200 @ 2.5ghz, march=core2
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Implementation</th><th>Sign</th><th>gcc</th><th>icc</th><th>clang</th><th>Verify</th><th>gcc</th><th>icc</th><th>clang</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>ed25519-donna 64bit </td><td></td><td>100k</td><td>110k</td><td>137k</td><td></td><td>327k (144k) </td><td>342k (163k) </td><td>422k (194k) </td></tr>
|
||||
<tr><td>amd64-64-24k </td><td></td><td>102k</td><td> </td><td> </td><td></td><td>355k (158k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 64bit</td><td></td><td>108k</td><td>111k</td><td>116k</td><td></td><td>353k (155k) </td><td>345k (154k) </td><td>360k (161k) </td></tr>
|
||||
<tr><td>amd64-51-32k </td><td></td><td>116k</td><td> </td><td> </td><td></td><td>380k (175k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 32bit</td><td></td><td>147k</td><td>147k</td><td>156k</td><td></td><td>380k (178k) </td><td>381k (173k) </td><td>430k (192k) </td></tr>
|
||||
<tr><td>ed25519-donna 32bit </td><td></td><td>597k</td><td>335k</td><td>380k</td><td></td><td>1693k (720k)</td><td>1052k (453k)</td><td>1141k (493k)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
##### E3-1270 @ 3.4ghz, march=corei7-avx
|
||||
|
||||
<table>
|
||||
<thead><tr><th>Implementation</th><th>Sign</th><th>gcc</th><th>icc</th><th>clang</th><th>Verify</th><th>gcc</th><th>icc</th><th>clang</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>amd64-64-24k </td><td></td><td> 68k</td><td> </td><td> </td><td></td><td>225k (104k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna 64bit </td><td></td><td> 71k</td><td> 75k</td><td> 90k</td><td></td><td>226k (105k) </td><td>226k (112k) </td><td>277k (125k) </td></tr>
|
||||
<tr><td>amd64-51-32k </td><td></td><td> 72k</td><td> </td><td> </td><td></td><td>218k (107k) </td><td> </td><td> </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 64bit</td><td></td><td> 79k</td><td> 82k</td><td> 92k</td><td></td><td>252k (122k) </td><td>259k (124k) </td><td>282k (131k) </td></tr>
|
||||
<tr><td>ed25519-donna-sse2 32bit</td><td></td><td> 94k</td><td> 95k</td><td>103k</td><td></td><td>296k (146k) </td><td>294k (137k) </td><td>306k (147k) </td></tr>
|
||||
<tr><td>ed25519-donna 32bit </td><td></td><td>525k</td><td>299k</td><td>316k</td><td></td><td>1502k (645k)</td><td>959k (418k) </td><td>954k (416k) </td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
#### Compilation
|
||||
|
||||
No configuration is needed **if you are compiling against OpenSSL**.
|
||||
|
||||
##### Hash Options
|
||||
|
||||
If you are not compiling aginst OpenSSL, you will need a hash function.
|
||||
|
||||
To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`.
|
||||
This should never be used except to verify the code works when OpenSSL is not available.
|
||||
|
||||
To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your
|
||||
custom hash implementation in ed25519-hash-custom.h. The hash must have a 512bit digest and implement
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
|
||||
##### Random Options
|
||||
|
||||
If you are not compiling aginst OpenSSL, you will need a random function for batch verification.
|
||||
|
||||
To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your
|
||||
custom hash implementation in ed25519-randombytes-custom.h. The random function must implement:
|
||||
|
||||
void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len);
|
||||
|
||||
Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG
|
||||
variant of Bob Jenkins [ISAAC](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29)
|
||||
|
||||
##### Minor options
|
||||
|
||||
Use `-DED25519_INLINE_ASM` to disable the use of custom assembler routines and instead rely on portable C.
|
||||
|
||||
Use `-DED25519_FORCE_32BIT` to force the use of 32 bit routines even when compiling for 64 bit.
|
||||
|
||||
##### 32-bit
|
||||
|
||||
gcc ed25519.c -m32 -O3 -c
|
||||
|
||||
##### 64-bit
|
||||
|
||||
gcc ed25519.c -m64 -O3 -c
|
||||
|
||||
##### SSE2
|
||||
|
||||
gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2
|
||||
gcc ed25519.c -m64 -O3 -c -DED25519_SSE2
|
||||
|
||||
clang and icc are also supported
|
||||
|
||||
|
||||
#### Usage
|
||||
|
||||
To use the code, link against `ed25519.o -mbits` and:
|
||||
|
||||
#include "ed25519.h"
|
||||
|
||||
Add `-lssl -lcrypto` when using OpenSSL (Some systems don't need -lcrypto? It might be trial and error).
|
||||
|
||||
To generate a private key, simply generate 32 bytes from a secure
|
||||
cryptographic source:
|
||||
|
||||
ed25519_secret_key sk;
|
||||
randombytes(sk, sizeof(ed25519_secret_key));
|
||||
|
||||
To generate a public key:
|
||||
|
||||
ed25519_public_key pk;
|
||||
ed25519_publickey(sk, pk);
|
||||
|
||||
To sign a message:
|
||||
|
||||
ed25519_signature sig;
|
||||
ed25519_sign(message, message_len, sk, pk, signature);
|
||||
|
||||
To verify a signature:
|
||||
|
||||
int valid = ed25519_sign_open(message, message_len, pk, signature) == 0;
|
||||
|
||||
To batch verify signatures:
|
||||
|
||||
const unsigned char *mp[num] = {message1, message2..}
|
||||
size_t ml[num] = {message_len1, message_len2..}
|
||||
const unsigned char *pkp[num] = {pk1, pk2..}
|
||||
const unsigned char *sigp[num] = {signature1, signature2..}
|
||||
int valid[num]
|
||||
|
||||
/* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */
|
||||
int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0;
|
||||
|
||||
**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in
|
||||
`ed25519-randombytes.h`, to generate random scalars for the verification code.
|
||||
The default implementation now uses OpenSSLs `RAND_bytes`.
|
||||
|
||||
Unlike the [SUPERCOP](http://bench.cr.yp.to/supercop.html) version, signatures are
|
||||
not appended to messages, and there is no need for padding in front of messages.
|
||||
Additionally, the secret key does not contain a copy of the public key, so it is
|
||||
32 bytes instead of 64 bytes, and the public key must be provided to the signing
|
||||
function.
|
||||
|
||||
##### Curve25519
|
||||
|
||||
Curve25519 public keys can be generated thanks to
|
||||
[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html)
|
||||
leveraging Ed25519's precomputed basepoint scalar multiplication.
|
||||
|
||||
curved25519_key sk, pk;
|
||||
randombytes(sk, sizeof(curved25519_key));
|
||||
curved25519_scalarmult_basepoint(pk, sk);
|
||||
|
||||
Note the name is curved25519, a combination of curve and ed25519, to prevent
|
||||
name clashes. Performance is slightly faster than short message ed25519
|
||||
signing due to both using the same code for the scalar multiply.
|
||||
|
||||
#### Testing
|
||||
|
||||
Fuzzing against reference implemenations is now available. See [fuzz/README](fuzz/README.md).
|
||||
|
||||
Building `ed25519.c` with `-DED25519_TEST` and linking with `test.c` will run basic sanity tests
|
||||
and benchmark each function. `test-batch.c` has been incorporated in to `test.c`.
|
||||
|
||||
`test-internals.c` is standalone and built the same way as `ed25519.c`. It tests the math primitives
|
||||
with extreme values to ensure they function correctly. SSE2 is now supported.
|
||||
|
||||
#### Papers
|
||||
|
||||
[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html)
|
681
crypto/ed25519-donna/curve25519-donna-32bit.c
Normal file
681
crypto/ed25519-donna/curve25519-donna-32bit.c
Normal file
@ -0,0 +1,681 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
uint32_t c;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t s0,s1,s2,s3,s4,s5,s6,s7,s8,s9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
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,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t d6,d7,d8,d9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
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,r1,r2,r3,r4,r5,r6,r7,r8,r9;
|
||||
uint32_t d6,d7,d8,d9;
|
||||
uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
|
||||
uint32_t p;
|
||||
|
||||
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,x1,x2,x3,x4,x5,x6,x7;
|
||||
#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;
|
||||
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,x1,x2,x3,x4,x5,x6,x7,x8,x9;
|
||||
|
||||
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];
|
||||
curve25519_contract(s, f);
|
||||
return s[0] & 1;
|
||||
}
|
||||
|
||||
int curve25519_isnonzero(const bignum25519 f) {
|
||||
unsigned char s[32];
|
||||
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;
|
||||
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;
|
||||
|
||||
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,x1,x2,x3,x4,x5,x6,x7;
|
||||
#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;
|
||||
}
|
79
crypto/ed25519-donna/curve25519-donna-32bit.h
Normal file
79
crypto/ed25519-donna/curve25519-donna-32bit.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
See: https://github.com/floodyberry/curve25519-donna
|
||||
|
||||
32 bit integer curve25519 implementation
|
||||
*/
|
||||
|
||||
typedef uint32_t bignum25519[10];
|
||||
|
||||
/* out = in */
|
||||
void curve25519_copy(bignum25519 out, const bignum25519 in);
|
||||
|
||||
/* out = a + b */
|
||||
void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
/* out = a - b */
|
||||
void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
/* out = in * scalar */
|
||||
void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar);
|
||||
|
||||
/* 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);
|
||||
|
||||
void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
/* out = -a */
|
||||
void curve25519_neg(bignum25519 out, const bignum25519 a);
|
||||
|
||||
/* out = a * b */
|
||||
#define curve25519_mul_noinline curve25519_mul
|
||||
void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b);
|
||||
|
||||
/* out = in * in */
|
||||
void curve25519_square(bignum25519 out, const bignum25519 in);
|
||||
|
||||
/* out = in ^ (2 * count) */
|
||||
void curve25519_square_times(bignum25519 out, const bignum25519 in, int count);
|
||||
|
||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
|
||||
void curve25519_expand(bignum25519 out, const unsigned char in[32]);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* if (iswap) swap(a, b) */
|
||||
void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap);
|
||||
|
||||
/* uint32_t to Zmod(2^255-19) */
|
||||
void curve25519_set(bignum25519 r, uint32_t x);
|
||||
|
||||
/* set d */
|
||||
void curve25519_set_d(bignum25519 r);
|
||||
|
||||
/* set 2d */
|
||||
void curve25519_set_2d(bignum25519 r);
|
||||
|
||||
/* set sqrt(-1) */
|
||||
void curve25519_set_sqrtneg1(bignum25519 r);
|
||||
|
||||
/* constant time Zmod(2^255-19) negative test */
|
||||
int curve25519_isnegative(const bignum25519 f);
|
||||
|
||||
/* constant time Zmod(2^255-19) non-zero test */
|
||||
int curve25519_isnonzero(const bignum25519 f);
|
||||
|
||||
/* reduce Zmod(2^255-19) */
|
||||
void curve25519_reduce(bignum25519 r, const bignum25519 in);
|
||||
|
||||
void curve25519_divpowm1(bignum25519 r, const bignum25519 u, const bignum25519 v);
|
||||
|
||||
/* Zmod(2^255-19) from byte array to bignum25519 expansion with modular reduction */
|
||||
void curve25519_expand_reduce(bignum25519 out, const unsigned char in[32]);
|
66
crypto/ed25519-donna/curve25519-donna-helpers.c
Normal file
66
crypto/ed25519-donna/curve25519-donna-helpers.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
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,c;
|
||||
|
||||
/* 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,t0,b;
|
||||
|
||||
/* 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);
|
||||
}
|
22
crypto/ed25519-donna/curve25519-donna-helpers.h
Normal file
22
crypto/ed25519-donna/curve25519-donna-helpers.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
See: https://github.com/floodyberry/curve25519-donna
|
||||
|
||||
Curve25519 implementation agnostic helpers
|
||||
*/
|
||||
|
||||
/*
|
||||
* In: b = 2^5 - 2^0
|
||||
* Out: b = 2^250 - 2^0
|
||||
*/
|
||||
void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b);
|
||||
|
||||
/*
|
||||
* z^(p - 2) = z(2^255 - 21)
|
||||
*/
|
||||
void curve25519_recip(bignum25519 out, const bignum25519 z);
|
||||
|
||||
/*
|
||||
* z^((p-5)/8) = z^(2^252 - 3)
|
||||
*/
|
||||
void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z);
|
67
crypto/ed25519-donna/curve25519-donna-scalarmult-base.c
Normal file
67
crypto/ed25519-donna/curve25519-donna-scalarmult-base.c
Normal file
@ -0,0 +1,67 @@
|
||||
#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;
|
||||
bignum25519 q, qx, qpqx, qqx, zzz, zmone;
|
||||
size_t bit, lastbit;
|
||||
int32_t i;
|
||||
|
||||
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);
|
||||
}
|
8
crypto/ed25519-donna/curve25519-donna-scalarmult-base.h
Normal file
8
crypto/ed25519-donna/curve25519-donna-scalarmult-base.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* 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);
|
63
crypto/ed25519-donna/ed25519-donna-32bit-tables.c
Normal file
63
crypto/ed25519-donna/ed25519-donna-32bit-tables.c
Normal file
@ -0,0 +1,63 @@
|
||||
#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}}
|
||||
};
|
17
crypto/ed25519-donna/ed25519-donna-32bit-tables.h
Normal file
17
crypto/ed25519-donna/ed25519-donna-32bit-tables.h
Normal file
@ -0,0 +1,17 @@
|
||||
extern const ge25519 ALIGN(16) ge25519_basepoint;
|
||||
|
||||
/*
|
||||
d
|
||||
*/
|
||||
|
||||
extern const bignum25519 ALIGN(16) ge25519_ecd;
|
||||
|
||||
extern const bignum25519 ALIGN(16) ge25519_ec2d;
|
||||
|
||||
/*
|
||||
sqrt(-1)
|
||||
*/
|
||||
|
||||
extern const bignum25519 ALIGN(16) ge25519_sqrtneg1;
|
||||
|
||||
extern const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32];
|
261
crypto/ed25519-donna/ed25519-donna-basepoint-table.c
Normal file
261
crypto/ed25519-donna/ed25519-donna-basepoint-table.c
Normal file
@ -0,0 +1,261 @@
|
||||
#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}
|
||||
};
|
2
crypto/ed25519-donna/ed25519-donna-basepoint-table.h
Normal file
2
crypto/ed25519-donna/ed25519-donna-basepoint-table.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* multiples of the base point in packed {ysubx, xaddy, t2d} form */
|
||||
extern const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96];
|
725
crypto/ed25519-donna/ed25519-donna-impl-base.c
Normal file
725
crypto/ed25519-donna/ed25519-donna-impl-base.c
Normal file
@ -0,0 +1,725 @@
|
||||
#include <assert.h>
|
||||
#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,b,c;
|
||||
|
||||
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,b,c;
|
||||
|
||||
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,b,c;
|
||||
|
||||
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;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_partial(r, &t);
|
||||
}
|
||||
|
||||
void ge25519_double(ge25519 *r, const ge25519 *p) {
|
||||
ge25519_p1p1 t;
|
||||
ge25519_double_p1p1(&t, p);
|
||||
ge25519_p1p1_to_full(r, &t);
|
||||
}
|
||||
|
||||
void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) {
|
||||
bignum25519 a,b,c,e,f,g,h;
|
||||
|
||||
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,b,c,x,y,z,t;
|
||||
|
||||
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, ty, zi;
|
||||
unsigned char parity[32];
|
||||
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];
|
||||
bignum25519 t, root, num, den, d3;
|
||||
|
||||
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], slide2[256];
|
||||
ge25519_pniels pre1[S1_TABLE_SIZE];
|
||||
#ifdef ED25519_NO_PRECOMP
|
||||
ge25519_pniels pre2[S2_TABLE_SIZE];
|
||||
#endif
|
||||
ge25519 dp;
|
||||
ge25519_p1p1 t;
|
||||
int32_t i;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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], slide2[256];
|
||||
ge25519_pniels pre1[S1_TABLE_SIZE];
|
||||
ge25519_pniels pre2[S1_TABLE_SIZE];
|
||||
ge25519 dp;
|
||||
ge25519_p1p1 t;
|
||||
int32_t i;
|
||||
|
||||
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);
|
||||
}
|
||||
#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, y1, y2, y3;
|
||||
for(; p<n; p+=stride) {
|
||||
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, y1, y2, y3;
|
||||
for(p+=stride; p<n; p+=stride) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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];
|
||||
ge25519_pniels pre1[9];
|
||||
ge25519_pniels pre;
|
||||
ge25519 d1;
|
||||
ge25519_p1p1 t;
|
||||
int32_t i;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
|
||||
bignum25519 neg;
|
||||
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];
|
||||
uint32_t i;
|
||||
ge25519_niels t;
|
||||
|
||||
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;
|
||||
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;
|
||||
ge25519_p1p1 P_11;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
104
crypto/ed25519-donna/ed25519-donna-impl-base.h
Normal file
104
crypto/ed25519-donna/ed25519-donna-impl-base.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
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);
|
24
crypto/ed25519-donna/ed25519-donna-portable.h
Normal file
24
crypto/ed25519-donna/ed25519-donna-portable.h
Normal file
@ -0,0 +1,24 @@
|
||||
#define mul32x32_64(a,b) (((uint64_t)(a))*(b))
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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));
|
||||
}
|
52
crypto/ed25519-donna/ed25519-donna.h
Normal file
52
crypto/ed25519-donna/ed25519-donna.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
Modified from the amd64-51-30k implementation by
|
||||
Daniel J. Bernstein
|
||||
Niels Duif
|
||||
Tanja Lange
|
||||
Peter Schwabe
|
||||
Bo-Yin Yang
|
||||
*/
|
||||
|
||||
#ifndef ED25519_DONNA_H
|
||||
#define ED25519_DONNA_H
|
||||
|
||||
#include "ed25519-donna-portable.h"
|
||||
|
||||
#include "curve25519-donna-32bit.h"
|
||||
|
||||
#include "curve25519-donna-helpers.h"
|
||||
|
||||
#include "modm-donna-32bit.h"
|
||||
|
||||
typedef unsigned char hash_512bits[64];
|
||||
|
||||
/*
|
||||
* Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
|
||||
* with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
|
||||
* Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
|
||||
*/
|
||||
|
||||
typedef struct ge25519_t {
|
||||
bignum25519 x, y, z, t;
|
||||
} ge25519;
|
||||
|
||||
typedef struct ge25519_p1p1_t {
|
||||
bignum25519 x, y, z, t;
|
||||
} ge25519_p1p1;
|
||||
|
||||
typedef struct ge25519_niels_t {
|
||||
bignum25519 ysubx, xaddy, t2d;
|
||||
} ge25519_niels;
|
||||
|
||||
typedef struct ge25519_pniels_t {
|
||||
bignum25519 ysubx, xaddy, z, t2d;
|
||||
} ge25519_pniels;
|
||||
|
||||
#include "ed25519-donna-basepoint-table.h"
|
||||
|
||||
#include "ed25519-donna-32bit-tables.h"
|
||||
|
||||
#include "ed25519-donna-impl-base.h"
|
||||
|
||||
#endif
|
23
crypto/ed25519-donna/ed25519-hash-custom-keccak.h
Normal file
23
crypto/ed25519-donna/ed25519-hash-custom-keccak.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
a custom hash must have a 512bit digest and implement:
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
*/
|
||||
|
||||
#ifndef ED25519_HASH_CUSTOM
|
||||
#define ED25519_HASH_CUSTOM
|
||||
|
||||
#include "sha3.h"
|
||||
|
||||
#define ed25519_hash_context SHA3_CTX
|
||||
#define ed25519_hash_init(ctx) keccak_512_Init(ctx)
|
||||
#define ed25519_hash_update(ctx, in, inlen) keccak_Update((ctx), (in), (inlen))
|
||||
#define ed25519_hash_final(ctx, hash) keccak_Final((ctx), (hash))
|
||||
#define ed25519_hash(hash, in, inlen) keccak_512((in), (inlen), (hash))
|
||||
|
||||
#endif // ED25519_HASH_CUSTOM
|
23
crypto/ed25519-donna/ed25519-hash-custom-sha3.h
Normal file
23
crypto/ed25519-donna/ed25519-hash-custom-sha3.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
a custom hash must have a 512bit digest and implement:
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
*/
|
||||
|
||||
#ifndef ED25519_HASH_CUSTOM
|
||||
#define ED25519_HASH_CUSTOM
|
||||
|
||||
#include "sha3.h"
|
||||
|
||||
#define ed25519_hash_context SHA3_CTX
|
||||
#define ed25519_hash_init(ctx) sha3_512_Init(ctx)
|
||||
#define ed25519_hash_update(ctx, in, inlen) sha3_Update((ctx), (in), (inlen))
|
||||
#define ed25519_hash_final(ctx, hash) sha3_Final((ctx), (hash))
|
||||
#define ed25519_hash(hash, in, inlen) sha3_512((in), (inlen), (hash))
|
||||
|
||||
#endif // ED25519_HASH_CUSTOM
|
23
crypto/ed25519-donna/ed25519-hash-custom.h
Normal file
23
crypto/ed25519-donna/ed25519-hash-custom.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
a custom hash must have a 512bit digest and implement:
|
||||
|
||||
struct ed25519_hash_context;
|
||||
|
||||
void ed25519_hash_init(ed25519_hash_context *ctx);
|
||||
void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen);
|
||||
void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash);
|
||||
void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen);
|
||||
*/
|
||||
|
||||
#ifndef ED25519_HASH_CUSTOM
|
||||
#define ED25519_HASH_CUSTOM
|
||||
|
||||
#include "sha2.h"
|
||||
|
||||
#define ed25519_hash_context SHA512_CTX
|
||||
#define ed25519_hash_init(ctx) sha512_Init(ctx)
|
||||
#define ed25519_hash_update(ctx, in, inlen) sha512_Update((ctx), (in), (inlen))
|
||||
#define ed25519_hash_final(ctx, hash) sha512_Final((ctx), (hash))
|
||||
#define ed25519_hash(hash, in, inlen) sha512_Raw((in), (inlen), (hash))
|
||||
|
||||
#endif // ED25519_HASH_CUSTOM
|
8
crypto/ed25519-donna/ed25519-keccak.c
Normal file
8
crypto/ed25519-donna/ed25519-keccak.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ed25519-keccak.h"
|
||||
#include "ed25519-hash-custom-keccak.h"
|
||||
|
||||
#define ED25519_SUFFIX _keccak
|
||||
|
||||
#include "ed25519.c"
|
21
crypto/ed25519-donna/ed25519-keccak.h
Normal file
21
crypto/ed25519-donna/ed25519-keccak.h
Normal file
@ -0,0 +1,21 @@
|
||||
#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, const ed25519_public_key pk, 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
|
8
crypto/ed25519-donna/ed25519-sha3.c
Normal file
8
crypto/ed25519-donna/ed25519-sha3.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ed25519-sha3.h"
|
||||
#include "ed25519-hash-custom-sha3.h"
|
||||
|
||||
#define ED25519_SUFFIX _sha3
|
||||
|
||||
#include "ed25519.c"
|
21
crypto/ed25519-donna/ed25519-sha3.h
Normal file
21
crypto/ed25519-donna/ed25519-sha3.h
Normal file
@ -0,0 +1,21 @@
|
||||
#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, const ed25519_public_key pk, 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
|
315
crypto/ed25519-donna/ed25519.c
Normal file
315
crypto/ed25519-donna/ed25519.c
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
|
||||
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"
|
||||
|
||||
/*
|
||||
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_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
|
||||
ed25519_hash_context ctx;
|
||||
ed25519_hash_init(&ctx);
|
||||
ed25519_hash_update(&ctx, RS, 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) {
|
||||
bignum256modm a;
|
||||
ge25519 ALIGN(16) A;
|
||||
hash_512bits extsk;
|
||||
|
||||
/* A = aB */
|
||||
ed25519_extsk(extsk, sk);
|
||||
|
||||
expand256_modm(a, extsk, 32);
|
||||
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||
ge25519_pack(pk, &A);
|
||||
}
|
||||
|
||||
#if USE_CARDANO
|
||||
void
|
||||
ED25519_FN(ed25519_publickey_ext) (const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_public_key pk) {
|
||||
bignum256modm a;
|
||||
ge25519 ALIGN(16) A;
|
||||
hash_512bits extsk;
|
||||
|
||||
/* we don't stretch the key through hashing first since its already 64 bytes */
|
||||
|
||||
memcpy(extsk, sk, 32);
|
||||
memcpy(extsk+32, skext, 32);
|
||||
expand256_modm(a, extsk, 32);
|
||||
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||
ge25519_pack(pk, &A);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
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, S, a;
|
||||
hash_512bits extsk, extnonce, hram;
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
ed25519_extsk(extnonce, nonce);
|
||||
|
||||
/* r = nonce */
|
||||
expand256_modm(r, extnonce, 32);
|
||||
|
||||
/* 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);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(sig, S);
|
||||
}
|
||||
|
||||
void
|
||||
ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
|
||||
ed25519_hash_context ctx;
|
||||
bignum256modm r, S, a;
|
||||
ge25519 ALIGN(16) R;
|
||||
hash_512bits extsk, hashr, hram;
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
/* R = rB */
|
||||
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
|
||||
ge25519_pack(RS, &R);
|
||||
|
||||
/* S = H(R,A,m).. */
|
||||
ed25519_hram(hram, RS, pk, m, mlen);
|
||||
expand256_modm(S, hram, 64);
|
||||
|
||||
/* S = H(R,A,m)a */
|
||||
expand256_modm(a, extsk, 32);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(RS + 32, S);
|
||||
}
|
||||
|
||||
#if USE_CARDANO
|
||||
void
|
||||
ED25519_FN(ed25519_sign_ext) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, const ed25519_public_key pk, ed25519_signature RS) {
|
||||
ed25519_hash_context ctx;
|
||||
bignum256modm r, S, a;
|
||||
ge25519 ALIGN(16) R;
|
||||
hash_512bits extsk, hashr, hram;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* R = rB */
|
||||
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
|
||||
ge25519_pack(RS, &R);
|
||||
|
||||
/* S = H(R,A,m).. */
|
||||
ed25519_hram(hram, RS, pk, m, mlen);
|
||||
expand256_modm(S, hram, 64);
|
||||
|
||||
/* S = H(R,A,m)a */
|
||||
expand256_modm(a, extsk, 32);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(RS + 32, S);
|
||||
}
|
||||
#endif
|
||||
|
||||
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, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
unsigned char checkR[32];
|
||||
|
||||
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;
|
||||
ge25519 ALIGN(16) A, P;
|
||||
hash_512bits extsk;
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
expand256_modm(a, extsk, 32);
|
||||
|
||||
if (!ge25519_unpack_negative_vartime(&P, pk)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ge25519_scalarmult(&A, &P, a);
|
||||
curve25519_neg(A.x, A.x);
|
||||
ge25519_pack(res, &A);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ED25519_SUFFIX
|
||||
|
||||
#include "curve25519-donna-scalarmult-base.h"
|
||||
|
||||
int
|
||||
ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) {
|
||||
size_t i = 0;
|
||||
ge25519 P;
|
||||
ge25519_pniels sump;
|
||||
ge25519_p1p1 sump1;
|
||||
|
||||
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, t;
|
||||
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;
|
||||
bignum256modm s;
|
||||
bignum25519 ALIGN(16) yplusz, zminusy;
|
||||
ge25519 ALIGN(16) p;
|
||||
size_t i;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* scalar * basepoint */
|
||||
ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, 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;
|
||||
size_t i;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif // ED25519_SUFFIX
|
48
crypto/ed25519-donna/ed25519.h
Normal file
48
crypto/ed25519-donna/ed25519.h
Normal file
@ -0,0 +1,48 @@
|
||||
#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);
|
||||
#if USE_CARDANO
|
||||
void ed25519_publickey_ext(const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_public_key pk);
|
||||
#endif
|
||||
|
||||
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, const ed25519_public_key pk, ed25519_signature RS);
|
||||
#if USE_CARDANO
|
||||
void ed25519_sign_ext(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, const ed25519_public_key pk, ed25519_signature RS);
|
||||
#endif
|
||||
|
||||
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_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
|
517
crypto/ed25519-donna/modm-donna-32bit.c
Normal file
517
crypto/ed25519-donna/modm-donna-32bit.c
Normal file
@ -0,0 +1,517 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
*/
|
||||
|
||||
#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;
|
||||
bignum256modm_element_t b = 0, pb, mask;
|
||||
|
||||
/* 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, r2;
|
||||
uint64_t c;
|
||||
bignum256modm_element_t f, b, pb;
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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, q1;
|
||||
uint64_t c;
|
||||
bignum256modm_element_t f;
|
||||
|
||||
/* 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];
|
||||
bignum256modm q1;
|
||||
|
||||
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];
|
||||
|
||||
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;
|
||||
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;
|
||||
signed char *quads = r;
|
||||
bignum256modm_element_t i, j, v;
|
||||
|
||||
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,j,k,b;
|
||||
int m = (1 << (windowsize - 1)) - 1, soplen = 256;
|
||||
signed char *bits = r;
|
||||
bignum256modm_element_t v;
|
||||
|
||||
/* 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);
|
||||
}
|
80
crypto/ed25519-donna/modm-donna-32bit.h
Normal file
80
crypto/ed25519-donna/modm-donna-32bit.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Public domain by Andrew M. <liquidsun@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#define bignum256modm_bits_per_limb 30
|
||||
#define bignum256modm_limb_size 9
|
||||
|
||||
typedef uint32_t bignum256modm_element_t;
|
||||
typedef bignum256modm_element_t bignum256modm[9];
|
||||
|
||||
/* see HAC, Alg. 14.42 Step 4 */
|
||||
void reduce256_modm(bignum256modm r);
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
/* addition modulo m */
|
||||
void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y);
|
||||
|
||||
/* -x modulo m */
|
||||
void neg256_modm(bignum256modm r, const bignum256modm x);
|
||||
|
||||
/* subtraction x-y modulo m */
|
||||
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 expand_raw256_modm(bignum256modm out, const unsigned char in[32]);
|
||||
|
||||
int is_reduced256_modm(const bignum256modm in);
|
||||
|
||||
void contract256_modm(unsigned char out[32], const bignum256modm in);
|
||||
|
||||
void contract256_window4_modm(signed char r[64], const bignum256modm in);
|
||||
|
||||
void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize);
|
||||
|
||||
/* 64bit uint to scalar value */
|
||||
void set256_modm(bignum256modm r, uint64_t v);
|
||||
|
||||
/* scalar value to 64bit uint */
|
||||
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);
|
||||
|
||||
/* comparison of two reduced scalar values */
|
||||
int cmp256_modm(const bignum256modm x, const bignum256modm y);
|
||||
|
||||
/* scalar null check, has to be reduced */
|
||||
int iszero256_modm(const bignum256modm x);
|
||||
|
||||
/* simple copy, no reduction */
|
||||
void copy256_modm(bignum256modm r, const bignum256modm x);
|
||||
|
||||
/* check if nonzero && same after reduction */
|
||||
int check256_modm(const bignum256modm x);
|
||||
|
||||
/* (cc - aa * bb) % l */
|
||||
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);
|
783
crypto/groestl.c
Normal file
783
crypto/groestl.c
Normal file
@ -0,0 +1,783 @@
|
||||
/* Groestl hash from https://github.com/Groestlcoin/vanitygen
|
||||
* Trezor adaptation by Yura Pakhuchiy <pakhuchiy@gmail.com>. */
|
||||
/*
|
||||
* Groestl implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "groestl_internal.h"
|
||||
#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)))
|
||||
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
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];
|
||||
|
||||
#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];
|
||||
|
||||
#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;
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
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;
|
||||
|
||||
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];
|
||||
size_t ptr, pad_len, u2;
|
||||
sph_u64 count;
|
||||
unsigned z;
|
||||
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_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_DoubleTrunc(void *cc, void *dst)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
groestl512_Final(cc, buf);
|
||||
groestl512_Update(cc, buf, sizeof(buf));
|
||||
groestl512_Final(cc, buf);
|
||||
memcpy(dst, buf, 32);
|
||||
}
|
95
crypto/groestl.h
Normal file
95
crypto/groestl.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* Groestl hash from https://github.com/Groestlcoin/vanitygen
|
||||
* Trezor adaptation by Yura Pakhuchiy <pakhuchiy@gmail.com>. */
|
||||
/**
|
||||
* Groestl interface. This code implements Groestl with the recommended
|
||||
* parameters for SHA-3, with outputs of 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_groestl.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef GROESTL_H__
|
||||
#define GROESTL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* This structure is a context for Groestl-384 and Groestl-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Groestl computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Groestl
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
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;
|
||||
} sph_groestl_big_context;
|
||||
|
||||
typedef sph_groestl_big_context GROESTL512_CTX;
|
||||
|
||||
/**
|
||||
* Initialize a Groestl-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Groestl-512 context (pointer to a
|
||||
* <code>GROESTL512_CTX</code>)
|
||||
*/
|
||||
void groestl512_Init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void groestl512_Update(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Groestl-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Groestl-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif
|
501
crypto/groestl_internal.h
Normal file
501
crypto/groestl_internal.h
Normal file
@ -0,0 +1,501 @@
|
||||
/* Groestl hash from https://github.com/Groestlcoin/vanitygen
|
||||
* Trezor adaptation by Yura Pakhuchiy <pakhuchiy@gmail.com>. */
|
||||
/**
|
||||
* Basic type definitions.
|
||||
*
|
||||
* This header file defines the generic integer types that will be used
|
||||
* for the implementation of hash functions; it also contains helper
|
||||
* functions which encode and decode multi-byte integer values, using
|
||||
* either little-endian or big-endian conventions.
|
||||
*
|
||||
* This file contains a compile-time test on the size of a byte
|
||||
* (the <code>unsigned char</code> C type). If bytes are not octets,
|
||||
* i.e. if they do not have a size of exactly 8 bits, then compilation
|
||||
* is aborted. Architectures where bytes are not octets are relatively
|
||||
* rare, even in the embedded devices market. We forbid non-octet bytes
|
||||
* because there is no clear convention on how octet streams are encoded
|
||||
* on such systems.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_types.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef GROESTL_INTERNAL_H__
|
||||
#define GROESTL_INTERNAL_H__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* All our I/O functions are defined over octet streams. We do not know
|
||||
* how to handle input data if bytes are not octets.
|
||||
*/
|
||||
#if CHAR_BIT != 8
|
||||
#error This code requires 8-bit bytes
|
||||
#endif
|
||||
|
||||
#if defined __STDC__ && __STDC_VERSION__ >= 199901L
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t sph_u32;
|
||||
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))
|
||||
|
||||
#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_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
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* ARM, little-endian.
|
||||
*/
|
||||
#elif defined __arm__ && __ARMEL__
|
||||
|
||||
#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
|
||||
#endif
|
||||
#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Byte-swap a 64-bit value.
|
||||
*
|
||||
* @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 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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 32-bit value into the provided buffer (big endian convention).
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 32-bit value into the provided buffer (big endian convention).
|
||||
* The destination buffer must be properly aligned.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
*(sph_u32 *)dst = sph_bswap32(val);
|
||||
#elif SPH_BIG_ENDIAN
|
||||
*(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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 32-bit value from the provided buffer (big endian convention).
|
||||
*
|
||||
* @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]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 32-bit value from the provided buffer (big endian convention).
|
||||
* The source buffer must be properly aligned.
|
||||
*
|
||||
* @param src the source buffer (32-bit aligned)
|
||||
* @return the decoded value
|
||||
*/
|
||||
static inline sph_u32
|
||||
sph_dec32be_aligned(const void *src)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
return sph_bswap32(*(const sph_u32 *)src);
|
||||
#elif SPH_BIG_ENDIAN
|
||||
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]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 32-bit value into the provided buffer (little endian convention).
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 32-bit value into the provided buffer (little endian convention).
|
||||
* The destination buffer must be properly aligned.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
*(sph_u32 *)dst = val;
|
||||
#elif SPH_BIG_ENDIAN
|
||||
*(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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 32-bit value from the provided buffer (little endian convention).
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 32-bit value from the provided buffer (little endian convention).
|
||||
* The source buffer must be properly aligned.
|
||||
*
|
||||
* @param src the source buffer (32-bit aligned)
|
||||
* @return the decoded value
|
||||
*/
|
||||
static inline sph_u32
|
||||
sph_dec32le_aligned(const void *src)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
return *(const sph_u32 *)src;
|
||||
#elif SPH_BIG_ENDIAN
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 64-bit value into the provided buffer (big endian convention).
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 64-bit value into the provided buffer (big endian convention).
|
||||
* The destination buffer must be properly aligned.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
*(sph_u64 *)dst = sph_bswap64(val);
|
||||
#elif SPH_BIG_ENDIAN
|
||||
*(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;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 64-bit value from the provided buffer (big endian convention).
|
||||
*
|
||||
* @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]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 64-bit value from the provided buffer (big endian convention).
|
||||
* The source buffer must be properly aligned.
|
||||
*
|
||||
* @param src the source buffer (64-bit aligned)
|
||||
* @return the decoded value
|
||||
*/
|
||||
static inline sph_u64
|
||||
sph_dec64be_aligned(const void *src)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
return sph_bswap64(*(const sph_u64 *)src);
|
||||
#elif SPH_BIG_ENDIAN
|
||||
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]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 64-bit value into the provided buffer (little endian convention).
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a 64-bit value into the provided buffer (little endian convention).
|
||||
* The destination buffer must be properly aligned.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
*(sph_u64 *)dst = val;
|
||||
#elif SPH_BIG_ENDIAN
|
||||
*(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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 64-bit value from the provided buffer (little endian convention).
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a 64-bit value from the provided buffer (little endian convention).
|
||||
* The source buffer must be properly aligned.
|
||||
*
|
||||
* @param src the source buffer (64-bit aligned)
|
||||
* @return the decoded value
|
||||
*/
|
||||
static inline sph_u64
|
||||
sph_dec64le_aligned(const void *src)
|
||||
{
|
||||
#if SPH_LITTLE_ENDIAN
|
||||
return *(const sph_u64 *)src;
|
||||
#elif SPH_BIG_ENDIAN
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
4
crypto/gui/.gitignore
vendored
Normal file
4
crypto/gui/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
gui.pro.user
|
||||
moc_mainwindow.cpp
|
||||
ui_mainwindow.h
|
||||
Makefile
|
32
crypto/gui/gui.pro
Normal file
32
crypto/gui/gui.pro
Normal file
@ -0,0 +1,32 @@
|
||||
QT += core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = gui
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += ../address.c
|
||||
SOURCES += ../bip32.c
|
||||
SOURCES += ../bip39.c
|
||||
SOURCES += ../sha2.c
|
||||
SOURCES += ../pbkdf2.c
|
||||
SOURCES += ../hmac.c
|
||||
SOURCES += ../rand.c
|
||||
SOURCES += ../bignum.c
|
||||
SOURCES += ../ecdsa.c
|
||||
SOURCES += ../ripemd160.c
|
||||
SOURCES += ../base58.c
|
||||
SOURCES += ../secp256k1.c
|
||||
SOURCES += ../nist256p1.c
|
||||
SOURCES += ../curves.c
|
||||
SOURCES += ../ed25519-donna/ed25519.c
|
||||
SOURCES += mainwindow.cpp
|
||||
SOURCES += main.cpp
|
||||
|
||||
HEADERS += mainwindow.h
|
||||
HEADERS += ../bip32.h
|
||||
HEADERS += ../bip39.h
|
||||
|
||||
FORMS += mainwindow.ui
|
||||
|
||||
INCLUDEPATH += ..
|
||||
INCLUDEPATH += ../ed25519-donna
|
10
crypto/gui/main.cpp
Normal file
10
crypto/gui/main.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
78
crypto/gui/mainwindow.cpp
Normal file
78
crypto/gui/mainwindow.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <QMessageBox>
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
extern "C" {
|
||||
#include "../bip32.h"
|
||||
#include "../bip39.h"
|
||||
#include "../ecdsa.h"
|
||||
#include "../curves.h"
|
||||
}
|
||||
|
||||
bool root_set = false;
|
||||
HDNode root;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ui->listAddress->insertRow(i);
|
||||
ui->listChange->insertRow(i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
// abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
|
||||
|
||||
void MainWindow::on_buttonLoad_clicked()
|
||||
{
|
||||
if (!mnemonic_check(ui->editMnemonic->text().toLocal8Bit().data())) {
|
||||
QMessageBox::critical(this, "Error", "Text is not a valid BIP39 mnemonic.", QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
uint8_t seed[64];
|
||||
mnemonic_to_seed(ui->editMnemonic->text().toLocal8Bit().data(), ui->editPassphrase->text().toLocal8Bit().data(), seed, 0);
|
||||
hdnode_from_seed(seed, 64, SECP256K1_NAME, &root);
|
||||
root_set = true;
|
||||
ui->spinAccount->setValue(1);
|
||||
on_spinAccount_valueChanged(1);
|
||||
}
|
||||
|
||||
void MainWindow::on_spinAccount_valueChanged(int arg1)
|
||||
{
|
||||
if (!root_set) return;
|
||||
// constants for Bitcoin
|
||||
const uint32_t version_public = 0x0488b21e;
|
||||
const uint32_t version_private = 0x0488ade4;
|
||||
const char addr_version = 0x00, wif_version = 0x80;
|
||||
const size_t buflen = 128;
|
||||
char buf[buflen + 1];
|
||||
HDNode node;
|
||||
uint32_t fingerprint;
|
||||
// external chain
|
||||
for (int chain = 0; chain < 2; chain++) {
|
||||
QTableWidget *list = chain == 0 ? ui->listAddress : ui->listChange;
|
||||
node = root;
|
||||
hdnode_private_ckd(&node, 44 | 0x80000000);
|
||||
hdnode_private_ckd(&node, 0 | 0x80000000); // bitcoin
|
||||
hdnode_private_ckd(&node, (arg1 - 1) | 0x80000000);
|
||||
fingerprint = hdnode_fingerprint(&node);
|
||||
hdnode_serialize_private(&node, fingerprint, version_private, buf, buflen); QString xprv = QString(buf); ui->lineXprv->setText(xprv);
|
||||
hdnode_serialize_public(&node, fingerprint, version_public, buf, buflen); QString xpub = QString(buf); ui->lineXpub->setText(xpub);
|
||||
hdnode_private_ckd(&node, chain); // external / internal
|
||||
for (int i = 0; i < 100; i++) {
|
||||
HDNode node2 = node;
|
||||
hdnode_private_ckd(&node2, i);
|
||||
hdnode_fill_public_key(&node2);
|
||||
ecdsa_get_address(node2.public_key, addr_version, buf, buflen); QString address = QString(buf);
|
||||
ecdsa_get_wif(node2.private_key, wif_version, buf, buflen); QString wif = QString(buf);
|
||||
list->setItem(i, 0, new QTableWidgetItem(address));
|
||||
list->setItem(i, 1, new QTableWidgetItem(wif));
|
||||
list->setItem(i, 2, new QTableWidgetItem("0.0"));
|
||||
}
|
||||
}
|
||||
}
|
27
crypto/gui/mainwindow.h
Normal file
27
crypto/gui/mainwindow.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QModelIndex>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_buttonLoad_clicked();
|
||||
void on_spinAccount_valueChanged(int arg1);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
161
crypto/gui/mainwindow.ui
Normal file
161
crypto/gui/mainwindow.ui
Normal file
@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TREZOR</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="lineXpub"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="editPassphrase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="buttonLoad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="4">
|
||||
<widget class="QTableWidget" name="listAddress">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>address</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>private key</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>balance</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="4">
|
||||
<widget class="QTableWidget" name="listChange">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>address</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>private key</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>balance</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelMnemonic">
|
||||
<property name="text">
|
||||
<string>Mnemonic:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labelPassphrase">
|
||||
<property name="text">
|
||||
<string>Passphrase:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelExternal">
|
||||
<property name="text">
|
||||
<string>External Chain:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="labelInternal">
|
||||
<property name="text">
|
||||
<string>Internal Chain:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QSpinBox" name="spinAccount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>130</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Account #</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="editMnemonic"/>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="lineXprv"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>editMnemonic</tabstop>
|
||||
<tabstop>editPassphrase</tabstop>
|
||||
<tabstop>buttonLoad</tabstop>
|
||||
<tabstop>spinAccount</tabstop>
|
||||
<tabstop>listAddress</tabstop>
|
||||
<tabstop>listChange</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
147
crypto/hasher.c
Normal file
147
crypto/hasher.c
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright (c) 2017 Saleem Rashid
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hasher.h"
|
||||
#include "ripemd160.h"
|
||||
|
||||
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param,
|
||||
uint32_t param_size) {
|
||||
hasher->type = type;
|
||||
hasher->param = param;
|
||||
hasher->param_size = param_size;
|
||||
|
||||
switch (hasher->type) {
|
||||
case HASHER_SHA2:
|
||||
case HASHER_SHA2D:
|
||||
case HASHER_SHA2_RIPEMD:
|
||||
sha256_Init(&hasher->ctx.sha2);
|
||||
break;
|
||||
case HASHER_SHA3:
|
||||
#if USE_KECCAK
|
||||
case HASHER_SHA3K:
|
||||
#endif
|
||||
sha3_256_Init(&hasher->ctx.sha3);
|
||||
break;
|
||||
case HASHER_BLAKE:
|
||||
case HASHER_BLAKED:
|
||||
case HASHER_BLAKE_RIPEMD:
|
||||
blake256_Init(&hasher->ctx.blake);
|
||||
break;
|
||||
case HASHER_GROESTLD_TRUNC:
|
||||
groestl512_Init(&hasher->ctx.groestl);
|
||||
break;
|
||||
case HASHER_BLAKE2B:
|
||||
blake2b_Init(&hasher->ctx.blake2b, 32);
|
||||
break;
|
||||
case HASHER_BLAKE2B_PERSONAL:
|
||||
blake2b_InitPersonal(&hasher->ctx.blake2b, 32, hasher->param,
|
||||
hasher->param_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void hasher_Init(Hasher *hasher, HasherType type) {
|
||||
hasher_InitParam(hasher, type, NULL, 0);
|
||||
}
|
||||
|
||||
void hasher_Reset(Hasher *hasher) {
|
||||
hasher_InitParam(hasher, hasher->type, hasher->param, hasher->param_size);
|
||||
}
|
||||
|
||||
void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length) {
|
||||
switch (hasher->type) {
|
||||
case HASHER_SHA2:
|
||||
case HASHER_SHA2D:
|
||||
case HASHER_SHA2_RIPEMD:
|
||||
sha256_Update(&hasher->ctx.sha2, data, length);
|
||||
break;
|
||||
case HASHER_SHA3:
|
||||
#if USE_KECCAK
|
||||
case HASHER_SHA3K:
|
||||
#endif
|
||||
sha3_Update(&hasher->ctx.sha3, data, length);
|
||||
break;
|
||||
case HASHER_BLAKE:
|
||||
case HASHER_BLAKED:
|
||||
case HASHER_BLAKE_RIPEMD:
|
||||
blake256_Update(&hasher->ctx.blake, data, length);
|
||||
break;
|
||||
case HASHER_GROESTLD_TRUNC:
|
||||
groestl512_Update(&hasher->ctx.groestl, data, length);
|
||||
break;
|
||||
case HASHER_BLAKE2B:
|
||||
case HASHER_BLAKE2B_PERSONAL:
|
||||
blake2b_Update(&hasher->ctx.blake2b, data, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) {
|
||||
switch (hasher->type) {
|
||||
case HASHER_SHA2:
|
||||
sha256_Final(&hasher->ctx.sha2, hash);
|
||||
break;
|
||||
case HASHER_SHA2D:
|
||||
sha256_Final(&hasher->ctx.sha2, hash);
|
||||
hasher_Raw(HASHER_SHA2, hash, HASHER_DIGEST_LENGTH, hash);
|
||||
break;
|
||||
case HASHER_SHA2_RIPEMD:
|
||||
sha256_Final(&hasher->ctx.sha2, hash);
|
||||
ripemd160(hash, HASHER_DIGEST_LENGTH, hash);
|
||||
break;
|
||||
case HASHER_SHA3:
|
||||
sha3_Final(&hasher->ctx.sha3, hash);
|
||||
break;
|
||||
#if USE_KECCAK
|
||||
case HASHER_SHA3K:
|
||||
keccak_Final(&hasher->ctx.sha3, hash);
|
||||
break;
|
||||
#endif
|
||||
case HASHER_BLAKE:
|
||||
blake256_Final(&hasher->ctx.blake, hash);
|
||||
break;
|
||||
case HASHER_BLAKED:
|
||||
blake256_Final(&hasher->ctx.blake, hash);
|
||||
hasher_Raw(HASHER_BLAKE, hash, HASHER_DIGEST_LENGTH, hash);
|
||||
break;
|
||||
case HASHER_BLAKE_RIPEMD:
|
||||
blake256_Final(&hasher->ctx.blake, hash);
|
||||
ripemd160(hash, HASHER_DIGEST_LENGTH, hash);
|
||||
break;
|
||||
case HASHER_GROESTLD_TRUNC:
|
||||
groestl512_DoubleTrunc(&hasher->ctx.groestl, hash);
|
||||
break;
|
||||
case HASHER_BLAKE2B:
|
||||
case HASHER_BLAKE2B_PERSONAL:
|
||||
blake2b_Final(&hasher->ctx.blake2b, hash, 32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void hasher_Raw(HasherType type, const uint8_t *data, size_t length,
|
||||
uint8_t hash[HASHER_DIGEST_LENGTH]) {
|
||||
Hasher hasher;
|
||||
|
||||
hasher_Init(&hasher, type);
|
||||
hasher_Update(&hasher, data, length);
|
||||
hasher_Final(&hasher, hash);
|
||||
}
|
82
crypto/hasher.h
Normal file
82
crypto/hasher.h
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright (c) 2017 Saleem Rashid
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __HASHER_H__
|
||||
#define __HASHER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "blake256.h"
|
||||
#include "blake2b.h"
|
||||
#include "groestl.h"
|
||||
#include "sha2.h"
|
||||
#include "sha3.h"
|
||||
|
||||
#define HASHER_DIGEST_LENGTH 32
|
||||
|
||||
typedef enum {
|
||||
HASHER_SHA2,
|
||||
HASHER_SHA2D,
|
||||
HASHER_SHA2_RIPEMD,
|
||||
|
||||
HASHER_SHA3,
|
||||
#if USE_KECCAK
|
||||
HASHER_SHA3K,
|
||||
#endif
|
||||
|
||||
HASHER_BLAKE,
|
||||
HASHER_BLAKED,
|
||||
HASHER_BLAKE_RIPEMD,
|
||||
|
||||
HASHER_GROESTLD_TRUNC, /* Double Groestl512 hasher truncated to 256 bits */
|
||||
|
||||
HASHER_BLAKE2B,
|
||||
HASHER_BLAKE2B_PERSONAL,
|
||||
} HasherType;
|
||||
|
||||
typedef struct {
|
||||
HasherType type;
|
||||
|
||||
union {
|
||||
SHA256_CTX sha2; // for HASHER_SHA2{,D}
|
||||
SHA3_CTX sha3; // for HASHER_SHA3{,K}
|
||||
BLAKE256_CTX blake; // for HASHER_BLAKE{,D}
|
||||
GROESTL512_CTX groestl; // for HASHER_GROESTLD_TRUNC
|
||||
BLAKE2B_CTX blake2b; // for HASHER_BLAKE2B{,_PERSONAL}
|
||||
} ctx;
|
||||
|
||||
const void *param;
|
||||
uint32_t param_size;
|
||||
} Hasher;
|
||||
|
||||
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param,
|
||||
uint32_t param_size);
|
||||
void hasher_Init(Hasher *hasher, HasherType type);
|
||||
void hasher_Reset(Hasher *hasher);
|
||||
void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length);
|
||||
void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]);
|
||||
|
||||
void hasher_Raw(HasherType type, const uint8_t *data, size_t length,
|
||||
uint8_t hash[HASHER_DIGEST_LENGTH]);
|
||||
|
||||
#endif
|
176
crypto/hmac.c
Normal file
176
crypto/hmac.c
Normal file
@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hmac.h"
|
||||
#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_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(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;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
REVERSE32(key_pad[i], data);
|
||||
#else
|
||||
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));
|
||||
}
|
||||
|
||||
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_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;
|
||||
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;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
REVERSE64(key_pad[i], data);
|
||||
#else
|
||||
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));
|
||||
}
|
60
crypto/hmac.h
Normal file
60
crypto/hmac.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2013-2014 Tomas Dzetkulic
|
||||
* Copyright (c) 2013-2014 Pavol Rusnak
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT HMAC_SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
||||
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __HMAC_H__
|
||||
#define __HMAC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sha2.h"
|
||||
|
||||
typedef struct _HMAC_SHA256_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;
|
||||
} 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_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
|
66
crypto/memzero.c
Normal file
66
crypto/memzero.c
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef __STDC_WANT_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1 // C11's bounds-checking interface.
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
#include <strings.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
// C11's bounds-checking interface.
|
||||
#if defined(__STDC_LIB_EXT1__)
|
||||
#define HAVE_MEMSET_S 1
|
||||
#endif
|
||||
|
||||
// GNU C Library version 2.25 or later.
|
||||
#if defined(__GLIBC__) && \
|
||||
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
#define HAVE_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
// Newlib
|
||||
#if defined(__NEWLIB__)
|
||||
#define HAVE_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
// FreeBSD version 11.0 or later.
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 1100037
|
||||
#define HAVE_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
// OpenBSD version 5.5 or later.
|
||||
#if defined(__OpenBSD__) && OpenBSD >= 201405
|
||||
#define HAVE_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
// NetBSD version 7.2 or later.
|
||||
#if defined(__NetBSD__) && __NetBSD_Version__ >= 702000000
|
||||
#define HAVE_EXPLICIT_MEMSET 1
|
||||
#endif
|
||||
|
||||
// Adapted from
|
||||
// https://github.com/jedisct1/libsodium/blob/1647f0d53ae0e370378a9195477e3df0a792408f/src/libsodium/sodium/utils.c#L102-L130
|
||||
|
||||
void memzero(void *const pnt, const size_t len) {
|
||||
#ifdef _WIN32
|
||||
SecureZeroMemory(pnt, len);
|
||||
#elif defined(HAVE_MEMSET_S)
|
||||
memset_s(pnt, (rsize_t)len, 0, (rsize_t)len);
|
||||
#elif defined(HAVE_EXPLICIT_BZERO)
|
||||
explicit_bzero(pnt, len);
|
||||
#elif defined(HAVE_EXPLICIT_MEMSET)
|
||||
explicit_memset(pnt, 0, len);
|
||||
#else
|
||||
volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile)pnt;
|
||||
size_t i = (size_t)0U;
|
||||
|
||||
while (i < len) {
|
||||
pnt_[i++] = 0U;
|
||||
}
|
||||
#endif
|
||||
}
|
8
crypto/memzero.h
Normal file
8
crypto/memzero.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __MEMZERO_H__
|
||||
#define __MEMZERO_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void memzero(void* const pnt, const size_t len);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user