diff --git a/.clang-format b/.clang-format index c3a9fa31eb5..84f2e87c9d7 100644 --- a/.clang-format +++ b/.clang-format @@ -12,7 +12,7 @@ PointerAlignment: Left IncludeCategories: - Regex: '^"\.\./' Priority: 2 - - Regex: '^<(TrustWalletCore|TrezorCrypto)/' + - Regex: '^<(TrustWalletCore)/' Priority: 3 - Regex: '<.*>' Priority: 4 diff --git a/.github/workflows/codegen-v2.yml b/.github/workflows/codegen-v2.yml index 8438d788d56..d7bde064e0d 100644 --- a/.github/workflows/codegen-v2.yml +++ b/.github/workflows/codegen-v2.yml @@ -21,7 +21,7 @@ jobs: tools/install-sys-dependencies-linux - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.8 - name: Install Rust dependencies run: | diff --git a/.github/workflows/linux-ci-rust.yml b/.github/workflows/linux-ci-rust.yml index 377c60ee23d..d2940428273 100644 --- a/.github/workflows/linux-ci-rust.yml +++ b/.github/workflows/linux-ci-rust.yml @@ -29,7 +29,7 @@ jobs: tools/install-sys-dependencies-linux - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.8 - name: Cache Rust uses: Swatinem/rust-cache@v2 @@ -74,7 +74,7 @@ jobs: tools/install-sys-dependencies-linux - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.8 - name: Cache Rust uses: Swatinem/rust-cache@v2 @@ -105,7 +105,7 @@ jobs: tools/install-sys-dependencies-mac - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.8 - name: Cache Rust uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index acda9dcfe10..ab246aee393 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -54,8 +54,7 @@ jobs: CXX: /usr/bin/clang++ - name: Build and test run: | - ninja -Cbuild tests TrezorCryptoTests - build/trezor-crypto/crypto/tests/TrezorCryptoTests + ninja -Cbuild tests build/tests/tests --gtest_output=xml env: CC: /usr/bin/clang diff --git a/.gitignore b/.gitignore index e7e97f12830..9b126ffe680 100644 --- a/.gitignore +++ b/.gitignore @@ -37,21 +37,11 @@ codegen-v2/bindings/ src/Generated/*.h src/Generated/*.cpp +include/TrustWalletCore/Generated/*.h include/TrustWalletCore/TWHRP.h include/TrustWalletCore/TW*Proto.h include/TrustWalletCore/TWEthereumChainID.h -# Generated -include/TrustWalletCore/TWTONAddressConverter.h -include/TrustWalletCore/TWFFITest.h -include/TrustWalletCore/TWTONWallet.h -include/TrustWalletCore/TWTONMessageSigner.h -include/TrustWalletCore/TWMessageSigner.h -include/TrustWalletCore/TWWalletConnectRequest.h -include/TrustWalletCore/TWSolanaTransaction.h -include/TrustWalletCore/TWCryptoBoxPublicKey.h -include/TrustWalletCore/TWCryptoBoxSecretKey.h - # Wasm emsdk/ wasm-build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fec5513326..57d49df4407 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,6 @@ target_link_directories(${PROJECT_NAME}_INTERFACE INTERFACE ${PREFIX}/lib) target_link_directories(${PROJECT_NAME}_INTERFACE INTERFACE ${WALLET_CORE_RS_TARGET_DIR}/release) set_project_warnings(${PROJECT_NAME}_INTERFACE) -add_subdirectory(trezor-crypto) set(WALLET_CORE_RS_LIB libwallet_core_rs.a) set(WALLET_CORE_BINDGEN ${WALLET_CORE_RS_TARGET_DIR}/release/${WALLET_CORE_RS_LIB}) @@ -72,7 +71,7 @@ if (${ANDROID}) elseif (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "x86_64") set(WALLET_CORE_BINDGEN ${WALLET_CORE_RS_TARGET_DIR}/x86_64-linux-android/release/${WALLET_CORE_RS_LIB}) endif () - target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE TrezorCrypto protobuf ${log-lib} Boost::boost) + target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE protobuf ${log-lib} Boost::boost) elseif (${TW_COMPILE_JAVA}) message("Configuring for JNI") file(GLOB_RECURSE core_sources src/*.c src/*.cc src/*.cpp src/*.h jni/cpp/*.cpp jni/cpp/*.h) @@ -90,12 +89,12 @@ elseif (${TW_COMPILE_JAVA}) add_library(TrustWalletCore SHARED ${sources} ${PROTO_SRCS} ${PROTO_HDRS}) find_package(JNI REQUIRED) target_include_directories(TrustWalletCore PRIVATE ${JNI_INCLUDE_DIRS}) - target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE TrezorCrypto protobuf Boost::boost) + target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE protobuf Boost::boost) else () message("Configuring standalone") file(GLOB_RECURSE sources src/*.c src/*.cc src/*.cpp src/*.h) add_library(TrustWalletCore STATIC ${sources} ${PROTO_SRCS} ${PROTO_HDRS}) - target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE TrezorCrypto protobuf Boost::boost) + target_link_libraries(TrustWalletCore PUBLIC ${WALLET_CORE_BINDGEN} ${PROJECT_NAME}_INTERFACE PRIVATE protobuf Boost::boost) endif () if (TW_CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") diff --git a/Dockerfile b/Dockerfile index 082d5fd1969..a2c6f399eda 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,7 @@ ENV CXX=/usr/bin/clang++-14 RUN wget "https://sh.rustup.rs" -O rustup.sh \ && sh rustup.sh -y ENV PATH="/root/.cargo/bin:${PATH}" -RUN rustup default nightly-2024-06-13 +RUN rustup default nightly-2025-01-16 RUN cargo install --force cbindgen \ && rustup target add wasm32-unknown-emscripten diff --git a/WalletCore.podspec b/WalletCore.podspec index ee960c3a1eb..77129c89049 100644 --- a/WalletCore.podspec +++ b/WalletCore.podspec @@ -37,8 +37,6 @@ Pod::Spec.new do |s| 'swift/Sources/*.{swift,h,m,cpp}', 'swift/Sources/Extensions/*.swift', 'swift/Sources/Generated/*.{swift,h}', - 'trezor-crypto/crypto/**/*.{c,h}', - 'trezor-crypto/include/**/*.{h}', "#{protobuf_source_dir}/src/google/protobuf/any.cc", "#{protobuf_source_dir}/src/google/protobuf/any.pb.cc", "#{protobuf_source_dir}/src/google/protobuf/any_lite.cc", @@ -125,11 +123,7 @@ Pod::Spec.new do |s| "#{protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc" ss.exclude_files = - 'trezor-crypto/include/TrezorCrypto/base58.h', - 'trezor-crypto/crypto/monero', - 'trezor-crypto/crypto/tests', - 'trezor-crypto/crypto/tools', - 'trezor-crypto/crypto/rand.c', + 'src/rand.cpp', 'swift/Sources/Generated/WalletCore.h' ss.public_header_files = @@ -137,7 +131,6 @@ Pod::Spec.new do |s| 'swift/Sources/*.h' ss.preserve_paths = - 'trezor-crypto/crypto/*.{table}', "#{protobuf_source_dir}/src/**/*.{h,inc}", "#{include_dir}/nlohmann/**/*.hpp", 'src/proto/*.proto' @@ -145,12 +138,10 @@ Pod::Spec.new do |s| ss.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(inherited) ' \ '$(SRCROOT)/../../wallet-core ' \ - '${SRCROOT}/../../trezor-crypto/crypto ', 'SYSTEM_HEADER_SEARCH_PATHS' => '$(inherited) ' \ '/usr/local/include ' \ '${SRCROOT}/../../include ' \ '${SRCROOT}/../../../build/local/include ' \ - "${SRCROOT}/../../trezor-crypto/include " \ "${SRCROOT}/../../protobuf ", 'GCC_WARN_UNUSED_FUNCTION' => 'NO', 'GCC_WARN_64_TO_32_BIT_CONVERSION' => 'NO', diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acala/TestAcalaAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acala/TestAcalaAddress.kt index 5e50f515ab4..3ad6a63eb03 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acala/TestAcalaAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acala/TestAcalaAddress.kt @@ -18,7 +18,7 @@ class TestAcalaAddress { @Test fun testAddress() { - val key = PrivateKey("0x9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0".toHexByteArray()) + val key = PrivateKey("0x9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0".toHexByteArray(), CoinType.ACALA.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.ACALA) assertEquals(address.description(), "269ZCS3WLGydTN8ynhyhZfzJrXkePUcdhwgLQs6TWFs5wVL5") diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acalaevm/TestAcalaEVMAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acalaevm/TestAcalaEVMAddress.kt index 6845bea3e89..7170c4995ae 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acalaevm/TestAcalaEVMAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/acalaevm/TestAcalaEVMAddress.kt @@ -17,7 +17,7 @@ class TestAcalaEVMAddress { @Test fun testAddress() { - val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray()) + val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray(), CoinType.ACALAEVM.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.ACALAEVM) val expected = AnyAddress("0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", CoinType.ACALAEVM) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricAddress.kt index 1164db16e14..f905b9e5397 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricAddress.kt @@ -19,7 +19,7 @@ class TestAgoricAddress { @Test fun testAddress() { - val key = PrivateKey("037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73".toHexByteArray()) + val key = PrivateKey("037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73".toHexByteArray(), CoinType.AGORIC.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.AGORIC) val expected = AnyAddress("agoric18zvvgk6j3eq5wd7mqxccgt20gz2w94cy88aek5", CoinType.AGORIC) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricSigner.kt index ecdf4372f3a..fe6be0c5c81 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/agoric/TestAgoricSigner.kt @@ -22,7 +22,7 @@ class TestAgoricSigner { @Test fun AgoricTransactionSigning() { - val key = PrivateKey("037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73".toHexByteArray()) + val key = PrivateKey("037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73".toHexByteArray(), CoinType.AGORIC.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, CoinType.AGORIC).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aion/TestAion.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aion/TestAion.kt index 8ecbff6e286..2b8c07debc3 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aion/TestAion.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/aion/TestAion.kt @@ -22,7 +22,7 @@ class TestAionAddress { @Test fun testAddressFromPublicKey() { - val privateKey = PrivateKey("db33ffdf82c7ba903daf68d961d3c23c20471a8ce6b408e52d579fd8add80cc9".toHexByteArray()) + val privateKey = PrivateKey("db33ffdf82c7ba903daf68d961d3c23c20471a8ce6b408e52d579fd8add80cc9".toHexByteArray(), CoinType.AION.curve()) val publicKey = privateKey.getPublicKeyEd25519() val address = AnyAddress(publicKey, CoinType.AION) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/algorand/TestAlgorandAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/algorand/TestAlgorandAddress.kt index 8883b93acc4..86d27a5611a 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/algorand/TestAlgorandAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/algorand/TestAlgorandAddress.kt @@ -14,7 +14,7 @@ class TestAlgorandAddress { @Test fun testAddress() { - val key = PrivateKey("a6c4394041e64fe93d889386d7922af1b9a87f12e433762759608e61434d6cf7".toHexByteArray()) + val key = PrivateKey("a6c4394041e64fe93d889386d7922af1b9a87f12e433762759608e61434d6cf7".toHexByteArray(), CoinType.ALGORAND.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.ALGORAND) val expected = AnyAddress("ADIYK65L3XR5ODNNCUIQVEET455L56MRKJHRBX5GU4TZI2752QIWK4UL5A", CoinType.ALGORAND) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainAddress.kt index ec361735357..b0ebff4c18c 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainAddress.kt @@ -19,7 +19,7 @@ class TestBandChainAddress { @Test fun testAddress() { - val key = PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray()) + val key = PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray(), CoinType.BANDCHAIN.curve()) val publicKey = key.getPublicKeySecp256k1(true) val address = AnyAddress(publicKey, CoinType.BANDCHAIN) val expected = AnyAddress("band1jf9aaj9myrzsnmpdr7twecnaftzmku2mgms4n3", CoinType.BANDCHAIN) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainSigner.kt index 001e9d90631..5b256ec2b11 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bandchain/TestBandChainSigner.kt @@ -10,6 +10,7 @@ import org.junit.Assert.assertEquals import org.junit.Test import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress +import wallet.core.jni.CoinType import wallet.core.jni.CoinType.BANDCHAIN import wallet.core.jni.PrivateKey import wallet.core.jni.proto.Cosmos @@ -24,7 +25,7 @@ class TestBandChainSigner { @Test fun testSigningTransaction() { val key = - PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray()) + PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray(), CoinType.BANDCHAIN.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, BANDCHAIN).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/binance/TestBinanceTransactionSigning.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/binance/TestBinanceTransactionSigning.kt index 011c8e08656..188fa8ce66d 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/binance/TestBinanceTransactionSigning.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/binance/TestBinanceTransactionSigning.kt @@ -17,11 +17,11 @@ class TestBinanceTransactionSigning { System.loadLibrary("TrustWalletCore") } - val testKey = PrivateKey("eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d".toHexBytes()) + val testKey = PrivateKey("eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d".toHexBytes(), BINANCE.curve()) @Test fun testSignBinanceTransaction() { - val privateKey = PrivateKey("95949f757db1f57ca94a5dff23314accbe7abee89597bf6a3c7382c84d7eb832".toHexBytes()) + val privateKey = PrivateKey("95949f757db1f57ca94a5dff23314accbe7abee89597bf6a3c7382c84d7eb832".toHexBytes(), BINANCE.curve()) val publicKey = privateKey.getPublicKeySecp256k1(true) val signingInput = Binance.SigningInput.newBuilder() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinPsbt.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinPsbt.kt index 884120800ca..973be37964b 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinPsbt.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinPsbt.kt @@ -64,7 +64,7 @@ class TestBitcoinPsbt { fun testPlanThorSwap() { // Successfully broadcasted tx: https://mempool.space/tx/634a416e82ac710166725f6a4090ac7b5db69687e86b2d2e38dcb3d91c956c32 - val privateKey = PrivateKey("f00ffbe44c5c2838c13d2778854ac66b75e04eb6054f0241989e223223ad5e55".toHexBytes()) + val privateKey = PrivateKey("f00ffbe44c5c2838c13d2778854ac66b75e04eb6054f0241989e223223ad5e55".toHexBytes(), CoinType.BITCOIN.curve()) val publicKey = privateKey.getPublicKeySecp256k1(true) val psbt = "70736274ff0100bc0200000001147010db5fbcf619067c1090fec65c131443fbc80fb4aaeebe940e44206098c60000000000ffffffff0360ea000000000000160014f22a703617035ef7f490743d50f26ae08c30d0a70000000000000000426a403d3a474149412e41544f4d3a636f736d6f7331737377797a666d743675396a373437773537753438746778646575393573757a666c6d7175753a303a743a35303e12000000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d000000000001011f6603010000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d00000000".toHexBytesInByteString() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinSigning.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinSigning.kt index 40b94298cd7..5802b34602f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinSigning.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoin/TestBitcoinSigning.kt @@ -169,7 +169,7 @@ class TestBitcoinSigning { val dustSatoshis = 546.toLong() val txId = Numeric.hexStringToByteArray("8ec895b4d30adb01e38471ca1019bfc8c3e5fbd1f28d9e7b5653260d89989008").reversedArray() - val privateKey = PrivateKey(privateKeyData) + val privateKey = PrivateKey(privateKeyData, CoinType.BITCOIN.curve()) val publicKey = ByteString.copyFrom(privateKey.getPublicKeySecp256k1(true).data()) val utxo0 = BitcoinV2.Input.newBuilder() @@ -235,7 +235,7 @@ class TestBitcoinSigning { val dustSatoshis = 546.toLong() val txIdCommit = Numeric.hexStringToByteArray("797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1").reversedArray() - val privateKey = PrivateKey(privateKeyData) + val privateKey = PrivateKey(privateKeyData, CoinType.BITCOIN.curve()) val publicKey = ByteString.copyFrom(privateKey.getPublicKeySecp256k1(true).data()) val utxo0 = BitcoinV2.Input.newBuilder() @@ -295,7 +295,7 @@ class TestBitcoinSigning { val txIdInscription = Numeric.hexStringToByteArray("7046dc2689a27e143ea2ad1039710885147e9485ab6453fa7e87464aa7dd3eca").reversedArray() val txIdForFees = Numeric.hexStringToByteArray("797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1").reversedArray() - val privateKey = PrivateKey(privateKeyData) + val privateKey = PrivateKey(privateKeyData, CoinType.BITCOIN.curve()) val publicKey = ByteString.copyFrom(privateKey.getPublicKeySecp256k1(true).data()) val bobAddress = "bc1qazgc2zhu2kmy42py0vs8d7yff67l3zgpwfzlpk" diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoindiamond/TestBitcoinDiamondAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoindiamond/TestBitcoinDiamondAddress.kt index 497b2d6dedc..7463027119d 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoindiamond/TestBitcoinDiamondAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bitcoindiamond/TestBitcoinDiamondAddress.kt @@ -18,7 +18,7 @@ class TestBitcoinDiamondAddress { @Test fun testAddress() { - val key = PrivateKey("d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee".toHexByteArray()) + val key = PrivateKey("d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee".toHexByteArray(), CoinType.BITCOINDIAMOND.curve()) val pubkey = key.getPublicKeySecp256k1(true); val address = AnyAddress(pubkey, CoinType.BITCOINDIAMOND) val expected = AnyAddress("1G15VvshDxwFTnahZZECJfFwEkq9fP79o8", CoinType.BITCOINDIAMOND) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleAddress.kt index d8eb3424893..97ffbbab724 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleAddress.kt @@ -19,7 +19,7 @@ class TestBluzelleAddress { @Test fun testAddressPublicKey() { - val key = PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray()) + val key = PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray(), CoinType.BLUZELLE.curve()) val publicKey = key.getPublicKeySecp256k1(true) val expectedAddress = "bluzelle1jf9aaj9myrzsnmpdr7twecnaftzmku2myvn4dg" val actualAddress = AnyAddress(publicKey, CoinType.BLUZELLE).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleSigner.kt index bf40f0dcc67..01751a8b32c 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/bluzelle/TestBluzelleSigner.kt @@ -13,6 +13,7 @@ import org.junit.Assert.assertEquals import org.junit.Test import wallet.core.java.AnySigner import wallet.core.jni.AnyAddress +import wallet.core.jni.CoinType import wallet.core.jni.CoinType.BLUZELLE import wallet.core.jni.PrivateKey import wallet.core.jni.proto.Cosmos @@ -29,7 +30,7 @@ class TestBluzelleSigner { // Submitted Realworld tx for the following test : https://bigdipper.net.bluzelle.com/transactions/B3A7F30539CCDF72D210BC995FAF65B43F9BE04FA9F8AFAE0EC969660744002F val key = - PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray()) + PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray(), CoinType.BLUZELLE.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, BLUZELLE).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoAddress.kt index a505e201176..ac2d43e801d 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoAddress.kt @@ -18,7 +18,7 @@ class TestCardanoAddress { @Test fun testAddress() { - val key = PrivateKey("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71effbf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7bed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a".toHexByteArray()) + val key = PrivateKey("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71effbf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7bed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a".toHexByteArray(), CoinType.CARDANO.curve()) val pubkey = key.publicKeyEd25519Cardano val address = AnyAddress(pubkey, CoinType.CARDANO) val expected = AnyAddress("addr1qx4z6twzknkkux0hhp0kq6hvdfutczp56g56y5em8r8mgvxalp7nkkk25vuspleke2zltaetmlwrfxv7t049cq9jmwjswmfw6t", CoinType.CARDANO) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoSigning.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoSigning.kt index d9450e9881c..25d61fb03bf 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoSigning.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cardano/TestCardanoSigning.kt @@ -78,7 +78,7 @@ class TestCardanoSigning { /// https://cardanoscan.io/transaction/0203ce2c91f59f169a26e9ef91254639d2b7911afac9c7c0ae64539f88ba46a5 @Test fun testSignTransferFromLegacy() { - val privateKey = PrivateKey("98f266d1aac660179bc2f456033941238ee6b2beb8ed0f9f34c9902816781f5a9903d1d395d6ab887b65ea5e344ef09b449507c21a75f0ce8c59d0ed1c6764eba7f484aa383806735c46fd769c679ee41f8952952036a6e2338ada940b8a91f4e890ca4eb6bec44bf751b5a843174534af64d6ad1f44e0613db78a7018781f5aa151d2997f52059466b715d8eefab30a78b874ae6ef4931fa58bb21ef8ce2423d46f19d0fbf75afb0b9a24e31d533f4fd74cee3b56e162568e8defe37123afc4".toHexByteArray()) + val privateKey = PrivateKey("98f266d1aac660179bc2f456033941238ee6b2beb8ed0f9f34c9902816781f5a9903d1d395d6ab887b65ea5e344ef09b449507c21a75f0ce8c59d0ed1c6764eba7f484aa383806735c46fd769c679ee41f8952952036a6e2338ada940b8a91f4e890ca4eb6bec44bf751b5a843174534af64d6ad1f44e0613db78a7018781f5aa151d2997f52059466b715d8eefab30a78b874ae6ef4931fa58bb21ef8ce2423d46f19d0fbf75afb0b9a24e31d533f4fd74cee3b56e162568e8defe37123afc4".toHexByteArray(), CoinType.CARDANO.curve()) var publicKey = privateKey.publicKeyEd25519Cardano var byronAddress = wallet.core.jni.Cardano.getByronAddress(publicKey) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/confluxespace/TestConfluxeSpaceAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/confluxespace/TestConfluxeSpaceAddress.kt index 25d5ae1c81e..d45cad3978f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/confluxespace/TestConfluxeSpaceAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/confluxespace/TestConfluxeSpaceAddress.kt @@ -17,7 +17,7 @@ class TestConfluxeSpaceAddress { @Test fun testAddress() { - val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray()) + val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray(), CoinType.CONFLUXESPACE.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.CONFLUXESPACE) val expected = AnyAddress("0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", CoinType.CONFLUXESPACE) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cosmos/TestCosmosTransactions.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cosmos/TestCosmosTransactions.kt index 4de24f9b60f..b9573a8225e 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cosmos/TestCosmosTransactions.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cosmos/TestCosmosTransactions.kt @@ -22,7 +22,7 @@ class TestCosmosTransactions { @Test fun testAuthStakingTransaction() { val key = - PrivateKey("c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc".toHexByteArray()) + PrivateKey("c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc".toHexByteArray(), CoinType.COSMOS.curve()) val stakeAuth = Cosmos.Message.StakeAuthorization.newBuilder().apply { allowList = Cosmos.Message.StakeAuthorization.Validators.newBuilder().apply { @@ -75,7 +75,7 @@ class TestCosmosTransactions { @Test fun testRemoveAuthStakingTransaction() { val key = - PrivateKey("c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc".toHexByteArray()) + PrivateKey("c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc".toHexByteArray(), CoinType.COSMOS.curve()) val removeAuthStakingMsg = Cosmos.Message.AuthRevoke.newBuilder().apply { grantee = "cosmos1fs7lu28hx5m9akm7rp0c2422cn8r2f7gurujhf" @@ -120,7 +120,7 @@ class TestCosmosTransactions { @Test fun testSigningTransaction() { val key = - PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray()) + PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray(), CoinType.COSMOS.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, COSMOS).description() @@ -196,7 +196,7 @@ class TestCosmosTransactions { } """ val key = - "c9b0a273831931aa4a5f8d1a570d5021dda91d3319bd3819becdaabfb7b44e3b".toHexByteArray() + PrivateKey("c9b0a273831931aa4a5f8d1a570d5021dda91d3319bd3819becdaabfb7b44e3b".toHexByteArray(), CoinType.COSMOS.curve()).data() val result = AnySigner.signJSON(json, key, COSMOS.value()) assertEquals( result, diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgAddress.kt index 214c391624d..b62909937f6 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgAddress.kt @@ -18,7 +18,7 @@ class TestCryptoorgAddress { @Test fun testAddress() { - val key = PrivateKey("7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e".toHexByteArray()) + val key = PrivateKey("7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e".toHexByteArray(), CoinType.CRYPTOORG.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.CRYPTOORG) val expected = AnyAddress("cro1z53wwe7md6cewz9sqwqzn0aavpaun0gw39h3rd", CoinType.CRYPTOORG) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgSigner.kt index 74090e73a29..97748349c63 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/cryptoorg/TestCryptoorgSigner.kt @@ -27,7 +27,7 @@ class TestCryptoorgSigner { @Test fun CryptoorgTransactionSigning() { - val key = PrivateKey("200e439e39cf1aad465ee3de6166247f914cbc0f823fc2dd48bf16dcd556f39d".toHexByteArray()) + val key = PrivateKey("200e439e39cf1aad465ee3de6166247f914cbc0f823fc2dd48bf16dcd556f39d".toHexByteArray(), CoinType.CRYPTOORG.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, CRYPTOORG).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt index 408f8fb4ae3..213439ec841 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/dydx/TestDydxAddress.kt @@ -17,7 +17,7 @@ class TestDydxAddress { @Test fun testAddress() { - val key = PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray()) + val key = PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray(), CoinType.DYDX.curve()) val pubKey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubKey, CoinType.DYDX) val expected = AnyAddress("dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz", CoinType.DYDX) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt index c1c0c80f905..7fec2add476 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt @@ -99,7 +99,7 @@ class TestBarz { fun testSignK1TransferAccountDeployed() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom("0x61".toHexByteArray()) nonce = ByteString.copyFrom("0x2".toHexByteArray()) toAddress = "0x61061fCAE11fD5461535e134EfF67A98CFFF44E9" @@ -144,7 +144,7 @@ class TestBarz { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom("0x61".toHexByteArray()) nonce = ByteString.copyFrom("0x00".toHexByteArray()) toAddress = "0x61061fCAE11fD5461535e134EfF67A98CFFF44E9" @@ -195,7 +195,7 @@ class TestBarz { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom("0x61".toHexByteArray()) nonce = ByteString.copyFrom("0x03".toHexByteArray()) txMode = TransactionMode.UserOp @@ -252,7 +252,7 @@ class TestBarz { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0xe148e40f06ee3ba316cdb2571f33486cf879c0ffd2b279ce9f9a88c41ce962e7".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0xe148e40f06ee3ba316cdb2571f33486cf879c0ffd2b279ce9f9a88c41ce962e7".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom("0x38".toHexByteArray()) nonce = ByteString.copyFrom("0x12".toHexByteArray()) txMode = TransactionMode.SetCode @@ -297,7 +297,7 @@ class TestBarz { fun testSignEnvelopedBiz() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0xe762e91cc4889a9fce79b2d2ffc079f86c48331f57b2cd16a33bee060fe448e1".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0xe762e91cc4889a9fce79b2d2ffc079f86c48331f57b2cd16a33bee060fe448e1".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom("0x38".toHexByteArray()) nonce = ByteString.copyFrom("0x02".toHexByteArray()) txMode = TransactionMode.Enveloped @@ -385,7 +385,7 @@ class TestBarz { // Create signing input val signingInput = Ethereum.SigningInput.newBuilder().apply { - privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) chainId = ByteString.copyFrom(chainIdByteArray) // 31337 nonce = ByteString.copyFrom("0x00".toHexByteArray()) txMode = Ethereum.TransactionMode.UserOp diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumMessageSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumMessageSigner.kt index 6245751d124..8a453fa6a63 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumMessageSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumMessageSigner.kt @@ -17,7 +17,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessageImmutableX() { val data = Numeric.hexStringToByteArray("3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = "Only sign this request if you’ve initiated an action with Immutable X.\n\nFor internal use:\nbd717ba31dca6e0f3f136f7c4197babce5f09a9f25176044c0b3112b1b6017a3" val signature = EthereumMessageSigner.signMessageImmutableX(privateKey, msg) @@ -28,7 +28,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessageLegacy() { val data = Numeric.hexStringToByteArray("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = "Foo" val signature = EthereumMessageSigner.signMessage(privateKey, msg) @@ -39,7 +39,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessageLegacyHex() { val data = Numeric.hexStringToByteArray("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = "0xc0a96273d5c3fbe4d4000491f08daef9c17f88df846c1d6f57eb5f33c1fbd035" val signature = EthereumMessageSigner.signMessage(privateKey, msg) @@ -50,7 +50,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessage712Legacy() { val data = Numeric.hexStringToByteArray("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = """ { @@ -87,7 +87,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessage712Eip155() { val data = Numeric.hexStringToByteArray("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = """ { @@ -124,7 +124,7 @@ class TestEthereumMessageSigner { @Test fun testEthereumSignAndVerifyMessageEip155() { val data = Numeric.hexStringToByteArray("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.ETHEREUM.curve()) val publicKey = privateKey.getPublicKey(CoinType.ETHEREUM) val msg = "Foo" val signature = EthereumMessageSigner.signMessageEip155(privateKey, msg, 0) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumTransactionSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumTransactionSigner.kt index 61a6b9a42df..aeb84e2eb00 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumTransactionSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestEthereumTransactionSigner.kt @@ -26,7 +26,7 @@ class TestEthereumTransactionSigner { fun testEthereumTransactionSigning() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0x4646464646464646464646464646464646464646464646464646464646464646".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x4646464646464646464646464646464646464646464646464646464646464646".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) toAddress = "0x3535353535353535353535353535353535353535" chainId = ByteString.copyFrom("0x1".toHexByteArray()) nonce = ByteString.copyFrom("0x9".toHexByteArray()) @@ -49,7 +49,7 @@ class TestEthereumTransactionSigner { fun testEthereumERC20Signing() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) toAddress = "0x6b175474e89094c44da98b954eedeac495271d0f" // DAI chainId = ByteString.copyFrom("0x1".toHexByteArray()) nonce = ByteString.copyFrom("0x0".toHexByteArray()) @@ -74,7 +74,7 @@ class TestEthereumTransactionSigner { fun testEthereumERC20_1559_Signing() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) toAddress = "0x6b175474e89094c44da98b954eedeac495271d0f" // DAI chainId = ByteString.copyFrom("0x1".toHexByteArray()) nonce = ByteString.copyFrom("0x0".toHexByteArray()) @@ -99,7 +99,7 @@ class TestEthereumTransactionSigner { fun testEthereumERC721Signing() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) toAddress = "0x0d8c864DA1985525e0af0acBEEF6562881827bd5" chainId = ByteString.copyFrom("0x1".toHexByteArray()) nonce = ByteString.copyFrom("0x02de".toHexByteArray()) @@ -125,7 +125,7 @@ class TestEthereumTransactionSigner { fun testEthereumERC1155Signing() { val signingInput = Ethereum.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) toAddress = "0x4e45e92ed38f885d39a733c14f1817217a89d425" // contract chainId = ByteString.copyFrom("0x01".toHexByteArray()) nonce = ByteString.copyFrom("0x00".toHexByteArray()) @@ -162,7 +162,7 @@ class TestEthereumTransactionSigner { maxFeePerGas = ByteString.copyFrom("067ef83700".toHexByteArray()) // 27900000000 maxInclusionFeePerGas = ByteString.copyFrom("3b9aca00".toHexByteArray()) // 1000000000 toAddress = "0x2cac916b2a963bf162f076c0a8a4a8200bcfbfb4" // contract - privateKey = ByteString.copyFrom(PrivateKey("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) transaction = Ethereum.Transaction.newBuilder().apply { transfer = Ethereum.Transaction.Transfer.newBuilder().apply { amount = ByteString.copyFrom("2386f26fc10000".toHexByteArray()) // 0.01 ETH @@ -193,7 +193,7 @@ class TestEthereumTransactionSigner { maxFeePerGas = ByteString.copyFrom("067ef83700".toHexByteArray()) // 27900000000 maxInclusionFeePerGas = ByteString.copyFrom("3b9aca00".toHexByteArray()) // 1000000000 toAddress = "0xae78736Cd615f374D3085123A210448E74Fc6393" // contract - privateKey = ByteString.copyFrom(PrivateKey("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) transaction = Ethereum.Transaction.newBuilder().apply { contractGeneric = Ethereum.Transaction.ContractGeneric.newBuilder().apply { amount = ByteString.copyFrom("00".toHexByteArray()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/everscale/TestEverscaleAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/everscale/TestEverscaleAddress.kt index 5922fa9f191..df03c0a7464 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/everscale/TestEverscaleAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/everscale/TestEverscaleAddress.kt @@ -18,7 +18,7 @@ class TestEverscaleAddress { @Test fun testAddress() { - val key = PrivateKey("5b59e0372d19b6355c73fa8cc708fa3301ae2ec21bb6277e8b79d386ccb7846f".toHexByteArray()) + val key = PrivateKey("5b59e0372d19b6355c73fa8cc708fa3301ae2ec21bb6277e8b79d386ccb7846f".toHexByteArray(), CoinType.EVERSCALE.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.EVERSCALE) val expected = AnyAddress("0:269fee242eb410786abe1777a14785c8bbeb1e34100c7570e17698b36ad66fb0", CoinType.EVERSCALE) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/filecoin/TestFilecoin.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/filecoin/TestFilecoin.kt index 82f292da61d..de1c1c424bf 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/filecoin/TestFilecoin.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/filecoin/TestFilecoin.kt @@ -18,7 +18,7 @@ class TestFilecoin { @Test fun testCreateAddress() { - val privateKey = PrivateKey("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe".toHexByteArray()) + val privateKey = PrivateKey("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe".toHexByteArray(), CoinType.FILECOIN.curve()) val publicKey = privateKey.getPublicKeySecp256k1(false) val address = AnyAddress(publicKey, CoinType.FILECOIN) assertEquals("f1z4a36sc7mfbv4z3qwutblp2flycdui3baffytbq", address.description()) @@ -26,7 +26,7 @@ class TestFilecoin { @Test fun testCreateDelegatedAddress() { - val privateKey = PrivateKey("825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a".toHexByteArray()) + val privateKey = PrivateKey("825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a".toHexByteArray(), CoinType.FILECOIN.curve()) val publicKey = privateKey.getPublicKeySecp256k1(false) val address = AnyAddress(publicKey, FilecoinAddressType.DELEGATED) assertEquals("f410fvak24cyg3saddajborn6idt7rrtfj2ptauk5pbq", address.description()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOAddress.kt index 4a9bef5fedb..04fed1c36eb 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOAddress.kt @@ -22,7 +22,7 @@ class TestFIOAddress { val addressFromString = AnyAddress("FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o", CoinType.FIO) assertEquals(addressFromString.description(), "FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o") - val key = PrivateKey("ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854".toHexByteArray()) + val key = PrivateKey("ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854".toHexByteArray(), CoinType.FIO.curve()) val pubkey = key.getPublicKeySecp256k1(false) val addressFromKey = AnyAddress(pubkey, CoinType.FIO) assertEquals(addressFromKey.description(), "FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o") diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOSigner.kt index 6992aa0b9f8..3e3402e2da8 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/fio/TestFIOSigner.kt @@ -26,7 +26,7 @@ class TestFIOSigner { @Test fun testRegisterFioAddress() { val chainId = ByteString.copyFrom("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77".toHexBytes()) - val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray()) + val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray(), CoinType.FIO.curve()) val publicKey = privateKey.getPublicKeySecp256k1(false) val address = AnyAddress(publicKey, CoinType.FIO) @@ -57,7 +57,7 @@ class TestFIOSigner { @Test fun testAddPubAddress() { val chainId = ByteString.copyFrom("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77".toHexBytes()) - val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray()) + val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray(), CoinType.FIO.curve()) val chainParams = FIO.ChainParams.newBuilder() .setChainId(chainId) @@ -88,7 +88,7 @@ class TestFIOSigner { @Test fun testTransfer() { val chainId = ByteString.copyFrom("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77".toHexBytes()) - val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray()) + val privateKey = PrivateKey("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035".toHexByteArray(), CoinType.FIO.curve()) val chainParams = FIO.ChainParams.newBuilder() .setChainId(chainId) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/greenfield/TestGreenfieldSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/greenfield/TestGreenfieldSigner.kt index cd7caf5e2ac..71c3c29b4f4 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/greenfield/TestGreenfieldSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/greenfield/TestGreenfieldSigner.kt @@ -24,7 +24,7 @@ class TestGreenfieldSigner { // Successfully broadcasted: https://greenfieldscan.com/tx/ED8508F3C174C4430B8EE718A6D6F0B02A8C516357BE72B1336CF74356529D19 val key = - PrivateKey("825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a".toHexByteArray()) + PrivateKey("825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a".toHexByteArray(), CoinType.GREENFIELD.curve()) val msgSend = Greenfield.Message.Send.newBuilder().apply { fromAddress = "0xA815ae0b06dC80318121745BE40e7F8c6654e9f3" @@ -74,7 +74,7 @@ class TestGreenfieldSigner { // BSC (parent transaction): https://testnet.bscscan.com/tx/0x7f73c8a362e14e58cb5e0ec17616afc50eff7aa398db472383a6d017c8a5861a val key = - PrivateKey("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0".toHexByteArray()) + PrivateKey("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0".toHexByteArray(), CoinType.GREENFIELD.curve()) val msgTransferOut = Greenfield.Message.BridgeTransferOut.newBuilder().apply { fromAddress = "0x9d1d97aDFcd324Bbd603D3872BD78e04098510b1" diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyAddress.kt index 691757d06ca..ea568d4cd5f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyAddress.kt @@ -14,7 +14,7 @@ class TestHarmonyAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey(Base58.decodeNoCheck("GGzxJ4QmKCXH2juK89RVAmvFAfdUfUARCvxEsBM356vX")) + val key = PrivateKey(Base58.decodeNoCheck("GGzxJ4QmKCXH2juK89RVAmvFAfdUfUARCvxEsBM356vX"), CoinType.HARMONY.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.HARMONY) assertEquals(address.description(), targetAddress) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyStakingDelegateSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyStakingDelegateSigner.kt index 6c411e829f2..684e22173fc 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyStakingDelegateSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyStakingDelegateSigner.kt @@ -6,6 +6,7 @@ import com.trustwallet.core.app.utils.toHexByteArray import org.junit.Assert.assertEquals import org.junit.Test import wallet.core.java.AnySigner +import wallet.core.jni.CoinType import wallet.core.jni.PrivateKey import wallet.core.jni.proto.Harmony import wallet.core.jni.proto.Harmony.SigningOutput @@ -14,7 +15,7 @@ import wallet.core.jni.CoinType.HARMONY class TestHarmonyStakingDelegateSigner { val oneAddress = "one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9" - val privateKeyData = ByteString.copyFrom(PrivateKey("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48".toHexByteArray()).data()) + val privateKeyData = ByteString.copyFrom(PrivateKey("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48".toHexByteArray(), CoinType.HARMONY.curve()).data()) val pubKeyData = ByteString.copyFrom("b9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b62247608611".toHexByteArray()) val blsSigData = ByteString.copyFrom("4252b0f1210efb0d5061e8a706a7ea9d62292a7947a975472fb77e1af7278a1c3c2e6eeba73c0581ece398613829940df129f3071c9a24b4b448bb1e880dc5872a58cb07eed94294c4e01a5c864771cafef7b96be541cb3c521a98f01838dd94".toHexByteArray()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyTransactionSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyTransactionSigner.kt index c0a9af1bd37..906e5c30b3e 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyTransactionSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/harmony/TestHarmonyTransactionSigner.kt @@ -9,6 +9,7 @@ import wallet.core.java.AnySigner import wallet.core.jni.proto.Harmony import wallet.core.jni.proto.Harmony.SigningOutput import com.trustwallet.core.app.utils.Numeric +import wallet.core.jni.CoinType import wallet.core.jni.CoinType.HARMONY class TestHarmonyTransactionSigner { @@ -31,7 +32,7 @@ class TestHarmonyTransactionSigner { } val signingInput = Harmony.SigningInput.newBuilder() signingInput.apply { - privateKey = ByteString.copyFrom(PrivateKey("0xb578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0xb578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e".toHexByteArray(), CoinType.HARMONY.curve()).data()) chainId = ByteString.copyFrom("0x02".toHexByteArray()) transactionMessage = transaction.build() } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerAddress.kt index 2861aea3a4a..b5904e9a991 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerAddress.kt @@ -18,7 +18,7 @@ class TestInternetComputerAddress { @Test fun testAddress() { - val key = PrivateKey("ee42eaada903e20ef6e5069f0428d552475c1ea7ed940842da6448f6ef9d48e7".toHexByteArray()) + val key = PrivateKey("ee42eaada903e20ef6e5069f0428d552475c1ea7ed940842da6448f6ef9d48e7".toHexByteArray(), CoinType.INTERNETCOMPUTER.curve()) val pubkey = key.getPublicKeySecp256k1(false); val address = AnyAddress(pubkey, CoinType.INTERNETCOMPUTER) val expected = AnyAddress("2f25874478d06cf68b9833524a6390d0ba69c566b02f46626979a3d6a4153211", CoinType.INTERNETCOMPUTER) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerSigner.kt index d3e97de972e..4e1f635967f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/internetcomputer/TestInternetComputerSigner.kt @@ -25,7 +25,7 @@ class TestInternetComputerSigner { @Test fun InternetComputerTransactionSigning() { - val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray()) + val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray(), CoinType.INTERNETCOMPUTER.curve()) val input = InternetComputer.SigningInput.newBuilder() .setTransaction(InternetComputer.Transaction.newBuilder().apply { @@ -43,7 +43,7 @@ class TestInternetComputerSigner { @Test fun InternetComputerTransactionSigningWithInvalidToAccountIdentifier() { - val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray()) + val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray(), CoinType.INTERNETCOMPUTER.curve()) val input = InternetComputer.SigningInput.newBuilder() .setTransaction(InternetComputer.Transaction.newBuilder().apply { @@ -61,7 +61,7 @@ class TestInternetComputerSigner { @Test fun InternetComputerTransactionSigningWithInvalidAmount() { - val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray()) + val key = PrivateKey("227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be".toHexByteArray(), CoinType.INTERNETCOMPUTER.curve()) val input = InternetComputer.SigningInput.newBuilder() .setTransaction(InternetComputer.Transaction.newBuilder().apply { diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kava/TestKavaTransactions.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kava/TestKavaTransactions.kt index b715150a080..dc06c59b8de 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kava/TestKavaTransactions.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kava/TestKavaTransactions.kt @@ -19,7 +19,7 @@ class TestKavaTransactions { @Test fun testSigningTransaction() { - val key = PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray()) + val key = PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray(), CoinType.KAVA.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, KAVA).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kcc/TestKuCoinCommunityChainAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kcc/TestKuCoinCommunityChainAddress.kt index 9a2ecfc3811..b90df357b37 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kcc/TestKuCoinCommunityChainAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kcc/TestKuCoinCommunityChainAddress.kt @@ -18,7 +18,7 @@ class TestKuCoinCommunityChainAddress { @Test fun testAddress() { - val key = PrivateKey("33b85056aabab539bcb68540735ecf054e38bc58b29b751530e2b54ecb4ca564".toHexByteArray()) + val key = PrivateKey("33b85056aabab539bcb68540735ecf054e38bc58b29b751530e2b54ecb4ca564".toHexByteArray(), CoinType.KUCOINCOMMUNITYCHAIN.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.KUCOINCOMMUNITYCHAIN) val expected = AnyAddress("0xE5cA667d795685E9915E5F4b4254ca832eEB398B", CoinType.KUCOINCOMMUNITYCHAIN) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kusama/TestKusamaAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kusama/TestKusamaAddress.kt index 39fc302d0ff..ca3463b784b 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kusama/TestKusamaAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/kusama/TestKusamaAddress.kt @@ -19,7 +19,7 @@ class TestKusamaAddress { @Test fun testAddress() { - val key = PrivateKey("0x85fca134b3fe3fd523d8b528608d803890e26c93c86dc3d97b8d59c7b3540c97".toHexByteArray()) + val key = PrivateKey("0x85fca134b3fe3fd523d8b528608d803890e26c93c86dc3d97b8d59c7b3540c97".toHexByteArray(), CoinType.KUSAMA.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.KUSAMA) val expected = AnyAddress("HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg", CoinType.KUSAMA) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXAddress.kt index ab3b1ec2483..a80526fac01 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXAddress.kt @@ -22,7 +22,7 @@ class TestMultiversXAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey(aliceSeedHex.toHexByteArray()) + val key = PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()) val pubKey = key.publicKeyEd25519 val address = AnyAddress(pubKey, CoinType.MULTIVERSX) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXSigner.kt index 82929dcb8c2..9290f2a5112 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/multiversx/TestMultiversXSigner.kt @@ -26,7 +26,7 @@ class TestMultiversXSigner { @Test fun signGenericAction() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(7) @@ -58,7 +58,7 @@ class TestMultiversXSigner { @Test fun signGenericActionWithGuardian() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(42) @@ -91,7 +91,7 @@ class TestMultiversXSigner { @Test fun signGenericActionWithRelayer() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(42) @@ -124,7 +124,7 @@ class TestMultiversXSigner { @Test fun signGenericActionUndelegate() { // Successfully broadcasted https://explorer.multiversx.com/transactions/3301ae5a6a77f0ab9ceb5125258f12539a113b0c6787de76a5c5867f2c515d65 - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(6) @@ -157,7 +157,7 @@ class TestMultiversXSigner { @Test fun signGenericActionDelegate() { // Successfully broadcasted https://explorer.multiversx.com/transactions/e5007662780f8ed677b37b156007c24bf60b7366000f66ec3525cfa16a4564e7 - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(1) @@ -189,7 +189,7 @@ class TestMultiversXSigner { @Test fun signEGLDTransfer() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(7) @@ -217,7 +217,7 @@ class TestMultiversXSigner { @Test fun signEGLDTransferWithGuardian() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(7) @@ -246,7 +246,7 @@ class TestMultiversXSigner { @Test fun signESDTTransfer() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(7) @@ -276,7 +276,7 @@ class TestMultiversXSigner { @Test fun signESDTNFTTransfer() { - val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray()).data()) + val privateKey = ByteString.copyFrom(PrivateKey(aliceSeedHex.toHexByteArray(), CoinType.MULTIVERSX.curve()).data()) val accounts = MultiversX.Accounts.newBuilder() .setSenderNonce(7) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveAddress.kt index 8c70eaf1dfe..74f363ae96f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveAddress.kt @@ -17,7 +17,7 @@ class TestNativeInjectiveAddress { @Test fun testAddress() { - val key = PrivateKey("9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1".toHexByteArray()) + val key = PrivateKey("9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1".toHexByteArray(), CoinType.NATIVEINJECTIVE.curve()) val pubKey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubKey, CoinType.NATIVEINJECTIVE) val expected = AnyAddress("inj13u6g7vqgw074mgmf2ze2cadzvkz9snlwcrtq8a", CoinType.NATIVEINJECTIVE) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveSigner.kt index b1295e2d823..dd4b136f975 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativeinjective/TestNativeInjectiveSigner.kt @@ -22,7 +22,7 @@ class TestNativeInjectiveSigner { @Test fun NativeInjectiveTransactionSigning() { - val key = PrivateKey("9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1".toHexByteArray()) + val key = PrivateKey("9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1".toHexByteArray(), CoinType.NATIVEINJECTIVE.curve()) val publicKey = key.getPublicKeySecp256k1(false) val from = AnyAddress(publicKey, CoinType.NATIVEINJECTIVE).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainAddress.kt index 93a2fbd2a3a..db9dc7dd8c6 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainAddress.kt @@ -18,7 +18,7 @@ class TestNativeZetaChainAddress { @Test fun testAddress() { - val key = PrivateKey("8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed".toHexByteArray()) + val key = PrivateKey("8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed".toHexByteArray(), CoinType.NATIVEZETACHAIN.curve()) val pubKey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubKey, CoinType.NATIVEZETACHAIN) val expected = AnyAddress("zeta14py36sx57ud82t9yrks9z6hdsrpn5x6kmxs0ne", CoinType.NATIVEZETACHAIN) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainSigner.kt index 2dd00e4f2f8..4758f4734df 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nativezetachain/TestNativeZetaChainSigner.kt @@ -22,7 +22,7 @@ class TestNativeZetaChainSigner { @Test fun NativeZetaChainTransactionSigning() { - val key = PrivateKey("8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed".toHexByteArray()) + val key = PrivateKey("8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed".toHexByteArray(), CoinType.NATIVEZETACHAIN.curve()) val publicKey = key.getPublicKeySecp256k1(false) val from = AnyAddress(publicKey, CoinType.NATIVEZETACHAIN).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/near/TestNEARAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/near/TestNEARAddress.kt index 5a42fe375f8..5c1cb2123dc 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/near/TestNEARAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/near/TestNEARAddress.kt @@ -15,7 +15,7 @@ class TestNEARAddress { @Test fun testAddressFromPrivateKey() { val privateKeyBytes = Base58.decodeNoCheck("3hoMW1HvnRLSFCLZnvPzWeoGwtdHzke34B2cTHM8rhcbG3TbuLKtShTv3DvyejnXKXKBiV7YPkLeqUHN1ghnqpFv").sliceArray(0..31) - val key = PrivateKey(privateKeyBytes) + val key = PrivateKey(privateKeyBytes, CoinType.NEAR.curve()) val pubkey = key.getPublicKeyEd25519() val address = AnyAddress(pubkey, CoinType.NEAR) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasAddress.kt index a1e25ec6af1..ee56548d785 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasAddress.kt @@ -25,7 +25,7 @@ class TestNebulasAddress { @Test fun testAddressFromPublicKey() { - var priKey = PrivateKey(("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b").toHexByteArray()) + var priKey = PrivateKey(("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b").toHexByteArray(), CoinType.NEBULAS.curve()) val pubkey = priKey.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.NEBULAS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasSigner.kt index 4547fad3643..9c1940c5b1c 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nebulas/TestNebulasSigner.kt @@ -8,6 +8,7 @@ import org.junit.Test import wallet.core.jni.CoinType.NEBULAS import wallet.core.jni.PrivateKey import wallet.core.java.AnySigner +import wallet.core.jni.CoinType import wallet.core.jni.proto.Nebulas import wallet.core.jni.proto.Nebulas.SigningOutput @@ -30,7 +31,7 @@ class TestNebulasSigner { amount = ByteString.copyFrom("0x98a7d9b8314c0000".toHexByteArray()) //11000000000000000000 payload = "" timestamp = ByteString.copyFrom("0x5cfc84ca".toHexByteArray()) //1560052938 - privateKey = ByteString.copyFrom(PrivateKey("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b".toHexByteArray(), CoinType.NEBULAS.curve()).data()) } val output = AnySigner.sign(signingInput.build(), NEBULAS, SigningOutput.parser()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOAddress.kt index 8eb3f6ac165..71c520429f8 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOAddress.kt @@ -33,7 +33,7 @@ class TestNEOAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey(Numeric.hexStringToByteArray("2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB")) + val key = PrivateKey(Numeric.hexStringToByteArray("2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB"), CoinType.NEO.curve()) val pubkey = key.publicKeyNist256p1 val address = AnyAddress(pubkey, CoinType.NEO) val expectedAddressString = "AQCSMB3oSDA1dHPn6GXN6KB4NHmdo1fX41" diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOSigner.kt index eb40bbf1892..272b5ad0a8e 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/neo/TestsNEOSigner.kt @@ -97,12 +97,7 @@ class TestNEOSigner { // https://testnet-explorer.o3.network/transactions/0x7b138c753c24f474d0f70af30a9d79756e0ee9c1f38c12ed07fbdf6fc5132eaf assertEquals( - "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf122956bc88746dc666759a2d67f120fe3ce1659f916d22a91e0b02421d3bddbd1232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", + "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", hex) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // assertEquals( - // "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", - // hex) } } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosAddress.kt index f77ce3858cd..fffb328eb33 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosAddress.kt @@ -17,7 +17,7 @@ class TestNervosAddress { @Test fun testAddress() { - val key = PrivateKey("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb".toHexByteArray()) + val key = PrivateKey("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb".toHexByteArray(), CoinType.NERVOS.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.NERVOS) val expected = AnyAddress("ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqwyk5x9erg8furras980hksatlslfaktks7epf25", CoinType.NERVOS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosSigner.kt index d556f883f17..2a8cdec36b2 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nervos/TestNervosSigner.kt @@ -23,7 +23,7 @@ class TestNervosSigner { @Test fun testSigning() { - val key = PrivateKey("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb".toHexByteArray()) + val key = PrivateKey("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb".toHexByteArray(), CoinType.NERVOS.curve()) val lockScript = Script.newBuilder().apply { codeHash = "9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8".toHexBytesInByteString() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nuls/TestNULSAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nuls/TestNULSAddress.kt index 43457f768c7..0d1a0b12ac3 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nuls/TestNULSAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/nuls/TestNULSAddress.kt @@ -13,7 +13,7 @@ class TestNULSAddress { @Test fun testAddress() { - val priKey = PrivateKey(Numeric.hexStringToByteArray("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")) + val priKey = PrivateKey(Numeric.hexStringToByteArray("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a"), CoinType.NULS.curve()) val pubkey = priKey.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.NULS) val expected = AnyAddress("NULSd6HghWa4CN5qdxqMwYVikQxRZyj57Jn4L", CoinType.NULS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/oasis/TestOasisAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/oasis/TestOasisAddress.kt index 00b315bc40a..465e2e6bbbc 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/oasis/TestOasisAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/oasis/TestOasisAddress.kt @@ -18,7 +18,7 @@ class TestOasisAddress { @Test fun testAddress() { - val key = PrivateKey("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0".toHexByteArray()) + val key = PrivateKey("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0".toHexByteArray(), CoinType.OASIS.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.OASIS) val expected = AnyAddress("oasis1qzawzy5kaa2xgphenf3r0f5enpr3mx5dps559yxm", CoinType.OASIS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ontology/TestOntologySigning.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ontology/TestOntologySigning.kt index 2bf777966fb..cea59e9659b 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ontology/TestOntologySigning.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ontology/TestOntologySigning.kt @@ -74,13 +74,8 @@ class TestOntologySigning { val hex = Numeric.toHexString(result, 0, result.size, false) assertEquals( - "00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb7cff28ddaf7f1048822c0ca21a0c4926323a2497875b963f3b8cbd3717aa6e7c2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", + "00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aacd6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", hex) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // assertEquals( - // "00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aacd6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // hex) } @Test @@ -103,13 +98,8 @@ class TestOntologySigning { val hex = Numeric.toHexString(result, 0, result.size, false) assertEquals( - "00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f73b8ab199a4d757b4c7b9ed46c4ff8cfa8aefaa90b7fb6485e358034448cba752321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d743b078bd4e21bb4404c0182a32ee05260e22454dffb34dacccf458dfbee6d32db232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", + "00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b00730143800049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", hex) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // assertEquals( - // "00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b00730143800049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // hex) } } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisAddress.kt index 88b33d1b9fd..64f18ba508a 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisAddress.kt @@ -18,7 +18,7 @@ class TestOsmosisAddress { @Test fun testAddress() { - val key = PrivateKey("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af".toHexByteArray()) + val key = PrivateKey("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af".toHexByteArray(), CoinType.OSMOSIS.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.OSMOSIS) val expected = AnyAddress("osmo1mky69cn8ektwy0845vec9upsdphktxt0en97f5", CoinType.OSMOSIS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisSigner.kt index 679583594f7..6358f0219cc 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/osmosis/TestOsmosisSigner.kt @@ -28,7 +28,7 @@ class TestOsmosisSigner { @Test fun OsmosisTransactionSigning() { - val key = PrivateKey("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af".toHexByteArray()) + val key = PrivateKey("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af".toHexByteArray(), CoinType.OSMOSIS.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, OSMOSIS).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusAddress.kt index b58b068b859..443b3e117d5 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusAddress.kt @@ -18,7 +18,7 @@ class TestPactusAddress { @Test fun testAddress() { - val key = PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6".toHexByteArray()) + val key = PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6".toHexByteArray(), CoinType.PACTUS.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.PACTUS) val expected = AnyAddress("pc1rwzvr8rstdqypr80ag3t6hqrtnss9nwymcxy3lr", CoinType.PACTUS) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusSigner.kt index 81bbe9bf532..5a0c8adbf90 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/pactus/TestPactusSigner.kt @@ -32,7 +32,7 @@ class TestPactusSigner { signingInput.apply { privateKey = ByteString.copyFrom( PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6" - .toHexByteArray()).data() + .toHexByteArray(), CoinType.PACTUS.curve()).data() ) transaction = Pactus.TransactionMessage.newBuilder().apply { lockTime = 2335524 @@ -73,7 +73,7 @@ class TestPactusSigner { signingInput.apply { privateKey = ByteString.copyFrom( PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6" - .toHexByteArray()).data() + .toHexByteArray(), CoinType.PACTUS.curve()).data() ) transaction = Pactus.TransactionMessage.newBuilder().apply { lockTime = 2339009 @@ -115,7 +115,7 @@ class TestPactusSigner { signingInput.apply { privateKey = ByteString.copyFrom( PrivateKey("4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6" - .toHexByteArray()).data() + .toHexByteArray(), CoinType.PACTUS.curve()).data() ) transaction = Pactus.TransactionMessage.newBuilder().apply { lockTime = 2335580 diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polkadot/TestPolkadotAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polkadot/TestPolkadotAddress.kt index 7ab39ef55f5..f1d7c0ec85f 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polkadot/TestPolkadotAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polkadot/TestPolkadotAddress.kt @@ -19,7 +19,7 @@ class TestPolkadotAddress { @Test fun testAddress() { - val key = PrivateKey("0xd65ed4c1a742699b2e20c0c1f1fe780878b1b9f7d387f934fe0a7dc36f1f9008".toHexByteArray()) + val key = PrivateKey("0xd65ed4c1a742699b2e20c0c1f1fe780878b1b9f7d387f934fe0a7dc36f1f9008".toHexByteArray(), CoinType.POLKADOT.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.POLKADOT) val expected = AnyAddress("12twBQPiG5yVSf3jQSBkTAKBKqCShQ5fm33KQhH3Hf6VDoKW", CoinType.POLKADOT) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polygon/TestPolygonAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polygon/TestPolygonAddress.kt index ab807796d5a..e2a5a4d3478 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polygon/TestPolygonAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polygon/TestPolygonAddress.kt @@ -18,7 +18,7 @@ class TestPolygonAddress { @Test fun testAddress() { - val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray()) + val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray(), CoinType.POLYGON.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.POLYGON) val expected = AnyAddress("0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", CoinType.POLYGON) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polymesh/TestPolymeshAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polymesh/TestPolymeshAddress.kt index a7e77d9a3e0..d3ca5e41ba5 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polymesh/TestPolymeshAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/polymesh/TestPolymeshAddress.kt @@ -19,7 +19,7 @@ class TestPolymeshAddress { @Test fun testAddress() { - val key = PrivateKey("0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4".toHexByteArray()) + val key = PrivateKey("0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4".toHexByteArray(), CoinType.POLYMESH.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.POLYMESH) val expected = AnyAddress("2EANwBfNsFu9KV8JsW5sbhF6ft8bzvw5EW1LCrgHhrqtK6Ys", CoinType.POLYMESH) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ripple/TestRippleTransactionSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ripple/TestRippleTransactionSigner.kt index 9ec91772b1b..78f2e6df4c1 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ripple/TestRippleTransactionSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ripple/TestRippleTransactionSigner.kt @@ -7,6 +7,7 @@ import org.junit.Assert.assertEquals import org.junit.Test import wallet.core.jni.PrivateKey import wallet.core.java.AnySigner +import wallet.core.jni.CoinType import wallet.core.jni.CoinType.XRP import wallet.core.jni.proto.Ripple import wallet.core.jni.proto.Ripple.SigningOutput @@ -30,7 +31,7 @@ class TestRippleTransactionSigner { fee = 10 sequence = 32268248 lastLedgerSequence = 32268269 - privateKey = ByteString.copyFrom(PrivateKey("a5576c0f63da10e584568c8d134569ff44017b0a249eb70657127ae04f38cc77".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("a5576c0f63da10e584568c8d134569ff44017b0a249eb70657127ae04f38cc77".toHexByteArray(), CoinType.XRP.curve()).data()) opPayment = operation.build() } diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/scroll/TestScrollAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/scroll/TestScrollAddress.kt index 23d77ff4ccb..e6e6afe95b6 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/scroll/TestScrollAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/scroll/TestScrollAddress.kt @@ -18,7 +18,7 @@ class TestScrollAddress { @Test fun testAddress() { - val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray()) + val key = PrivateKey("828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0".toHexByteArray(), CoinType.SCROLL.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.SCROLL) val expected = AnyAddress("0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", CoinType.SCROLL) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretAddress.kt index 5315c57c9ad..65486e85fac 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretAddress.kt @@ -18,7 +18,7 @@ class TestSecretAddress { @Test fun testAddress() { - val key = PrivateKey("87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada".toHexByteArray()) + val key = PrivateKey("87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada".toHexByteArray(), CoinType.SECRET.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.SECRET) val expected = AnyAddress("secret18mdrja40gfuftt5yx6tgj0fn5lurplezyp894y", CoinType.SECRET) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretSigner.kt index 3f1ef6330a0..a9040d89155 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/secret/TestSecretSigner.kt @@ -27,7 +27,7 @@ class TestSecretSigner { @Test fun SecretTransactionSigning() { - val key = PrivateKey("87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada".toHexByteArray()) + val key = PrivateKey("87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada".toHexByteArray(), CoinType.SECRET.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, SECRET).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartbitcoincash/TestSmartBitcoinCashAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartbitcoincash/TestSmartBitcoinCashAddress.kt index 64c33ba9c58..99bebb7e605 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartbitcoincash/TestSmartBitcoinCashAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartbitcoincash/TestSmartBitcoinCashAddress.kt @@ -18,7 +18,7 @@ class TestSmartBitcoinCashAddress { @Test fun testAddress() { - val key = PrivateKey("155cbd57319f3d938977b4c18000473eb3c432c4e31b667b63e88559c497d82d".toHexByteArray()) + val key = PrivateKey("155cbd57319f3d938977b4c18000473eb3c432c4e31b667b63e88559c497d82d".toHexByteArray(), CoinType.SMARTBITCOINCASH.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.SMARTBITCOINCASH) val expected = AnyAddress("0x8bFC9477684987dcAf0970b9bce5E3D9267C99C0", CoinType.SMARTBITCOINCASH) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartchain/TestBinanceSmartChainAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartchain/TestBinanceSmartChainAddress.kt index a9a83132c36..3303d90a2df 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartchain/TestBinanceSmartChainAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/smartchain/TestBinanceSmartChainAddress.kt @@ -18,7 +18,7 @@ class TestBinanceSmartChainAddress { @Test fun testAddress() { - val key = PrivateKey("727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06".toHexByteArray()) + val key = PrivateKey("727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06".toHexByteArray(), CoinType.SMARTCHAIN.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.SMARTCHAIN) val expected = AnyAddress("0xf3d468DBb386aaD46E92FF222adDdf872C8CC064", CoinType.SMARTCHAIN) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/solana/TestSolanaAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/solana/TestSolanaAddress.kt index f2653b68222..f8116fa2854 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/solana/TestSolanaAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/solana/TestSolanaAddress.kt @@ -14,7 +14,7 @@ class TestSolanaAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey(Base58.decodeNoCheck("A7psj2GW7ZMdY4E5hJq14KMeYg7HFjULSsWSrTXZLvYr")) + val key = PrivateKey(Base58.decodeNoCheck("A7psj2GW7ZMdY4E5hJq14KMeYg7HFjULSsWSrTXZLvYr"), CoinType.SOLANA.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.SOLANA) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeAddress.kt index 54577d7971d..62a993a6d2a 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeAddress.kt @@ -18,7 +18,7 @@ class TestStargazeAddress { @Test fun testAddress() { - val key = PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray()) + val key = PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray(), CoinType.STARGAZE.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.STARGAZE) val expected = AnyAddress("stars1mry47pkga5tdswtluy0m8teslpalkdq02a8nhy", CoinType.STARGAZE) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeSigner.kt index 63a7a166b60..c449cfe5c4b 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stargaze/TestStargazeSigner.kt @@ -23,7 +23,7 @@ class TestStargazeSigner { @Test fun stargazeTransactionCW721Signing() { val key = - PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray()) + PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray(), CoinType.STARGAZE.curve()) val txMsg = Cosmos.Message.WasmExecuteContractGeneric.newBuilder().apply { senderAddress = "stars1mry47pkga5tdswtluy0m8teslpalkdq02a8nhy" @@ -69,7 +69,7 @@ class TestStargazeSigner { @Test fun stargazeTransactionSigning() { val key = - PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray()) + PrivateKey("a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433".toHexByteArray(), CoinType.STARGAZE.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, CoinType.STARGAZE).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/starkex/TestStarkExMessageSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/starkex/TestStarkExMessageSigner.kt index d68cd722b80..b34c7e62cbc 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/starkex/TestStarkExMessageSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/starkex/TestStarkExMessageSigner.kt @@ -4,6 +4,8 @@ import com.trustwallet.core.app.utils.Numeric import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test +import wallet.core.jni.CoinType +import wallet.core.jni.Curve import wallet.core.jni.PrivateKey import wallet.core.jni.PublicKeyType import wallet.core.jni.StarkExMessageSigner @@ -17,7 +19,7 @@ class TestStarkExMessageSigner { @Test fun testStarkExSignAndVerifyMessage() { val data = Numeric.hexStringToByteArray("04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, Curve.STARKEX) val publicKey = privateKey.getPublicKeyByType(PublicKeyType.STARKEX) val msg = "463a2240432264a3aa71a5713f2a4e4c1b9e12bbb56083cd56af6d878217cf" val signature = StarkExMessageSigner.signMessage(privateKey, msg) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarAddress.kt index 9d11510cf1f..f06214dd5b9 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarAddress.kt @@ -14,7 +14,7 @@ class TestAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()) + val key = PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()) val pubkey = key.publicKeyEd25519 val address = AnyAddress(pubkey, CoinType.STELLAR) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarSigner.kt index a76ea84550a..d88d0335cf9 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/stellar/TestStellarSigner.kt @@ -7,6 +7,7 @@ import org.junit.Test import wallet.core.jni.PrivateKey import wallet.core.jni.StellarPassphrase import wallet.core.java.AnySigner +import wallet.core.jni.CoinType import wallet.core.jni.CoinType.STELLAR import wallet.core.jni.proto.Stellar import wallet.core.jni.proto.Stellar.SigningOutput @@ -31,7 +32,7 @@ class TestStellarTransactionSigner { sequence = 2 passphrase = StellarPassphrase.STELLAR.toString() opPayment = operation.build() - privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) @@ -55,7 +56,7 @@ class TestStellarTransactionSigner { passphrase = StellarPassphrase.STELLAR.toString() opPayment = operation.build() memoHash = Stellar.MemoHash.newBuilder().setHash(ByteString.copyFrom("315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3".toHexByteArray())).build() - privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) @@ -79,7 +80,7 @@ class TestStellarTransactionSigner { passphrase = StellarPassphrase.STELLAR.toString() opPayment = operation.build() memoReturnHash = Stellar.MemoHash.newBuilder().setHash(ByteString.copyFrom("315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3".toHexByteArray())).build() - privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) @@ -103,7 +104,7 @@ class TestStellarTransactionSigner { passphrase = StellarPassphrase.STELLAR.toString() opPayment = operation.build() memoId = Stellar.MemoId.newBuilder().setId(1234567890).build() - privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) @@ -127,7 +128,7 @@ class TestStellarTransactionSigner { passphrase = StellarPassphrase.STELLAR.toString() opCreateAccount = operation.build() memoId = Stellar.MemoId.newBuilder().setId(1234567890).build() - privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) @@ -155,7 +156,7 @@ class TestStellarTransactionSigner { sequence = 144098454883270659 passphrase = StellarPassphrase.STELLAR.toString() opChangeTrust = operation.build() - privateKey = ByteString.copyFrom(PrivateKey("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9".toHexByteArray(), CoinType.STELLAR.curve()).data()) } val sign = AnySigner.sign(signingInput.build(), STELLAR, SigningOutput.parser()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraClassicTxs.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraClassicTxs.kt index 538d0efb76b..0c1fed7b096 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraClassicTxs.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraClassicTxs.kt @@ -20,7 +20,7 @@ class TestTerraClassicTxs { @Test fun testSigningTransaction() { val key = - PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray()) + PrivateKey("1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6".toHexByteArray(), CoinType.TERRA.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRA).description() @@ -71,7 +71,7 @@ class TestTerraClassicTxs { @Test fun testSigningWasmTerraTransferTxProtobuf() { val key = - PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray()) + PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray(), CoinType.TERRA.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRA).description() @@ -116,7 +116,7 @@ class TestTerraClassicTxs { @Test fun testSigningWasmTerraGenericProtobuf() { val key = - PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray()) + PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray(), CoinType.TERRA.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRA).description() @@ -160,7 +160,7 @@ class TestTerraClassicTxs { @Test fun testSigningWasmTerraGenericWithCoinsProtobuf() { val key = - PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray()) + PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray(), CoinType.TERRA.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRA).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraTransactions.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraTransactions.kt index e4591ff57e3..c83148572ed 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraTransactions.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/terra/TestTerraTransactions.kt @@ -20,7 +20,7 @@ class TestTerraTransactions { @Test fun testSigningTransaction() { val key = - PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray()) + PrivateKey("80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005".toHexByteArray(), CoinType.TERRAV2.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRAV2).description() @@ -70,7 +70,7 @@ class TestTerraTransactions { @Test fun testSigningWasmTerraTransferTx() { val key = - PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray()) + PrivateKey("cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616".toHexByteArray(), CoinType.TERRAV2.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, TERRAV2).description() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tezos/TestTezosMessageSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tezos/TestTezosMessageSigner.kt index 57b06f83714..90fe210d099 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tezos/TestTezosMessageSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tezos/TestTezosMessageSigner.kt @@ -18,7 +18,7 @@ class TestTezosMessageSigner { @Test fun testMessageSignerSignAndVerify() { val data = Numeric.hexStringToByteArray("91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.TEZOS.curve()) val msg = "05010000004254657a6f73205369676e6564204d6573736167653a207465737455726c20323032332d30322d30385431303a33363a31382e3435345a2048656c6c6f20576f726c64" val signature = TezosMessageSigner.signMessage(privateKey, msg) assertEquals("edsigu3se2fcEJUCm1aqxjzbHdf7Wsugr4mLaA9YM2UVZ9Yy5meGv87VqHN3mmDeRwApTj1JKDaYjqmLZifSFdWCqBoghqaowwJ", signature) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkAddress.kt index f37d4c7e4e9..b428a5ac64c 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkAddress.kt @@ -18,7 +18,7 @@ class TestTheOpenNetworkAddress { @Test fun testAddressFromPrivateKey() { - val privateKey = PrivateKey("63474e5fe9511f1526a50567ce142befc343e71a49b865ac3908f58667319cb8".toHexByteArray()) + val privateKey = PrivateKey("63474e5fe9511f1526a50567ce142befc343e71a49b865ac3908f58667319cb8".toHexByteArray(), CoinType.TON.curve()) val publicKey = privateKey.getPublicKeyEd25519() val address = AnyAddress(publicKey, CoinType.TON) assertEquals(publicKey.data().toHex(), "0xf42c77f931bea20ec5d0150731276bbb2e2860947661245b2319ef8133ee8d41") diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkMessageSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkMessageSigner.kt index 64c4627cb97..348636d7486 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkMessageSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkMessageSigner.kt @@ -7,6 +7,7 @@ package com.trustwallet.core.app.blockchains.theopennetwork import com.trustwallet.core.app.utils.toHexByteArray import org.junit.Assert.assertEquals import org.junit.Test +import wallet.core.jni.CoinType import wallet.core.jni.PrivateKey import wallet.core.jni.TONMessageSigner import wallet.core.jni.TONWallet @@ -21,7 +22,7 @@ class TestTheOpenNetworkMessageSigner { // The private key has been derived by using [ton-mnemonic](https://www.npmjs.com/package/tonweb-mnemonic/v/0.0.2) // from the following mnemonic: // document shield addict crime broom point story depend suit satisfy test chicken valid tail speak fortune sound drill seek cube cheap body music recipe - val privateKey = PrivateKey("112d4e2e700a468f1eae699329202f1ee671d6b665caa2d92dea038cf3868c18".toHexByteArray()) + val privateKey = PrivateKey("112d4e2e700a468f1eae699329202f1ee671d6b665caa2d92dea038cf3868c18".toHexByteArray(), CoinType.TON.curve()) val message = "Hello world" val signature = TONMessageSigner.signMessage(privateKey, message) // The following signature has been computed by calling `window.ton.send("ton_personalSign", { data: "Hello world" });`. diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkSigner.kt index 69dd91abada..c46f285bdc1 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/theopennetwork/TestTheOpenNetworkSigner.kt @@ -22,7 +22,7 @@ class TestTheOpenNetworkSigner { @Test fun TheOpenNetworkTransactionSigning() { - val privateKey = PrivateKey("c38f49de2fb13223a9e7d37d5d0ffbdd89a5eb7c8b0ee4d1c299f2cefe7dc4a0".toHexByteArray()) + val privateKey = PrivateKey("c38f49de2fb13223a9e7d37d5d0ffbdd89a5eb7c8b0ee4d1c299f2cefe7dc4a0".toHexByteArray(), CoinType.TON.curve()) val transfer = TheOpenNetwork.Transfer.newBuilder() .setDest("EQBm--PFwDv1yCeS-QTJ-L8oiUpqo9IT1BwgVptlSq3ts90Q") @@ -49,7 +49,7 @@ class TestTheOpenNetworkSigner { @Test fun TheOpenNetworkJettonTransferSigning() { - val privateKey = PrivateKey("c054900a527538c1b4325688a421c0469b171c29f23a62da216e90b0df2412ee".toHexByteArray()) + val privateKey = PrivateKey("c054900a527538c1b4325688a421c0469b171c29f23a62da216e90b0df2412ee".toHexByteArray(), CoinType.TON.curve()) val jettonTransfer = TheOpenNetwork.JettonTransfer.newBuilder() .setJettonAmount(500 * 1000 * 1000) @@ -84,7 +84,7 @@ class TestTheOpenNetworkSigner { @Test fun TheOpenNetworkTransferCustomPayload() { - val privateKey = PrivateKey("5525e673087587bc0efd7ab09920ef7d3c1bf6b854a661430244ca59ab19e9d1".toHexByteArray()) + val privateKey = PrivateKey("5525e673087587bc0efd7ab09920ef7d3c1bf6b854a661430244ca59ab19e9d1".toHexByteArray(), CoinType.TON.curve()) // Doge chatbot contract payload to be deployed. // Docs: https://docs.ton.org/develop/dapps/ton-connect/transactions#smart-contract-deployment diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thetafuel/TestThetaFuelAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thetafuel/TestThetaFuelAddress.kt index 17e60b89aeb..625279f8f1a 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thetafuel/TestThetaFuelAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thetafuel/TestThetaFuelAddress.kt @@ -17,7 +17,7 @@ class TestThetaFuelAddress { @Test fun testAddress() { - val key = PrivateKey("4646464646464646464646464646464646464646464646464646464646464646".toHexByteArray()) + val key = PrivateKey("4646464646464646464646464646464646464646464646464646464646464646".toHexByteArray(), CoinType.THETAFUEL.curve()) val pubkey = key.getPublicKeySecp256k1(false) val address = AnyAddress(pubkey, CoinType.THETAFUEL) val expected = AnyAddress("0x9d8A62f656a8d1615C1294fd71e9CFb3E4855A4F", CoinType.THETAFUEL) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORChainSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORChainSigner.kt index fde6325529f..c57b062da2a 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORChainSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORChainSigner.kt @@ -28,7 +28,7 @@ class TestTHORChainSigner { @Test fun THORChainTransactionSigning() { val key = - PrivateKey("7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e".toHexByteArray()) + PrivateKey("7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e".toHexByteArray(), CoinType.THORCHAIN.curve()) val publicKey = key.getPublicKeySecp256k1(true) val from = AnyAddress(publicKey, THORCHAIN).data() val to = AnyAddress("thor1e2ryt8asq4gu0h6z2sx9u7rfrykgxwkmr9upxn", THORCHAIN).data() diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORSwapSigning.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORSwapSigning.kt index 68f0f8acc55..334ac0ddc58 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORSwapSigning.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/thorchain/TestTHORSwapSigning.kt @@ -12,6 +12,7 @@ import wallet.core.jni.proto.Ethereum.SigningOutput import wallet.core.jni.proto.THORChainSwap import wallet.core.jni.THORChainSwap.buildSwap import com.trustwallet.core.app.utils.Numeric +import wallet.core.jni.CoinType class TestTHORChainSwap { @@ -64,7 +65,7 @@ class TestTHORChainSwap { nonce = ByteString.copyFrom("0x03".toHexByteArray()) gasPrice = ByteString.copyFrom("0x06FC23AC00".toHexByteArray()) gasLimit = ByteString.copyFrom("0x013880".toHexByteArray()) - privateKey = ByteString.copyFrom(PrivateKey("0x4f96ed80e9a7555a6f74b3d658afdd9c756b0a40d4ca30c42c2039eb449bb904".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x4f96ed80e9a7555a6f74b3d658afdd9c756b0a40d4ca30c42c2039eb449bb904".toHexByteArray(), CoinType.THORCHAIN.curve()).data()) }.build() // sign and encode resulting input diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tron/TestTronMessageSigner.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tron/TestTronMessageSigner.kt index 7730a59f9ca..c0e8f704fef 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tron/TestTronMessageSigner.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/tron/TestTronMessageSigner.kt @@ -17,7 +17,7 @@ class TestTronMessageSigner { @Test fun testMessageSignerSignAndVerify() { val data = Numeric.hexStringToByteArray("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a") - val privateKey = PrivateKey(data) + val privateKey = PrivateKey(data, CoinType.TRON.curve()) val msg = "Hello World" val signature = TronMessageSigner.signMessage(privateKey, msg) assertEquals("bc0753c070cc55693097df11bc11e1a7c4bd5e1a40b9dc94c75568e59bcc9d6b50a7873ef25b469e494490a54de37327b4bc7fc825c81a377b555e34fb7261ba1c", signature) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/waves/TestWavesAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/waves/TestWavesAddress.kt index ef8b4217e6c..92d476af82d 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/waves/TestWavesAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/waves/TestWavesAddress.kt @@ -14,7 +14,7 @@ class TestAddress { @Test fun testAddressFromPrivateKey() { - val key = PrivateKey("9864a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a".toHexByteArray()) + val key = PrivateKey("9864a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a".toHexByteArray(), CoinType.WAVES.curve()) val pubkey = key.publicKeyCurve25519 val address = AnyAddress(pubkey, CoinType.WAVES) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/zen/TestZenAddress.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/zen/TestZenAddress.kt index 8398b636928..bbcb4638b6b 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/zen/TestZenAddress.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/zen/TestZenAddress.kt @@ -18,7 +18,7 @@ class TestZenAddress { @Test fun testAddress() { - val key = PrivateKey("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a".toHexByteArray()) + val key = PrivateKey("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a".toHexByteArray(), CoinType.ZEN.curve()) val pubkey = key.getPublicKeySecp256k1(true) val address = AnyAddress(pubkey, CoinType.ZEN) val expected = AnyAddress("znk19H1wcARcCa7TM6zgmJUbWoWWtZ8k5cg", CoinType.ZEN) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestLiquidStaking.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestLiquidStaking.kt index 44701d5f2b1..64f484edb52 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestLiquidStaking.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestLiquidStaking.kt @@ -50,7 +50,7 @@ class TestLiquidStaking { maxFeePerGas = ByteString.copyFrom("0x8fbcc8fcd8".toHexByteArray()) maxInclusionFeePerGas = ByteString.copyFrom("0x085e42c7c0".toHexByteArray()) gasLimit = ByteString.copyFrom("0x01c520".toHexByteArray()) - privateKey = ByteString.copyFrom(PrivateKey("0x4a160b803c4392ea54865d0c5286846e7ad5e68fbd78880547697472b22ea7ab".toHexByteArray()).data()) + privateKey = ByteString.copyFrom(PrivateKey("0x4a160b803c4392ea54865d0c5286846e7ad5e68fbd78880547697472b22ea7ab".toHexByteArray(), CoinType.ETHEREUM.curve()).data()) }.build() val output = AnySigner.sign(txInputFull, CoinType.ETHEREUM, Ethereum.SigningOutput.parser()) diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPrivateKey.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPrivateKey.kt index d84bccd69c5..eee64645304 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPrivateKey.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPrivateKey.kt @@ -14,7 +14,7 @@ class TestPrivateKey { @Test fun testCreate() { - var privateKey = PrivateKey() + var privateKey = PrivateKey(Curve.SECP256K1) var data = privateKey.data() assertTrue(data.size == 32); } @@ -23,7 +23,7 @@ class TestPrivateKey { fun testCreateStarkKey() { val data = Numeric.hexStringToByteArray("06cf0a8bf113352eb863157a45c5e5567abb34f8d32cddafd2c22aa803f4892c") assertTrue(PrivateKey.isValid(data, Curve.STARKEX)) - var privateKey = PrivateKey(data) + var privateKey = PrivateKey(data, Curve.STARKEX) var pubKey = privateKey.getPublicKeyByType(PublicKeyType.STARKEX) assertEquals(pubKey.data().toHex(), "0x02d2bbdc1adaf887b0027cdde2113cfd81c60493aa6dc15d7887ddf1a82bc831") } @@ -31,9 +31,9 @@ class TestPrivateKey { @Test fun testCreateStarkKeySigning() { val data = Numeric.hexStringToByteArray("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") - var privateKey = PrivateKey(data) + var privateKey = PrivateKey(data, Curve.STARKEX) val digest = Numeric.hexStringToByteArray("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") - val signature = privateKey.sign(digest, Curve.STARKEX) + val signature = privateKey.sign(digest) assertEquals(signature.toHex(), "0x061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") } @@ -42,7 +42,7 @@ class TestPrivateKey { val bytes = Numeric.hexStringToByteArray("deadbeaf") var privateKey: PrivateKey? = null try { - privateKey = PrivateKey(bytes) + privateKey = PrivateKey(bytes, Curve.SECP256K1) } catch (ex: Exception) { } assertNull(privateKey) @@ -73,7 +73,7 @@ class TestPrivateKey { assertTrue(PrivateKey.isValid(validPrivateKeyData, Curve.SECP256K1)) var privateKey: PrivateKey? = null try { - privateKey = PrivateKey(validPrivateKeyData) + privateKey = PrivateKey(validPrivateKeyData, Curve.SECP256K1) } catch (ex: Exception) { } @@ -83,7 +83,16 @@ class TestPrivateKey { @Test fun testGetPublicKeyCoinType() { val privateKeyData = "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5".toHexBytes() - val privateKey = PrivateKey(privateKeyData) + val privateKey = PrivateKey(privateKeyData, Curve.SECP256K1) assertEquals(privateKey.getPublicKey(CoinType.ETHEREUM).data().toHex(), "0x0499c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c166b489a4b7c491e7688e6ebea3a71fc3a1a48d60f98d5ce84c93b65e423fde91"); } + + @Test + fun testCreateKeySigningWithoutCurve() { + val data = Numeric.hexStringToByteArray("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79") + var privateKey = PrivateKey(data, Curve.STARKEX) + val digest = Numeric.hexStringToByteArray("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76") + val signature = privateKey.sign(digest) + assertEquals(signature.toHex(), "0x061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + } } \ No newline at end of file diff --git a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPublicKey.kt b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPublicKey.kt index bfecc51014e..e3e5d068726 100644 --- a/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPublicKey.kt +++ b/android/app/src/androidTest/java/com/trustwallet/core/app/utils/TestPublicKey.kt @@ -18,7 +18,7 @@ class TestPublicKey { fun testPublicKeyCompressed() { var privateKey: PrivateKey? = null try { - privateKey = PrivateKey(validPrivateKeyData) + privateKey = PrivateKey(validPrivateKeyData, Curve.SECP256K1) } catch (ex: Exception) { } @@ -41,25 +41,26 @@ class TestPublicKey { fun testSign() { val validSign = "0x8720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba624d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de901" val data = Hash.keccak256("hello".toByteArray()) - val sign = PrivateKey(validPrivateKeyData).sign(data, Curve.SECP256K1) + val sign = PrivateKey(validPrivateKeyData, Curve.SECP256K1).sign(data) assertEquals(sign.toHex(), validSign) } @Test fun testVerify() { - val privateKey = PrivateKey(validPrivateKeyData) - val message = Hash.sha256("hello".toByteArray()) - val sig1 = privateKey.sign(message, Curve.ED25519) - val result1 = privateKey.getPublicKeyEd25519().verify(sig1, message) + val privateKey1 = PrivateKey(validPrivateKeyData, Curve.ED25519) + val sig1 = privateKey1.sign(message) + val result1 = privateKey1.getPublicKeyEd25519().verify(sig1, message) assert(result1) - val sig2 = privateKey.sign(message, Curve.ED25519BLAKE2BNANO) - val result2 = privateKey.getPublicKeyEd25519Blake2b().verify(sig2, message) + val privateKey2 = PrivateKey(validPrivateKeyData, Curve.ED25519BLAKE2BNANO) + val sig2 = privateKey2.sign(message) + val result2 = privateKey2.getPublicKeyEd25519Blake2b().verify(sig2, message) assert(result2) - val sig3 = privateKey.sign(message, Curve.SECP256K1) - val result3 = privateKey.getPublicKeySecp256k1(true).verify(sig3, message) + val privateKey3 = PrivateKey(validPrivateKeyData, Curve.SECP256K1) + val sig3 = privateKey3.sign(message) + val result3 = privateKey3.getPublicKeySecp256k1(true).verify(sig3, message) assert(result3) } } diff --git a/codegen-v2/src/codegen/cpp/code_gen.rs b/codegen-v2/src/codegen/cpp/code_gen.rs index e83f3af603e..fae1f93d5aa 100644 --- a/codegen-v2/src/codegen/cpp/code_gen.rs +++ b/codegen-v2/src/codegen/cpp/code_gen.rs @@ -8,7 +8,8 @@ use crate::Error::BadFormat; use crate::Result; static IN_DIR: &str = "../rust/bindings/"; -static HEADER_OUT_DIR: &str = "../include/TrustWalletCore/"; +static HEADER_IN_DIR: &str = "../include/TrustWalletCore/"; +static HEADER_OUT_DIR: &str = "../include/TrustWalletCore/Generated/"; static SOURCE_OUT_DIR: &str = "../src/Generated/"; fn generate_license(file: &mut std::fs::File) -> Result<()> { @@ -24,7 +25,7 @@ fn generate_header_guard(file: &mut std::fs::File) -> Result<()> { } fn generate_header_includes(file: &mut std::fs::File, info: &TWConfig) -> Result<()> { - writeln!(file, "#include \"TWBase.h\"")?; + writeln!(file, "#include ")?; // Include headers based on argument types let mut included_headers = std::collections::HashSet::new(); @@ -37,7 +38,17 @@ fn generate_header_includes(file: &mut std::fs::File, info: &TWConfig) -> Result continue; } if included_headers.insert(header_name.clone()) { - writeln!(file, "#include \"{}.h\"", header_name)?; + if std::path::Path::new(&format!("{}{}.h", HEADER_IN_DIR, header_name)) + .exists() + { + writeln!(file, "#include ", header_name)?; + } else { + writeln!( + file, + "#include ", + header_name + )?; + } } } TWType::Standard(ty) => { @@ -45,7 +56,11 @@ fn generate_header_includes(file: &mut std::fs::File, info: &TWConfig) -> Result && included_headers.insert("TWCoinType.h".to_string()) { // Need to handle this case separately because it's not a pointer type - writeln!(file, "#include \"TWCoinType.h\"")?; + writeln!(file, "#include ")?; + } else if ty.contains("TWFFIAESPaddingMode") + && included_headers.insert("TWAESPaddingMode.h".to_string()) + { + writeln!(file, "#include ")?; } } } @@ -170,7 +185,11 @@ fn generate_wrapper_header(info: &TWConfig) -> Result<()> { } fn generate_source_includes(file: &mut std::fs::File, info: &TWConfig) -> Result<()> { - writeln!(file, "#include ", info.class)?; + writeln!( + file, + "#include ", + info.class + )?; writeln!(file, "#include \"rust/Wrapper.h\"")?; // Include headers based on argument types @@ -235,7 +254,15 @@ fn generate_return_type(func: &TWFunction, converted_args: &Vec) -> Resu .map_err(|e| BadFormat(e.to_string()))?; } (TWPointerType::NonnullMut, "TWString") | (TWPointerType::Nonnull, "TWString") => { - panic!("Nonnull TWString is not supported"); + write!( + &mut return_string, + "\tconst Rust::TWStringWrapper result = Rust::{}{}\n\ + \tconst auto resultString = result.toStringOrDefault();\n\ + \treturn TWStringCreateWithUTF8Bytes(resultString.c_str());\n", + func.rust_name, + generate_function_call(&converted_args)?.as_str() + ) + .map_err(|e| BadFormat(e.to_string()))?; } (TWPointerType::NullableMut, "TWData") | (TWPointerType::Nullable, "TWData") => { write!( @@ -303,7 +330,7 @@ fn generate_return_type(func: &TWFunction, converted_args: &Vec) -> Resu let wrapper_class_name = class_name.replace("TW", ""); let null_return = match pointer_type { TWPointerType::Nullable | TWPointerType::NullableMut => { - "if (!resultRaw) {{ return nullptr; }}\n" + "\tif (!resultRaw) {{ return nullptr; }}\n" } _ => "", }; @@ -395,7 +422,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result writeln!( &mut conversion_code, "\tauto &{name}PrivateKey = *reinterpret_cast({name});\n\ - \tauto* {name}RustRaw = Rust::tw_private_key_create_with_data({name}PrivateKey.bytes.data(), {name}PrivateKey.bytes.size());\n\ + \tauto* {name}RustRaw = Rust::tw_private_key_create_with_data({name}PrivateKey.bytes.data(), {name}PrivateKey.bytes.size(), static_cast({name}PrivateKey.curve()));\n\ \tconst auto {name}RustPrivateKey = Rust::wrapTWPrivateKey({name}RustRaw);" ) .map_err(|e| BadFormat(e.to_string()))?; @@ -408,7 +435,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result "\tstd::shared_ptr {name}RustPrivateKey;\n\ \tif ({name} != nullptr) {{\n\ \t\tconst auto& {name}PrivateKey = {name};\n\ - \t\tauto* {name}RustRaw = Rust::tw_private_key_create_with_data({name}PrivateKey->impl.bytes.data(), {name}PrivateKey->impl.bytes.size());\n\ + \t\tauto* {name}RustRaw = Rust::tw_private_key_create_with_data({name}PrivateKey->impl.bytes.data(), {name}PrivateKey->impl.bytes.size(), static_cast({name}PrivateKey->impl.curve()));\n\ \t\t{name}RustPrivateKey = Rust::wrapTWPrivateKey({name}RustRaw);\n\ \t}}" ) diff --git a/codegen-v2/src/codegen/cpp/code_gen_types.rs b/codegen-v2/src/codegen/cpp/code_gen_types.rs index 555fa8b8e88..d306fc3d537 100644 --- a/codegen-v2/src/codegen/cpp/code_gen_types.rs +++ b/codegen-v2/src/codegen/cpp/code_gen_types.rs @@ -128,11 +128,13 @@ impl TWType { "u16" => "uint16_t".to_string(), "u32" => "uint32_t".to_string(), "u64" => "uint64_t".to_string(), + "usize" => "size_t".to_string(), "i8" => "int8_t".to_string(), "i16" => "int16_t".to_string(), "i32" => "int32_t".to_string(), "i64" => "int64_t".to_string(), "TWFFICoinType" => "enum TWCoinType".to_string(), + "TWFFIAESPaddingMode" => "enum TWAESPaddingMode".to_string(), _ => ty.to_string(), }, TWType::Pointer(pointer_type, ty) => { diff --git a/codegen-v2/src/codegen/swift/templates/WalletCore.h b/codegen-v2/src/codegen/swift/templates/WalletCore.h index 76f61b9fa74..896d167eb4e 100644 --- a/codegen-v2/src/codegen/swift/templates/WalletCore.h +++ b/codegen-v2/src/codegen/swift/templates/WalletCore.h @@ -16,7 +16,6 @@ FOUNDATION_EXPORT const unsigned char WalletCoreVersionString[]; #include "TWAnySigner.h" -#include "TWAES.h" #include "TWAESPaddingMode.h" #include "TWAccount.h" #include "TWAnyAddress.h" @@ -54,7 +53,6 @@ FOUNDATION_EXPORT const unsigned char WalletCoreVersionString[]; #include "TWHRP.h" #include "TWHash.h" #include "TWLiquidStaking.h" -#include "TWMnemonic.h" #include "TWNEARAccount.h" #include "TWNervosAddress.h" #include "TWPBKDF2.h" diff --git a/codegen/bin/codegen b/codegen/bin/codegen index f34931b21ab..78c9a8901b0 100755 --- a/codegen/bin/codegen +++ b/codegen/bin/codegen @@ -62,17 +62,29 @@ end.parse! entities = [] files = [] -Dir.foreach(options.input) do |item| - next if ['.', '..', '.DS_Store'].include?(item) - - file_path = File.expand_path(File.join(options.input, item)) +def process_file(file_path, entities, files) entity = Parser.new(path: file_path).parse - next if entity.nil? + return if entity.nil? entities << entity - files << File.basename(item, '.h').sub(/^TW/, '') + files << File.basename(file_path, '.h').sub(/^TW/, '') +end + +def process_directory(dir_path, entities, files) + Dir.foreach(dir_path) do |item| + next if ['.', '..', '.DS_Store'].include?(item) + + path = File.expand_path(File.join(dir_path, item)) + if File.directory?(path) + process_directory(path, entities, files) + else + process_file(path, entities, files) if item.end_with?('.h') + end + end end +process_directory(options.input, entities, files) + generator = CodeGenerator.new(entities: entities, files: files, output_folder: options.output) if options.swift generator.render_swift diff --git a/codegen/lib/coin_skeleton_gen.rb b/codegen/lib/coin_skeleton_gen.rb index feec8fef8e6..eafdf3c45f1 100755 --- a/codegen/lib/coin_skeleton_gen.rb +++ b/codegen/lib/coin_skeleton_gen.rb @@ -108,7 +108,7 @@ def generate_skeleton(coin_id, mode) json_string = File.read('registry.json') coins = JSON.parse(json_string).sort_by { |x| x['name'] } - entity = EntityDecl.new(name: "New" + coin_id, is_struct: false, comment: '') + entity = EntityDecl.new(name: "New" + coin_id, is_struct: false, is_generated: false, comment: '') file = "new"+ coin_id generator = CodeGenerator.new(entities: [entity], files: [file], output_folder: ".") diff --git a/codegen/lib/entity_decl.rb b/codegen/lib/entity_decl.rb index aee285ef97b..303633c02d6 100644 --- a/codegen/lib/entity_decl.rb +++ b/codegen/lib/entity_decl.rb @@ -3,11 +3,12 @@ # Class or struct declaration class EntityDecl attr_reader :name, :comment - attr_accessor :is_struct, :methods, :properties, :static_methods, :static_properties + attr_accessor :is_struct, :is_generated, :methods, :properties, :static_methods, :static_properties - def initialize(name:, is_struct:, comment:) + def initialize(name:, is_struct:, is_generated:, comment:) @name = name @is_struct = is_struct + @is_generated = is_generated @methods = [] @properties = [] @static_methods = [] @@ -19,6 +20,10 @@ def struct? is_struct end + def generated? + is_generated + end + def class? !is_struct end diff --git a/codegen/lib/enum_decl.rb b/codegen/lib/enum_decl.rb index 0fae5774f50..a74d533c034 100644 --- a/codegen/lib/enum_decl.rb +++ b/codegen/lib/enum_decl.rb @@ -25,6 +25,10 @@ def class? false end + def generated? + false + end + def enum? true end diff --git a/codegen/lib/parser.rb b/codegen/lib/parser.rb index e4e287614a0..55bdcab0a9e 100644 --- a/codegen/lib/parser.rb +++ b/codegen/lib/parser.rb @@ -9,12 +9,13 @@ # C header parser class Parser - attr_reader :path, :entity, :entity_comment + attr_reader :path, :entity, :entity_comment, :is_generated def initialize(path:, string: nil) @path = path @buffer = StringScanner.new(string || File.read(path)) @entity = nil + @is_generated = path.include?('Generated') end # Parses a C header file for class/struct declarations @@ -134,7 +135,7 @@ def handle_class @buffer.skip(/\s*/) report_error 'Invalid type name' if @buffer.scan(/struct TW(\w+)\s*;/).nil? report_error 'Found more than one class/struct in the same file' unless @entity.nil? - @entity = EntityDecl.new(name: @buffer[1], is_struct: false, comment: @entity_comment) + @entity = EntityDecl.new(name: @buffer[1], is_struct: false, is_generated: @is_generated, comment: @entity_comment) puts "Found a class #{@entity.name}" end @@ -142,7 +143,7 @@ def handle_struct @buffer.skip(/\s*/) report_error 'Invalid type name at' if @buffer.scan(/struct TW(\w+)\s*\{?/).nil? report_error 'Found more than one class/struct in the same file' unless @entity.nil? - @entity = EntityDecl.new(name: @buffer[1], is_struct: true, comment: @entity_comment) + @entity = EntityDecl.new(name: @buffer[1], is_struct: true, is_generated: @is_generated, comment: @entity_comment) puts "Found a struct #{@buffer[1]}" end diff --git a/codegen/lib/templates/cpp/includes.erb b/codegen/lib/templates/cpp/includes.erb index 6c3d2e996c4..a38484ee5c2 100644 --- a/codegen/lib/templates/cpp/includes.erb +++ b/codegen/lib/templates/cpp/includes.erb @@ -1,19 +1,28 @@ <%# Include entity headers -%> <% require 'set' -%> -<% includes = Set.new([entity.name]) -%> +<% includes = Set.new -%> +<% includes.add({name: entity.name, generated: entity.generated?}) -%> <% (entity.static_methods + entity.methods).each do |method| -%> -<% includes << method.return_type.name if method.return_type.is_struct || method.return_type.is_class -%> +<% if method.return_type.is_struct || method.return_type.is_class -%> +<% includes.add({name: method.return_type.name, generated: method.return_type.is_generated}) -%> +<% end -%> <% method.parameters.each do |param| -%> -<% includes << param.type.name if param.type.is_struct || param.type.is_class -%> +<% if param.type.is_struct || param.type.is_class -%> +<% includes.add({name: param.type.name, generated: param.type.is_generated}) -%> +<% end -%> <% end -%> <% end -%> <% includes.each do |include| -%> -#include .h> +<% if include[:generated] -%> +#include .h> +<% else -%> +#include .h> +<% end -%> <% end -%> <% includes.each do |include| -%> -<% next if include == entity.name -%> -#include "./<%= include %>.h" +<% next if include[:name] == entity.name -%> +#include "./<%= include[:name] %>.h" <% end -%> #include diff --git a/codegen/lib/templates/jni_c.erb b/codegen/lib/templates/jni_c.erb index 5f7f56125bc..5fccafa36cd 100644 --- a/codegen/lib/templates/jni_c.erb +++ b/codegen/lib/templates/jni_c.erb @@ -3,15 +3,24 @@ #include <% require 'set' -%> -<% includes = Set.new([entity.name]) -%> +<% includes = Set.new -%> +<% includes.add({name: entity.name, generated: entity.generated?}) -%> <% entity.static_methods.each do |method| -%> -<% includes << method.return_type.name if method.return_type.is_struct || method.return_type.is_class -%> +<% if method.return_type.is_struct || method.return_type.is_class -%> +<% includes.add({name: method.return_type.name, generated: method.return_type.is_generated}) -%> +<% end -%> <% method.parameters.each do |param| -%> -<% includes << param.type.name if param.type.is_struct || param.type.is_class -%> +<% if param.type.is_struct || param.type.is_class -%> +<% includes.add({name: param.type.name, generated: param.type.is_generated}) -%> +<% end -%> <% end -%> <% end -%> <% includes.each do |include| -%> -#include .h> +<% if include[:generated] -%> +#include .h> +<% else -%> +#include .h> +<% end -%> <% end -%> #include "TWJNI.h" diff --git a/codegen/lib/templates/kotlin_jni_c.erb b/codegen/lib/templates/kotlin_jni_c.erb index 3b1f05b0588..6eaa3fe1b7d 100644 --- a/codegen/lib/templates/kotlin_jni_c.erb +++ b/codegen/lib/templates/kotlin_jni_c.erb @@ -3,15 +3,24 @@ #include <% require 'set' -%> -<% includes = Set.new([entity.name]) -%> +<% includes = Set.new -%> +<% includes.add({name: entity.name, generated: entity.generated?}) -%> <% entity.static_methods.each do |method| -%> -<% includes << method.return_type.name if method.return_type.is_struct || method.return_type.is_class -%> +<% if method.return_type.is_struct || method.return_type.is_class -%> +<% includes.add({name: method.return_type.name, generated: method.return_type.is_generated}) -%> +<% end -%> <% method.parameters.each do |param| -%> -<% includes << param.type.name if param.type.is_struct || param.type.is_class -%> +<% if param.type.is_struct || param.type.is_class -%> +<% includes.add({name: param.type.name, generated: param.type.is_generated}) -%> +<% end -%> <% end -%> <% end -%> <% includes.each do |include| -%> -#include .h> +<% if include[:generated] -%> +#include .h> +<% else -%> +#include .h> +<% end -%> <% end -%> #include "TWJNI.h" diff --git a/codegen/lib/type_decl.rb b/codegen/lib/type_decl.rb index 1abc1c60104..a6fe4399283 100644 --- a/codegen/lib/type_decl.rb +++ b/codegen/lib/type_decl.rb @@ -3,7 +3,7 @@ # Type declaration class TypeDecl attr_reader :name - attr_accessor :is_class, :is_struct, :is_enum, :is_proto, :is_nullable, :is_inout, :size + attr_accessor :is_class, :is_struct, :is_enum, :is_proto, :is_nullable, :is_inout, :size, :is_generated def initialize(name:, **options) @name = name @@ -14,6 +14,7 @@ def initialize(name:, **options) @is_nullable = options.fetch(:is_nullable, false) @is_inout = options.fetch(:is_inout, false) @size = options.fetch(:size, nil) + @is_generated = !File.exist?("include/TrustWalletCore/TW#{name}.h") end def self.fromPrimitive(string) diff --git a/codegen/test/test_jni_helper.rb b/codegen/test/test_jni_helper.rb index 595ff1e53e2..f1a98713727 100644 --- a/codegen/test/test_jni_helper.rb +++ b/codegen/test/test_jni_helper.rb @@ -8,7 +8,7 @@ def test_format_name end def test_function_name - entity = EntityDecl.new(name: 'Test', is_struct: false, comment: '') + entity = EntityDecl.new(name: 'Test', is_struct: false, is_generated: false, comment: '') method = FunctionDecl.new(name: 'Function', entity: entity, is_method: true) name = JNIHelper.function_name(entity: entity, function: method) assert_equal(name, 'Java_wallet_core_jni_Test_function') diff --git a/include/TrustWalletCore/TWAES.h b/include/TrustWalletCore/TWAES.h deleted file mode 100644 index e4a30c656d1..00000000000 --- a/include/TrustWalletCore/TWAES.h +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#pragma once - -#include "TWBase.h" -#include "TWData.h" -#include "TWAESPaddingMode.h" - -TW_EXTERN_C_BEGIN - -/// AES encryption/decryption methods. -TW_EXPORT_STRUCT -struct TWAES { - uint8_t unused; // C doesn't allow zero-sized struct -}; - -/// Encrypts a block of Data using AES in Cipher Block Chaining (CBC) mode. -/// -/// \param key encryption key Data, must be 16, 24, or 32 bytes long. -/// \param data Data to encrypt. -/// \param iv initialization vector. -/// \param mode padding mode. -/// \return encrypted Data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWAESEncryptCBC(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv, enum TWAESPaddingMode mode); - -/// Decrypts a block of data using AES in Cipher Block Chaining (CBC) mode. -/// -/// \param key decryption key Data, must be 16, 24, or 32 bytes long. -/// \param data Data to decrypt. -/// \param iv initialization vector Data. -/// \param mode padding mode. -/// \return decrypted Data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWAESDecryptCBC(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv, enum TWAESPaddingMode mode); - -/// Encrypts a block of data using AES in Counter (CTR) mode. -/// -/// \param key encryption key Data, must be 16, 24, or 32 bytes long. -/// \param data Data to encrypt. -/// \param iv initialization vector Data. -/// \return encrypted Data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWAESEncryptCTR(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv); - -/// Decrypts a block of data using AES in Counter (CTR) mode. -/// -/// \param key decryption key Data, must be 16, 24, or 32 bytes long. -/// \param data Data to decrypt. -/// \param iv initialization vector Data. -/// \return decrypted Data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWAESDecryptCTR(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv); - -TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWCryptoBox.h b/include/TrustWalletCore/TWCryptoBox.h index abd27ca8191..7894d5806dd 100644 --- a/include/TrustWalletCore/TWCryptoBox.h +++ b/include/TrustWalletCore/TWCryptoBox.h @@ -5,8 +5,8 @@ #pragma once #include "TWBase.h" -#include "TWCryptoBoxPublicKey.h" -#include "TWCryptoBoxSecretKey.h" +#include +#include #include "TWData.h" #include "TWString.h" diff --git a/include/TrustWalletCore/TWCurve.h b/include/TrustWalletCore/TWCurve.h index 3b7f2b003bd..80940124d2b 100644 --- a/include/TrustWalletCore/TWCurve.h +++ b/include/TrustWalletCore/TWCurve.h @@ -18,6 +18,8 @@ enum TWCurve { TWCurveNIST256p1 /* "nist256p1" */, TWCurveED25519ExtendedCardano /* "ed25519-cardano-seed" */, TWCurveStarkex /* "starkex" */, + TWCurveSchnorr /* "schnorr" */, + TWCurveZILLIQASchnorr /* "zilliqa-schnorr" */, TWCurveNone }; diff --git a/include/TrustWalletCore/TWHDWallet.h b/include/TrustWalletCore/TWHDWallet.h index 9e902a55587..dae14812dcc 100644 --- a/include/TrustWalletCore/TWHDWallet.h +++ b/include/TrustWalletCore/TWHDWallet.h @@ -96,9 +96,9 @@ TWData* _Nonnull TWHDWalletEntropy(struct TWHDWallet* _Nonnull wallet); /// \param wallet non-null TWHDWallet /// \param curve a curve /// \note Returned object needs to be deleted with \TWPrivateKeyDelete -/// \return Non-null corresponding private key +/// \return Corresponding private key. Returns null for `TWCurveED25519ExtendedCardano`. TW_EXPORT_METHOD -struct TWPrivateKey* _Nonnull TWHDWalletGetMasterKey(struct TWHDWallet* _Nonnull wallet, enum TWCurve curve); +struct TWPrivateKey* _Nullable TWHDWalletGetMasterKey(struct TWHDWallet* _Nonnull wallet, enum TWCurve curve); /// Generates the default private key for the specified coin, using default derivation. /// diff --git a/include/TrustWalletCore/TWMnemonic.h b/include/TrustWalletCore/TWMnemonic.h deleted file mode 100644 index 2cfba1dba70..00000000000 --- a/include/TrustWalletCore/TWMnemonic.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#pragma once - -#include "TWBase.h" -#include "TWString.h" - -TW_EXTERN_C_BEGIN - -/// Mnemonic validate / lookup functions -TW_EXPORT_STRUCT -struct TWMnemonic; - -/// Determines whether a BIP39 English mnemonic phrase is valid. -/// -/// \param mnemonic Non-null BIP39 english mnemonic -/// \return true if the mnemonic is valid, false otherwise -TW_EXPORT_STATIC_METHOD -bool TWMnemonicIsValid(TWString *_Nonnull mnemonic); - -/// Determines whether word is a valid BIP39 English mnemonic word. -/// -/// \param word Non-null BIP39 English mnemonic word -/// \return true if the word is a valid BIP39 English mnemonic word, false otherwise -TW_EXPORT_STATIC_METHOD -bool TWMnemonicIsValidWord(TWString *_Nonnull word); - -/// Return BIP39 English words that match the given prefix. A single string is returned, with space-separated list of words. -/// -/// \param prefix Non-null string prefix -/// \return Single non-null string, space-separated list of words containing BIP39 words that match the given prefix. -TW_EXPORT_STATIC_METHOD -TWString* _Nonnull TWMnemonicSuggest(TWString *_Nonnull prefix); - -TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWPBKDF2.h b/include/TrustWalletCore/TWPBKDF2.h deleted file mode 100644 index 86c6cca6801..00000000000 --- a/include/TrustWalletCore/TWPBKDF2.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#pragma once - -#include "TWBase.h" -#include "TWData.h" - -TW_EXTERN_C_BEGIN - -/// Password-Based Key Derivation Function 2 -TW_EXPORT_STRUCT -struct TWPBKDF2; - -/// Derives a key from a password and a salt using PBKDF2 + Sha256. -/// -/// \param password is the master password from which a derived key is generated -/// \param salt is a sequence of bits, known as a cryptographic salt -/// \param iterations is the number of iterations desired -/// \param dkLen is the desired bit-length of the derived key -/// \return the derived key data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWPBKDF2HmacSha256(TWData *_Nonnull password, TWData *_Nonnull salt, uint32_t iterations, uint32_t dkLen); - -/// Derives a key from a password and a salt using PBKDF2 + Sha512. -/// -/// \param password is the master password from which a derived key is generated -/// \param salt is a sequence of bits, known as a cryptographic salt -/// \param iterations is the number of iterations desired -/// \param dkLen is the desired bit-length of the derived key -/// \return the derived key data. -TW_EXPORT_STATIC_METHOD -TWData *_Nullable TWPBKDF2HmacSha512(TWData *_Nonnull password, TWData *_Nonnull salt, uint32_t iterations, uint32_t dkLen); - -TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWPrivateKey.h b/include/TrustWalletCore/TWPrivateKey.h index 5fdfc61bcde..462d44ca67a 100644 --- a/include/TrustWalletCore/TWPrivateKey.h +++ b/include/TrustWalletCore/TWPrivateKey.h @@ -18,20 +18,22 @@ struct TWPrivateKey; static const size_t TWPrivateKeySize = 32; -/// Create a random private key +/// Create a random private key with the given curve /// +/// \param curve the curve of the private key /// \note Should be deleted with \TWPrivateKeyDelete /// \return Non-null Private key TW_EXPORT_STATIC_METHOD -struct TWPrivateKey* _Nonnull TWPrivateKeyCreate(void); +struct TWPrivateKey* _Nonnull TWPrivateKeyCreate(enum TWCurve curve); -/// Create a private key with the given block of data +/// Create a private key with the given block of data and curve /// /// \param data a block of data +/// \param curve the curve of the private key /// \note Should be deleted with \TWPrivateKeyDelete /// \return Nullable pointer to Private Key TW_EXPORT_STATIC_METHOD -struct TWPrivateKey* _Nullable TWPrivateKeyCreateWithData(TWData* _Nonnull data); +struct TWPrivateKey* _Nullable TWPrivateKeyCreateWithData(TWData* _Nonnull data, enum TWCurve curve); /// Deep copy a given private key /// @@ -121,14 +123,20 @@ struct TWPublicKey* _Nonnull TWPrivateKeyGetPublicKeyEd25519Cardano(struct TWPri TW_EXPORT_METHOD struct TWPublicKey* _Nonnull TWPrivateKeyGetPublicKeyCurve25519(struct TWPrivateKey* _Nonnull pk); -/// Signs a digest using ECDSA and given curve. +/// Returns the Zilliqa Schnorr public key associated with the given private key +/// +/// \param pk Non-null pointer to the private key +/// \return Non-null pointer to the corresponding public key +TW_EXPORT_METHOD +struct TWPublicKey *_Nonnull TWPrivateKeyGetPublicKeyZilliqaSchnorr(struct TWPrivateKey *_Nonnull pk); + +/// Signs a digest using ECDSA /// /// \param pk Non-null pointer to a Private key /// \param digest Non-null digest block of data -/// \param curve Eliptic curve /// \return Signature as a Non-null block of data TW_EXPORT_METHOD -TWData* _Nullable TWPrivateKeySign(struct TWPrivateKey* _Nonnull pk, TWData* _Nonnull digest, enum TWCurve curve); +TWData* _Nullable TWPrivateKeySign(struct TWPrivateKey* _Nonnull pk, TWData* _Nonnull digest); /// Signs a digest using ECDSA. The result is encoded with DER. /// @@ -138,12 +146,4 @@ TWData* _Nullable TWPrivateKeySign(struct TWPrivateKey* _Nonnull pk, TWData* _No TW_EXPORT_METHOD TWData* _Nullable TWPrivateKeySignAsDER(struct TWPrivateKey* _Nonnull pk, TWData* _Nonnull digest); -/// Signs a digest using ECDSA and Zilliqa schnorr signature scheme. -/// -/// \param pk Non-null pointer to a Private key -/// \param message Non-null message -/// \return Signature as a Non-null block of data -TW_EXPORT_METHOD -TWData* _Nullable TWPrivateKeySignZilliqaSchnorr(struct TWPrivateKey* _Nonnull pk, TWData* _Nonnull message); - TW_EXTERN_C_END diff --git a/include/TrustWalletCore/TWPublicKey.h b/include/TrustWalletCore/TWPublicKey.h index 7187ac564af..a003d24f781 100644 --- a/include/TrustWalletCore/TWPublicKey.h +++ b/include/TrustWalletCore/TWPublicKey.h @@ -87,15 +87,6 @@ bool TWPublicKeyVerify(struct TWPublicKey *_Nonnull pk, TWData *_Nonnull signatu TW_EXPORT_METHOD bool TWPublicKeyVerifyAsDER(struct TWPublicKey *_Nonnull pk, TWData *_Nonnull signature, TWData *_Nonnull message); -/// Verify a Zilliqa schnorr signature with a signature and message. -/// -/// \param pk Non-null pointer to a public key -/// \param signature Non-null pointer to a block of data corresponding to the signature -/// \param message Non-null pointer to a block of data corresponding to the message -/// \return true if the signature and the message belongs to the given public key, false otherwise -TW_EXPORT_METHOD -bool TWPublicKeyVerifyZilliqaSchnorr(struct TWPublicKey *_Nonnull pk, TWData *_Nonnull signature, TWData *_Nonnull message); - /// Give the public key type (eliptic) of a given public key /// /// \param publicKey Non-null pointer to a public key diff --git a/include/TrustWalletCore/TWPublicKeyType.h b/include/TrustWalletCore/TWPublicKeyType.h index f175fc8c471..99f10b68fc3 100644 --- a/include/TrustWalletCore/TWPublicKeyType.h +++ b/include/TrustWalletCore/TWPublicKeyType.h @@ -20,6 +20,8 @@ enum TWPublicKeyType { TWPublicKeyTypeCURVE25519 = 6, TWPublicKeyTypeED25519Cardano = 7, TWPublicKeyTypeStarkex = 8, + TWPublicKeyTypeSchnorr = 9, + TWPublicKeyTypeZILLIQASchnorr = 10, }; TW_EXTERN_C_END diff --git a/kotlin/wallet-core-kotlin/build.gradle.kts b/kotlin/wallet-core-kotlin/build.gradle.kts index 9d49f0c003d..e93ef5997e8 100644 --- a/kotlin/wallet-core-kotlin/build.gradle.kts +++ b/kotlin/wallet-core-kotlin/build.gradle.kts @@ -104,7 +104,16 @@ kotlin { rootDir.parentFile.resolve("include"), rootDir.parentFile.resolve("include/TrustWalletCore"), ) - headers(rootDir.parentFile.resolve("include/TrustWalletCore").listFiles()!!) + + // Include headers from TrustWalletCore directory + val trustWalletCoreDir = rootDir.parentFile.resolve("include/TrustWalletCore") + headers(trustWalletCoreDir.listFiles()!!.filter { it.isFile }) + + // Include headers from Generated directory + val generatedDir = rootDir.parentFile.resolve("include/TrustWalletCore/Generated") + if (generatedDir.exists()) { + headers(generatedDir.listFiles()!!.filter { it.isFile }) + } } } } diff --git a/registry.json b/registry.json index e53e559ab61..dd65ffc741e 100644 --- a/registry.json +++ b/registry.json @@ -1892,8 +1892,8 @@ "path": "m/44'/313'/0'/0/0" } ], - "curve": "secp256k1", - "publicKeyType": "secp256k1", + "curve": "zilliqaSchnorr", + "publicKeyType": "zilliqaSchnorr", "hrp": "zil", "explorer": { "url": "https://viewblock.io", diff --git a/rust/Cargo.lock b/rust/Cargo.lock index b60b8a02478..81f10be8aa5 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -12,6 +12,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -62,7 +73,7 @@ dependencies = [ "ark-serialize", "ark-std", "derivative", - "digest 0.10.6", + "digest 0.10.7", "itertools", "num-bigint", "num-traits", @@ -101,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-std", - "digest 0.10.6", + "digest 0.10.7", "num-bigint", ] @@ -187,6 +198,38 @@ dependencies = [ "serde", ] +[[package]] +name = "bip32" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db40d3dfbeab4e031d78c844642fa0caa0b0db11ce1607ac9d2986dff1405c69" +dependencies = [ + "bs58 0.5.1", + "hmac", + "k256", + "once_cell", + "pbkdf2", + "rand_core", + "ripemd", + "secp256k1", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" +dependencies = [ + "bitcoin_hashes", + "rand", + "rand_core", + "serde", + "unicode-normalization", +] + [[package]] name = "bitcoin" version = "0.30.1" @@ -267,7 +310,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -294,6 +337,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + [[package]] name = "borsh" version = "1.3.1" @@ -324,6 +376,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2", + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -348,6 +410,15 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.79" @@ -507,6 +578,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cryptoxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -516,7 +602,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.6", + "digest 0.10.7", "fiat-crypto", "rustc_version", "subtle", @@ -600,9 +686,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.3", "const-oid", @@ -617,12 +703,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" dependencies = [ "der", - "digest 0.10.6", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", ] +[[package]] +name = "ed25519-bip32" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb588f93c0d91b2f668849fd6d030cddb0b2e31f105963be189da5acdf492a21" +dependencies = [ + "cryptoxide", +] + [[package]] name = "either" version = "1.8.1" @@ -637,7 +732,7 @@ checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -739,7 +834,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343cfc165f92a988fd60292f7a0bfde4352a5a0beff9fbec29251ca4e9676e4d" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -807,7 +902,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -864,6 +959,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] @@ -1119,6 +1215,16 @@ dependencies = [ "nom", ] +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -1331,7 +1437,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -1493,18 +1599,18 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -1513,7 +1619,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] @@ -1523,7 +1629,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core", ] @@ -1706,6 +1812,21 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "toml_datetime" version = "0.6.5" @@ -1935,6 +2056,31 @@ dependencies = [ "tw_proto", ] +[[package]] +name = "tw_crypto" +version = "0.1.0" +dependencies = [ + "aes", + "bip32", + "bip39", + "bs58 0.5.1", + "cbc", + "ctr", + "ed25519-bip32", + "pbkdf2", + "salsa20", + "serde_json", + "sha2", + "strum_macros", + "tw_encoding", + "tw_hash", + "tw_keypair", + "tw_macros", + "tw_memory", + "tw_misc", + "zeroize", +] + [[package]] name = "tw_decred" version = "0.1.0" @@ -1957,7 +2103,7 @@ dependencies = [ "arbitrary 1.3.0", "bcs", "bech32", - "bs58", + "bs58 0.4.0", "ciborium", "data-encoding", "hex", @@ -2037,7 +2183,7 @@ dependencies = [ "arbitrary 1.3.0", "blake-hash", "blake2b-ref", - "digest 0.10.6", + "digest 0.10.7", "groestl", "hmac", "ripemd", @@ -2046,6 +2192,7 @@ dependencies = [ "sha1", "sha2", "sha3", + "strum_macros", "tw_encoding", "tw_memory", "zeroize", @@ -2076,7 +2223,7 @@ dependencies = [ "crypto_box", "curve25519-dalek", "der", - "digest 0.10.6", + "digest 0.10.7", "ecdsa", "k256", "lazy_static", @@ -2464,6 +2611,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.10" @@ -2515,6 +2671,7 @@ dependencies = [ "tw_any_coin", "tw_bitcoin", "tw_coin_registry", + "tw_crypto", "tw_encoding", "tw_ethereum", "tw_hash", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 09ab546a720..ab72b60c61b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -37,6 +37,7 @@ members = [ "tw_evm", "tw_hash", "tw_keypair", + "tw_crypto", "tw_macros", "tw_memory", "tw_misc", @@ -56,11 +57,14 @@ panic = "abort" [profile.wasm-test] inherits = "release" -# Fixes an incredibly slow compilation of `curve25519-dalek` package. -opt-level = 1 +opt-level = 3 debug = true debug-assertions = true overflow-checks = true +# Fixes an incredibly slow compilation of `curve25519-dalek` package. +[profile.wasm-test.package.curve25519-dalek] +opt-level = 1 + [profile.release.package.curve25519-dalek] opt-level = 2 diff --git a/rust/tw_any_coin/src/test_utils/address_utils.rs b/rust/tw_any_coin/src/test_utils/address_utils.rs index 7d7b9cff373..36cf926ee3d 100644 --- a/rust/tw_any_coin/src/test_utils/address_utils.rs +++ b/rust/tw_any_coin/src/test_utils/address_utils.rs @@ -49,7 +49,7 @@ pub fn test_address_derive_with_derivation( let public_key = match key { KeyType::PrivateKey(key) => { - let private_key = TWPrivateKeyHelper::with_hex(key); + let private_key = TWPrivateKeyHelper::with_hex(key, coin_item.curve.to_raw()); TWPublicKeyHelper::wrap(unsafe { tw_private_key_get_public_key_by_type( private_key.ptr(), @@ -156,7 +156,8 @@ pub struct AddressCreateBech32WithPublicKey<'a> { } pub fn test_address_create_bech32_with_public_key(input: AddressCreateBech32WithPublicKey<'_>) { - let private_key = TWPrivateKeyHelper::with_hex(input.private_key); + let coin_item = get_coin_item(input.coin).unwrap(); + let private_key = TWPrivateKeyHelper::with_hex(input.private_key, coin_item.curve.to_raw()); let public_key = TWPublicKeyHelper::wrap(unsafe { tw_private_key_get_public_key_by_type(private_key.ptr(), input.public_key_type as u32) }); diff --git a/rust/tw_bech32_address/src/lib.rs b/rust/tw_bech32_address/src/lib.rs index ed35f0ba8f9..cce8a7235bf 100644 --- a/rust/tw_bech32_address/src/lib.rs +++ b/rust/tw_bech32_address/src/lib.rs @@ -202,7 +202,7 @@ impl Serialize for Bech32Address { mod tests { use super::*; use tw_encoding::hex::{DecodeHex, ToHex}; - + use tw_keypair::tw::Curve; struct FromPublicKeyTestInput<'a> { hrp: &'a str, private_key: &'a str, @@ -212,7 +212,8 @@ mod tests { } fn test_from_public_key(input: FromPublicKeyTestInput<'_>) { - let private_key = PrivateKey::new(input.private_key.decode_hex().unwrap()).unwrap(); + let private_key = + PrivateKey::new(input.private_key.decode_hex().unwrap(), Curve::Secp256k1).unwrap(); let public_key = private_key .get_public_key_by_type(input.public_key_type) .unwrap(); diff --git a/rust/tw_coin_entry/src/coin_context.rs b/rust/tw_coin_entry/src/coin_context.rs index bc80004caae..b2bfa82b42b 100644 --- a/rust/tw_coin_entry/src/coin_context.rs +++ b/rust/tw_coin_entry/src/coin_context.rs @@ -4,13 +4,16 @@ use crate::derivation::DerivationWithPath; use tw_hash::hasher::Hasher; -use tw_keypair::tw::PublicKeyType; +use tw_keypair::tw::{Curve, PublicKeyType}; /// Extend the trait with methods required for blockchain additions. pub trait CoinContext { /// Necessary chain property. fn public_key_type(&self) -> PublicKeyType; + /// Returns the curve for the coin. + fn curve(&self) -> Curve; + /// Optional chain property. fn address_hasher(&self) -> Option; diff --git a/rust/tw_coin_entry/src/coin_entry_ext.rs b/rust/tw_coin_entry/src/coin_entry_ext.rs index 05976df99ef..97e6cee6ab9 100644 --- a/rust/tw_coin_entry/src/coin_entry_ext.rs +++ b/rust/tw_coin_entry/src/coin_entry_ext.rs @@ -179,7 +179,7 @@ where return TWError::err(SigningErrorType::Error_not_supported); }; - let private_key = PrivateKey::new(private_key)?; + let private_key = PrivateKey::new(private_key, coin.curve())?; json_signer.sign_json(coin, input_json, &private_key) } diff --git a/rust/tw_coin_entry/src/error/impl_from.rs b/rust/tw_coin_entry/src/error/impl_from.rs index 12d95dddd82..7c060a8bdea 100644 --- a/rust/tw_coin_entry/src/error/impl_from.rs +++ b/rust/tw_coin_entry/src/error/impl_from.rs @@ -45,7 +45,10 @@ impl From for SigningError { | KeyPairError::InvalidSignature | KeyPairError::InvalidSignMessage | KeyPairError::SignatureVerifyError - | KeyPairError::InvalidEncryptedMessage => { + | KeyPairError::InvalidEncryptedMessage + | KeyPairError::InvalidMessage + | KeyPairError::InvalidRecId + | KeyPairError::UnsupportedCurve => { TWError::new(SigningErrorType::Error_invalid_params) }, KeyPairError::SigningError => TWError::new(SigningErrorType::Error_signing), diff --git a/rust/tw_coin_entry/src/test_utils/test_context.rs b/rust/tw_coin_entry/src/test_utils/test_context.rs index 5aaedceb221..22168d1793f 100644 --- a/rust/tw_coin_entry/src/test_utils/test_context.rs +++ b/rust/tw_coin_entry/src/test_utils/test_context.rs @@ -5,12 +5,13 @@ use crate::coin_context::CoinContext; use crate::derivation::DerivationWithPath; use tw_hash::hasher::Hasher; -use tw_keypair::tw::PublicKeyType; +use tw_keypair::tw::{Curve, PublicKeyType}; /// Test coin context that panics on any `CoinContext` method call. #[derive(Default)] pub struct TestCoinContext { pub public_key_type: Option, + pub curve: Option, pub address_hasher: Option, pub hrp: Option, pub p2pkh: Option, @@ -35,6 +36,12 @@ impl CoinContext for TestCoinContext { .expect("EmptyCoinContext::public_key_type was not set") } + fn curve(&self) -> Curve { + self.curve + .clone() + .expect("EmptyCoinContext::curve was not set") + } + fn address_hasher(&self) -> Option { self.address_hasher } diff --git a/rust/tw_coin_registry/src/coin_context.rs b/rust/tw_coin_registry/src/coin_context.rs index 9f38d9cd28b..4dc39680b99 100644 --- a/rust/tw_coin_registry/src/coin_context.rs +++ b/rust/tw_coin_registry/src/coin_context.rs @@ -6,7 +6,7 @@ use crate::registry::CoinItem; use tw_coin_entry::coin_context::CoinContext; use tw_coin_entry::derivation::DerivationWithPath; use tw_hash::hasher::Hasher; -use tw_keypair::tw::PublicKeyType; +use tw_keypair::tw::{Curve, PublicKeyType}; pub struct CoinRegistryContext { item: &'static CoinItem, @@ -25,6 +25,11 @@ impl CoinContext for CoinRegistryContext { self.item.public_key_type } + #[inline] + fn curve(&self) -> Curve { + self.item.curve.clone() + } + #[inline] fn address_hasher(&self) -> Option { self.item.address_hasher diff --git a/rust/tw_coin_registry/src/registry.rs b/rust/tw_coin_registry/src/registry.rs index 48a270a45e9..e75f0314794 100644 --- a/rust/tw_coin_registry/src/registry.rs +++ b/rust/tw_coin_registry/src/registry.rs @@ -10,7 +10,7 @@ use serde::Deserialize; use std::collections::HashMap; use tw_coin_entry::derivation::DerivationWithPath; use tw_hash::hasher::Hasher; -use tw_keypair::tw::PublicKeyType; +use tw_keypair::tw::{Curve, PublicKeyType}; type RegistryMap = HashMap; @@ -32,6 +32,7 @@ pub struct CoinItem { pub blockchain: BlockchainType, pub derivation: Vec, pub public_key_type: PublicKeyType, + pub curve: Curve, pub address_hasher: Option, pub hrp: Option, pub p2pkh_prefix: Option, diff --git a/rust/tw_cosmos_sdk/src/private_key/secp256k1.rs b/rust/tw_cosmos_sdk/src/private_key/secp256k1.rs index 655b80d5a51..d942c214d01 100644 --- a/rust/tw_cosmos_sdk/src/private_key/secp256k1.rs +++ b/rust/tw_cosmos_sdk/src/private_key/secp256k1.rs @@ -21,14 +21,12 @@ impl<'a> TryFrom<&'a [u8]> for Secp256PrivateKey { type Error = KeyPairError; fn try_from(value: &'a [u8]) -> Result { - tw::PrivateKey::new(value.to_vec()).map(Secp256PrivateKey) + tw::PrivateKey::new(value.to_vec(), Curve::Secp256k1).map(Secp256PrivateKey) } } impl CosmosPrivateKey for Secp256PrivateKey { fn sign_tx_hash(&self, hash: &[u8]) -> SigningResult { - self.0 - .sign(hash, Curve::Secp256k1) - .map_err(SigningError::from) + self.0.sign(hash).map_err(SigningError::from) } } diff --git a/rust/tw_crypto/Cargo.toml b/rust/tw_crypto/Cargo.toml new file mode 100644 index 00000000000..5540a3bf822 --- /dev/null +++ b/rust/tw_crypto/Cargo.toml @@ -0,0 +1,29 @@ + +[package] +name = "tw_crypto" +version = "0.1.0" +edition = "2021" + +[dependencies] +aes = "0.8.4" +bip32 = "0.5.3" +bip39 = { version = "2.1.0", features = ["rand" ] } +bs58 = { version = "0.5.0" } +cbc = "0.1.2" +ctr = "0.9.2" +ed25519-bip32 = "0.4.1" +pbkdf2 = "0.12.2" +salsa20 = "0.10.2" +sha2 = "0.10.8" +strum_macros = "0.25" +tw_encoding = { path = "../tw_encoding" } +tw_hash = { path = "../tw_hash" } +tw_keypair = { path = "../tw_keypair" } +tw_macros = { path = "../tw_macros" } +tw_memory = { path = "../tw_memory" } +tw_misc = { path = "../tw_misc" } +zeroize = "1.8.1" + +[dev-dependencies] +tw_memory = { path = "../tw_memory", features = ["test-utils"] } +serde_json = "1.0" diff --git a/rust/tw_crypto/fuzz/.gitignore b/rust/tw_crypto/fuzz/.gitignore new file mode 100644 index 00000000000..5c404b9583f --- /dev/null +++ b/rust/tw_crypto/fuzz/.gitignore @@ -0,0 +1,5 @@ +target +corpus +artifacts +coverage +Cargo.lock diff --git a/rust/tw_crypto/fuzz/Cargo.toml b/rust/tw_crypto/fuzz/Cargo.toml new file mode 100644 index 00000000000..e24a3f503f1 --- /dev/null +++ b/rust/tw_crypto/fuzz/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "tw_crypto-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = { version = "0.4", features = ["arbitrary-derive"] } + +[dependencies.tw_crypto] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[profile.release] +debug = 1 + +[[bin]] +name = "crypto_scrypt" +path = "fuzz_targets/crypto_scrypt.rs" +test = false +doc = false diff --git a/rust/tw_crypto/fuzz/fuzz_targets/crypto_scrypt.rs b/rust/tw_crypto/fuzz/fuzz_targets/crypto_scrypt.rs new file mode 100644 index 00000000000..3bccbdcf800 --- /dev/null +++ b/rust/tw_crypto/fuzz/fuzz_targets/crypto_scrypt.rs @@ -0,0 +1,36 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![no_main] + +use libfuzzer_sys::{arbitrary, fuzz_target}; +use tw_crypto::crypto_scrypt::{params::Params, scrypt}; + +#[derive(arbitrary::Arbitrary, Debug)] +struct ScryptInput<'a> { + password: &'a [u8], + salt: &'a [u8], + log_n: u8, + r: u32, + p: u32, + desired_len: usize, +} + +fuzz_target!(|input: ScryptInput<'_>| { + // Greater r, p parameters make `scrypt` incredibly slow. + if input.r > 16 || input.p > 16 { + return; + } + + let params = Params { + log_n: input.log_n, + r: input.r, + p: input.p, + desired_len: input.desired_len, + }; + + let _ = scrypt(input.password, input.salt, ¶ms); +}); diff --git a/rust/tw_crypto/src/crypto_aes_cbc/mod.rs b/rust/tw_crypto/src/crypto_aes_cbc/mod.rs new file mode 100644 index 00000000000..1c2da6782e7 --- /dev/null +++ b/rust/tw_crypto/src/crypto_aes_cbc/mod.rs @@ -0,0 +1,150 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod padding; + +use crate::{KEY_SIZE_AES_128, KEY_SIZE_AES_192, KEY_SIZE_AES_256}; +use aes::cipher::{ + Block, BlockDecryptMut, BlockEncryptMut, BlockSizeUser, KeyIvInit, StreamCipherError, +}; +use padding::{PaddingMode, BLOCK_SIZE_AES}; + +type Aes128CbcEnc = cbc::Encryptor; +type Aes128CbcDec = cbc::Decryptor; +type Aes192CbcEnc = cbc::Encryptor; +type Aes192CbcDec = cbc::Decryptor; +type Aes256CbcEnc = cbc::Encryptor; +type Aes256CbcDec = cbc::Decryptor; + +fn blocks(data: &[u8]) -> Vec> { + data.chunks(BLOCK_SIZE_AES) + .map(Block::::clone_from_slice) + .collect() +} + +fn aes_cbc_encrypt_impl( + data: &[u8], + iv: &[u8], + key: &[u8], + key_size: usize, + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + let key = if key.len() > key_size { + &key[0..key_size] + } else { + key + }; + let data = padding_mode.pad(data); + let mut blocks = blocks::(&data); + let mut cipher = E::new(key.into(), iv.into()); + cipher.encrypt_blocks_mut(&mut blocks[..]); + let buffer = blocks.concat(); + Ok(buffer) +} + +fn aes_cbc_decrypt_impl( + data: &[u8], + iv: &[u8], + key: &[u8], + key_size: usize, + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + let key = if key.len() > key_size { + &key[0..key_size] + } else { + key + }; + if data.len() % BLOCK_SIZE_AES != 0 { + return Err(StreamCipherError); + } + let mut blocks = blocks::(data); + let mut cipher = D::new(key.into(), iv.into()); + cipher.decrypt_blocks_mut(&mut blocks[..]); + let buffer = blocks.concat(); + Ok(padding_mode.unpad(&buffer)) +} + +pub fn aes_cbc_encrypt_128( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_encrypt_impl::(data, iv, key, KEY_SIZE_AES_128, padding_mode) +} + +pub fn aes_cbc_decrypt_128( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_decrypt_impl::(data, iv, key, KEY_SIZE_AES_128, padding_mode) +} + +pub fn aes_cbc_encrypt_192( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_encrypt_impl::(data, iv, key, KEY_SIZE_AES_192, padding_mode) +} + +pub fn aes_cbc_decrypt_192( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_decrypt_impl::(data, iv, key, KEY_SIZE_AES_192, padding_mode) +} + +pub fn aes_cbc_encrypt_256( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_encrypt_impl::(data, iv, key, KEY_SIZE_AES_256, padding_mode) +} + +pub fn aes_cbc_decrypt_256( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + aes_cbc_decrypt_impl::(data, iv, key, KEY_SIZE_AES_256, padding_mode) +} + +pub fn aes_cbc_encrypt( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + match key.len() { + KEY_SIZE_AES_128 => aes_cbc_encrypt_128(data, iv, key, padding_mode), + KEY_SIZE_AES_192 => aes_cbc_encrypt_192(data, iv, key, padding_mode), + KEY_SIZE_AES_256 => aes_cbc_encrypt_256(data, iv, key, padding_mode), + _ => Err(StreamCipherError), + } +} + +pub fn aes_cbc_decrypt( + data: &[u8], + iv: &[u8], + key: &[u8], + padding_mode: PaddingMode, +) -> Result, StreamCipherError> { + match key.len() { + KEY_SIZE_AES_128 => aes_cbc_decrypt_128(data, iv, key, padding_mode), + KEY_SIZE_AES_192 => aes_cbc_decrypt_192(data, iv, key, padding_mode), + KEY_SIZE_AES_256 => aes_cbc_decrypt_256(data, iv, key, padding_mode), + _ => Err(StreamCipherError), + } +} diff --git a/rust/tw_crypto/src/crypto_aes_cbc/padding.rs b/rust/tw_crypto/src/crypto_aes_cbc/padding.rs new file mode 100644 index 00000000000..7439c8425e2 --- /dev/null +++ b/rust/tw_crypto/src/crypto_aes_cbc/padding.rs @@ -0,0 +1,116 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub const BLOCK_SIZE_AES: usize = 16; + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub enum PaddingMode { + Zero = 0, + PKCS7 = 1, +} + +pub type TWFFIAESPaddingMode = u32; + +#[derive(Clone, Copy, Debug)] +pub struct InvalidPaddingMode; + +impl TryFrom for PaddingMode { + type Error = InvalidPaddingMode; + + fn try_from(value: u32) -> Result { + match value { + 0 => Ok(PaddingMode::Zero), + 1 => Ok(PaddingMode::PKCS7), + _ => Err(InvalidPaddingMode), + } + } +} + +impl PaddingMode { + pub fn padding_size(&self, data_size: usize) -> usize { + match self { + PaddingMode::Zero => { + if data_size % BLOCK_SIZE_AES == 0 { + 0 + } else { + BLOCK_SIZE_AES - (data_size % BLOCK_SIZE_AES) + } + }, + PaddingMode::PKCS7 => { + if data_size % BLOCK_SIZE_AES == 0 { + BLOCK_SIZE_AES + } else { + BLOCK_SIZE_AES - (data_size % BLOCK_SIZE_AES) + } + }, + } + } + + pub fn pad(&self, data: &[u8]) -> Vec { + let padding_size = self.padding_size(data.len()); + let mut padded = data.to_vec(); + match self { + PaddingMode::Zero => { + padded.extend(std::iter::repeat(0).take(padding_size)); + }, + PaddingMode::PKCS7 => { + padded.extend(std::iter::repeat(padding_size as u8).take(padding_size)); + }, + } + padded + } + + pub fn unpad(&self, data: &[u8]) -> Vec { + if data.is_empty() { + return data.to_vec(); + } + match self { + PaddingMode::PKCS7 => { + let padding_len = data[data.len() - 1] as usize; + if padding_len <= data.len() { + data[..data.len() - padding_len].to_vec() + } else { + data.to_vec() + } + }, + // Zero padding can be ambiguous, so we return the original data + // and the caller can strip the padding if needed + PaddingMode::Zero => data.to_vec(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_padding_size() { + let zero_mode = PaddingMode::Zero; + let pkcs7_mode = PaddingMode::PKCS7; + + assert_eq!(zero_mode.padding_size(0), 0); + assert_eq!(zero_mode.padding_size(1), 15); + assert_eq!(zero_mode.padding_size(8), 8); + assert_eq!(zero_mode.padding_size(15), 1); + assert_eq!(zero_mode.padding_size(16), 0); + assert_eq!(zero_mode.padding_size(17), 15); + assert_eq!(zero_mode.padding_size(24), 8); + assert_eq!(zero_mode.padding_size(31), 1); + assert_eq!(zero_mode.padding_size(32), 0); + + assert_eq!(pkcs7_mode.padding_size(0), 16); + assert_eq!(pkcs7_mode.padding_size(1), 15); + assert_eq!(pkcs7_mode.padding_size(8), 8); + assert_eq!(pkcs7_mode.padding_size(15), 1); + assert_eq!(pkcs7_mode.padding_size(16), 16); + assert_eq!(pkcs7_mode.padding_size(17), 15); + assert_eq!(pkcs7_mode.padding_size(24), 8); + assert_eq!(pkcs7_mode.padding_size(31), 1); + assert_eq!(pkcs7_mode.padding_size(32), 16); + } +} diff --git a/rust/tw_crypto/src/crypto_aes_ctr/mod.rs b/rust/tw_crypto/src/crypto_aes_ctr/mod.rs new file mode 100644 index 00000000000..66addbfa980 --- /dev/null +++ b/rust/tw_crypto/src/crypto_aes_ctr/mod.rs @@ -0,0 +1,97 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use crate::{KEY_SIZE_AES_128, KEY_SIZE_AES_192, KEY_SIZE_AES_256}; +use aes::cipher::{KeyIvInit, StreamCipher, StreamCipherError}; +use aes::{Aes128, Aes192, Aes256}; +use ctr::Ctr64BE; + +type Aes128Ctr64BE = Ctr64BE; +type Aes192Ctr64BE = Ctr64BE; +type Aes256Ctr64BE = Ctr64BE; + +fn aes_ctr_process( + data: &[u8], + iv: &[u8], + key: &[u8], + key_size: usize, +) -> Result, StreamCipherError> { + let key = if key.len() > key_size { + &key[0..key_size] + } else { + key + }; + let mut cipher = C::new(key.into(), iv.into()); + let mut data_vec = data.to_vec(); + cipher.try_apply_keystream(&mut data_vec)?; + Ok(data_vec) +} + +pub fn aes_ctr_encrypt_128( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_128) +} + +pub fn aes_ctr_decrypt_128( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_128) +} + +pub fn aes_ctr_encrypt_192( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_192) +} + +pub fn aes_ctr_decrypt_192( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_192) +} + +pub fn aes_ctr_encrypt_256( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_256) +} + +pub fn aes_ctr_decrypt_256( + data: &[u8], + iv: &[u8], + key: &[u8], +) -> Result, StreamCipherError> { + aes_ctr_process::(data, iv, key, KEY_SIZE_AES_256) +} + +pub fn aes_ctr_encrypt(data: &[u8], iv: &[u8], key: &[u8]) -> Result, StreamCipherError> { + match key.len() { + KEY_SIZE_AES_128 => aes_ctr_encrypt_128(data, iv, key), + KEY_SIZE_AES_192 => aes_ctr_encrypt_192(data, iv, key), + KEY_SIZE_AES_256 => aes_ctr_encrypt_256(data, iv, key), + _ => Err(StreamCipherError), + } +} + +pub fn aes_ctr_decrypt(data: &[u8], iv: &[u8], key: &[u8]) -> Result, StreamCipherError> { + match key.len() { + KEY_SIZE_AES_128 => aes_ctr_decrypt_128(data, iv, key), + KEY_SIZE_AES_192 => aes_ctr_decrypt_192(data, iv, key), + KEY_SIZE_AES_256 => aes_ctr_decrypt_256(data, iv, key), + _ => Err(StreamCipherError), + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/ecdsa/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ecdsa/mod.rs new file mode 100644 index 00000000000..91c3f231868 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ecdsa/mod.rs @@ -0,0 +1,8 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod nist256p1; +pub mod secp256k1; diff --git a/rust/tw_crypto/src/crypto_hd_node/ecdsa/nist256p1/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ecdsa/nist256p1/mod.rs new file mode 100644 index 00000000000..85055eaa0e5 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ecdsa/nist256p1/mod.rs @@ -0,0 +1,45 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::ChildNumber; +use tw_hash::H256; +use tw_keypair::traits::DerivableKeyTrait; +use tw_keypair::{ecdsa::nist256p1, tw::Curve}; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for nist256p1::PrivateKey { + type BIP32PublicKey = nist256p1::PublicKey; + + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } + + fn curve() -> Curve { + Curve::Nist256p1 + } + + fn bip32_name() -> &'static str { + "Nist256p1 seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for nist256p1::PublicKey { + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/ecdsa/secp256k1/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ecdsa/secp256k1/mod.rs new file mode 100644 index 00000000000..cbec66022e5 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ecdsa/secp256k1/mod.rs @@ -0,0 +1,45 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::ChildNumber; +use tw_hash::H256; +use tw_keypair::traits::DerivableKeyTrait; +use tw_keypair::{ecdsa::secp256k1, tw::Curve}; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for secp256k1::PrivateKey { + type BIP32PublicKey = secp256k1::PublicKey; + + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } + + fn curve() -> Curve { + Curve::Secp256k1 + } + + fn bip32_name() -> &'static str { + "Bitcoin seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for secp256k1::PublicKey { + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/ed25519/cardano/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ed25519/cardano/mod.rs new file mode 100644 index 00000000000..caadd306dd0 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ed25519/cardano/mod.rs @@ -0,0 +1,86 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use std::str::FromStr; + +use bip32::{ChildNumber, DerivationPath}; +use ed25519_bip32::{XPRV_SIZE, XPUB_SIZE}; +use tw_keypair::{ed25519, tw::Curve}; +use tw_misc::traits::{ToBytesVec, ToBytesZeroizing}; +use zeroize::Zeroizing; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for ed25519::cardano::ExtendedPrivateKey { + type BIP32PublicKey = ed25519::cardano::ExtendedPublicKey; + + fn derive_tweak( + &self, + chain_code: &bip32::ChainCode, + _child_number: bip32::ChildNumber, + ) -> Result<(Zeroizing>, bip32::ChainCode)> { + Ok((Zeroizing::new(vec![]), *chain_code)) + } + + fn derive_child(&self, _other: &[u8], child_number: ChildNumber) -> Result { + let bytes = self.to_zeroizing_vec(); + let bytes: [u8; XPRV_SIZE] = bytes.as_slice()[..XPRV_SIZE] + .try_into() + .expect("Should not fail"); + let bip32_xpr = + ed25519_bip32::XPrv::from_bytes_verified(bytes).map_err(|_| Error::InvalidKeyData)?; + let child: ed25519_bip32::XPrv = + bip32_xpr.derive(ed25519_bip32::DerivationScheme::V2, child_number.0); + Self::try_from(child.as_ref()).map_err(|_| Error::InvalidKeyData) + } + + fn curve() -> Curve { + Curve::Ed25519ExtendedCardano + } + + fn bip32_name() -> &'static str { + "ed25519 cardano seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for ed25519::cardano::ExtendedPublicKey { + fn derive_child(&self, _other: &[u8], child_number: ChildNumber) -> Result { + let bytes = self.to_vec(); + let bytes: [u8; XPUB_SIZE] = bytes[..XPUB_SIZE].try_into().expect("Should not fail"); + let bip32_xpub = ed25519_bip32::XPub::from_bytes(bytes); + let child: ed25519_bip32::XPub = bip32_xpub + .derive(ed25519_bip32::DerivationScheme::V2, child_number.0) + .map_err(|_| Error::DerivationFailed)?; + Self::try_from(child.as_ref()).map_err(|_| Error::InvalidKeyData) + } +} + +pub fn cardano_staking_derivation_path(path: &DerivationPath) -> Result { + if path.len() < 4 { + return Err(Error::InvalidDerivationPath); + } + let mut staking_path = DerivationPath::from_str("m")?; + for (i, item) in path.iter().enumerate() { + if i == 3 { + if item.index() > 1 { + return Err(Error::InvalidDerivationPath); + } + staking_path.push(ChildNumber::new(2, false)?); + } else if i == 4 { + staking_path.push(ChildNumber::new(0, false)?); + } else { + staking_path.push(item); + } + } + Ok(staking_path) +} diff --git a/rust/tw_crypto/src/crypto_hd_node/ed25519/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ed25519/mod.rs new file mode 100644 index 00000000000..f15e4e5391d --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ed25519/mod.rs @@ -0,0 +1,84 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod cardano; +pub mod waves; + +use bip32::ChildNumber; +use tw_keypair::{ed25519, tw::Curve}; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for ed25519::sha512::PrivateKey { + type BIP32PublicKey = ed25519::sha512::PublicKey; + + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } + + fn curve() -> Curve { + Curve::Ed25519 + } + + fn bip32_name() -> &'static str { + "ed25519 seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for ed25519::sha512::PublicKey { + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } +} + +impl BIP32PrivateKey for ed25519::blake2b::PrivateKey { + type BIP32PublicKey = ed25519::blake2b::PublicKey; + + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } + + fn curve() -> Curve { + Curve::Ed25519Blake2bNano + } + + fn bip32_name() -> &'static str { + "ed25519 seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for ed25519::blake2b::PublicKey { + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/ed25519/waves/mod.rs b/rust/tw_crypto/src/crypto_hd_node/ed25519/waves/mod.rs new file mode 100644 index 00000000000..b4602cccd91 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/ed25519/waves/mod.rs @@ -0,0 +1,47 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::ChildNumber; +use tw_keypair::{ed25519, tw::Curve}; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for ed25519::waves::PrivateKey { + type BIP32PublicKey = ed25519::waves::PublicKey; + + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } + + fn curve() -> Curve { + Curve::Curve25519Waves + } + + fn bip32_name() -> &'static str { + "curve25519 seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for ed25519::waves::PublicKey { + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result { + if child_number.is_hardened() { + Self::try_from(other).map_err(|_| Error::InvalidKeyData) + } else { + Ok(self.clone()) + } + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/error.rs b/rust/tw_crypto/src/crypto_hd_node/error.rs new file mode 100644 index 00000000000..1d35740410f --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/error.rs @@ -0,0 +1,84 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_keypair::KeyPairError; + +pub type Result = core::result::Result; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Error { + /// BIP32 error + BIP32(bip32::Error), + + /// Unsupported curve + UnsupportedCurve(u32), + + /// Invalid length + InvalidLength, + + /// Decode error + Decode, + + /// Invalid key data + InvalidKeyData, + + /// Invalid checksum + InvalidChecksum, + + /// Base58 error + Base58, + + /// Invalid depth + InvalidDepth, + + /// Invalid child number + InvalidChildNumber, + + /// Derivation failed + DerivationFailed, + + /// Invalid derivation path + InvalidDerivationPath, + + /// Invalid chain code + InvalidChainCode, +} + +impl From for Error { + fn from(error: bip32::Error) -> Error { + Error::BIP32(error) + } +} + +impl From for Error { + fn from(_: core::array::TryFromSliceError) -> Error { + Error::Decode + } +} + +impl From for Error { + fn from(_: tw_encoding::hex::FromHexError) -> Error { + Error::Decode + } +} + +impl From for Error { + fn from(_: bs58::decode::Error) -> Error { + Error::Base58 + } +} + +impl From for Error { + fn from(_: bs58::encode::Error) -> Error { + Error::Base58 + } +} + +impl From for Error { + fn from(_: KeyPairError) -> Error { + Error::InvalidKeyData + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_private_key.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_private_key.rs new file mode 100644 index 00000000000..0c1e5f913d6 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_private_key.rs @@ -0,0 +1,70 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use std::str::FromStr; + +use bip32::{ChainCode, ChildNumber, KEY_SIZE}; +use sha2::digest::Mac; +use tw_hash::hmac::HmacSha512; +use tw_keypair::tw::Curve; +use tw_misc::traits::{FromSlice, ToBytesVec, ToBytesZeroizing}; +use zeroize::Zeroizing; + +use crate::crypto_hd_node::error::Result; +use crate::crypto_hd_node::extended_key::bip32_public_key::BIP32PublicKey; + +/// Trait for key types which can be derived using BIP32. +pub trait BIP32PrivateKey: Sized + Clone + ToBytesZeroizing + FromSlice + FromStr { + /// Public key type which corresponds to this private key. + type BIP32PublicKey: BIP32PublicKey; + + /// Derive a child key from a parent key and the a provided tweak value, + /// i.e. where `other` is referred to as "I sub L" in BIP32 and sourced + /// from the left half of the HMAC-SHA-512 output. + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result; + + /// Get the curve of the private key. + fn curve() -> Curve; + + /// Get the BIP32 name of the curve. + fn bip32_name() -> &'static str; + + /// Get the [`Self::PublicKey`] that corresponds to this private key. + fn public_key(&self) -> Self::BIP32PublicKey; + + /// Derive a tweak value that can be used to generate the child key (see [`derive_child`]). + /// + /// The `chain_code` is either a newly initialized one, + /// or one obtained from the previous invocation of `derive_tweak()` + /// (for a multi-level derivation). + /// + /// **Warning:** make sure that if you are creating a new `chain_code`, you are doing so + /// in a cryptographically safe way. + /// Normally this would be done according to BIP-39 (within [`ExtendedPrivateKey::new`]). + fn derive_tweak( + &self, + chain_code: &ChainCode, + child_number: ChildNumber, + ) -> Result<(Zeroizing>, ChainCode)> { + let mut hmac = HmacSha512::new_from_slice(chain_code).expect("Should not fail"); + + if child_number.is_hardened() { + hmac.update(&[0]); + hmac.update(&self.to_zeroizing_vec()); + } else { + hmac.update(&self.public_key().to_vec()); + } + + hmac.update(&child_number.to_bytes()); + + let result = hmac.finalize().into_bytes(); + let (tweak_bytes, chain_code_bytes) = result.split_at(KEY_SIZE); + + let chain_code = chain_code_bytes.try_into()?; + + Ok((Zeroizing::new(tweak_bytes.to_vec()), chain_code)) + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_public_key.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_public_key.rs new file mode 100644 index 00000000000..7bf04731048 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/bip32_public_key.rs @@ -0,0 +1,61 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::{ChainCode, ChildNumber, KeyFingerprint, KEY_SIZE}; +use sha2::digest::Mac; +use tw_hash::hasher::{Hasher, StatefulHasher}; +use tw_hash::hmac::HmacSha512; +use tw_misc::traits::{FromSlice, ToBytesVec}; + +use crate::crypto_hd_node::error::{Error, Result}; + +/// Trait for key types which can be derived using BIP32. +pub trait BIP32PublicKey: Sized + Clone + ToBytesVec + FromSlice { + /// Compute a 4-byte key fingerprint for this public key. + /// + /// Default implementation uses `RIPEMD160(SHA256(public_key))`. + fn fingerprint(&self, hasher: Hasher) -> KeyFingerprint { + let digest = hasher.hash(self.to_vec().as_slice()); + digest[..4].try_into().expect("digest truncated") + } + + /// Derive a child key from a parent key and a provided tweak value. + fn derive_child(&self, other: &[u8], child_number: ChildNumber) -> Result; + + /// Derive a tweak value that can be used to generate the child key (see [`derive_child`]). + /// + /// The `chain_code` is either a newly initialized one, + /// or one obtained from the previous invocation of `derive_tweak()` + /// (for a multi-level derivation). + /// + /// **Warning:** make sure that if you are creating a new `chain_code`, you are doing so + /// in a cryptographically safe way. + /// Normally this would be done according to BIP-39 (within [`ExtendedPrivateKey::new`]). + /// + /// **Note:** `child_number` cannot be a hardened one (will result in an error). + fn derive_tweak( + &self, + chain_code: &ChainCode, + child_number: ChildNumber, + ) -> Result<(Vec, ChainCode)> { + if child_number.is_hardened() { + // Cannot derive child public keys for hardened `ChildNumber`s + return Err(Error::InvalidChildNumber); + } + + let mut hmac = HmacSha512::new_from_slice(chain_code).expect("Should not fail"); + + hmac.update(&self.to_vec()); + hmac.update(&child_number.to_bytes()); + + let result = hmac.finalize().into_bytes(); + let (tweak_bytes, chain_code_bytes) = result.split_at(KEY_SIZE); + + let chain_code = chain_code_bytes.try_into()?; + + Ok((tweak_bytes.to_vec(), chain_code)) + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_private_key.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_private_key.rs new file mode 100644 index 00000000000..7ff92d0decf --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_private_key.rs @@ -0,0 +1,304 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::{ + ChildNumber, DerivationPath, ExtendedKey, ExtendedKeyAttrs, KeyFingerprint, Prefix, Version, + KEY_SIZE, +}; +use sha2::digest::Mac; +use tw_encoding::hex::{self, ToHex}; +use tw_hash::hasher::Hasher; +use tw_hash::hasher::StatefulHasher; +use tw_hash::hmac::HmacSha512; +use tw_keypair::tw::Curve; +use tw_misc::traits::ToBytesZeroizing; +use zeroize::Zeroize; +use zeroize::Zeroizing; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, extended_public_key::ExtendedPublicKey, +}; + +use super::hd_version::HDVersion; + +/// Extended private keys derived using BIP32. +/// +/// Generic around a [`PrivateKey`] type. When the `secp256k1` feature of this +/// crate is enabled, the [`XPrv`] type provides a convenient alias for +/// extended ECDSA/secp256k1 private keys. +#[derive(Clone)] +pub struct ExtendedPrivateKey { + /// Derived private key + private_key: K, + + /// Extended key attributes. + attrs: ExtendedKeyAttrs, +} + +impl ExtendedPrivateKey +where + K: BIP32PrivateKey, +{ + /// Create the root extended key for the given seed value. + pub fn new(seed: S) -> Result + where + S: AsRef<[u8]>, + { + let (private_key, chain_code) = if K::curve() == Curve::Ed25519ExtendedCardano { + let mut digest = [0u8; 128]; + pbkdf2::pbkdf2_hmac::(&[], seed.as_ref(), 4096, &mut digest); + + let secret = &mut digest[0..96]; + secret[0] &= 0xf8; + secret[31] &= 0x1f; + secret[31] |= 0x40; + + ( + K::try_from(&digest[0..96]).map_err(|_| Error::InvalidKeyData)?, + digest[64..96].try_into()?, + ) + } else { + let domain_separator = hex::decode(&K::bip32_name().to_hex())?; + + let mut hmac = HmacSha512::new_from_slice(&domain_separator).expect("Should not fail"); + hmac.update(seed.as_ref()); + + let result = hmac.finalize().into_bytes(); + let (private_key, chain_code) = result.split_at(KEY_SIZE); + ( + K::try_from(private_key).map_err(|_| Error::InvalidKeyData)?, + chain_code.try_into()?, + ) + }; + + let attrs = ExtendedKeyAttrs { + depth: 0, + parent_fingerprint: KeyFingerprint::default(), + child_number: ChildNumber::default(), + chain_code, + }; + + Ok(ExtendedPrivateKey { private_key, attrs }) + } + + /// Derive a child key from the given [`DerivationPath`]. + pub fn derive_from_path(&self, path: &DerivationPath, hasher: Hasher) -> Result { + path.iter().try_fold(self.clone(), |key, child_num| { + key.derive_child(child_num, hasher) + }) + } + + /// Derive a child key for a particular [`ChildNumber`]. + pub fn derive_child(&self, child_number: ChildNumber, hasher: Hasher) -> Result { + let depth = self.attrs.depth.checked_add(1).ok_or(Error::InvalidDepth)?; + let (tweak, chain_code) = self + .private_key + .derive_tweak(&self.attrs.chain_code, child_number)?; + + // We should technically loop here if the tweak is zero or overflows + // the order of the underlying elliptic curve group, incrementing the + // index, however per "Child key derivation (CKD) functions": + // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions + // + // > "Note: this has probability lower than 1 in 2^127." + // + // ...so instead, we simply return an error if this were ever to happen, + // as the chances of it happening are vanishingly small. + let private_key = self.private_key.derive_child(&tweak, child_number)?; + + let attrs = ExtendedKeyAttrs { + parent_fingerprint: self.public_key().fingerprint(hasher), + child_number, + chain_code, + depth, + }; + + Ok(ExtendedPrivateKey { private_key, attrs }) + } + + /// Borrow the derived private key value. + pub fn private_key(&self) -> &K { + &self.private_key + } + + /// Serialize the derived public key as bytes. + pub fn public_key(&self) -> ExtendedPublicKey { + self.into() + } + + /// Get attributes for this key such as depth, parent fingerprint, + /// child number, and chain code. + pub fn attrs(&self) -> &ExtendedKeyAttrs { + &self.attrs + } + + /// Serialize this key as an [`ExtendedKey`]. + pub fn to_extended_key(&self, prefix: Prefix) -> Result { + if K::curve() == Curve::Ed25519ExtendedCardano { + return Err(Error::UnsupportedCurve(K::curve().to_raw())); + } + // Add leading `0` byte + let mut key_bytes = [0u8; KEY_SIZE + 1]; + key_bytes[1..].copy_from_slice(&self.private_key.to_zeroizing_vec()); + + Ok(ExtendedKey { + prefix, + attrs: self.attrs.clone(), + key_bytes, + }) + } + + /// Serialize this key as a self-[`Zeroizing`] `String`. + pub fn to_string(&self, prefix: Prefix) -> Result> { + Ok(Zeroizing::new(self.to_extended_key(prefix)?.to_string())) + } + + pub fn from_base58(xprv: &str, hasher: Hasher) -> Result { + let extended_key = decode_base58(xprv, hasher)?; + extended_key.try_into() + } +} + +impl TryFrom for ExtendedPrivateKey +where + K: BIP32PrivateKey, +{ + type Error = Error; + + fn try_from(key: ExtendedKey) -> Result { + let version = HDVersion::from_repr(key.prefix.version()).ok_or(Error::InvalidKeyData)?; + if version.is_private() && key.key_bytes[0] == 0 { + Ok(ExtendedPrivateKey { + private_key: K::try_from(&key.key_bytes[1..]).map_err(|_| Error::InvalidKeyData)?, + attrs: key.attrs.clone(), + }) + } else { + Err(Error::InvalidKeyData) + } + } +} + +impl ToBytesZeroizing for ExtendedPrivateKey +where + K: BIP32PrivateKey, +{ + fn to_zeroizing_vec(&self) -> Zeroizing> { + self.private_key.to_zeroizing_vec() + } +} + +/// Size of an extended key when deserialized into bytes from Base58. +const BYTE_SIZE: usize = 78; + +/// Size of the checksum in a Base58Check-encoded extended key. +const CHECKSUM_LEN: usize = 4; + +/// Maximum size of a Base58Check-encoded extended key in bytes. +/// +/// Note that extended keys can also be 111-bytes. +const MAX_BASE58_SIZE: usize = 112; + +/// Write a Base58-encoded key to the provided buffer, returning a `String` +/// containing the serialized data. +pub fn encode_base58(extended_key: &ExtendedKey, hasher: Hasher) -> Result { + let mut buffer = [0u8; MAX_BASE58_SIZE]; + + let mut bytes = [0u8; BYTE_SIZE]; // with 4-byte checksum + bytes[..4].copy_from_slice(&extended_key.prefix.to_bytes()); + bytes[4] = extended_key.attrs.depth; + bytes[5..9].copy_from_slice(&extended_key.attrs.parent_fingerprint); + bytes[9..13].copy_from_slice(&extended_key.attrs.child_number.to_bytes()); + bytes[13..45].copy_from_slice(&extended_key.attrs.chain_code); + bytes[45..78].copy_from_slice(&extended_key.key_bytes); + + let checksum = hasher.hash(&bytes); + + let mut bytes_with_checksum = [0u8; BYTE_SIZE + CHECKSUM_LEN]; + bytes_with_checksum[..BYTE_SIZE].copy_from_slice(&bytes); + bytes_with_checksum[78..].copy_from_slice(&checksum[..CHECKSUM_LEN]); + bytes.zeroize(); + + let base58_len = bs58::encode(&bytes_with_checksum).onto(buffer.as_mut())?; + bytes_with_checksum.zeroize(); + + String::from_utf8(buffer[..base58_len].to_vec()).map_err(|_| Error::Base58) +} + +pub fn decode_base58(base58: &str, hasher: Hasher) -> Result { + let mut bytes = [0u8; BYTE_SIZE + CHECKSUM_LEN]; // with 4-byte checksum + let decoded_len = bs58::decode(base58).onto(&mut bytes)?; + + if decoded_len != BYTE_SIZE + CHECKSUM_LEN { + return Err(Error::Decode); + } + + let checksum_index = decoded_len - CHECKSUM_LEN; + + let expected_checksum = &bytes[checksum_index..decoded_len]; + + let hash = hasher.hash(&bytes[0..checksum_index]); + let (checksum, _) = hash.split_at(CHECKSUM_LEN); + + if checksum != expected_checksum { + return Err(Error::InvalidChecksum); + } + + let prefix = base58.get(..4).ok_or(Error::Decode).and_then(|chars| { + validate_prefix(chars)?; + let version = Version::from_be_bytes(bytes[..4].try_into()?); + Ok(Prefix::from_parts_unchecked(chars, version)) + })?; + + let depth = bytes[4]; + let parent_fingerprint = bytes[5..9].try_into()?; + let child_number = ChildNumber::from_bytes(bytes[9..13].try_into()?); + let chain_code = bytes[13..45].try_into()?; + let key_bytes = bytes[45..78].try_into()?; + bytes.zeroize(); + + let attrs = ExtendedKeyAttrs { + depth, + parent_fingerprint, + child_number, + chain_code, + }; + + Ok(ExtendedKey { + prefix, + attrs, + key_bytes, + }) +} + +const fn validate_prefix(s: &str) -> Result<&str> { + if s.len() != Prefix::LENGTH { + return Err(Error::Decode); + } + + let mut i = 0; + + while i < Prefix::LENGTH { + if s.as_bytes()[i].is_ascii_alphabetic() { + i += 1; + } else { + return Err(Error::Decode); + } + } + + Ok(s) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_validate_prefix() { + assert!(validate_prefix("eaab").is_ok()); + assert!(validate_prefix("eaab1").is_err()); + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_public_key.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_public_key.rs new file mode 100644 index 00000000000..dde1a40accb --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/extended_public_key.rs @@ -0,0 +1,151 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::{ + ChildNumber, DerivationPath, ExtendedKey, ExtendedKeyAttrs, KeyFingerprint, Prefix, KEY_SIZE, +}; +use tw_misc::traits::ToBytesVec; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, + extended_private_key::ExtendedPrivateKey, +}; + +use super::{extended_private_key::decode_base58, hd_version::HDVersion}; +use tw_hash::hasher::Hasher; + +/// Extended public keys derived using BIP32. +/// +/// Generic around a [`PublicKey`] type. When the `secp256k1` feature of this +/// crate is enabled, the [`XPub`] type provides a convenient alias for +/// extended ECDSA/secp256k1 public keys. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct ExtendedPublicKey { + /// Derived public key + public_key: K, + + /// Extended key attributes. + attrs: ExtendedKeyAttrs, +} + +impl ExtendedPublicKey +where + K: BIP32PublicKey, +{ + /// Obtain the non-extended public key value `K`. + pub fn public_key(&self) -> &K { + &self.public_key + } + + /// Compute a 4-byte key fingerprint for this extended public key. + pub fn fingerprint(&self, hasher: Hasher) -> KeyFingerprint { + self.public_key().fingerprint(hasher) + } + + /// Serialize the raw public key as a byte array (e.g. SEC1-encoded). + pub fn to_bytes(&self) -> Vec { + self.public_key.to_vec() + } + + /// Serialize this key as an [`ExtendedKey`]. + pub fn to_extended_key(&self, prefix: Prefix) -> ExtendedKey { + let bytes = self.to_bytes(); + + let mut key_bytes = [0u8; KEY_SIZE + 1]; + if bytes.len() == KEY_SIZE { + // Add leading `0` byte + key_bytes[1..].copy_from_slice(&self.to_bytes()); + } else { + key_bytes.copy_from_slice(&self.to_bytes()); + } + + ExtendedKey { + prefix, + attrs: self.attrs.clone(), + key_bytes, + } + } + + pub fn derive_from_path(&self, path: &DerivationPath, hasher: Hasher) -> Result { + path.iter().try_fold(self.clone(), |key, child_num| { + key.derive_child(child_num, hasher) + }) + } + + /// Derive a child key for a particular [`ChildNumber`]. + pub fn derive_child(&self, child_number: ChildNumber, hasher: Hasher) -> Result { + let depth = self.attrs.depth.checked_add(1).ok_or(Error::InvalidDepth)?; + let (tweak, chain_code) = self + .public_key + .derive_tweak(&self.attrs.chain_code, child_number)?; + + // We should technically loop here if the tweak is zero or overflows + // the order of the underlying elliptic curve group, incrementing the + // index, however per "Child key derivation (CKD) functions": + // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions + // + // > "Note: this has probability lower than 1 in 2^127." + // + // ...so instead, we simply return an error if this were ever to happen, + // as the chances of it happening are vanishingly small. + let public_key = self.public_key.derive_child(&tweak, child_number)?; + + let attrs = ExtendedKeyAttrs { + parent_fingerprint: self.public_key.fingerprint(hasher), + child_number, + chain_code, + depth, + }; + + Ok(ExtendedPublicKey { public_key, attrs }) + } + + pub fn from_base58(xpub: &str, hasher: Hasher) -> Result { + let extended_key = decode_base58(xpub, hasher)?; + extended_key.try_into() + } +} + +impl From<&ExtendedPrivateKey> for ExtendedPublicKey +where + K: BIP32PrivateKey, +{ + fn from(xprv: &ExtendedPrivateKey) -> ExtendedPublicKey { + ExtendedPublicKey { + public_key: xprv.private_key().public_key(), + attrs: xprv.attrs().clone(), + } + } +} + +impl TryFrom for ExtendedPublicKey +where + K: BIP32PublicKey, +{ + type Error = Error; + + fn try_from(key: ExtendedKey) -> Result { + let version = HDVersion::from_repr(key.prefix.version()).ok_or(Error::InvalidKeyData)?; + if version.is_public() { + Ok(ExtendedPublicKey { + public_key: K::try_from(&key.key_bytes).map_err(|_| Error::InvalidKeyData)?, + attrs: key.attrs.clone(), + }) + } else { + Err(Error::InvalidKeyData) + } + } +} + +impl ToBytesVec for ExtendedPublicKey +where + K: BIP32PublicKey, +{ + fn to_vec(&self) -> Vec { + self.public_key.to_vec() + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/hd_version.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/hd_version.rs new file mode 100644 index 00000000000..15ebde44c50 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/hd_version.rs @@ -0,0 +1,67 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#[repr(u32)] +#[derive(strum_macros::FromRepr)] +pub enum HDVersion { + None = 0, + + // Bitcoin + XPUB = 0x0488b21e, + XPRV = 0x0488ade4, + YPUB = 0x049d7cb2, + YPRV = 0x049d7878, + ZPUB = 0x04b24746, + ZPRV = 0x04b2430c, + VPUB = 0x045f1cf6, + VPRV = 0x045f18bc, + TPUB = 0x043587cf, + TPRV = 0x04358394, + + // Litecoin + LTUB = 0x019da462, + LTPV = 0x019d9cfe, + MTUB = 0x01b26ef6, + MTPV = 0x01b26792, + TTUB = 0x0436f6e1, + TTPV = 0x0436ef7d, + + // Decred + DPUB = 0x2fda926, + DPRV = 0x2fda4e8, + + // Dogecoin + DGUB = 0x02facafd, + DGPV = 0x02fac398, +} + +impl HDVersion { + pub fn is_public(&self) -> bool { + matches!( + self, + HDVersion::XPUB + | HDVersion::YPUB + | HDVersion::ZPUB + | HDVersion::LTUB + | HDVersion::MTUB + | HDVersion::DPUB + | HDVersion::DGUB + ) + } + + pub fn is_private(&self) -> bool { + matches!( + self, + HDVersion::XPRV + | HDVersion::YPRV + | HDVersion::ZPRV + | HDVersion::LTPV + | HDVersion::MTPV + | HDVersion::DPRV + | HDVersion::DGPV + ) + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/extended_key/mod.rs b/rust/tw_crypto/src/crypto_hd_node/extended_key/mod.rs new file mode 100644 index 00000000000..fbd87b529d7 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/extended_key/mod.rs @@ -0,0 +1,11 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod bip32_private_key; +pub mod bip32_public_key; +pub mod extended_private_key; +pub mod extended_public_key; +pub mod hd_version; diff --git a/rust/tw_crypto/src/crypto_hd_node/hd_node.rs b/rust/tw_crypto/src/crypto_hd_node/hd_node.rs new file mode 100644 index 00000000000..d8624e56353 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/hd_node.rs @@ -0,0 +1,234 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use std::str::FromStr; + +use bip32::{DerivationPath, Prefix}; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_misc::traits::{ToBytesVec, ToBytesZeroizing}; +use zeroize::Zeroizing; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::extended_private_key::ExtendedPrivateKey; + +use super::ed25519::cardano::cardano_staking_derivation_path; +use super::extended_key::extended_private_key::encode_base58; + +pub type XPrvSecp256k1 = ExtendedPrivateKey; +pub type XPrvNist256p1 = ExtendedPrivateKey; +pub type XPrvEd25519 = ExtendedPrivateKey; +pub type XPrvEd25519Blake2bNano = ExtendedPrivateKey; +pub type XPrvCurve25519Waves = ExtendedPrivateKey; +pub type XPrvCardano = ExtendedPrivateKey; +pub type XPrvZilliqaSchnorr = ExtendedPrivateKey; + +pub enum HDNode { + Secp256k1(XPrvSecp256k1), + Nist256p1(XPrvNist256p1), + Ed25519(XPrvEd25519), + Ed25519Blake2bNano(XPrvEd25519Blake2bNano), + Curve25519Waves(XPrvCurve25519Waves), + Ed25519ExtendedCardano(Box, Option>), + ZilliqaSchnorr(XPrvZilliqaSchnorr), +} + +impl HDNode { + pub fn new(seed: &[u8], curve: Curve) -> Result { + match curve { + Curve::Secp256k1 => { + let xprv = XPrvSecp256k1::new(seed)?; + Ok(HDNode::Secp256k1(xprv)) + }, + Curve::Nist256p1 => { + let xprv = XPrvNist256p1::new(seed)?; + Ok(HDNode::Nist256p1(xprv)) + }, + Curve::Ed25519 => { + let xprv = XPrvEd25519::new(seed)?; + Ok(HDNode::Ed25519(xprv)) + }, + Curve::Ed25519Blake2bNano => { + let xprv = XPrvEd25519Blake2bNano::new(seed)?; + Ok(HDNode::Ed25519Blake2bNano(xprv)) + }, + Curve::Curve25519Waves => { + let xprv = XPrvCurve25519Waves::new(seed)?; + Ok(HDNode::Curve25519Waves(xprv)) + }, + Curve::Ed25519ExtendedCardano => { + let xprv = XPrvCardano::new(seed)?; + Ok(HDNode::Ed25519ExtendedCardano(Box::new(xprv), None)) + }, + Curve::ZilliqaSchnorr => { + let xprv = XPrvZilliqaSchnorr::new(seed)?; + Ok(HDNode::ZilliqaSchnorr(xprv)) + }, + _ => Err(Error::UnsupportedCurve(curve.to_raw())), + } + } + + pub fn derive_from_path(&self, path: &str, hasher: Hasher) -> Result { + let path = DerivationPath::from_str(path)?; + match self { + HDNode::Secp256k1(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::Secp256k1(xprv)) + }, + HDNode::Nist256p1(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::Nist256p1(xprv)) + }, + HDNode::Ed25519(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::Ed25519(xprv)) + }, + HDNode::Ed25519Blake2bNano(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::Ed25519Blake2bNano(xprv)) + }, + HDNode::Curve25519Waves(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::Curve25519Waves(xprv)) + }, + HDNode::Ed25519ExtendedCardano(xprv, _) => { + let xprv1 = xprv.derive_from_path(&path, hasher)?; + let staking_path = cardano_staking_derivation_path(&path)?; + let xprv2 = xprv.derive_from_path(&staking_path, hasher)?; + Ok(HDNode::Ed25519ExtendedCardano( + Box::new(xprv1), + Some(Box::new(xprv2)), + )) + }, + HDNode::ZilliqaSchnorr(xprv) => { + let xprv = xprv.derive_from_path(&path, hasher)?; + Ok(HDNode::ZilliqaSchnorr(xprv)) + }, + } + } + + pub fn private_key_data(&self) -> Result>> { + match self { + HDNode::Secp256k1(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + HDNode::Nist256p1(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + HDNode::Ed25519(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + HDNode::Ed25519Blake2bNano(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + HDNode::Curve25519Waves(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + HDNode::Ed25519ExtendedCardano(xprv, xprv2) => { + let mut data = xprv.private_key().to_zeroizing_vec(); + if let Some(xprv2) = xprv2 { + data.extend(xprv2.private_key().to_zeroizing_vec().as_slice()); + } + Ok(data) + }, + HDNode::ZilliqaSchnorr(xprv) => Ok(xprv.private_key().to_zeroizing_vec()), + } + } + + pub fn public_key_data(&self) -> Result> { + match self { + HDNode::Secp256k1(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + HDNode::Nist256p1(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + HDNode::Ed25519(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + HDNode::Ed25519Blake2bNano(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + HDNode::Curve25519Waves(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + HDNode::Ed25519ExtendedCardano(xprv, xprv2) => { + let mut data = xprv.public_key().to_bytes().to_vec(); + if let Some(xprv2) = xprv2 { + data.extend(xprv2.public_key().to_bytes().to_vec()); + } + Ok(data) + }, + HDNode::ZilliqaSchnorr(xprv) => Ok(xprv.public_key().to_bytes().to_vec()), + } + } + + pub fn chain_code(&self) -> Result> { + match self { + HDNode::Secp256k1(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::Nist256p1(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::Ed25519(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::Ed25519Blake2bNano(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::Curve25519Waves(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::Ed25519ExtendedCardano(xprv, _) => Ok(xprv.attrs().chain_code.to_vec()), + HDNode::ZilliqaSchnorr(xprv) => Ok(xprv.attrs().chain_code.to_vec()), + } + } + + pub fn depth(&self) -> Result { + match self { + HDNode::Secp256k1(xprv) => Ok(xprv.attrs().depth), + HDNode::Nist256p1(xprv) => Ok(xprv.attrs().depth), + HDNode::Ed25519(xprv) => Ok(xprv.attrs().depth), + HDNode::Ed25519Blake2bNano(xprv) => Ok(xprv.attrs().depth), + HDNode::Curve25519Waves(xprv) => Ok(xprv.attrs().depth), + HDNode::Ed25519ExtendedCardano(xprv, _) => Ok(xprv.attrs().depth), + HDNode::ZilliqaSchnorr(xprv) => Ok(xprv.attrs().depth), + } + } + + pub fn child_number(&self) -> Result { + match self { + HDNode::Secp256k1(xprv) => Ok(xprv.attrs().child_number.0), + HDNode::Nist256p1(xprv) => Ok(xprv.attrs().child_number.0), + HDNode::Ed25519(xprv) => Ok(xprv.attrs().child_number.0), + HDNode::Ed25519Blake2bNano(xprv) => Ok(xprv.attrs().child_number.0), + HDNode::Curve25519Waves(xprv) => Ok(xprv.attrs().child_number.0), + HDNode::Ed25519ExtendedCardano(xprv, _) => Ok(xprv.attrs().child_number.0), + HDNode::ZilliqaSchnorr(xprv) => Ok(xprv.attrs().child_number.0), + } + } + + pub fn extended_private_key(&self, version: u32, hasher: Hasher) -> Result { + let prefix = Prefix::try_from(version)?; + let extended_key = match self { + HDNode::Secp256k1(xprv) => xprv.to_extended_key(prefix)?, + HDNode::Nist256p1(xprv) => xprv.to_extended_key(prefix)?, + HDNode::Ed25519(xprv) => xprv.to_extended_key(prefix)?, + HDNode::Ed25519Blake2bNano(xprv) => xprv.to_extended_key(prefix)?, + HDNode::Curve25519Waves(xprv) => xprv.to_extended_key(prefix)?, + HDNode::Ed25519ExtendedCardano(xprv, _) => xprv.to_extended_key(prefix)?, + HDNode::ZilliqaSchnorr(xprv) => xprv.to_extended_key(prefix)?, + }; + encode_base58(&extended_key, hasher) + } + + pub fn extended_public_key(&self, version: u32, hasher: Hasher) -> Result { + let prefix = Prefix::try_from(version)?; + let extended_key = match self { + HDNode::Secp256k1(xprv) => xprv.public_key().to_extended_key(prefix), + HDNode::Nist256p1(xprv) => xprv.public_key().to_extended_key(prefix), + HDNode::Ed25519(xprv) => xprv.public_key().to_extended_key(prefix), + HDNode::Ed25519Blake2bNano(xprv) => xprv.public_key().to_extended_key(prefix), + HDNode::Curve25519Waves(xprv) => xprv.public_key().to_extended_key(prefix), + HDNode::Ed25519ExtendedCardano(xprv, _) => xprv.public_key().to_extended_key(prefix), + HDNode::ZilliqaSchnorr(xprv) => xprv.public_key().to_extended_key(prefix), + }; + encode_base58(&extended_key, hasher) + } + + pub fn try_from(s: &str, curve: Curve, hasher: Hasher) -> Result { + match curve { + Curve::Secp256k1 => Ok(HDNode::Secp256k1(XPrvSecp256k1::from_base58(s, hasher)?)), + Curve::Nist256p1 => Ok(HDNode::Nist256p1(XPrvNist256p1::from_base58(s, hasher)?)), + Curve::Ed25519 => Ok(HDNode::Ed25519(XPrvEd25519::from_base58(s, hasher)?)), + Curve::Ed25519Blake2bNano => Ok(HDNode::Ed25519Blake2bNano( + XPrvEd25519Blake2bNano::from_base58(s, hasher)?, + )), + Curve::Curve25519Waves => Ok(HDNode::Curve25519Waves( + XPrvCurve25519Waves::from_base58(s, hasher)?, + )), + Curve::Ed25519ExtendedCardano => Ok(HDNode::Ed25519ExtendedCardano( + Box::new(XPrvCardano::from_base58(s, hasher)?), + None, + )), + Curve::ZilliqaSchnorr => Ok(HDNode::ZilliqaSchnorr(XPrvZilliqaSchnorr::from_base58( + s, hasher, + )?)), + _ => Err(Error::UnsupportedCurve(curve.to_raw())), + } + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/hd_node_public.rs b/rust/tw_crypto/src/crypto_hd_node/hd_node_public.rs new file mode 100644 index 00000000000..717546f5080 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/hd_node_public.rs @@ -0,0 +1,122 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use std::str::FromStr; + +use bip32::DerivationPath; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_misc::traits::ToBytesVec; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::extended_public_key::ExtendedPublicKey; + +use super::ed25519::cardano::cardano_staking_derivation_path; + +pub type XPubSecp256k1 = ExtendedPublicKey; +pub type XPubNist256p1 = ExtendedPublicKey; +pub type XPubEd25519 = ExtendedPublicKey; +pub type XPubEd25519Blake2bNano = ExtendedPublicKey; +pub type XPubCurve25519Waves = ExtendedPublicKey; +pub type XPubCardano = ExtendedPublicKey; +pub type XPubZilliqaSchnorr = ExtendedPublicKey; + +pub enum HDNodePublic { + Secp256k1(XPubSecp256k1), + Nist256p1(XPubNist256p1), + Ed25519(XPubEd25519), + Ed25519Blake2bNano(XPubEd25519Blake2bNano), + Curve25519Waves(XPubCurve25519Waves), + Ed25519ExtendedCardano(Box, Option>), + ZilliqaSchnorr(XPubZilliqaSchnorr), +} + +impl HDNodePublic { + pub fn try_from(s: &str, curve: Curve, hasher: Hasher) -> Result { + match curve { + Curve::Secp256k1 => { + let xpub = XPubSecp256k1::from_base58(s, hasher)?; + Ok(HDNodePublic::Secp256k1(xpub)) + }, + Curve::Nist256p1 => { + let xpub = XPubNist256p1::from_base58(s, hasher)?; + Ok(HDNodePublic::Nist256p1(xpub)) + }, + Curve::Ed25519 => { + let xpub = XPubEd25519::from_base58(s, hasher)?; + Ok(HDNodePublic::Ed25519(xpub)) + }, + Curve::Ed25519Blake2bNano => { + let xpub = XPubEd25519Blake2bNano::from_base58(s, hasher)?; + Ok(HDNodePublic::Ed25519Blake2bNano(xpub)) + }, + Curve::Curve25519Waves => { + let xpub = XPubCurve25519Waves::from_base58(s, hasher)?; + Ok(HDNodePublic::Curve25519Waves(xpub)) + }, + Curve::Ed25519ExtendedCardano => { + let xpub = XPubCardano::from_base58(s, hasher)?; + Ok(HDNodePublic::Ed25519ExtendedCardano(Box::new(xpub), None)) + }, + Curve::ZilliqaSchnorr => { + let xpub = XPubZilliqaSchnorr::from_base58(s, hasher)?; + Ok(HDNodePublic::ZilliqaSchnorr(xpub)) + }, + _ => Err(Error::UnsupportedCurve(curve.to_raw())), + } + } + + pub fn derive_from_path(&self, path: &str, hasher: Hasher) -> Result { + let path = DerivationPath::from_str(path)?; + match self { + HDNodePublic::Secp256k1(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::Secp256k1(xpub)) + }, + HDNodePublic::Nist256p1(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::Nist256p1(xpub)) + }, + HDNodePublic::Ed25519(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::Ed25519(xpub)) + }, + HDNodePublic::Ed25519Blake2bNano(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::Ed25519Blake2bNano(xpub)) + }, + HDNodePublic::Curve25519Waves(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::Curve25519Waves(xpub)) + }, + HDNodePublic::Ed25519ExtendedCardano(xpub, _) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + let staking_path = cardano_staking_derivation_path(&path)?; + let xpub2 = xpub.derive_from_path(&staking_path, hasher)?; + Ok(HDNodePublic::Ed25519ExtendedCardano( + Box::new(xpub), + Some(Box::new(xpub2)), + )) + }, + HDNodePublic::ZilliqaSchnorr(xpub) => { + let xpub = xpub.derive_from_path(&path, hasher)?; + Ok(HDNodePublic::ZilliqaSchnorr(xpub)) + }, + } + } + + pub fn public_key_data(&self) -> Result> { + match self { + HDNodePublic::Secp256k1(xpub) => Ok(xpub.public_key().to_vec()), + HDNodePublic::Nist256p1(xpub) => Ok(xpub.public_key().to_vec()), + HDNodePublic::Ed25519(xpub) => Ok(xpub.public_key().to_vec()), + HDNodePublic::Ed25519Blake2bNano(xpub) => Ok(xpub.public_key().to_vec()), + HDNodePublic::Curve25519Waves(xpub) => Ok(xpub.public_key().to_vec()), + HDNodePublic::Ed25519ExtendedCardano(xpub, _) => Ok(xpub.public_key().to_vec()), + HDNodePublic::ZilliqaSchnorr(xpub) => Ok(xpub.public_key().to_vec()), + } + } +} diff --git a/rust/tw_crypto/src/crypto_hd_node/mod.rs b/rust/tw_crypto/src/crypto_hd_node/mod.rs new file mode 100644 index 00000000000..8435e7cfbd0 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/mod.rs @@ -0,0 +1,13 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod ecdsa; +pub mod ed25519; +pub mod error; +pub mod extended_key; +pub mod hd_node; +pub mod hd_node_public; +pub mod zilliqa_schnorr; diff --git a/rust/tw_crypto/src/crypto_hd_node/zilliqa_schnorr/mod.rs b/rust/tw_crypto/src/crypto_hd_node/zilliqa_schnorr/mod.rs new file mode 100644 index 00000000000..59df32c2698 --- /dev/null +++ b/rust/tw_crypto/src/crypto_hd_node/zilliqa_schnorr/mod.rs @@ -0,0 +1,45 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::ChildNumber; +use tw_hash::H256; +use tw_keypair::traits::DerivableKeyTrait; +use tw_keypair::{tw::Curve, zilliqa_schnorr}; + +use crate::crypto_hd_node::error::{Error, Result}; +use crate::crypto_hd_node::extended_key::{ + bip32_private_key::BIP32PrivateKey, bip32_public_key::BIP32PublicKey, +}; + +impl BIP32PrivateKey for zilliqa_schnorr::PrivateKey { + type BIP32PublicKey = zilliqa_schnorr::PublicKey; + + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } + + fn curve() -> Curve { + Curve::ZilliqaSchnorr + } + + fn bip32_name() -> &'static str { + "Bitcoin seed" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + self.public() + } +} + +impl BIP32PublicKey for zilliqa_schnorr::PublicKey { + fn derive_child(&self, other: &[u8], _child_number: ChildNumber) -> Result { + let other = H256::try_from(other).map_err(|_| Error::InvalidKeyData)?; + ::derive_child(self, other) + .map_err(|_| Error::DerivationFailed) + } +} diff --git a/rust/tw_crypto/src/crypto_mnemonic/mnemonic.rs b/rust/tw_crypto/src/crypto_mnemonic/mnemonic.rs new file mode 100644 index 00000000000..329faeac544 --- /dev/null +++ b/rust/tw_crypto/src/crypto_mnemonic/mnemonic.rs @@ -0,0 +1,107 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip39::{Error, Language, Mnemonic as Bip39Mnemonic}; +use std::fmt; + +const SUGGEST_MAX_COUNT: usize = 10; +const PBKDF2_ROUNDS: u32 = 2048; +const SEED_SIZE: usize = 64; + +pub struct Mnemonic { + mnemonic: Bip39Mnemonic, +} + +impl Mnemonic { + pub fn generate(strength: u32) -> Result { + if strength % 32 != 0 || !(128..=256).contains(&strength) { + return Err(Error::BadEntropyBitCount(strength as usize)); + } + + let length = strength / 8; + let mnemonic_length = length * 3 / 4; + + let mut rng = bip39::rand::thread_rng(); + let mnemonic = + Bip39Mnemonic::generate_in_with(&mut rng, Language::English, mnemonic_length as usize)?; + + Ok(Self { mnemonic }) + } + + pub fn generate_from_data(data: &[u8]) -> Result { + let mnemonic = Bip39Mnemonic::from_entropy(data)?; + Ok(Self { mnemonic }) + } + + pub fn parse(mnemonic: &str) -> Result { + if mnemonic.trim() != mnemonic || mnemonic.contains(" ") { + return Err(Error::InvalidChecksum); + } + let mnemonic = Bip39Mnemonic::parse_in(Language::English, mnemonic)?; + Ok(Self { mnemonic }) + } + + pub fn is_valid(mnemonic: &str) -> bool { + Self::parse(mnemonic).is_ok() + } + + pub fn is_valid_word(word: &str) -> bool { + let language = Language::English; + language.find_word(word).is_some() + } + + pub fn get_word(index: u32) -> Option { + let language = Language::English; + language + .word_list() + .get(index as usize) + .map(|w| w.to_string()) + } + + pub fn find_word(word: &str) -> Option { + let language = Language::English; + language.find_word(word).map(|index| index as u32) + } + + pub fn suggest(prefix: &str) -> String { + if prefix.is_empty() { + return "".to_string(); + } + let language = Language::English; + let prefix_string = prefix.to_lowercase(); + let words = language.words_by_prefix(&prefix_string); + let words_string = words + .iter() + .take(SUGGEST_MAX_COUNT) + .map(|w| w.to_string()) + .collect::>() + .join(" "); + words_string + } + + // Taken from https://github.com/iqlusioninc/crates/blob/95c6b87ce657dc51a0bd11159ef39c603a197f8d/bip32/src/mnemonic/phrase.rs#L134 + pub fn to_seed(mnemonic: &str, passphrase: &str) -> [u8; SEED_SIZE] { + let mut seed = [0u8; SEED_SIZE]; + let salt = zeroize::Zeroizing::new(format!("mnemonic{}", passphrase)); + pbkdf2::pbkdf2_hmac::( + mnemonic.as_bytes(), + salt.as_bytes(), + PBKDF2_ROUNDS, + &mut seed, + ); + seed + } + + pub fn to_entropy(&self) -> Vec { + self.mnemonic.to_entropy() + } +} + +impl fmt::Display for Mnemonic { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.mnemonic) + } +} diff --git a/rust/tw_crypto/src/crypto_mnemonic/mod.rs b/rust/tw_crypto/src/crypto_mnemonic/mod.rs new file mode 100644 index 00000000000..84cdb0d18dd --- /dev/null +++ b/rust/tw_crypto/src/crypto_mnemonic/mod.rs @@ -0,0 +1,7 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod mnemonic; diff --git a/rust/tw_crypto/src/crypto_pbkdf2/mod.rs b/rust/tw_crypto/src/crypto_pbkdf2/mod.rs new file mode 100644 index 00000000000..f18d85aa014 --- /dev/null +++ b/rust/tw_crypto/src/crypto_pbkdf2/mod.rs @@ -0,0 +1,30 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use pbkdf2::pbkdf2_hmac; +use sha2::{Sha256, Sha512}; + +pub fn pbkdf2_hmac_sha256( + password: &[u8], + salt: &[u8], + iterations: u32, + desired_len: usize, +) -> Vec { + let mut output = vec![0u8; desired_len]; + pbkdf2_hmac::(password, salt, iterations, &mut output); + output +} + +pub fn pbkdf2_hmac_512( + password: &[u8], + salt: &[u8], + iterations: u32, + desired_len: usize, +) -> Vec { + let mut output = vec![0u8; desired_len]; + pbkdf2_hmac::(password, salt, iterations, &mut output); + output +} diff --git a/rust/tw_crypto/src/crypto_scrypt/mod.rs b/rust/tw_crypto/src/crypto_scrypt/mod.rs new file mode 100644 index 00000000000..8e0b475d853 --- /dev/null +++ b/rust/tw_crypto/src/crypto_scrypt/mod.rs @@ -0,0 +1,42 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use crate::crypto_scrypt::params::{InvalidParams, Params}; +use pbkdf2::pbkdf2_hmac; +use sha2::Sha256; + +pub mod params; +mod romix; + +/// The scrypt key derivation function. +/// Original: https://github.com/RustCrypto/password-hashes/blob/a737bef1f992368f165face097d621bb1e76eba4/scrypt/src/lib.rs#L89 +/// +/// The only reason we should have rewritten the function is that it does unnecessary `log_n >= r * 16` check: +/// https://github.com/RustCrypto/password-hashes/blob/a737bef1f992368f165face097d621bb1e76eba4/scrypt/src/params.rs#L67-L72 +pub fn scrypt(password: &[u8], salt: &[u8], params: &Params) -> Result, InvalidParams> { + params.check_params()?; + + // The checks in the `Params::check_params` guarantee + // that the following is safe: + let n = params.n as usize; + let r128 = (params.r as usize) * 128; + let pr128 = (params.p as usize) * r128; + let nr128 = n * r128; + + let mut b = vec![0u8; pr128]; + pbkdf2_hmac::(password, salt, 1, &mut b); + + let mut v = vec![0u8; nr128]; + let mut t = vec![0u8; r128]; + + for chunk in &mut b.chunks_mut(r128) { + romix::scrypt_ro_mix(chunk, &mut v, &mut t, n); + } + + let mut output = vec![0u8; params.desired_len]; + pbkdf2_hmac::(password, &b, 1, &mut output); + Ok(output) +} diff --git a/rust/tw_crypto/src/crypto_scrypt/params.rs b/rust/tw_crypto/src/crypto_scrypt/params.rs new file mode 100644 index 00000000000..e4a76d43e3f --- /dev/null +++ b/rust/tw_crypto/src/crypto_scrypt/params.rs @@ -0,0 +1,94 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use std::mem::size_of; + +#[derive(Clone, Copy, Debug)] +pub struct InvalidParams; + +pub struct Params { + /// Scrypt parameter `N`: CPU/memory cost. + /// Must be a power of 2. + pub n: u32, + /// Scrypt parameter `r`: block size. + pub r: u32, + /// Scrypt parameter `p`: parallelism. + pub p: u32, + /// Scrypt parameter `Key length`. + pub desired_len: usize, +} + +impl Params { + /// Create a new instance of [`Params`]. + /// + /// # Conditions + /// - `log_n` must be less than `64` + /// - `r` must be greater than `0` and less than or equal to `4294967295` + /// - `p` must be greater than `0` and less than `4294967295` + /// - `desired_len` must be greater than `9` and less than or equal to `64` + /// + /// Original: https://github.com/RustCrypto/password-hashes/blob/a737bef1f992368f165face097d621bb1e76eba4/scrypt/src/params.rs#L44 + /// + /// The only reason we should have rewritten the function is that it does unnecessary `log_n >= r * 16` check: + /// https://github.com/RustCrypto/password-hashes/blob/a737bef1f992368f165face097d621bb1e76eba4/scrypt/src/params.rs#L67-L72 + pub fn check_params(&self) -> Result<(), InvalidParams> { + let log_n = self.try_log_n()?; + + let cond1 = (log_n as usize) < usize::BITS as usize; + let cond2 = size_of::() >= size_of::(); + let cond3 = self.r <= usize::MAX as u32 && self.p < usize::MAX as u32; + let cond4 = (10..=64).contains(&self.desired_len); + if !(self.r > 0 && self.p > 0 && cond1 && (cond2 || cond3) && cond4) { + return Err(InvalidParams); + } + + let r = self.r as usize; + let p = self.p as usize; + let n = self.n as usize; + + // check that r * 128 doesn't overflow + let r128 = r.checked_mul(128).ok_or(InvalidParams)?; + + // check that n * r * 128 doesn't overflow + r128.checked_mul(n).ok_or(InvalidParams)?; + + // check that p * r * 128 doesn't overflow + r128.checked_mul(p).ok_or(InvalidParams)?; + + // This check required by Scrypt: + // check: p <= ((2^32-1) * 32) / (128 * r) + // It takes a bit of re-arranging to get the check above into this form, + // but it is indeed the same. + if r * p >= 0x4000_0000 { + return Err(InvalidParams); + } + + // The following checks are copied from C++: + // https://github.com/trustwallet/wallet-core/blob/b530432921d7a9709428b0162673e0ab72de1c3d/src/Keystore/ScryptParameters.cpp#L27-L42 + + if (n & (n - 1)) != 0 || n < 2 { + // Invalid cost factor. + return Err(InvalidParams); + } + + let max_r = u32::MAX as usize / 128_usize / p; + let max_n = u32::MAX as usize / 128 / r; + if r > max_r || n > max_n { + return Err(InvalidParams); + } + + Ok(()) + } + + fn try_log_n(&self) -> Result { + let log_n = self.n.checked_ilog2().ok_or(InvalidParams)?; + // `Params::n` must be equal to 2^log_n. + if 1 << log_n != self.n { + return Err(InvalidParams); + } + log_n.try_into().map_err(|_| InvalidParams) + } +} diff --git a/rust/tw_crypto/src/crypto_scrypt/romix.rs b/rust/tw_crypto/src/crypto_scrypt/romix.rs new file mode 100644 index 00000000000..6eab91877bc --- /dev/null +++ b/rust/tw_crypto/src/crypto_scrypt/romix.rs @@ -0,0 +1,81 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +//! Original: https://github.com/RustCrypto/password-hashes/blob/master/scrypt/src/romix.rs +/// Execute the ROMix operation in-place. +/// b - the data to operate on +/// v - a temporary variable to store the vector V +/// t - a temporary variable to store the result of the xor +/// n - the scrypt parameter N +#[allow(clippy::many_single_char_names)] +pub(crate) fn scrypt_ro_mix(b: &mut [u8], v: &mut [u8], t: &mut [u8], n: usize) { + fn integerify(x: &[u8], n: usize) -> usize { + // n is a power of 2, so n - 1 gives us a bitmask that we can use to perform a calculation + // mod n using a simple bitwise and. + let mask = n - 1; + // This cast is safe since we're going to get the value mod n (which is a power of 2), so we + // don't have to care about truncating any of the high bits off + //let result = (LittleEndian::read_u32(&x[x.len() - 64..x.len() - 60]) as usize) & mask; + let t = u32::from_le_bytes(x[x.len() - 64..x.len() - 60].try_into().unwrap()); + (t as usize) & mask + } + + let len = b.len(); + + for chunk in v.chunks_mut(len) { + chunk.copy_from_slice(b); + scrypt_block_mix(chunk, b); + } + + for _ in 0..n { + let j = integerify(b, n); + xor(b, &v[j * len..(j + 1) * len], t); + scrypt_block_mix(t, b); + } +} + +/// Execute the BlockMix operation +/// input - the input vector. The length must be a multiple of 128. +/// output - the output vector. Must be the same length as input. +fn scrypt_block_mix(input: &[u8], output: &mut [u8]) { + use salsa20::{ + cipher::{typenum::U4, StreamCipherCore}, + SalsaCore, + }; + + type Salsa20_8 = SalsaCore; + + let mut x = [0u8; 64]; + x.copy_from_slice(&input[input.len() - 64..]); + + let mut t = [0u8; 64]; + + for (i, chunk) in input.chunks(64).enumerate() { + xor(&x, chunk, &mut t); + + let mut t2 = [0u32; 16]; + + for (c, b) in t.chunks_exact(4).zip(t2.iter_mut()) { + *b = u32::from_le_bytes(c.try_into().unwrap()); + } + + Salsa20_8::from_raw_state(t2).write_keystream_block((&mut x).into()); + + let pos = if i % 2 == 0 { + (i / 2) * 64 + } else { + (i / 2) * 64 + input.len() / 2 + }; + + output[pos..pos + 64].copy_from_slice(&x); + } +} + +fn xor(x: &[u8], y: &[u8], output: &mut [u8]) { + for ((out, &x_i), &y_i) in output.iter_mut().zip(x.iter()).zip(y.iter()) { + *out = x_i ^ y_i; + } +} diff --git a/rust/tw_crypto/src/ffi/crypto_aes_cbc.rs b/rust/tw_crypto/src/ffi/crypto_aes_cbc.rs new file mode 100644 index 00000000000..e0c0df6ce6e --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_aes_cbc.rs @@ -0,0 +1,187 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_aes_cbc::{ + aes_cbc_decrypt, aes_cbc_decrypt_128, aes_cbc_decrypt_192, aes_cbc_decrypt_256, + aes_cbc_encrypt, aes_cbc_encrypt_128, aes_cbc_encrypt_192, aes_cbc_encrypt_256, + padding::{PaddingMode, TWFFIAESPaddingMode}, +}; +use aes::cipher::StreamCipherError; +use tw_macros::tw_ffi; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; +use tw_misc::try_or_else; + +unsafe fn handle_aes_cbc_operation( + data: Nonnull, + iv: Nonnull, + key: Nonnull, + padding_mode: TWFFIAESPaddingMode, + operation: F, +) -> NullableMut +where + F: FnOnce(&[u8], &[u8], &[u8], PaddingMode) -> Result, StreamCipherError>, +{ + let padding_mode = try_or_else!(PaddingMode::try_from(padding_mode), std::ptr::null_mut); + let data = TWData::from_ptr_as_ref(data) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let iv = TWData::from_ptr_as_ref(iv) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let key = TWData::from_ptr_as_ref(key) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + operation(data, iv, key, padding_mode) + .map(|output| TWData::from(output).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Encrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 128-bit key. +/// +/// \param key encryption key Data, must be 16 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCBC128)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_cbc_128( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_encrypt_128) +} + +/// Decrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 128-bit key. +/// +/// \param key decryption key Data, must be 16 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCBC128)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_cbc_128( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_decrypt_128) +} + +/// Encrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 192-bit key. +/// +/// \param key encryption key Data, must be 24 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCBC192)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_cbc_192( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_encrypt_192) +} + +/// Decrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 192-bit key. +/// +/// \param key decryption key Data, must be 24 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCBC192)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_cbc_192( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_decrypt_192) +} + +/// Encrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 256-bit key. +/// +/// \param key encryption key Data, must be 32 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCBC256)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_cbc_256( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_encrypt_256) +} + +/// Decrypts a block of Data using AES in Cipher Block Chaining (CBC) mode with 256-bit key. +/// +/// \param key decryption key Data, must be 32 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCBC256)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_cbc_256( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_decrypt_256) +} + +/// Encrypts a block of Data using AES in Cipher Block Chaining (CBC) mode. +/// +/// \param key encryption key Data, must be 16, 24, or 32 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector. +/// \param mode padding mode. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCBC)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_cbc( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_encrypt) +} + +/// Decrypts a block of data using AES in Cipher Block Chaining (CBC) mode. +/// +/// \param key decryption key Data, must be 16, 24, or 32 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector Data. +/// \param mode padding mode. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCBC)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_cbc( + key: Nonnull, + data: Nonnull, + iv: Nonnull, + mode: TWFFIAESPaddingMode, +) -> NullableMut { + handle_aes_cbc_operation(data, iv, key, mode, aes_cbc_decrypt) +} diff --git a/rust/tw_crypto/src/ffi/crypto_aes_ctr.rs b/rust/tw_crypto/src/ffi/crypto_aes_ctr.rs new file mode 100644 index 00000000000..c7390c23a3b --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_aes_ctr.rs @@ -0,0 +1,167 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_aes_ctr::{ + aes_ctr_decrypt, aes_ctr_decrypt_128, aes_ctr_decrypt_192, aes_ctr_decrypt_256, + aes_ctr_encrypt, aes_ctr_encrypt_128, aes_ctr_encrypt_192, aes_ctr_encrypt_256, +}; +use aes::cipher::StreamCipherError; +use tw_macros::tw_ffi; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; + +unsafe fn handle_aes_ctr_operation( + data: Nonnull, + iv: Nonnull, + key: Nonnull, + operation: F, +) -> NullableMut +where + F: FnOnce(&[u8], &[u8], &[u8]) -> Result, StreamCipherError>, +{ + let data = TWData::from_ptr_as_ref(data) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let iv = TWData::from_ptr_as_ref(iv) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let key = TWData::from_ptr_as_ref(key) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + operation(data, iv, key) + .map(|output| TWData::from(output).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Encrypts a block of data using AES in Counter (CTR) mode with 128-bit key. +/// +/// \param key encryption key Data, must be 16 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector Data. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCTR128)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_ctr_128( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_encrypt_128) +} + +/// Decrypts a block of data using AES in Counter (CTR) mode with 128-bit key. +/// +/// \param key decryption key Data, must be 16 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector Data. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCTR128)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_ctr_128( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_decrypt_128) +} + +/// Encrypts a block of data using AES in Counter (CTR) mode with 192-bit key. +/// +/// \param key encryption key Data, must be 24 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector Data. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCTR192)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_ctr_192( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_encrypt_192) +} + +/// Decrypts a block of data using AES in Counter (CTR) mode with 192-bit key. +/// +/// \param key decryption key Data, must be 24 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector Data. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCTR192)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_ctr_192( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_decrypt_192) +} + +/// Encrypts a block of data using AES in Counter (CTR) mode with 256-bit key. +/// +/// \param key encryption key Data, must be 32 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector Data. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCTR256)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_ctr_256( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_encrypt_256) +} + +/// Decrypts a block of data using AES in Counter (CTR) mode with 256-bit key. +/// +/// \param key decryption key Data, must be 32 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector Data. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCTR256)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_ctr_256( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_decrypt_256) +} + +/// Encrypts a block of data using AES in Counter (CTR) mode. +/// +/// \param key encryption key Data, must be 16, 24, or 32 bytes long. +/// \param data Data to encrypt. +/// \param iv initialization vector Data. +/// \return encrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = EncryptCTR)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_encrypt_ctr( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_encrypt) +} + +/// Decrypts a block of data using AES in Counter (CTR) mode. +/// +/// \param key decryption key Data, must be 16, 24, or 32 bytes long. +/// \param data Data to decrypt. +/// \param iv initialization vector Data. +/// \return decrypted Data. +#[tw_ffi(ty = static_function, class = TWAES, name = DecryptCTR)] +#[no_mangle] +pub unsafe extern "C" fn tw_aes_decrypt_ctr( + key: Nonnull, + data: Nonnull, + iv: Nonnull, +) -> NullableMut { + handle_aes_ctr_operation(data, iv, key, aes_ctr_decrypt) +} diff --git a/rust/tw_crypto/src/ffi/crypto_hd_node.rs b/rust/tw_crypto/src/ffi/crypto_hd_node.rs new file mode 100644 index 00000000000..5518d632e55 --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_hd_node.rs @@ -0,0 +1,219 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_hd_node::hd_node::HDNode; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_macros::tw_ffi; +use tw_memory::ffi::{ + tw_data::TWData, tw_string::TWString, Nonnull, NonnullMut, NullableMut, RawPtrTrait, +}; +use tw_misc::try_or_else; + +pub struct TWHDNode(pub(crate) HDNode); + +impl RawPtrTrait for TWHDNode {} + +impl AsRef for TWHDNode { + fn as_ref(&self) -> &HDNode { + &self.0 + } +} + +/// Create a HDNode with the given seed and curve. +/// +/// \param seed *non-null* byte array. +/// \param curve the curve to use. +/// \note Should be deleted with \tw_hd_node_delete. +/// \return Nullable pointer to HDNode. +#[tw_ffi(ty = constructor, class = TWHDNode, name = CreateWithSeed)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_create_with_seed( + seed: Nonnull, + curve: u32, +) -> NullableMut { + let data = TWData::from_ptr_as_ref(seed) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let curve = try_or_else!(Curve::from_raw(curve), std::ptr::null_mut); + + HDNode::new(data, curve) + .map(|hd_node| TWHDNode(hd_node).into_ptr()) + // Return null if the private key is invalid. + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Create a HDNode from an extended private key. +/// +/// \param extended_private_key *non-null* string. +/// \param curve the curve to use. +/// \param hasher the hasher to use. +/// \return Nullable pointer to HDNode. +#[tw_ffi(ty = constructor, class = TWHDNode, name = CreateWithExtendedPrivateKey)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_create_with_extended_private_key( + extended_private_key: Nonnull, + curve: u32, + hasher: u32, +) -> NullableMut { + let extended_private_key_ref = try_or_else!( + TWString::from_ptr_as_ref(extended_private_key), + std::ptr::null_mut + ); + let extended_private_key_str = + try_or_else!(extended_private_key_ref.as_str(), std::ptr::null_mut); + let curve = try_or_else!(Curve::from_raw(curve), std::ptr::null_mut); + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + HDNode::try_from(extended_private_key_str, curve, hasher) + .map(|hd_node| TWHDNode(hd_node).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Delete the given HDNode. +/// +/// \param key *non-null* pointer to HDNode. +#[tw_ffi(ty = destructor, class = TWHDNode, name = Delete)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_delete(key: NonnullMut) { + // Take the ownership back to rust and drop the owner. + let _ = TWHDNode::from_ptr(key); +} + +/// Derive a child node from a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \param path the path to derive. +/// \return Nullable pointer to HDNode. +#[tw_ffi(ty = static_function, class = TWHDNode, name = DeriveFromPath)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_derive_from_path( + hd_node: Nonnull, + path: Nonnull, + hasher: u32, +) -> NullableMut { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + let path_ref = try_or_else!(TWString::from_ptr_as_ref(path), std::ptr::null_mut); + let path_str = try_or_else!(path_ref.as_str(), std::ptr::null_mut); + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + hd_node_ref + .0 + .derive_from_path(path_str, hasher) + .map(|hd_node| TWHDNode(hd_node).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the raw private-key data of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return byte array. +#[tw_ffi(ty = property, class = TWHDNode, name = PrivateKeyData)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_private_key_data( + hd_node: Nonnull, +) -> NonnullMut { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .private_key_data() + .map(|data| TWData::from(data.to_vec()).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the raw public-key data of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return byte array. +#[tw_ffi(ty = property, class = TWHDNode, name = PublicKeyData)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_public_key_data( + hd_node: Nonnull, +) -> NonnullMut { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .public_key_data() + .map(|data| TWData::from(data).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the chain code of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return byte array. +#[tw_ffi(ty = property, class = TWHDNode, name = ChainCode)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_chain_code(hd_node: Nonnull) -> NonnullMut { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .chain_code() + .map(|data| TWData::from(data).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the depth of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return depth. +#[tw_ffi(ty = property, class = TWHDNode, name = Depth)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_depth(hd_node: Nonnull) -> u8 { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), || 0); + hd_node_ref.0.depth().unwrap_or_default() +} + +/// Returns the child number of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return child number. +#[tw_ffi(ty = property, class = TWHDNode, name = ChildNumber)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_child_number(hd_node: Nonnull) -> u32 { + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), || 0); + hd_node_ref.0.child_number().unwrap_or_default() +} + +/// Returns the extended private key of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return extended private key. +#[tw_ffi(ty = static_function, class = TWHDNode, name = ExtendedPrivateKey)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_extended_private_key( + hd_node: Nonnull, + version: u32, + hasher: u32, +) -> NonnullMut { + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .extended_private_key(version, hasher) + .map(|key| TWString::from(key).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the extended public key of a given hd_node. +/// +/// \param hd_node *non-null* pointer to a hd_node. +/// \return extended public key. +#[tw_ffi(ty = static_function, class = TWHDNode, name = ExtendedPublicKey)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_extended_public_key( + hd_node: Nonnull, + version: u32, + hasher: u32, +) -> NonnullMut { + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + let hd_node_ref = try_or_else!(TWHDNode::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .extended_public_key(version, hasher) + .map(|key| TWString::from(key).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} diff --git a/rust/tw_crypto/src/ffi/crypto_hd_node_public.rs b/rust/tw_crypto/src/ffi/crypto_hd_node_public.rs new file mode 100644 index 00000000000..c161bf2212d --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_hd_node_public.rs @@ -0,0 +1,102 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_hd_node::hd_node_public::HDNodePublic; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_macros::tw_ffi; +use tw_memory::ffi::{ + tw_data::TWData, tw_string::TWString, Nonnull, NonnullMut, NullableMut, RawPtrTrait, +}; +use tw_misc::try_or_else; + +pub struct TWHDNodePublic(pub(crate) HDNodePublic); + +impl RawPtrTrait for TWHDNodePublic {} + +impl AsRef for TWHDNodePublic { + fn as_ref(&self) -> &HDNodePublic { + &self.0 + } +} + +/// Create a HDNodePublic from an extended public key. +/// +/// \param extended_public_key *non-null* string. +/// \param curve the curve to use. +/// \param hasher the hasher to use. +/// \return Nullable pointer to HDNodePublic. +#[tw_ffi(ty = constructor, class = TWHDNodePublic, name = CreateWithExtendedPublicKey)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_public_create_with_extended_public_key( + extended_public_key: Nonnull, + curve: u32, + hasher: u32, +) -> NullableMut { + let extended_public_key_ref = try_or_else!( + TWString::from_ptr_as_ref(extended_public_key), + std::ptr::null_mut + ); + let extended_public_key_str = + try_or_else!(extended_public_key_ref.as_str(), std::ptr::null_mut); + let curve = try_or_else!(Curve::from_raw(curve), std::ptr::null_mut); + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + HDNodePublic::try_from(extended_public_key_str, curve, hasher) + .map(|hd_node| TWHDNodePublic(hd_node).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Delete the given HDNode. +/// +/// \param key *non-null* pointer to HDNode. +#[tw_ffi(ty = destructor, class = TWHDNodePublic, name = Delete)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_public_delete(key: NonnullMut) { + // Take the ownership back to rust and drop the owner. + let _ = TWHDNodePublic::from_ptr(key); +} + +/// Derive a child key for a particular path. +/// +/// \param hd_node *non-null* pointer to HDNodePublic. +/// \param path *non-null* string. +/// \return Nullable pointer to HDNodePublic. +#[tw_ffi(ty = static_function, class = TWHDNodePublic, name = DeriveFromPath)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_public_derive_from_path( + hd_node: Nonnull, + path: Nonnull, + hasher: u32, +) -> NullableMut { + let hd_node_ref = try_or_else!(TWHDNodePublic::from_ptr_as_ref(hd_node), std::ptr::null_mut); + let path_ref = try_or_else!(TWString::from_ptr_as_ref(path), std::ptr::null_mut); + let path_str = try_or_else!(path_ref.as_str(), std::ptr::null_mut); + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + hd_node_ref + .0 + .derive_from_path(path_str, hasher) + .map(|hd_node| TWHDNodePublic(hd_node).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Get the public key data. +/// +/// \param hd_node *non-null* pointer to HDNodePublic. +/// \return *non-null* pointer to TWData. +#[tw_ffi(ty = property, class = TWHDNodePublic, name = PublicKeyData)] +#[no_mangle] +pub unsafe extern "C" fn tw_hd_node_public_public_key_data( + hd_node: Nonnull, +) -> NonnullMut { + let hd_node_ref = try_or_else!(TWHDNodePublic::from_ptr_as_ref(hd_node), std::ptr::null_mut); + hd_node_ref + .0 + .public_key_data() + .map(|data| TWData::from(data).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} diff --git a/rust/tw_crypto/src/ffi/crypto_mnemonic.rs b/rust/tw_crypto/src/ffi/crypto_mnemonic.rs new file mode 100644 index 00000000000..5a5ee41bab3 --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_mnemonic.rs @@ -0,0 +1,102 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_mnemonic::mnemonic::Mnemonic; +use tw_macros::tw_ffi; +use tw_memory::ffi::{ + tw_data::TWData, tw_string::TWString, Nonnull, NonnullMut, NullableMut, RawPtrTrait, +}; +use tw_misc::{try_or_else, try_or_false}; + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = Generate)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_generate(strength: u32) -> NullableMut { + let mnemonic = try_or_else!(Mnemonic::generate(strength), std::ptr::null_mut); + TWString::from(mnemonic.to_string()).into_ptr() +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = GenerateFromData)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_generate_from_data( + data: Nonnull, +) -> NullableMut { + let data = TWData::from_ptr_as_ref(data) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + let mnemonic = try_or_else!(Mnemonic::generate_from_data(data), std::ptr::null_mut); + TWString::from(mnemonic.to_string()).into_ptr() +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = IsValid)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_is_valid(mnemonic: Nonnull) -> bool { + let mnemonic_string = try_or_false!(TWString::from_ptr_as_ref(mnemonic)); + let mnemonic_string = try_or_false!(mnemonic_string.as_str()); + Mnemonic::is_valid(mnemonic_string) +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = IsValidWord)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_is_valid_word(word: Nonnull) -> bool { + let word_string = try_or_false!(TWString::from_ptr_as_ref(word)); + let word_string = try_or_false!(word_string.as_str()); + Mnemonic::is_valid_word(word_string) +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = GetWord)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_get_word(index: u32) -> NullableMut { + let word = try_or_else!(Mnemonic::get_word(index), std::ptr::null_mut); + TWString::from(word.to_string()).into_ptr() +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = FindWord)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_find_word(word: Nonnull) -> i32 { + let word_string = try_or_else!(TWString::from_ptr_as_ref(word), || -1); + let word_string = try_or_else!(word_string.as_str(), || -1); + let index = Mnemonic::find_word(word_string); + index.map(|index| index as i32).unwrap_or(-1) +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = Suggest)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_suggest(prefix: Nonnull) -> NonnullMut { + let prefix_string = try_or_else!(TWString::from_ptr_as_ref(prefix), std::ptr::null_mut); + let prefix_string = try_or_else!(prefix_string.as_str(), std::ptr::null_mut); + let words_string = Mnemonic::suggest(prefix_string); + TWString::from(words_string).into_ptr() +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = ToSeed)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_to_seed( + mnemonic: Nonnull, + passphrase: Nonnull, +) -> NullableMut { + let mnemonic_string = try_or_else!(TWString::from_ptr_as_ref(mnemonic), std::ptr::null_mut); + let mnemonic_string = try_or_else!(mnemonic_string.as_str(), std::ptr::null_mut); + let passphrase_string = try_or_else!(TWString::from_ptr_as_ref(passphrase), std::ptr::null_mut); + let passphrase_string = try_or_else!(passphrase_string.as_str(), std::ptr::null_mut); + let seed = Mnemonic::to_seed(mnemonic_string, passphrase_string); + TWData::from(seed.to_vec()).into_ptr() +} + +#[tw_ffi(ty = static_function, class = TWMnemonic, name = ToEntropy)] +#[no_mangle] +pub unsafe extern "C" fn tw_mnemonic_to_entropy( + mnemonic: Nonnull, +) -> NullableMut { + let mnemonic_string = try_or_else!(TWString::from_ptr_as_ref(mnemonic), std::ptr::null_mut); + let mnemonic_string = try_or_else!(mnemonic_string.as_str(), std::ptr::null_mut); + let mnemonic = try_or_else!(Mnemonic::parse(mnemonic_string), || TWData::from(vec![]) + .into_ptr()); + let entropy = mnemonic.to_entropy(); + TWData::from(entropy).into_ptr() +} diff --git a/rust/tw_crypto/src/ffi/crypto_pbkdf2.rs b/rust/tw_crypto/src/ffi/crypto_pbkdf2.rs new file mode 100644 index 00000000000..1d1fb8e7e18 --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_pbkdf2.rs @@ -0,0 +1,63 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_pbkdf2::{pbkdf2_hmac_512, pbkdf2_hmac_sha256}; +use tw_macros::tw_ffi; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; + +/// The PBKDF2 key derivation function. +/// +/// \param password data. +/// \param salt data. +/// \param iterations PBKDF2 parameter `iterations`. +/// \param dk_len PBKDF2 parameter `desired_len`. +/// \return *nullable* data. +#[tw_ffi(ty = static_function, class = TWPBKDF2, name = HmacSha256)] +#[no_mangle] +pub unsafe extern "C" fn tw_pbkdf2_hmac_sha256( + password: Nonnull, + salt: Nonnull, + iterations: u32, + dk_len: usize, +) -> NullableMut { + let password = TWData::from_ptr_as_ref(password) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let salt = TWData::from_ptr_as_ref(salt) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + let output = pbkdf2_hmac_sha256(password, salt, iterations, dk_len); + TWData::from(output).into_ptr() +} + +/// The PBKDF2 key derivation function. +/// +/// \param password data. +/// \param salt data. +/// \param iterations PBKDF2 parameter `iterations`. +/// \param dk_len PBKDF2 parameter `desired_len`. +/// \return *nullable* data. +#[tw_ffi(ty = static_function, class = TWPBKDF2, name = HmacSha512)] +#[no_mangle] +pub unsafe extern "C" fn tw_pbkdf2_hmac_sha512( + password: Nonnull, + salt: Nonnull, + iterations: u32, + dk_len: usize, +) -> NullableMut { + let password = TWData::from_ptr_as_ref(password) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let salt = TWData::from_ptr_as_ref(salt) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + let output = pbkdf2_hmac_512(password, salt, iterations, dk_len); + TWData::from(output).into_ptr() +} diff --git a/rust/tw_crypto/src/ffi/crypto_scrypt.rs b/rust/tw_crypto/src/ffi/crypto_scrypt.rs new file mode 100644 index 00000000000..295a0d60767 --- /dev/null +++ b/rust/tw_crypto/src/ffi/crypto_scrypt.rs @@ -0,0 +1,62 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +#![allow(clippy::missing_safety_doc)] + +use crate::crypto_scrypt::params::Params; +use crate::crypto_scrypt::scrypt; +use tw_macros::tw_ffi; +use tw_memory::ffi::c_result::ErrorCode; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; + +#[repr(C)] +pub enum ScryptError { + Ok = 0, + InvalidParams = 1, +} + +impl From for ErrorCode { + fn from(error: ScryptError) -> Self { + error as ErrorCode + } +} + +/// The scrypt key derivation function. +/// +/// \param password data. +/// \param salt data. +/// \param n scrypt parameter `N`: CPU/memory cost. +/// \param r scrypt parameter `r`: block size. +/// \param p scrypt parameter `p`: parallelism. +/// \param desired_len scrypt parameter `Key length`. +/// \return C-compatible byte array. +#[tw_ffi(ty = static_function, class = TWCrypto, name = Scrypt)] +#[no_mangle] +pub unsafe extern "C" fn crypto_scrypt( + password: Nonnull, + salt: Nonnull, + n: u32, + r: u32, + p: u32, + desired_len: usize, +) -> NullableMut { + let password = TWData::from_ptr_as_ref(password) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let salt = TWData::from_ptr_as_ref(salt) + .map(|data| data.as_slice()) + .unwrap_or_default(); + + let params = Params { + n, + r, + p, + desired_len, + }; + scrypt(password, salt, ¶ms) + .map(|output| TWData::from(output).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} diff --git a/rust/tw_crypto/src/ffi/mod.rs b/rust/tw_crypto/src/ffi/mod.rs new file mode 100644 index 00000000000..fa8a5064491 --- /dev/null +++ b/rust/tw_crypto/src/ffi/mod.rs @@ -0,0 +1,13 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod crypto_aes_cbc; +pub mod crypto_aes_ctr; +pub mod crypto_hd_node; +pub mod crypto_hd_node_public; +pub mod crypto_mnemonic; +pub mod crypto_pbkdf2; +pub mod crypto_scrypt; diff --git a/rust/tw_crypto/src/lib.rs b/rust/tw_crypto/src/lib.rs new file mode 100644 index 00000000000..5178982a713 --- /dev/null +++ b/rust/tw_crypto/src/lib.rs @@ -0,0 +1,17 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +pub mod crypto_aes_cbc; +pub mod crypto_aes_ctr; +pub mod crypto_hd_node; +pub mod crypto_mnemonic; +pub mod crypto_pbkdf2; +pub mod crypto_scrypt; +pub mod ffi; + +pub const KEY_SIZE_AES_128: usize = 16; +pub const KEY_SIZE_AES_192: usize = 24; +pub const KEY_SIZE_AES_256: usize = 32; diff --git a/rust/tw_crypto/tests/bip39_vectors.json b/rust/tw_crypto/tests/bip39_vectors.json new file mode 100644 index 00000000000..c15add0e28e --- /dev/null +++ b/rust/tw_crypto/tests/bip39_vectors.json @@ -0,0 +1,148 @@ +{ + "english": [ + [ + "00000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04", + "xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607", + "xprv9s21ZrQH143K2gA81bYFHqU68xz1cX2APaSq5tt6MFSLeXnCKV1RVUJt9FWNTbrrryem4ZckN8k4Ls1H6nwdvDTvnV7zEXs2HgPezuVccsq" + ], + [ + "80808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8", + "xprv9s21ZrQH143K2shfP28KM3nr5Ap1SXjz8gc2rAqqMEynmjt6o1qboCDpxckqXavCwdnYds6yBHZGKHv7ef2eTXy461PXUjBFQg6PrwY4Gzq" + ], + [ + "ffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069", + "xprv9s21ZrQH143K2V4oox4M8Zmhi2Fjx5XK4Lf7GKRvPSgydU3mjZuKGCTg7UPiBUD7ydVPvSLtg9hjp7MQTYsW67rZHAXeccqYqrsx8LcXnyd" + ], + [ + "000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa", + "xprv9s21ZrQH143K3mEDrypcZ2usWqFgzKB6jBBx9B6GfC7fu26X6hPRzVjzkqkPvDqp6g5eypdk6cyhGnBngbjeHTe4LsuLG1cCmKJka5SMkmU" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c392d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd", + "xprv9s21ZrQH143K3Lv9MZLj16np5GzLe7tDKQfVusBni7toqJGcnKRtHSxUwbKUyUWiwpK55g1DUSsw76TF1T93VT4gz4wt5RM23pkaQLnvBh7" + ], + [ + "808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ffb796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65", + "xprv9s21ZrQH143K3VPCbxbUtpkh9pRG371UCLDz3BjceqP1jz7XZsQ5EnNkYAEkfeZp62cDNj13ZTEVG1TEro9sZ9grfRmcYWLBhCocViKEJae" + ], + [ + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b43348d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528", + "xprv9s21ZrQH143K36Ao5jHRVhFGDbLP6FCx8BEEmpru77ef3bmA928BxsqvVM27WnvvyfWywiFN8K6yToqMaGYfzS6Db1EHAXT5TuyCLBXUfdm" + ], + [ + "0000000000000000000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8", + "xprv9s21ZrQH143K32qBagUJAMU2LsHg3ka7jqMcV98Y7gVeVyNStwYS3U7yVVoDZ4btbRNf4h6ibWpY22iRmXq35qgLs79f312g2kj5539ebPM" + ], + [ + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87", + "xprv9s21ZrQH143K3Y1sd2XVu9wtqxJRvybCfAetjUrMMco6r3v9qZTBeXiBZkS8JxWbcGJZyio8TrZtm6pkbzG8SYt1sxwNLh3Wx7to5pgiVFU" + ], + [ + "8080808080808080808080808080808080808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f", + "xprv9s21ZrQH143K3CSnQNYC3MqAAqHwxeTLhDbhF43A4ss4ciWNmCY9zQGvAKUSqVUf2vPHBTSE1rB2pg4avopqSiLVzXEU8KziNnVPauTqLRo" + ], + [ + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad", + "xprv9s21ZrQH143K2WFF16X85T2QCpndrGwx6GueB72Zf3AHwHJaknRXNF37ZmDrtHrrLSHvbuRejXcnYxoZKvRquTPyp2JiNG3XcjQyzSEgqCB" + ], + [ + "9e885d952ad362caeb4efe34a8e91bd2", + "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic", + "274ddc525802f7c828d8ef7ddbcdc5304e87ac3535913611fbbfa986d0c9e5476c91689f9c8a54fd55bd38606aa6a8595ad213d4c9c9f9aca3fb217069a41028", + "xprv9s21ZrQH143K2oZ9stBYpoaZ2ktHj7jLz7iMqpgg1En8kKFTXJHsjxry1JbKH19YrDTicVwKPehFKTbmaxgVEc5TpHdS1aYhB2s9aFJBeJH" + ], + [ + "6610b25967cdcca9d59875f5cb50b0ea75433311869e930b", + "gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog", + "628c3827a8823298ee685db84f55caa34b5cc195a778e52d45f59bcf75aba68e4d7590e101dc414bc1bbd5737666fbbef35d1f1903953b66624f910feef245ac", + "xprv9s21ZrQH143K3uT8eQowUjsxrmsA9YUuQQK1RLqFufzybxD6DH6gPY7NjJ5G3EPHjsWDrs9iivSbmvjc9DQJbJGatfa9pv4MZ3wjr8qWPAK" + ], + [ + "68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c", + "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length", + "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440", + "xprv9s21ZrQH143K2XTAhys3pMNcGn261Fi5Ta2Pw8PwaVPhg3D8DWkzWQwjTJfskj8ofb81i9NP2cUNKxwjueJHHMQAnxtivTA75uUFqPFeWzk" + ], + [ + "c0ba5a8e914111210f2bd131f3d5e08d", + "scheme spot photo card baby mountain device kick cradle pact join borrow", + "ea725895aaae8d4c1cf682c1bfd2d358d52ed9f0f0591131b559e2724bb234fca05aa9c02c57407e04ee9dc3b454aa63fbff483a8b11de949624b9f1831a9612", + "xprv9s21ZrQH143K3FperxDp8vFsFycKCRcJGAFmcV7umQmcnMZaLtZRt13QJDsoS5F6oYT6BB4sS6zmTmyQAEkJKxJ7yByDNtRe5asP2jFGhT6" + ], + [ + "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3", + "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave", + "fd579828af3da1d32544ce4db5c73d53fc8acc4ddb1e3b251a31179cdb71e853c56d2fcb11aed39898ce6c34b10b5382772db8796e52837b54468aeb312cfc3d", + "xprv9s21ZrQH143K3R1SfVZZLtVbXEB9ryVxmVtVMsMwmEyEvgXN6Q84LKkLRmf4ST6QrLeBm3jQsb9gx1uo23TS7vo3vAkZGZz71uuLCcywUkt" + ], + [ + "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863", + "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside", + "72be8e052fc4919d2adf28d5306b5474b0069df35b02303de8c1729c9538dbb6fc2d731d5f832193cd9fb6aeecbc469594a70e3dd50811b5067f3b88b28c3e8d", + "xprv9s21ZrQH143K2WNnKmssvZYM96VAr47iHUQUTUyUXH3sAGNjhJANddnhw3i3y3pBbRAVk5M5qUGFr4rHbEWwXgX4qrvrceifCYQJbbFDems" + ], + [ + "23db8160a31d3e0dca3688ed941adbf3", + "cat swing flag economy stadium alone churn speed unique patch report train", + "deb5f45449e615feff5640f2e49f933ff51895de3b4381832b3139941c57b59205a42480c52175b6efcffaa58a2503887c1e8b363a707256bdd2b587b46541f5", + "xprv9s21ZrQH143K4G28omGMogEoYgDQuigBo8AFHAGDaJdqQ99QKMQ5J6fYTMfANTJy6xBmhvsNZ1CJzRZ64PWbnTFUn6CDV2FxoMDLXdk95DQ" + ], + [ + "8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0", + "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access", + "4cbdff1ca2db800fd61cae72a57475fdc6bab03e441fd63f96dabd1f183ef5b782925f00105f318309a7e9c3ea6967c7801e46c8a58082674c860a37b93eda02", + "xprv9s21ZrQH143K3wtsvY8L2aZyxkiWULZH4vyQE5XkHTXkmx8gHo6RUEfH3Jyr6NwkJhvano7Xb2o6UqFKWHVo5scE31SGDCAUsgVhiUuUDyh" + ], + [ + "066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad", + "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform", + "26e975ec644423f4a4c4f4215ef09b4bd7ef924e85d1d17c4cf3f136c2863cf6df0a475045652c57eb5fb41513ca2a2d67722b77e954b4b3fc11f7590449191d", + "xprv9s21ZrQH143K3rEfqSM4QZRVmiMuSWY9wugscmaCjYja3SbUD3KPEB1a7QXJoajyR2T1SiXU7rFVRXMV9XdYVSZe7JoUXdP4SRHTxsT1nzm" + ], + [ + "f30f8c1da665478f49b001d94c5fc452", + "vessel ladder alter error federal sibling chat ability sun glass valve picture", + "2aaa9242daafcee6aa9d7269f17d4efe271e1b9a529178d7dc139cd18747090bf9d60295d0ce74309a78852a9caadf0af48aae1c6253839624076224374bc63f", + "xprv9s21ZrQH143K2QWV9Wn8Vvs6jbqfF1YbTCdURQW9dLFKDovpKaKrqS3SEWsXCu6ZNky9PSAENg6c9AQYHcg4PjopRGGKmdD313ZHszymnps" + ], + [ + "c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05", + "scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump", + "7b4a10be9d98e6cba265566db7f136718e1398c71cb581e1b2f464cac1ceedf4f3e274dc270003c670ad8d02c4558b2f8e39edea2775c9e232c7cb798b069e88", + "xprv9s21ZrQH143K4aERa2bq7559eMCCEs2QmmqVjUuzfy5eAeDX4mqZffkYwpzGQRE2YEEeLVRoH4CSHxianrFaVnMN2RYaPUZJhJx8S5j6puX" + ], + [ + "f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f", + "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold", + "01f5bced59dec48e362f2c45b5de68b9fd6c92c6634f44d6d40aab69056506f0e35524a518034ddc1192e1dacd32c1ed3eaa3c3b131c88ed8e7e54c49a5d0998", + "xprv9s21ZrQH143K39rnQJknpH1WEPFJrzmAqqasiDcVrNuk926oizzJDDQkdiTvNPr2FYDYzWgiMiC63YmfPAa2oPyNB23r2g7d1yiK6WpqaQS" + ] + ] +} \ No newline at end of file diff --git a/rust/tw_crypto/tests/crypto_aes_ctr_ffi.rs b/rust/tw_crypto/tests/crypto_aes_ctr_ffi.rs new file mode 100644 index 00000000000..9602a3dbbb5 --- /dev/null +++ b/rust/tw_crypto/tests/crypto_aes_ctr_ffi.rs @@ -0,0 +1,179 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_aes_ctr::*; +use tw_encoding::hex; +use tw_memory::ffi::tw_data::TWData; +use tw_memory::ffi::RawPtrTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; + +#[test] +fn test_crypto_aes_ctr_128_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_ctr_128(key.ptr(), data.ptr(), iv.ptr()) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_ctr_128(key.ptr(), encrypted, iv.ptr()) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} + +#[test] +fn test_crypto_aes_ctr_192_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = hex::decode("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_ctr_192(key.ptr(), data.ptr(), iv.ptr()) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_ctr_192(key.ptr(), encrypted, iv.ptr()) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} + +#[test] +fn test_crypto_aes_ctr_256_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_ctr_256(key.ptr(), data.ptr(), iv.ptr()) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_ctr_256(key.ptr(), encrypted, iv.ptr()) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} + +#[test] +fn test_crypto_aes_ctr_encrypt() { + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let data = hex::decode("6bc1bee22e409f96e93d7e117393172a").unwrap(); + let data = TWDataHelper::create(data); + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let encrypt_result = unsafe { tw_aes_encrypt_ctr(key.ptr(), data.ptr(), iv.ptr()) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "601ec313775789a5b7a7f504bbf3d228" + ); +} + +#[test] +fn test_crypto_aes_ctr_decrypt() { + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let cipher = hex::decode("601ec313775789a5b7a7f504bbf3d228").unwrap(); + let cipher = TWDataHelper::create(cipher); + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let decrypt_result = unsafe { tw_aes_decrypt_ctr(key.ptr(), cipher.ptr(), iv.ptr()) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&decrypt_result.to_vec(), false), + "6bc1bee22e409f96e93d7e117393172a" + ); +} + +#[test] +fn test_crypto_aes_ctr_decrypt_multiple_blocks() { + let key = hex::decode("fac192ceb5fd772906bea3e118a69e8b").unwrap(); + let key = TWDataHelper::create(key); + let iv = hex::decode("83dbcc02d8ccb40e466191a123791e0e").unwrap(); + let iv = TWDataHelper::create(iv); + let data = + hex::decode("d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c").unwrap(); + let data = TWDataHelper::create(data); + + let decrypt_result = unsafe { tw_aes_decrypt_ctr(key.ptr(), data.ptr(), iv.ptr()) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&decrypt_result.to_vec(), false), + "7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d" + ); +} + +#[test] +fn test_crypto_aes_ctr_encrypt_multiple_blocks() { + let key = hex::decode("e1094a016e6029eabc6f9e3c3cd9afb8").unwrap(); + let key = TWDataHelper::create(key); + let iv = hex::decode("884b972d70acece4ecf9b790ffce177e").unwrap(); + let iv = TWDataHelper::create(iv); + let data = hex::decode("726970706c652073636973736f7273206b69636b206d616d6d616c206869726520636f6c756d6e206f616b20616761696e2073756e206f66666572207765616c746820746f6d6f72726f77207761676f6e207475726e20666174616c00").unwrap(); + let data = TWDataHelper::create(data); + + let result = unsafe { tw_aes_encrypt_ctr(key.ptr(), data.ptr(), iv.ptr()) }; + let result = unsafe { TWData::from_ptr_as_mut(result).unwrap() }; + + assert_eq!( + hex::encode(&result.to_vec(), false), + "76b0a3ae037e7d6a50236c4c3ba7560edde4a8a951bf97bc10709e74d8e926c0431866b0ba9852d95bb0bbf41d109f1f3cf2f0af818f96d4f4109a1e3e5b224e3efd57288906a48d47b0006ccedcf96fde7362dedca952dda7cbdd359d" + ); +} + +#[test] +fn test_crypto_aes_ctr_encrypt_invalid_key_size() { + let iv = vec![0; 16]; + let iv = TWDataHelper::create(iv); + let key = vec![0; 19]; // Invalid key size + let key = TWDataHelper::create(key); + let data = vec![0; 100]; + let data = TWDataHelper::create(data); + + let result = unsafe { tw_aes_encrypt_ctr(key.ptr(), data.ptr(), iv.ptr()) }; + assert!( + result.is_null(), + "Expected null result for invalid key size" + ); +} + +#[test] +fn test_crypto_aes_ctr_decrypt_invalid_key_size() { + let iv = vec![0; 16]; + let iv = TWDataHelper::create(iv); + let key = vec![0; 19]; // Invalid key size + let key = TWDataHelper::create(key); + let data = vec![0; 100]; + let data = TWDataHelper::create(data); + + let result = unsafe { tw_aes_decrypt_ctr(key.ptr(), data.ptr(), iv.ptr()) }; + assert!( + result.is_null(), + "Expected null result for invalid key size" + ); +} diff --git a/rust/tw_crypto/tests/crypto_mnemonic_ffi.rs b/rust/tw_crypto/tests/crypto_mnemonic_ffi.rs new file mode 100644 index 00000000000..fd2a4d9d0d1 --- /dev/null +++ b/rust/tw_crypto/tests/crypto_mnemonic_ffi.rs @@ -0,0 +1,349 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_mnemonic::*; +use tw_encoding::hex; +use tw_memory::ffi::tw_data::TWData; +use tw_memory::ffi::tw_string::TWString; +use tw_memory::ffi::RawPtrTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; +use tw_memory::test_utils::tw_string_helper::TWStringHelper; + +#[test] +fn test_bip39_generate_and_check_mnemonic() { + let strength = 128; + let res = unsafe { tw_mnemonic_generate(strength) }; + let res = unsafe { TWString::from_ptr_as_ref(res).unwrap() }; + let mnemonic_string = res.as_str().unwrap(); + let mnemonic_words = mnemonic_string.split(" ").collect::>(); + assert_eq!(mnemonic_words.len(), 12); + + let is_valid = unsafe { tw_mnemonic_is_valid(res) }; + assert!(is_valid); + + let strength = 192; + let res = unsafe { tw_mnemonic_generate(strength) }; + let res = unsafe { TWString::from_ptr_as_ref(res).unwrap() }; + let mnemonic_string = res.as_str().unwrap(); + let mnemonic_words = mnemonic_string.split(" ").collect::>(); + assert_eq!(mnemonic_words.len(), 18); + + let is_valid = unsafe { tw_mnemonic_is_valid(res) }; + assert!(is_valid); + + let strength = 256; + let res = unsafe { tw_mnemonic_generate(strength) }; + let res = unsafe { TWString::from_ptr_as_ref(res).unwrap() }; + let mnemonic_string = res.as_str().unwrap(); + let mnemonic_words = mnemonic_string.split(" ").collect::>(); + assert_eq!(mnemonic_words.len(), 24); + + let is_valid = unsafe { tw_mnemonic_is_valid(res) }; + assert!(is_valid); +} + +#[test] +fn test_bip39_generate_mnemonic_from_data() { + let test_vectors = [ + // entropy, expected mnemonic, expected seed with passphrase "TREZOR" + ("00000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04"), + + ("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607"), + + ("80808080808080808080808080808080", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8"), + + ("ffffffffffffffffffffffffffffffff", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069"), + + ("0000000000000000000000000000000000000000000000000000000000000000", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8"), + + ("18ab19a9f54a9274f03e5209a2ac8a91", + "board flee heavy tunnel powder denial science ski answer betray cargo cat", + "6eff1bb21562918509c73cb990260db07c0ce34ff0e3cc4a8cb3276129fbcb300bddfe005831350efd633909f476c45c88253276d9fd0df6ef48609e8bb7dca8"), + + ("15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419", + "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + "b15509eaa2d09d3efd3e006ef42151b30367dc6e3aa5e44caba3fe4d3e352e65101fbdb86a96776b91946ff06f8eac594dc6ee1d3e82a42dfe1b40fef6bcc3fd"), + ]; + + for (entropy_hex, expected_mnemonic, expected_seed) in test_vectors.iter() { + let entropy = hex::decode(entropy_hex).unwrap(); + let entropy_data = TWDataHelper::create(entropy); + + let mnemonic_ptr = unsafe { tw_mnemonic_generate_from_data(entropy_data.ptr()) }; + let mnemonic_data = unsafe { TWString::from_ptr_as_ref(mnemonic_ptr).unwrap() }; + let mnemonic_string = mnemonic_data.as_str().unwrap(); + + assert_eq!(mnemonic_string, *expected_mnemonic); + + let is_valid = unsafe { tw_mnemonic_is_valid(mnemonic_ptr) }; + assert!(is_valid); + + let passphrase_string = TWStringHelper::create("TREZOR"); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_ptr, passphrase_string.ptr()) }; + let seed_data = unsafe { TWData::from_ptr_as_ref(seed_ptr).unwrap() }; + assert_eq!(hex::encode(seed_data.to_vec(), false), *expected_seed); + } +} + +#[test] +fn test_bip39_check_mnemonic() { + let vectors_ok = [ + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "jelly better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "renew stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "afford alter spike radar gate glance object seek swamp infant panel yellow", + "indicate race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "clutch control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "turtle front uncle idea crush write shrug there lottery flower risk shell", + "kiss carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "exile ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "board flee heavy tunnel powder denial science ski answer betray cargo cat", + "board blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "beyond stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + ]; + + let vectors_fail = [ + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "above winner thank year wave sausage worth useful legal winner thank yellow", + "above advice cage absurd amount doctor acoustic avoid letter advice cage above", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "above abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "above winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "above advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "above better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "above stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "above pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "above alter spike radar gate glance object seek swamp infant panel yellow", + "above race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "above control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "above front uncle idea crush write shrug there lottery flower risk shell", + "above carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "above ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "above flee heavy tunnel powder denial science ski answer betray cargo cat", + "above blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "above stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "winner thank year wave sausage worth useful legal winner thank yellow", + "advice cage absurd amount doctor acoustic avoid letter advice cage above", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "better achieve collect unaware mountain thought cargo oxygen act hood bridge", + "stay biology evidence goat welcome casual join adapt armor shuffle fault little machine walk stumble urge swap", + "pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic", + "alter spike radar gate glance object seek swamp infant panel yellow", + "race push merry suffer human cruise dwarf pole review arch keep canvas theme poem divorce alter left", + "control vehicle tonight unusual clog visa ice plunge glimpse recipe series open hour vintage deposit universe tip job dress radar refuse motion taste", + "front uncle idea crush write shrug there lottery flower risk shell", + "carry display unusual confirm curtain upgrade antique rotate hello void custom frequent obey nut hole price segment", + "ask congress lamp submit jacket era scheme attend cousin alcohol catch course end lucky hurt sentence oven short ball bird grab wing top", + "flee heavy tunnel powder denial science ski answer betray cargo cat", + "blade invite damage undo sun mimic interest slam gaze truly inherit resist great inject rocket museum chief", + "stage sleep clip because twist token leaf atom beauty genius food business side grid unable middle armed observe pair crouch tonight away coconut", + ]; + + for mnemonic in vectors_ok { + let mnemonic_string = TWStringHelper::create(mnemonic); + let is_valid = unsafe { tw_mnemonic_is_valid(mnemonic_string.ptr()) }; + assert!(is_valid); + } + + for mnemonic in vectors_fail { + let mnemonic_string = TWStringHelper::create(mnemonic); + let is_valid = unsafe { tw_mnemonic_is_valid(mnemonic_string.ptr()) }; + assert!(!is_valid); + } +} + +#[test] +fn test_bip39_find_word() { + let word_string = TWStringHelper::create("aaaa"); + let index = unsafe { tw_mnemonic_find_word(word_string.ptr()) }; + assert_eq!(index, -1); + + let word_string = TWStringHelper::create("zzzz"); + let index = unsafe { tw_mnemonic_find_word(word_string.ptr()) }; + assert_eq!(index, -1); + + for i in 0..2048 { + let word = unsafe { tw_mnemonic_get_word(i) }; + let word_string = unsafe { TWString::from_ptr_as_ref(word).unwrap() }; + let index = unsafe { tw_mnemonic_find_word(word_string) }; + assert_eq!(index, i as i32); + } +} + +#[test] +fn test_mnemonic_is_valid() { + let valid_inputs = [ + "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal", + // 12 + "credit expect life fade cover suit response wash pear what skull force", + // 15 + "rebuild park fatigue flame one clap grocery scheme upon symbol rifle flush brave feed clutch", + // 18 + "find view amazing inject mistake school zone ticket deposit edit deer fuel expect pioneer alpha mirror joke private", + // 21 + "tiger parent future endorse chuckle crazy seat tomato orient prevent swarm nerve duty crazy chief cruel purity team happy strategy level", + // 24 + "admit smart swim bulk empty mystery state lyrics wrap welcome install seat supreme sunny sting roof once accuse envelope uncover arrive twice spoon squeeze", + ]; + + for mnemonic in valid_inputs { + let mnemonic_string = TWStringHelper::create(mnemonic); + let is_valid = unsafe { tw_mnemonic_is_valid(mnemonic_string.ptr()) }; + assert!(is_valid, "Expected valid: {}", mnemonic); + } + + let invalid_inputs = [ + // invalid word + "ripple scissors hisc mammal hire column oak again sun offer wealth tomorrow", + // invalid word + "high culture ostrich wrist exist ignore interest hybridous exclude width more", + // invalid checksum + "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow", + // invalid word count + "credit expect life fade cover suit response wash what skull force", + // extra space + " credit expect life fade cover suit response wash pear what skull force ", + // upper + "CREDIT expect life fade cover suit response wash pear what skull force", + // back is invalid word + "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn back", + // Spanish + "llanto radical atraer riesgo actuar masa fondo cielo dieta archivo sonrisa mamut", + ]; + + for mnemonic in invalid_inputs { + let mnemonic_string = TWStringHelper::create(mnemonic); + let is_valid = unsafe { tw_mnemonic_is_valid(mnemonic_string.ptr()) }; + assert!(!is_valid, "Expected invalid: {}", mnemonic); + } +} + +#[test] +fn test_mnemonic_is_valid_word() { + assert!(unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("credit").ptr()) }); + assert!(unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("airport").ptr()) }); + assert!(unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("robot").ptr()) }); + + assert!(!unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("hybridous").ptr()) }); + assert!(!unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("CREDIT").ptr()) }); + assert!(!unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("credit ").ptr()) }); + assert!(!unsafe { tw_mnemonic_is_valid_word(TWStringHelper::create("back").ptr()) }); +} + +#[test] +fn test_mnemonic_suggest() { + let test_cases = [ + ("air", "air airport"), + ("AIR", "air airport"), + ("abc", ""), + ("ai", "aim air airport aisle"), + ( + "an", + "analyst anchor ancient anger angle angry animal ankle announce annual", + ), + ( + "a", + "abandon ability able about above absent absorb abstract absurd abuse", + ), + ("str", "strategy street strike strong struggle"), + ("rob", "robot robust"), + ("saus", "sausage"), + ("saos", ""), + ("", ""), + ("3", ""), + (" a", ""), + (" ", ""), + ( + "f", + "fabric face faculty fade faint faith fall false fame family", + ), + ( + "fa", + "fabric face faculty fade faint faith fall false fame family", + ), + ("fam", "fame family famous"), + ("fami", "family"), + ("famil", "family"), + ("family", "family"), + ( + "p", + "pact paddle page pair palace palm panda panel panic panther", + ), + ( + "pr", + "practice praise predict prefer prepare present pretty prevent price pride", + ), + ( + "pro", + "problem process produce profit program project promote proof property prosper", + ), + ("prog", "program"), + ("progr", "program"), + ("progra", "program"), + ("program", "program"), + ]; + + for (prefix, expected) in test_cases { + let prefix_string = TWStringHelper::create(prefix); + let result = unsafe { tw_mnemonic_suggest(prefix_string.ptr()) }; + let result_string = unsafe { TWString::from_ptr_as_ref(result).unwrap() }; + let result_string = result_string.as_str().unwrap(); + assert_eq!(result_string, expected); + } +} + +#[test] +fn test_spanish_mnemonic() { + let mnemonic = + "llanto radical atraer riesgo actuar masa fondo cielo dieta archivo sonrisa mamut"; + let mnemonic_string = TWStringHelper::create(mnemonic); + + let entropy = unsafe { tw_mnemonic_to_entropy(mnemonic_string.ptr()) }; + let entropy_data = unsafe { TWData::from_ptr_as_ref(entropy).unwrap() }; + assert_eq!(hex::encode(entropy_data.to_vec(), false), ""); + + let seed = + unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), TWStringHelper::create("").ptr()) }; + let seed_data = unsafe { TWData::from_ptr_as_ref(seed).unwrap() }; + assert_eq!(hex::encode(seed_data.to_vec(), false), "ec8f8703432fc7d32e699ee056e9d84b1435e6a64a6a40ad63dbde11eab189a276ddcec20f3326d3c6ee39cbd018585b104fc3633b801c011063ae4c318fb9b6"); +} diff --git a/rust/tw_crypto/tests/crypto_pbkdf2.rs b/rust/tw_crypto/tests/crypto_pbkdf2.rs new file mode 100644 index 00000000000..709ca804dac --- /dev/null +++ b/rust/tw_crypto/tests/crypto_pbkdf2.rs @@ -0,0 +1,34 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::crypto_pbkdf2::pbkdf2_hmac_sha256; +use tw_encoding::{base64, base64::STANDARD, hex}; + +#[test] +fn test_pbkdf2_hmac_sha256() { + let password = hex::decode("70617373776f7264").unwrap(); + let salt = hex::decode("73616C74").unwrap(); + + let data = pbkdf2_hmac_sha256(&password, &salt, 1, 20); + assert_eq!( + hex::encode(&data, false), + "120fb6cffcf8b32c43e7225256c4f837a86548c9" + ); + + let data = pbkdf2_hmac_sha256(&password, &salt, 4096, 20); + assert_eq!( + hex::encode(&data, false), + "c5e478d59288c841aa530db6845c4c8d962893a0" + ); + + let salt2 = base64::decode("kNHS+Mx//slRsmLF9396HQ==", STANDARD).unwrap(); + + let data = pbkdf2_hmac_sha256(&password, &salt2, 100, 32); + assert_eq!( + hex::encode(&data, false), + "9cf33ebd3542c691fac6f61609a8d13355a0adf4d15eed77cc9d13f792b77c3a" + ); +} diff --git a/rust/tw_crypto/tests/crypto_pbkdf2_ffi.rs b/rust/tw_crypto/tests/crypto_pbkdf2_ffi.rs new file mode 100644 index 00000000000..16831fe2f48 --- /dev/null +++ b/rust/tw_crypto/tests/crypto_pbkdf2_ffi.rs @@ -0,0 +1,61 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_pbkdf2::{tw_pbkdf2_hmac_sha256, tw_pbkdf2_hmac_sha512}; +use tw_encoding::{base64, base64::STANDARD, hex}; +use tw_memory::ffi::tw_data::TWData; +use tw_memory::ffi::RawPtrTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; + +#[test] +fn test_pbkdf2_hmac_sha256_ffi() { + let password = hex::decode("70617373776f7264").unwrap(); + let password = TWDataHelper::create(password); + + let salt = hex::decode("73616C74").unwrap(); + let salt = TWDataHelper::create(salt); + + let res = unsafe { tw_pbkdf2_hmac_sha256(password.ptr(), salt.ptr(), 1, 20) }; + let res = unsafe { TWData::from_ptr_as_mut(res).unwrap() }; + assert_eq!( + hex::encode(res.to_vec(), false), + "120fb6cffcf8b32c43e7225256c4f837a86548c9" + ); + + let res = unsafe { tw_pbkdf2_hmac_sha256(password.ptr(), salt.ptr(), 4096, 20) }; + let res = unsafe { TWData::from_ptr_as_mut(res).unwrap() }; + assert_eq!( + hex::encode(res.to_vec(), false), + "c5e478d59288c841aa530db6845c4c8d962893a0" + ); + + let salt2 = base64::decode("kNHS+Mx//slRsmLF9396HQ==", STANDARD).unwrap(); + let salt2 = TWDataHelper::create(salt2); + + let res = unsafe { tw_pbkdf2_hmac_sha256(password.ptr(), salt2.ptr(), 100, 32) }; + let res = unsafe { TWData::from_ptr_as_mut(res).unwrap() }; + assert_eq!( + hex::encode(res.to_vec(), false), + "9cf33ebd3542c691fac6f61609a8d13355a0adf4d15eed77cc9d13f792b77c3a" + ); +} + +#[test] +fn test_pbkdf2_hmac_sha512_ffi() { + let password = hex::decode("70617373776f7264").unwrap(); + let password = TWDataHelper::create(password); + + let salt = hex::decode("73616C74").unwrap(); + let salt = TWDataHelper::create(salt); + + let res = unsafe { tw_pbkdf2_hmac_sha512(password.ptr(), salt.ptr(), 1, 20) }; + let res = unsafe { TWData::from_ptr_as_mut(res).unwrap() }; + + assert_eq!( + hex::encode(res.to_vec(), false), + "867f70cf1ade02cff3752599a3a53dc4af34c7a6" + ); +} diff --git a/rust/tw_crypto/tests/crypto_scrypt.rs b/rust/tw_crypto/tests/crypto_scrypt.rs new file mode 100644 index 00000000000..4dc59443e0b --- /dev/null +++ b/rust/tw_crypto/tests/crypto_scrypt.rs @@ -0,0 +1,44 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::crypto_scrypt::params::Params; +use tw_crypto::crypto_scrypt::scrypt; +use tw_encoding::hex; + +#[test] +fn test_scrypt() { + let password = hex::decode("70617373776f7264").unwrap(); + let salt = + hex::decode("80132842c6cde8f9d04582932ef92c3cad3ba6b41e1296ef681692372886db86").unwrap(); + + let params = Params { + n: 1 << 12, + r: 8, + p: 6, + desired_len: 32, + }; + let res = scrypt(&password, &salt, ¶ms).unwrap(); + assert_eq!( + hex::encode(&res, false), + "1217705511f43b7d2faea767a156a9946c579b3436ba27252a73278a7162cedc" + ); +} + +#[test] +fn test_scrypt_invalid_n() { + let password = hex::decode("70617373776f7264").unwrap(); + let salt = + hex::decode("80132842c6cde8f9d04582932ef92c3cad3ba6b41e1296ef681692372886db86").unwrap(); + + let params = Params { + // Must be a power of 2. + n: (1 << 12) + 1, + r: 8, + p: 6, + desired_len: 32, + }; + scrypt(&password, &salt, ¶ms).unwrap_err(); +} diff --git a/rust/tw_crypto/tests/crypto_scrypt_ffi.rs b/rust/tw_crypto/tests/crypto_scrypt_ffi.rs new file mode 100644 index 00000000000..5df66f70710 --- /dev/null +++ b/rust/tw_crypto/tests/crypto_scrypt_ffi.rs @@ -0,0 +1,26 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_scrypt::crypto_scrypt; +use tw_encoding::hex; +use tw_memory::ffi::tw_data::TWData; +use tw_memory::ffi::RawPtrTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; + +#[test] +fn test_crypto_scrypt_ffi_null_salt() { + let password = hex::decode("70617373776f7264").unwrap(); + let password = TWDataHelper::create(password); + + let salt = TWDataHelper::create(Vec::new()); + + let res = unsafe { crypto_scrypt(password.ptr(), salt.ptr(), 16384, 8, 4, 32) }; + let res = unsafe { TWData::from_ptr_as_mut(res).unwrap() }; + assert_eq!( + hex::encode(res.to_vec(), false), + "004f57df809101216a343d6215879a9a7f1d7e2c04ef2845b4494cf5f10181a1" + ); +} diff --git a/rust/tw_crypto/tests/cryto_aes_cbc_ffi.rs b/rust/tw_crypto/tests/cryto_aes_cbc_ffi.rs new file mode 100644 index 00000000000..27efcfc914c --- /dev/null +++ b/rust/tw_crypto/tests/cryto_aes_cbc_ffi.rs @@ -0,0 +1,347 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_aes_cbc::*; +use tw_encoding::hex; +use tw_memory::ffi::tw_data::TWData; +use tw_memory::ffi::RawPtrTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; + +#[test] +fn test_crypto_aes_cbc_encrypt_zero_padding() { + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let iv = hex::decode("000102030405060708090A0B0C0D0E0F").unwrap(); + let iv = TWDataHelper::create(iv); + + let data = hex::decode("6bc1bee22e409f96e93d7e117393172a").unwrap(); + let data = TWDataHelper::create(data); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "f58c4c04d6e5f1ba779eabfb5f7bfbd6" + ); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_zero_padding() { + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let iv = hex::decode("000102030405060708090A0B0C0D0E0F").unwrap(); + let iv = TWDataHelper::create(iv); + + let cipher = hex::decode("f58c4c04d6e5f1ba779eabfb5f7bfbd6").unwrap(); + let cipher = TWDataHelper::create(cipher); + + let decrypt_result = unsafe { tw_aes_decrypt_cbc(key.ptr(), cipher.ptr(), iv.ptr(), 0) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&decrypt_result.to_vec(), false), + "6bc1bee22e409f96e93d7e117393172a" + ); +} + +#[test] +fn test_crypto_aes_cbc_encrypt_pkcs7_padding() { + let key2 = + hex::decode("bbc82a01ebdb14698faee4a9e5038de72c995a9f6bcdb21903d62408b0c5ca96").unwrap(); + let key2 = TWDataHelper::create(key2); + + let iv = hex::decode("37f8687086d31852979e228f4a97925b").unwrap(); + let iv = TWDataHelper::create(iv); + + let data = hex::decode("7b226a736f6e727063223a22322e30222c226964223a313535343334333833343735323434362c226572726f72223a7b22636f6465223a2d33323030302c226d657373616765223a2253657373696f6e2052656a6563746564227d7d").unwrap(); + let data = TWDataHelper::create(data); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key2.ptr(), data.ptr(), iv.ptr(), 1) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!(hex::encode(&encrypt_result.to_vec(), false), "23c75d1b3228742ddb12eeef5a5016e37a8980a77fabc6dd01e6a355d88851c611d37e0d17a2f9c30f659da6d42ba77aca9b84bd6a95e3924f47d9093fbf16e0fb55b165ec193489645b4f7d2573959305c8fa70f88fe5affc43e3084a5878d1"); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_pkcs7_padding() { + let key2 = + hex::decode("bbc82a01ebdb14698faee4a9e5038de72c995a9f6bcdb21903d62408b0c5ca96").unwrap(); + let key2 = TWDataHelper::create(key2); + + let iv = hex::decode("debb62725b21c7577e4e498e10f096c7").unwrap(); + let iv = TWDataHelper::create(iv); + + let cipher = hex::decode("e7df9810ce66defcc03023ee945f5958c1d4697bf97945daeab5059c2bc6262642cbca82982ac690e77e16671770c200f348f743a7c6e5df5c74eb892ef9b45a9b5ddf0f08fa60c49e5b694688d1b0b521b43975e65b4e8d557a83f4d1aab0af").unwrap(); + let cipher = TWDataHelper::create(cipher); + + let decrypt_result = unsafe { tw_aes_decrypt_cbc(key2.ptr(), cipher.ptr(), iv.ptr(), 1) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!(hex::encode(&decrypt_result.to_vec(), false), "7b226a736f6e727063223a22322e30222c226964223a313535343334333833343735323434362c226572726f72223a7b22636f6465223a2d33323030302c226d657373616765223a2253657373696f6e2052656a6563746564227d7d"); +} + +#[test] +fn test_crypto_aes_cbc_encrypt() { + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let iv = hex::decode("000102030405060708090A0B0C0D0E0F").unwrap(); + let iv = TWDataHelper::create(iv); + + let data = hex::decode("6bc1bee22e409f96e93d7e117393172a").unwrap(); + let data = TWDataHelper::create(data); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "f58c4c04d6e5f1ba779eabfb5f7bfbd6" + ); +} + +#[test] +fn test_crypto_aes_cbc_encrypt_with_padding() { + let key = + hex::decode("bf6cfdd852f79460981062f551f1dc3215b5e26609bc2a275d5b2da21798b489").unwrap(); + let key = TWDataHelper::create(key); + + let message = "secret message".as_bytes(); + let message = TWDataHelper::create(message.to_vec()); + + // Test with PKCS7 padding + { + let iv = hex::decode("f300888ca4f512cebdc0020ff0f7224c").unwrap(); + let iv = TWDataHelper::create(iv); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key.ptr(), message.ptr(), iv.ptr(), 1) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "7f896315e90e172bed65d005138f224d" + ); + } + + // Test with Zero padding + { + let iv = hex::decode("f300888ca4f512cebdc0020ff0f7224c").unwrap(); + let iv = TWDataHelper::create(iv); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key.ptr(), message.ptr(), iv.ptr(), 0) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "11bcbfebb2db19fb5a5cbf458e0f699e" + ); + } +} + +#[test] +fn test_crypto_aes_cbc_decrypt() { + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let iv = hex::decode("000102030405060708090A0B0C0D0E0F").unwrap(); + let iv = TWDataHelper::create(iv); + + let cipher = hex::decode("f58c4c04d6e5f1ba779eabfb5f7bfbd6").unwrap(); + let cipher = TWDataHelper::create(cipher); + + let decrypt_result = unsafe { tw_aes_decrypt_cbc(key.ptr(), cipher.ptr(), iv.ptr(), 0) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&decrypt_result.to_vec(), false), + "6bc1bee22e409f96e93d7e117393172a" + ); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_with_padding() { + let key = + hex::decode("bf6cfdd852f79460981062f551f1dc3215b5e26609bc2a275d5b2da21798b489").unwrap(); + let key = TWDataHelper::create(key); + + // Test with PKCS7 padding + { + let encrypted_padded = hex::decode("7f896315e90e172bed65d005138f224d").unwrap(); + let encrypted_padded = TWDataHelper::create(encrypted_padded); + + let iv = hex::decode("f300888ca4f512cebdc0020ff0f7224c").unwrap(); + let iv = TWDataHelper::create(iv); + + let decrypt_result = + unsafe { tw_aes_decrypt_cbc(key.ptr(), encrypted_padded.ptr(), iv.ptr(), 1) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + let secret_message = "secret message".as_bytes(); + assert_eq!(decrypt_result.to_vec(), secret_message); + } + + // Test with no padding + { + let encrypted_not_padded = hex::decode("11bcbfebb2db19fb5a5cbf458e0f699e").unwrap(); + let encrypted_not_padded = TWDataHelper::create(encrypted_not_padded); + + let iv = hex::decode("f300888ca4f512cebdc0020ff0f7224c").unwrap(); + let iv = TWDataHelper::create(iv); + + let decrypt_result = + unsafe { tw_aes_decrypt_cbc(key.ptr(), encrypted_not_padded.ptr(), iv.ptr(), 0) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + let mut expected = "secret message".as_bytes().to_vec(); + expected.push(0); + expected.push(0); + assert_eq!(decrypt_result.to_vec(), expected); + } +} + +#[test] +fn test_crypto_aes_cbc_encrypt_multiple_blocks() { + let key = hex::decode("e1094a016e6029eabc6f9e3c3cd9afb8").unwrap(); + let key = TWDataHelper::create(key); + let iv = hex::decode("884b972d70acece4ecf9b790ffce177e").unwrap(); + let iv = TWDataHelper::create(iv); + let data = hex::decode("726970706c652073636973736f7273206b69636b206d616d6d616c206869726520636f6c756d6e206f616b20616761696e2073756e206f66666572207765616c746820746f6d6f72726f77207761676f6e207475726e20666174616c00").unwrap(); + let data = TWDataHelper::create(data); + + let encrypt_result = unsafe { tw_aes_encrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypt_result = unsafe { TWData::from_ptr_as_mut(encrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&encrypt_result.to_vec(), false), + "30e3ce939cdc80df375aaf6c2cdc7bc265f4eea20c90ab4825c5fc4b5c4517395ea1c28559bf0832a07f9a7fb8fc58786683a48aa8319be215a6b4a597eeaa443973b76401fe959c1bcb4991c9ee20b54c0244f8f43f0f0adcbb50e9ea913bf0" + ); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_multiple_blocks() { + let key = hex::decode("fac192ceb5fd772906bea3e118a69e8b").unwrap(); + let key = TWDataHelper::create(key); + let iv = hex::decode("83dbcc02d8ccb40e466191a123791e0e").unwrap(); + let iv = TWDataHelper::create(iv); + let data = + hex::decode("d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c").unwrap(); + let data = TWDataHelper::create(data); + + let decrypt_result = unsafe { tw_aes_decrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let decrypt_result = unsafe { TWData::from_ptr_as_mut(decrypt_result).unwrap() }; + + assert_eq!( + hex::encode(&decrypt_result.to_vec(), false), + "d4ade7189ee99ba50399e60a27c9e0fd02cfd1cfa2d15e7491329f361645d2a4" + ); +} + +#[test] +fn test_crypto_aes_cbc_encrypt_invalid_key_size() { + let iv = TWDataHelper::create(vec![0; 16]); + let key = TWDataHelper::create(vec![0; 19]); + let data = TWDataHelper::create(vec![0; 100]); + + let result = unsafe { tw_aes_encrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + assert!( + result.is_null(), + "Expected null result for invalid key size" + ); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_invalid_key_size() { + let iv = TWDataHelper::create(vec![0; 16]); + let key = TWDataHelper::create(vec![0; 19]); + let data = TWDataHelper::create(vec![0; 100]); + + let result = unsafe { tw_aes_decrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + assert!( + result.is_null(), + "Expected null result for invalid key size" + ); +} + +#[test] +fn test_crypto_aes_cbc_decrypt_invalid_data_size() { + let iv = TWDataHelper::create(vec![0; 16]); + let key = TWDataHelper::create(vec![0; 16]); + let data = TWDataHelper::create(vec![0; 100]); + + let result = unsafe { tw_aes_decrypt_cbc(key.ptr(), data.ptr(), iv.ptr(), 0) }; + assert!( + result.is_null(), + "Expected null result for invalid data size" + ); +} + +#[test] +fn test_crypto_aes_cbc_128_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_cbc_128(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_cbc_128(key.ptr(), encrypted, iv.ptr(), 0) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} + +#[test] +fn test_crypto_aes_cbc_192_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = hex::decode("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_cbc_192(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_cbc_192(key.ptr(), encrypted, iv.ptr(), 0) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} + +#[test] +fn test_crypto_aes_cbc_256_ffi() { + let data_hex = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let data = hex::decode(data_hex).unwrap(); + let data = TWDataHelper::create(data); + let iv = hex::decode("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap(); + let iv = TWDataHelper::create(iv); + let key = + hex::decode("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4").unwrap(); + let key = TWDataHelper::create(key); + + let encrypted = unsafe { tw_aes_encrypt_cbc_256(key.ptr(), data.ptr(), iv.ptr(), 0) }; + let encrypted = unsafe { TWData::from_ptr_as_mut(encrypted).unwrap() }; + + let decrypted = unsafe { tw_aes_decrypt_cbc_256(key.ptr(), encrypted, iv.ptr(), 0) }; + let decrypted = unsafe { TWData::from_ptr_as_mut(decrypted).unwrap() }; + + let decrypted_data = decrypted.to_vec(); + assert_eq!(hex::encode(&decrypted_data, false), data_hex); +} diff --git a/rust/tw_crypto/tests/extended_private_key.rs b/rust/tw_crypto/tests/extended_private_key.rs new file mode 100644 index 00000000000..92c9fc25312 --- /dev/null +++ b/rust/tw_crypto/tests/extended_private_key.rs @@ -0,0 +1,768 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use bip32::{ChildNumber, DerivationPath, Prefix, XPub}; +use std::str::FromStr; +use tw_crypto::crypto_hd_node::ed25519::cardano::cardano_staking_derivation_path; +use tw_crypto::crypto_hd_node::error::{Error, Result}; +use tw_crypto::crypto_hd_node::extended_key::bip32_private_key::BIP32PrivateKey; +use tw_crypto::crypto_hd_node::extended_key::bip32_public_key::BIP32PublicKey; +use tw_crypto::crypto_hd_node::extended_key::extended_private_key::ExtendedPrivateKey; +use tw_crypto::crypto_hd_node::extended_key::extended_private_key::{decode_base58, encode_base58}; +use tw_crypto::crypto_hd_node::hd_node::{ + XPrvCardano, XPrvCurve25519Waves, XPrvEd25519, XPrvEd25519Blake2bNano, XPrvNist256p1, + XPrvSecp256k1, XPrvZilliqaSchnorr, +}; +use tw_crypto::crypto_hd_node::hd_node_public::XPubSecp256k1; +use tw_crypto::crypto_mnemonic::mnemonic::Mnemonic; +use tw_encoding::hex; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_misc::traits::{ToBytesVec, ToBytesZeroizing}; +use zeroize::Zeroizing; + +#[test] +fn test_from_seed() { + let seed = Mnemonic::to_seed( + "tiny escape drive pupil flavor endless love walk gadget match filter luxury", + "", + ); + assert_eq!(hex::encode(seed, false), "d430216f5b506dfd281d6ff6e92150d205868923df00774bc301e5ffdc2f4d1ad38a602017ddea6fc7d6315345d8b9cadbd8213ed2ffce5dfc550fa918665eb8"); + let xprv = XPrvSecp256k1::new(&seed); + assert!(xprv.is_ok()); +} + +#[test] +fn test_extended_private_key() { + let seed = Mnemonic::to_seed("ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal", ""); + let xprv = XPrvSecp256k1::new(&seed).unwrap(); + + let child_xprv = xprv + .derive_from_path( + &DerivationPath::from_str("m/44'/0'/0'").unwrap(), + Hasher::Sha256ripemd, + ) + .unwrap(); + let child_extended_key = child_xprv.to_string(Prefix::ZPRV).unwrap().to_string(); + assert_eq!(child_extended_key, "zprvAcwsTZNaY1f7rfwsy5GseSDStYBrxwtsBZDkb3iyuQUs4NF6n58BuH7Xj54RuaSCWtU5CiQzuYQgFgqr1HokgKcVAeGeXokhJUAJeP3VmvY"); + + let child_extended_key = child_xprv.to_extended_key(Prefix::ZPRV).unwrap(); + assert_eq!(child_extended_key.to_string(), "zprvAcwsTZNaY1f7rfwsy5GseSDStYBrxwtsBZDkb3iyuQUs4NF6n58BuH7Xj54RuaSCWtU5CiQzuYQgFgqr1HokgKcVAeGeXokhJUAJeP3VmvY"); + + let encoded = encode_base58(&child_extended_key, Hasher::Sha256d).unwrap(); + assert_eq!(encoded, child_extended_key.to_string()); + + let decoded = decode_base58(&child_extended_key.to_string(), Hasher::Sha256d).unwrap(); + assert_eq!(decoded.to_string(), child_extended_key.to_string()); + + let decoded_failed = decode_base58(&child_extended_key.to_string(), Hasher::Sha256ripemd); + assert!(decoded_failed.is_err()); + + let decode_invalid = decode_base58("invalid", Hasher::Sha256d); + assert!(decode_invalid.is_err()); + + let decode_invalid = decode_base58("ea", Hasher::Sha256d); + assert!(decode_invalid.is_err()); + + let child_xprv = xprv + .derive_from_path( + &DerivationPath::from_str("m/44'/0'/1'").unwrap(), + Hasher::Sha256ripemd, + ) + .unwrap(); + let child_extended_key = child_xprv.to_extended_key(Prefix::ZPRV).unwrap(); + assert_eq!(child_extended_key.to_string(), "zprvAcwsTZNaY1f7sifgNNgdNa4P9mPtyg3zRVgwkx2qF9Sn7F255MzP6Zyumn6bgV5xuoS8ZrDvjzE7APcFSacXdzFYpGvyybb1bnAoh5nHxpn"); +} + +#[test] +fn test_extended_private_key_mtpv() { + let xprv = XPrvSecp256k1::from_base58("Mtpv7SkyM349Svcf1WiRtB5hC91ZZkVsGuv3kz1V7tThGxBFBzBLFnw6LpaSvwpHHuy8dAfMBqpBvaSAHzbffvhj2TwfojQxM7Ppm3CzW67AFL5", Hasher::Sha256d).unwrap(); + + let path = "m/0/4"; + let child_xprv = xprv + .derive_from_path( + &DerivationPath::from_str(path).unwrap(), + Hasher::Sha256ripemd, + ) + .unwrap(); + + let public_key = child_xprv.public_key(); + assert_eq!( + hex::encode(public_key.to_bytes(), false), + "02c36f9c3051e9cfbb196ecc35311f3ad705ea6798ffbe6b039e70f6bd047e6f2c" + ); +} + +#[test] +fn test_extended_public_key() { + let seed = Mnemonic::to_seed("ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal", ""); + let xprv = XPrvSecp256k1::new(&seed).unwrap(); + + let extended_key = xprv.to_extended_key(Prefix::ZPRV).unwrap(); + let xpub = XPubSecp256k1::try_from(extended_key); + assert!(xpub.is_err()); + + let child_xprv = xprv + .derive_from_path( + &DerivationPath::from_str("m/44'/0'/0'").unwrap(), + Hasher::Sha256ripemd, + ) + .unwrap(); + let child_extended_key = child_xprv.public_key().to_extended_key(Prefix::ZPUB); + assert_eq!(child_extended_key.to_string(), "zpub6qwDs4uUNPDR5A2M56ot1aABSa2MNQciYn9MPS8bTk1qwAaFKcSST5S1aLidvPp9twqpaumG7vikR2vHhBXjp5oGgHyMvWK3AtUkfeEgyns"); + + let child_xprv = xprv + .derive_from_path( + &DerivationPath::from_str("m/44'/0'/1'").unwrap(), + Hasher::Sha256ripemd, + ) + .unwrap(); + let child_extended_key = child_xprv.public_key().to_extended_key(Prefix::ZPUB); + assert_eq!(child_extended_key.to_string(), "zpub6qwDs4uUNPDR6Ck9UQDdji17hoEPP8mqnicYZLSSoUykz3MDcuJdeNJPd3BozqEafeLZkegWqzAvkgA4JZZ5tTN2rDpGKfk54essyfx1eZP"); +} + +#[test] +fn test_get_key_by_curve() { + let deriv_path = "m/44'/539'/0'/0/0"; + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + + // Test with Secp256k1 curve + { + let xprv = XPrvSecp256k1::new(&seed).unwrap(); + let path = DerivationPath::from_str(deriv_path).unwrap(); + let xprv = xprv.derive_from_path(&path, Hasher::Sha256ripemd).unwrap(); + let private_key = xprv.private_key().to_zeroizing_vec(); + assert_eq!( + hex::encode(private_key, false), + "4fb8657d6464adcaa086d6758d7f0b6b6fc026c98dc1671fcc6460b5a74abc62" + ); + } + + // Test with NIST256p1 curve + { + let xprv = XPrvNist256p1::new(&seed).unwrap(); + let path = DerivationPath::from_str(deriv_path).unwrap(); + let xprv = xprv.derive_from_path(&path, Hasher::Sha256ripemd).unwrap(); + + let private_key = xprv.to_zeroizing_vec(); + assert_eq!( + hex::encode(private_key, false), + "a13df52d5a5b438bbf921bbf86276e4347fe8e2f2ed74feaaee12b77d6d26f86" + ); + } +} + +#[test] +fn test_derive_xpub_pub_vs_priv_pub() { + // Test different routes for deriving address from mnemonic, result should be the same: + // - Direct: mnemonic -> seed -> privateKey -> publicKey -> address + // - Extended Public: mnemonic -> seed -> zpub -> publicKey -> address + // - Extended Private: mnemonic -> seed -> zpriv -> privateKey -> publicKey -> address + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let xprv = XPrvSecp256k1::new(&seed).unwrap(); + + let deriv_path1 = DerivationPath::from_str("m/84'/0'/0'/0/0").unwrap(); + let deriv_path2 = DerivationPath::from_str("m/84'/0'/0'/0/2").unwrap(); + let expected_public_key1 = "02df9ef2a7a5552765178b181e1e1afdefc7849985c7dfe9647706dd4fa40df6ac"; + let expected_public_key2 = "031e1f64d2f6768dccb6814545b2e2d58e26ad5f91b7cbaffe881ed572c65060db"; + + // -> privateKey -> publicKey + { + let xprv1 = xprv + .derive_from_path(&deriv_path1, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv1.public_key().to_bytes(), false), + expected_public_key1 + ); + } + { + let xprv2 = xprv + .derive_from_path(&deriv_path2, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv2.public_key().to_bytes(), false), + expected_public_key2 + ); + } + + // zpub -> publicKey + let account_path = DerivationPath::from_str("m/84'/0'/0'").unwrap(); + let account_xprv = xprv + .derive_from_path(&account_path, Hasher::Sha256ripemd) + .unwrap(); + let zpub = account_xprv + .public_key() + .to_extended_key(Prefix::ZPUB) + .to_string(); + assert_eq!(zpub, "zpub6rNUNtxSa9Gxvm4Bdxf1MPMwrvkzwDx6vP96Hkzw3jiQKdg3fhXBStxjn12YixQB8h88B3RMSRscRstf9AEVaYr3MAqVBEWBDuEJU4PGaT9"); + + let deriv_path1 = DerivationPath::from_str("m/0/0").unwrap(); + { + let public_key1 = XPub::from_str(&zpub).unwrap(); + let public_key1 = deriv_path1.iter().fold(public_key1, |key, child_num| { + key.derive_child(child_num).unwrap() //_or(key) + }); + assert_eq!( + hex::encode(public_key1.to_bytes(), false), + expected_public_key1 + ); + } + let deriv_path2 = DerivationPath::from_str("m/0/2").unwrap(); + { + let public_key2 = XPub::from_str(&zpub).unwrap(); + let public_key2 = deriv_path2.iter().fold(public_key2, |key, child_num| { + key.derive_child(child_num).unwrap() //_or(key) + }); + assert_eq!( + hex::encode(public_key2.to_bytes(), false), + expected_public_key2 + ); + } + + // zpriv -> privateKey -> publicKey + let zpriv = account_xprv + .to_extended_key(Prefix::ZPRV) + .unwrap() + .to_string(); + assert_eq!(zpriv, "zprvAdP7yPRYjmifiGyiXw7zzFRDJtvWXmEFZADVVNbKVQBRSqLu8ACvu6eFvhrnnw4QwdTD8PUVa48MguwiPTiyfn85zWx9iA5MYy4Eufu5bas"); + + let deriv_path1 = DerivationPath::from_str("m/0/0").unwrap(); + { + let private_key1 = XPrvSecp256k1::from_base58(&zpriv, Hasher::Sha256d).unwrap(); + let private_key1 = deriv_path1.iter().fold(private_key1, |key, child_num| { + key.derive_child(child_num, Hasher::Sha256ripemd).unwrap() //_or(key) + }); + assert_eq!( + hex::encode(private_key1.public_key().to_bytes(), false), + expected_public_key1 + ); + } + + let deriv_path2 = DerivationPath::from_str("m/0/2").unwrap(); + { + let private_key2 = XPrvSecp256k1::from_base58(&zpriv, Hasher::Sha256d).unwrap(); + let private_key2 = deriv_path2.iter().fold(private_key2, |key, child_num| { + key.derive_child(child_num, Hasher::Sha256ripemd).unwrap() //_or(key) + }); + assert_eq!( + hex::encode(private_key2.public_key().to_bytes(), false), + expected_public_key2 + ); + } +} + +#[test] +fn test_aptos_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let xprv = XPrvEd25519::new(&seed).unwrap(); + + let deriv_path = DerivationPath::from_str("m/44'/637'/0'/0'/0'").unwrap(); + let xprv = xprv + .derive_from_path(&deriv_path, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "7f2634c0e2414a621e96e39c41d09021700cee12ee43328ed094c5580cd0bd6f" + ); + + let public_key = xprv.public_key(); + assert_eq!( + hex::encode(public_key.to_vec(), false), + "633e5c7e355bdd484706436ce1f06fdf280bd7c2229a7f9b6489684412c6967c" + ); + + let child_public_key = public_key.derive_child(bip32::ChildNumber(0), Hasher::Sha256ripemd); + assert!(child_public_key.is_ok()); +} + +#[test] +fn test_cardano_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let entropy = Mnemonic::parse(mnemonic).unwrap().to_entropy(); + let xprv = XPrvCardano::new(&entropy).unwrap(); + + let deriv_path = DerivationPath::from_str("m/44'/637'/0'/0'/0").unwrap(); + let xprv = xprv + .derive_from_path(&deriv_path, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "680113743091be93bcdab47ec2f6a2e3c710812f3f051ebb84ac70aa15a14952c8d771b5dd2726467412ed62c37d6c819c36d1dba83991a8585c31bb4790f2cde5232f0770ce99adfc7e6ec1a5270f52d6435c30ceb51415258d1eaccd28b5fe" + ); + + let extended_key = xprv.to_extended_key(Prefix::ZPRV); + assert!(extended_key.is_err()); + + let public_key = xprv.public_key(); + assert_eq!( + hex::encode(public_key.to_vec(), false), + "797a077d4f2cca772b45fa67ada88502000470adf7f81fcb578357a73649fc76e5232f0770ce99adfc7e6ec1a5270f52d6435c30ceb51415258d1eaccd28b5fe" + ); + + let child_public_key = public_key.derive_child(bip32::ChildNumber(0), Hasher::Sha256ripemd); + assert!(child_public_key.is_ok()); +} + +#[test] +fn test_nano_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let xprv = XPrvEd25519Blake2bNano::new(&seed).unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "d258c2521f7802b8e83c32f2cc97bd06b69747847390c5e247a3d19faa74202e" + ); + let xpub = xprv.public_key(); + assert_eq!( + hex::encode(xpub.to_bytes(), false), + "9833ff5684764ca31955727966df954be334ea051ad8c285eea6e4fbaa549001" + ); + + let deriv_path = DerivationPath::from_str("m/44'/637'/0'/0'").unwrap(); + let xprv = xprv + .derive_from_path(&deriv_path, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "ffd43b8b4273e69a8278b9dbb4ac724134a878adc82927e503145c935b432959" + ); + + let public_key = xprv.public_key(); + assert_eq!( + hex::encode(public_key.to_bytes(), false), + "37d29aff891f03abaa1ea1989cff6de0f46bd677f3ca7b3abb6e7f1c03786540" + ); + + let child_public_key = public_key.derive_child(bip32::ChildNumber(0), Hasher::Sha256ripemd); + assert!(child_public_key.is_ok()); +} + +#[test] +fn test_waves_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let xprv = XPrvCurve25519Waves::new(&seed).unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "7374826cbd731cf656c11b3fdd458084288f655c8fd4056175996655d0fda4c9" + ); + let xpub = xprv.public_key(); + assert_eq!( + hex::encode(xpub.to_bytes(), false), + "b6c00ffdacb469da62062a1dc8218a733a61720ab0942ba3625194281faf7d3d" + ); + + let deriv_path = DerivationPath::from_str("m/44'/5741564'/0'/0'/0").unwrap(); + let xprv = xprv.derive_from_path(&deriv_path, Hasher::Sha256ripemd); + assert!(xprv.is_ok()); + + let child_public_key = xprv + .unwrap() + .public_key() + .derive_child(bip32::ChildNumber(0), Hasher::Sha256ripemd); + assert!(child_public_key.is_ok()); +} + +#[test] +fn test_zilliqa_schnorr_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let xprv = XPrvZilliqaSchnorr::new(&seed).unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "d1b2b553b053f278d510a8494ead811252b1d5ec0da4434d0997a75de92bcea9" + ); + let xpub = xprv.public_key(); + assert_eq!( + hex::encode(xpub.to_bytes(), false), + "02f54cd391076f956b1cfc37cf182c18373f7c1566408c1748132cf4e782498e19" + ); + + let deriv_path = DerivationPath::from_str("m/44'/637'/0'/0'/0").unwrap(); + let xprv = xprv + .derive_from_path(&deriv_path, Hasher::Sha256ripemd) + .unwrap(); + assert_eq!( + hex::encode(xprv.private_key().to_zeroizing_vec(), false), + "4fc45a32e714677a8d3fbed23a8e1afbba8decbf60d479149129342dc894d2a4" + ); + + let public_key = xprv.public_key(); + assert_eq!( + hex::encode(public_key.to_bytes(), false), + "03758382b7e39cf4790a6b4388254e36fa7aedd48e4595ad219687a8495c27d364" + ); + + let child_public_key = public_key.derive_child(bip32::ChildNumber(0), Hasher::Sha256ripemd); + assert!(child_public_key.is_ok()); +} + +#[test] +fn test_nist256p1_key_derivation_failure() { + let private_key = tw_keypair::ecdsa::nist256p1::PrivateKey::from_str( + "a13df52d5a5b438bbf921bbf86276e4347fe8e2f2ed74feaaee12b77d6d26f86", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber(0)); + assert!(child_key.is_err()); + + let public_key = tw_keypair::ecdsa::nist256p1::PublicKey::try_from( + "02d03f2d72c850abe7fbde0507c661a9c940808f751d6d1c08f1c632b632af52ce", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_secp256k1_key_derivation_failure() { + let private_key = tw_keypair::ecdsa::secp256k1::PrivateKey::from_str( + "4fb8657d6464adcaa086d6758d7f0b6b6fc026c98dc1671fcc6460b5a74abc62", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x50], ChildNumber(0)); + assert!(child_key.is_err()); + + let public_key = tw_keypair::ecdsa::secp256k1::PublicKey::try_from( + "023fc76c1210da890c598a3868f267d7d6a2c2c1fa4c60e6e105c9ef9f9f6e6532", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_ed25519_key_derivation() { + let private_key = tw_keypair::ed25519::sha512::PrivateKey::from_str( + "7f2634c0e2414a621e96e39c41d09021700cee12ee43328ed094c5580cd0bd6f", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber::new(0, false).unwrap()); + assert!(child_key.is_ok()); + + let child_key = private_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let public_key = tw_keypair::ed25519::sha512::PublicKey::try_from( + "633e5c7e355bdd484706436ce1f06fdf280bd7c2229a7f9b6489684412c6967c", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_cardano_key_derivation() { + let private_key = tw_keypair::ed25519::cardano::ExtendedPrivateKey::from_str("680113743091be93bcdab47ec2f6a2e3c710812f3f051ebb84ac70aa15a14952c8d771b5dd2726467412ed62c37d6c819c36d1dba83991a8585c31bb4790f2cde5232f0770ce99adfc7e6ec1a5270f52d6435c30ceb51415258d1eaccd28b5fe").unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber(0)); + assert!(child_key.is_ok()); + + let public_key = tw_keypair::ed25519::cardano::ExtendedPublicKey::try_from("797a077d4f2cca772b45fa67ada88502000470adf7f81fcb578357a73649fc76e5232f0770ce99adfc7e6ec1a5270f52d6435c30ceb51415258d1eaccd28b5fe").unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + assert_eq!( + ::bip32_name(), + "ed25519 cardano seed" + ); + + let path = + cardano_staking_derivation_path(&DerivationPath::from_str("m/1852'/1815'/0'/0/0").unwrap()) + .unwrap(); + assert_eq!(path.to_string(), "m/1852'/1815'/0'/2/0"); + + let invalid = + cardano_staking_derivation_path(&DerivationPath::from_str("m/1852'/1815'").unwrap()); + assert!(invalid.is_err()); + + let invalid = + cardano_staking_derivation_path(&DerivationPath::from_str("m/1852'/1815'/0'/4/0").unwrap()); + assert!(invalid.is_err()); +} + +#[test] +fn test_nano_key_derivation_failure() { + let private_key = tw_keypair::ed25519::blake2b::PrivateKey::from_str( + "d258c2521f7802b8e83c32f2cc97bd06b69747847390c5e247a3d19faa74202e", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let public_key = tw_keypair::ed25519::blake2b::PublicKey::try_from( + "9833ff5684764ca31955727966df954be334ea051ad8c285eea6e4fbaa549001", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, false).unwrap()); + assert!(child_key.is_ok()); +} + +#[test] +fn test_wave_key_derivation_failure() { + let private_key = tw_keypair::ed25519::waves::PrivateKey::from_str( + "7374826cbd731cf656c11b3fdd458084288f655c8fd4056175996655d0fda4c9", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let public_key = tw_keypair::ed25519::waves::PublicKey::try_from( + "b6c00ffdacb469da62062a1dc8218a733a61720ab0942ba3625194281faf7d3d", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_zilliqa_schnorr_key_derivation_failure() { + let private_key = tw_keypair::zilliqa_schnorr::PrivateKey::from_str( + "d1b2b553b053f278d510a8494ead811252b1d5ec0da4434d0997a75de92bcea9", + ) + .unwrap(); + let child_key = private_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let public_key = tw_keypair::zilliqa_schnorr::PublicKey::from_str( + "02f54cd391076f956b1cfc37cf182c18373f7c1566408c1748132cf4e782498e19", + ) + .unwrap(); + let child_key = public_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_bip_tweak() { + let private_key = tw_keypair::ecdsa::secp256k1::PrivateKey::from_str( + "4fb8657d6464adcaa086d6758d7f0b6b6fc026c98dc1671fcc6460b5a74abc62", + ) + .unwrap(); + let tweak = private_key.derive_tweak(&[0; 32], ChildNumber::new(0, true).unwrap()); + assert!(tweak.is_ok()); + + let public_key = tw_keypair::ecdsa::secp256k1::PublicKey::try_from( + "023fc76c1210da890c598a3868f267d7d6a2c2c1fa4c60e6e105c9ef9f9f6e6532", + ) + .unwrap(); + let tweak = public_key.derive_tweak(&[0; 32], ChildNumber::new(0, true).unwrap()); + assert!(tweak.is_err()); +} + +#[test] +fn test_invalid_key_cardano() { + #[derive(Clone)] + struct InvalidPrivateKey; + + #[derive(Clone)] + struct InvalidPublicKey; + + impl BIP32PrivateKey for InvalidPrivateKey { + type BIP32PublicKey = InvalidPublicKey; + + fn curve() -> Curve { + Curve::Ed25519ExtendedCardano + } + + fn derive_child(&self, _other: &[u8], _child_number: ChildNumber) -> Result { + Err(Error::InvalidKeyData) + } + + fn bip32_name() -> &'static str { + "InvalidPrivateKey" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + InvalidPublicKey + } + } + + impl BIP32PublicKey for InvalidPublicKey { + fn derive_child(&self, _other: &[u8], _child_number: ChildNumber) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl ToBytesZeroizing for InvalidPrivateKey { + fn to_zeroizing_vec(&self) -> Zeroizing> { + Zeroizing::new(vec![]) + } + } + + impl FromStr for InvalidPrivateKey { + type Err = Error; + + fn from_str(_s: &str) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl ToBytesVec for InvalidPublicKey { + fn to_vec(&self) -> Vec { + vec![] + } + } + + impl TryFrom<&[u8]> for InvalidPrivateKey { + type Error = Error; + + fn try_from(_slice: &[u8]) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl TryFrom<&[u8]> for InvalidPublicKey { + type Error = Error; + + fn try_from(_slice: &[u8]) -> Result { + Err(Error::InvalidKeyData) + } + } + + let xprv = ExtendedPrivateKey::::new("00"); + assert!(xprv.is_err()); + + let invalid_key = InvalidPrivateKey; + let child_key = invalid_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); + + let invalid_key = InvalidPublicKey; + let child_key = invalid_key.derive_child(&[0x00], ChildNumber::new(0, true).unwrap()); + assert!(child_key.is_err()); +} + +#[test] +fn test_invalid_key_secp256k1() { + #[derive(Clone)] + struct InvalidPrivateKey; + + #[derive(Clone)] + struct InvalidPublicKey; + + impl BIP32PrivateKey for InvalidPrivateKey { + type BIP32PublicKey = InvalidPublicKey; + + fn curve() -> Curve { + Curve::Secp256k1 + } + + fn derive_child(&self, _other: &[u8], _child_number: ChildNumber) -> Result { + Err(Error::InvalidKeyData) + } + + fn bip32_name() -> &'static str { + "InvalidPrivateKey" + } + + fn public_key(&self) -> Self::BIP32PublicKey { + InvalidPublicKey + } + } + + impl BIP32PublicKey for InvalidPublicKey { + fn derive_child(&self, _other: &[u8], _child_number: ChildNumber) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl ToBytesZeroizing for InvalidPrivateKey { + fn to_zeroizing_vec(&self) -> Zeroizing> { + Zeroizing::new(vec![]) + } + } + + impl FromStr for InvalidPrivateKey { + type Err = Error; + + fn from_str(_s: &str) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl ToBytesVec for InvalidPublicKey { + fn to_vec(&self) -> Vec { + vec![] + } + } + + impl TryFrom<&[u8]> for InvalidPrivateKey { + type Error = Error; + + fn try_from(_slice: &[u8]) -> Result { + Err(Error::InvalidKeyData) + } + } + + impl TryFrom<&[u8]> for InvalidPublicKey { + type Error = Error; + + fn try_from(_slice: &[u8]) -> Result { + Err(Error::InvalidKeyData) + } + } + + let xprv = ExtendedPrivateKey::::new("00"); + assert!(xprv.is_err()); +} + +#[test] +fn test_error_from_slice_error() { + let test = |vec: Vec| -> Result<[u8; 4]> { Ok(vec.as_slice().try_into()?) }; + + assert!(test(vec![1, 2, 3]).unwrap_err() == Error::Decode); + assert!(test(vec![1, 2, 3, 4]).is_ok()); +} + +#[test] +fn test_error_from_hex_error() { + let test = |hex: &str| -> Result<()> { + let _ = hex::decode(hex)?; + Ok(()) + }; + + assert!(test("ZZ").unwrap_err() == Error::Decode); + assert!(test("eaab").is_ok()); +} + +#[test] +fn test_error_from_base58_encode_error() { + let test = |vec: Vec| -> Result<()> { + let mut buffer = [0u8; 100]; + let _ = bs58::encode(vec).onto(buffer.as_mut())?; + Ok(()) + }; + + assert!(test(vec![0; 300]).unwrap_err() == Error::Base58); + assert!(test(vec![1, 2, 3, 4]).is_ok()); +} + +#[test] +fn test_error_from_base58_decode_error() { + let test = |base58: &str| -> Result<()> { + let _ = bs58::decode(base58).into_vec()?; + Ok(()) + }; + + assert!(test("hello world").unwrap_err() == Error::Base58); + assert!(test("eaab").is_ok()); +} + +#[test] +fn test_error_from_key_pair_error() { + let test = |data: &[u8]| -> Result<()> { + let _ = tw_keypair::ecdsa::nist256p1::PrivateKey::try_from(data)?; + Ok(()) + }; + + assert!(test(&[1, 2, 3, 4]).unwrap_err() == Error::InvalidKeyData); +} diff --git a/rust/tw_crypto/tests/hd_node_ffi.rs b/rust/tw_crypto/tests/hd_node_ffi.rs new file mode 100644 index 00000000000..3068382ed80 --- /dev/null +++ b/rust/tw_crypto/tests/hd_node_ffi.rs @@ -0,0 +1,935 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::crypto_hd_node::hd_node::HDNode; +use tw_crypto::crypto_mnemonic::mnemonic::Mnemonic; +use tw_crypto::ffi::crypto_hd_node::{ + tw_hd_node_chain_code, tw_hd_node_child_number, tw_hd_node_create_with_extended_private_key, + tw_hd_node_create_with_seed, tw_hd_node_delete, tw_hd_node_depth, tw_hd_node_derive_from_path, + tw_hd_node_extended_private_key, tw_hd_node_extended_public_key, tw_hd_node_private_key_data, + tw_hd_node_public_key_data, TWHDNode, +}; +use tw_crypto::ffi::crypto_hd_node_public::{ + tw_hd_node_public_create_with_extended_public_key, tw_hd_node_public_derive_from_path, + tw_hd_node_public_public_key_data, TWHDNodePublic, +}; +use tw_crypto::ffi::crypto_mnemonic::{tw_mnemonic_to_entropy, tw_mnemonic_to_seed}; +use tw_encoding::hex; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_memory::ffi::{tw_data::TWData, tw_string::TWString, RawPtrTrait}; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; +use tw_memory::test_utils::tw_string_helper::TWStringHelper; +use tw_misc::traits::ToBytesVec; + +const BIP39_TEST_VECTORS: &str = include_str!("bip39_vectors.json"); + +#[test] +fn test_extended_private_key() { + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let seed = Mnemonic::to_seed(mnemonic, ""); + let hd_node = HDNode::new(&seed, Curve::Secp256k1).unwrap(); + + // BIP44 purpose and Bitcoin coin type + let purpose = 44; + let coin = 0; + + // ZPRV version + let hd_version = 0x04b2430c; + + // default path m/44'/0'/0' + let path = format!("m/{}'/{}'/{}'", purpose, coin, 0); + let derived_node = hd_node + .derive_from_path(&path, Hasher::Sha256ripemd) + .unwrap(); + let ext_priv_key1 = derived_node + .extended_private_key(hd_version, Hasher::Sha256d) + .unwrap(); + assert_eq!(ext_priv_key1, "zprvAcwsTZNaY1f7rfwsy5GseSDStYBrxwtsBZDkb3iyuQUs4NF6n58BuH7Xj54RuaSCWtU5CiQzuYQgFgqr1HokgKcVAeGeXokhJUAJeP3VmvY"); + + // explicitly specify default account=0 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 0); + let derived_node = hd_node + .derive_from_path(&path, Hasher::Sha256ripemd) + .unwrap(); + let ext_priv_key2 = derived_node + .extended_private_key(hd_version, Hasher::Sha256d) + .unwrap(); + assert_eq!(ext_priv_key2, "zprvAcwsTZNaY1f7rfwsy5GseSDStYBrxwtsBZDkb3iyuQUs4NF6n58BuH7Xj54RuaSCWtU5CiQzuYQgFgqr1HokgKcVAeGeXokhJUAJeP3VmvY"); + + // custom account=1 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 1); + let derived_node = hd_node + .derive_from_path(&path, Hasher::Sha256ripemd) + .unwrap(); + let ext_priv_key3 = derived_node + .extended_private_key(hd_version, Hasher::Sha256d) + .unwrap(); + assert_eq!(ext_priv_key3, "zprvAcwsTZNaY1f7sifgNNgdNa4P9mPtyg3zRVgwkx2qF9Sn7F255MzP6Zyumn6bgV5xuoS8ZrDvjzE7APcFSacXdzFYpGvyybb1bnAoh5nHxpn"); +} + +#[test] +fn test_extended_private_key_ffi() { + let curve: Curve = Curve::Secp256k1; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let chain_code = unsafe { tw_hd_node_chain_code(hd_node_ptr) }; + assert!(!chain_code.is_null()); + + let pubkey_hasher = Hasher::Sha256ripemd; + + let base58_hasher = Hasher::Sha256d; + + // BIP44 purpose and Bitcoin coin type + let purpose = 44; + let coin = 0; + + // ZPRV version + let hd_version = 0x04b2430c; + + // explicitly specify default account=0 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 0); + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + let derived_node = unsafe { TWHDNode::from_ptr_as_ref(derived_node_ptr).unwrap() }; + + let ext_priv_key = + unsafe { tw_hd_node_extended_private_key(derived_node, hd_version, base58_hasher as u32) }; + let ext_priv_key_string = unsafe { TWString::from_ptr_as_ref(ext_priv_key).unwrap() }; + let ext_priv_key_string = ext_priv_key_string.as_str().unwrap(); + assert_eq!(ext_priv_key_string, "zprvAcwsTZNaY1f7rfwsy5GseSDStYBrxwtsBZDkb3iyuQUs4NF6n58BuH7Xj54RuaSCWtU5CiQzuYQgFgqr1HokgKcVAeGeXokhJUAJeP3VmvY"); + + // custom account=1 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 1); + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + let derived_node = unsafe { TWHDNode::from_ptr_as_ref(derived_node_ptr).unwrap() }; + + let ext_priv_key = + unsafe { tw_hd_node_extended_private_key(derived_node, hd_version, base58_hasher as u32) }; + let ext_priv_key_string = unsafe { TWString::from_ptr_as_ref(ext_priv_key).unwrap() }; + let ext_priv_key_string = ext_priv_key_string.as_str().unwrap(); + assert_eq!(ext_priv_key_string, "zprvAcwsTZNaY1f7sifgNNgdNa4P9mPtyg3zRVgwkx2qF9Sn7F255MzP6Zyumn6bgV5xuoS8ZrDvjzE7APcFSacXdzFYpGvyybb1bnAoh5nHxpn"); + + let depth = unsafe { tw_hd_node_depth(derived_node_ptr) }; + assert_eq!(depth, 3); + + let child_number = unsafe { tw_hd_node_child_number(derived_node_ptr) }; + assert_eq!(child_number, 2147483649); + + unsafe { tw_hd_node_delete(hd_node_ptr) }; +} + +#[test] +fn test_extended_private_key_nist256p1_ffi() { + let curve: Curve = Curve::Nist256p1; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let chain_code = unsafe { tw_hd_node_chain_code(hd_node_ptr) }; + assert!(!chain_code.is_null()); + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/539'/0'/0/0"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, false), + "a13df52d5a5b438bbf921bbf86276e4347fe8e2f2ed74feaaee12b77d6d26f86" + ); + + let pubkey_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + assert!(!pubkey_data.is_null()); + + let depth = unsafe { tw_hd_node_depth(derived_node_ptr) }; + assert_eq!(depth, 5); + + let child_number = unsafe { tw_hd_node_child_number(derived_node_ptr) }; + assert_eq!(child_number, 0); +} + +#[test] +fn test_extended_private_key_ed25519_blake2b_ffi() { + let curve: Curve = Curve::Ed25519Blake2bNano; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/637'/0'/0'"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, false), + "ffd43b8b4273e69a8278b9dbb4ac724134a878adc82927e503145c935b432959" + ); + + let pubkey_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + let pubkey_bytes = unsafe { TWData::from_ptr_as_ref(pubkey_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(pubkey_bytes, false), + "37d29aff891f03abaa1ea1989cff6de0f46bd677f3ca7b3abb6e7f1c03786540" + ); + + let chain_code = unsafe { tw_hd_node_chain_code(hd_node_ptr) }; + assert!(!chain_code.is_null()); + + let depth = unsafe { tw_hd_node_depth(derived_node_ptr) }; + assert_eq!(depth, 4); + + let child_number = unsafe { tw_hd_node_child_number(derived_node_ptr) }; + assert_eq!(child_number, 2147483648); +} + +#[test] +fn test_extended_private_key_waves_ffi() { + let curve: Curve = Curve::Curve25519Waves; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(hd_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, false), + "7374826cbd731cf656c11b3fdd458084288f655c8fd4056175996655d0fda4c9" + ); + + let pubkey_data = unsafe { tw_hd_node_public_key_data(hd_node_ptr) }; + let pubkey_bytes = unsafe { TWData::from_ptr_as_ref(pubkey_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(pubkey_bytes, false), + "b6c00ffdacb469da62062a1dc8218a733a61720ab0942ba3625194281faf7d3d" + ); + + let chain_code = unsafe { tw_hd_node_chain_code(hd_node_ptr) }; + assert!(!chain_code.is_null()); + + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/5741564'/0'/0'/0'"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + assert!(!derived_node_ptr.is_null()); + + let depth = unsafe { tw_hd_node_depth(derived_node_ptr) }; + assert_eq!(depth, 5); + + let child_number = unsafe { tw_hd_node_child_number(derived_node_ptr) }; + assert_eq!(child_number, 2147483648); +} + +#[test] +fn test_extended_private_key_zillqa_schnorr_ffi() { + let curve: Curve = Curve::ZilliqaSchnorr; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(hd_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, false), + "d1b2b553b053f278d510a8494ead811252b1d5ec0da4434d0997a75de92bcea9" + ); + + let pubkey_data = unsafe { tw_hd_node_public_key_data(hd_node_ptr) }; + let pubkey_bytes = unsafe { TWData::from_ptr_as_ref(pubkey_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(pubkey_bytes, false), + "02f54cd391076f956b1cfc37cf182c18373f7c1566408c1748132cf4e782498e19" + ); + + let chain_code = unsafe { tw_hd_node_chain_code(hd_node_ptr) }; + assert!(!chain_code.is_null()); + + let depth = unsafe { tw_hd_node_depth(hd_node_ptr) }; + assert_eq!(depth, 0); + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/637'/0'/0'/0"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node_ptr, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, false), + "4fc45a32e714677a8d3fbed23a8e1afbba8decbf60d479149129342dc894d2a4" + ); + + let pubkey_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + let pubkey_bytes = unsafe { TWData::from_ptr_as_ref(pubkey_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(pubkey_bytes, false), + "03758382b7e39cf4790a6b4388254e36fa7aedd48e4595ad219687a8495c27d364" + ); + + let depth = unsafe { tw_hd_node_depth(derived_node_ptr) }; + assert_eq!(depth, 5); + + let child_number = unsafe { tw_hd_node_child_number(derived_node_ptr) }; + assert_eq!(child_number, 0); +} + +#[test] +fn test_extended_public_key_ffi() { + let curve: Curve = Curve::Secp256k1; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create("TREZOR"); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + // BIP44 purpose and Bitcoin coin type + let purpose = 44; + let coin = 42; + + // DPRV version + let prv_hd_version = 0x2fda4e8; + let pub_hd_version = 0x2fda926; + + let pubkey_hasher = Hasher::Blake256ripemd; + + let base58_hasher = Hasher::Blake256d; + + // explicitly specify default account=0 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 0); + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + let derived_node = unsafe { TWHDNode::from_ptr_as_ref(derived_node_ptr).unwrap() }; + + let ext_pub_key = unsafe { + tw_hd_node_extended_public_key(derived_node, pub_hd_version, base58_hasher as u32) + }; + let ext_pub_key_string = unsafe { TWString::from_ptr_as_ref(ext_pub_key).unwrap() }; + let ext_pub_key_string = ext_pub_key_string.as_str().unwrap(); + assert_eq!(ext_pub_key_string, "dpubZFUmm9oh5zmQkR2Tr2AXS4tCkTWg4B27SpCPFkapZrrAqgU1EwgEFgrmi6EnLGXhak86yDHhXPxFAnGU58W5S4e8NCKG1ASUVaxwRqqNdfP"); + + let ext_priv_key = unsafe { + tw_hd_node_extended_private_key(derived_node, prv_hd_version, base58_hasher as u32) + }; + let ext_priv_key_string = unsafe { TWString::from_ptr_as_ref(ext_priv_key).unwrap() }; + let ext_priv_key_string = ext_priv_key_string.as_str().unwrap(); + assert_eq!(ext_priv_key_string, "dprv3oggQ2FQ1chcr18hbW7Aur5x8SxQdES3FGa4WqeTZnFY88SNMzLdB7LkZLroF4bGAqWS8sDm3w4DKyYV7sDKfC6JMSVHnVJdpDLgHioq1vq"); +} + +#[test] +fn test_private_key_from_xprv() { + use tw_keypair::ecdsa::secp256k1::PrivateKey; + + let xprv = "xprv9yqEgpMG2KCjvotCxaiMkzmKJpDXz2xZi3yUe4XsURvo9DUbPySW1qRbdeDLiSxZt88hESHUhm2AAe2EqfWM9ucdQzH3xv1HoKoLDqHMK9n"; + let xprv_string = TWStringHelper::create(xprv); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_create_with_extended_private_key( + xprv_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/0/3"; + let path_string = TWStringHelper::create(path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node_ptr, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + assert!(!private_key_data.is_null()); + + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + let private_key = PrivateKey::try_from(private_key_bytes.as_slice()).unwrap(); + let public_key = private_key.public(); + + let public_key_hex = hex::encode(public_key.to_vec(), false); + assert_eq!( + public_key_hex, + "025108168f7e5aad52f7381c18d8f880744dbee21dc02c15abe512da0b1cca7e2f" + ); +} + +#[test] +fn test_private_key_from_xprv_invalid() { + let pubkey_hasher = Hasher::Sha256ripemd; + + { + // Version bytes (first 4) are invalid, 0x00000000 + let xprv = "11117pE7xwz2GARukXY8Vj2ge4ozfX4HLgy5ztnJXjr5btzJE8EbtPhZwrcPWAodW2aFeYiXkXjSxJYm5QrnhSKFXDgACcFdMqGns9VLqESCq3"; + let xprv_string = TWStringHelper::create(xprv); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_create_with_extended_private_key( + xprv_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let path = "m/0/3"; + let path_string = TWStringHelper::create(path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node_ptr, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + assert!(private_key_data.is_null()); + } + + { + // Version bytes (first 4) are invalid, 0xdeadbeef + let xprv = "pGoh3VZXR4mTkT4bfqj4paog12KmHkAWkdLY8HNsZagD1ihVccygLr1ioLBhVQsny47uEh5swP3KScFc4JJrazx1Y7xvzmH2y5AseLgVMwomBTg2"; + let xprv_string = TWStringHelper::create(xprv); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_create_with_extended_private_key( + xprv_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let path = "m/0/3"; + let path_string = TWStringHelper::create(path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node_ptr, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + assert!(private_key_data.is_null()); + } +} + +#[test] +fn test_derive_xpub_pub_vs_priv_pub() { + // Test different routes for deriving address from mnemonic, result should be the same: + // - Direct: mnemonic -> seed -> privateKey -> publicKey -> address + // - Extended Public: mnemonic -> seed -> zpub -> publicKey -> address + // - Extended Private: mnemonic -> seed -> zpriv -> privateKey -> publicKey -> address + let curve: Curve = Curve::Secp256k1; + + let mnemonic = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let deriv_path1 = "m/84'/0'/0'/0/0"; + let deriv_path2 = "m/84'/0'/0'/0/2"; + let expected_public_key1 = "02df9ef2a7a5552765178b181e1e1afdefc7849985c7dfe9647706dd4fa40df6ac"; + let expected_public_key2 = "031e1f64d2f6768dccb6814545b2e2d58e26ad5f91b7cbaffe881ed572c65060db"; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let base58_hasher = Hasher::Sha256d; + + // -> privateKey -> publicKey + { + let path_string = TWStringHelper::create(deriv_path1); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode( + tw_keypair::ecdsa::secp256k1::PrivateKey::try_from(private_key_bytes.as_slice()) + .unwrap() + .public() + .to_vec(), + false, + ); + assert_eq!(public_key_hex, expected_public_key1); + } + { + let path_string = TWStringHelper::create(deriv_path2); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode( + tw_keypair::ecdsa::secp256k1::PrivateKey::try_from(private_key_bytes.as_slice()) + .unwrap() + .public() + .to_vec(), + false, + ); + assert_eq!(public_key_hex, expected_public_key2); + } + + // zpub -> publicKey + let account_path = "m/84'/0'/0'"; + let account_path_string = TWStringHelper::create(account_path); + let account_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, account_path_string.ptr(), pubkey_hasher as u32) + }; + let account_node = unsafe { TWHDNode::from_ptr_as_ref(account_node_ptr).unwrap() }; + + let zpub_version = 0x04b24746; // TWHDVersionZPUB + let zpub_ptr = + unsafe { tw_hd_node_extended_public_key(account_node, zpub_version, base58_hasher as u32) }; + let zpub = unsafe { + TWString::from_ptr_as_ref(zpub_ptr) + .unwrap() + .as_str() + .unwrap() + }; + + assert_eq!(zpub, "zpub6rNUNtxSa9Gxvm4Bdxf1MPMwrvkzwDx6vP96Hkzw3jiQKdg3fhXBStxjn12YixQB8h88B3RMSRscRstf9AEVaYr3MAqVBEWBDuEJU4PGaT9"); + + { + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + zpub_ptr, + curve.to_raw(), + Hasher::Sha256d as u32, + ) + }; + let hd_node = unsafe { TWHDNodePublic::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let child_path = "m/0/0"; + let child_path_string = TWStringHelper::create(child_path); + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path( + hd_node, + child_path_string.ptr(), + pubkey_hasher as u32, + ) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + let public_key_bytes = + unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode(public_key_bytes, false); + assert_eq!(public_key_hex, expected_public_key1); + } + + { + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + zpub_ptr, + curve.to_raw(), + Hasher::Sha256d as u32, + ) + }; + let hd_node = unsafe { TWHDNodePublic::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let child_path = "m/0/2"; + let child_path_string = TWStringHelper::create(child_path); + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path( + hd_node, + child_path_string.ptr(), + pubkey_hasher as u32, + ) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + let public_key_bytes = + unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode(public_key_bytes, false); + assert_eq!(public_key_hex, expected_public_key2); + } + + // zpriv -> privateKey -> publicKey + let zpriv_version = 0x04b2430c; // TWHDVersionZPRV + let zpriv_ptr = unsafe { + tw_hd_node_extended_private_key(account_node, zpriv_version, base58_hasher as u32) + }; + let zpriv = unsafe { + TWString::from_ptr_as_ref(zpriv_ptr) + .unwrap() + .as_str() + .unwrap() + }; + + assert_eq!(zpriv, "zprvAdP7yPRYjmifiGyiXw7zzFRDJtvWXmEFZADVVNbKVQBRSqLu8ACvu6eFvhrnnw4QwdTD8PUVa48MguwiPTiyfn85zWx9iA5MYy4Eufu5bas"); + + { + let zpriv_string = TWStringHelper::create(zpriv); + let zpriv_node_ptr = unsafe { + tw_hd_node_create_with_extended_private_key( + zpriv_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let child_path = "m/0/0"; + let child_path_string = TWStringHelper::create(child_path); + let child_node_ptr = unsafe { + tw_hd_node_derive_from_path( + zpriv_node_ptr, + child_path_string.ptr(), + pubkey_hasher as u32, + ) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(child_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode( + tw_keypair::ecdsa::secp256k1::PrivateKey::try_from(private_key_bytes.as_slice()) + .unwrap() + .public() + .to_vec(), + false, + ); + assert_eq!(public_key_hex, expected_public_key1); + } + { + let zpriv_string = TWStringHelper::create(zpriv); + let zpriv_node_ptr = unsafe { + tw_hd_node_create_with_extended_private_key( + zpriv_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let child_path = "m/0/2"; + let child_path_string = TWStringHelper::create(child_path); + let child_node_ptr = unsafe { + tw_hd_node_derive_from_path( + zpriv_node_ptr, + child_path_string.ptr(), + pubkey_hasher as u32, + ) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(child_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + let public_key_hex = hex::encode( + tw_keypair::ecdsa::secp256k1::PrivateKey::try_from(private_key_bytes.as_slice()) + .unwrap() + .public() + .to_vec(), + false, + ); + assert_eq!(public_key_hex, expected_public_key2); + } +} + +#[test] +fn test_hedera_key() { + let curve: Curve = Curve::Ed25519; + + // Hedera specific DER prefixes + let hedera_der_prefix_private = "302e020100300506032b657004220420"; + let hedera_der_prefix_public = "302a300506032b6570032100"; + + let pubkey_hasher = Hasher::Sha256ripemd; + + { + let mnemonic = "inmate flip alley wear offer often piece magnet surge toddler submit right radio absent pear floor belt raven price stove replace reduce plate home"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = + unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let path = "m/44'/3030'/0'/0'/0"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + let public_key_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + let public_key_bytes = + unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + + assert_eq!( + format!("{}{}", hedera_der_prefix_private, hex::encode(private_key_bytes, false)), + "302e020100300506032b657004220420853f15aecd22706b105da1d709b4ac05b4906170c2b9c7495dff9af49e1391da" + ); + assert_eq!( + format!("{}{}", hedera_der_prefix_public, hex::encode(public_key_bytes, false)), + "302a300506032b6570032100b63b3815f453cf697b53b290b1d78e88c725d39bde52c34c79fb5b4c93894673" + ); + } + + { + let mnemonic = + "walk gun glide frequent exhaust sugar siege prosper staff skill swarm label"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = + unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let path = "m/44'/3030'/0'/0'/0"; + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) + }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = + unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + let public_key_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + let public_key_bytes = + unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + + assert_eq!( + format!("{}{}", hedera_der_prefix_private, hex::encode(private_key_bytes, false)), + "302e020100300506032b657004220420650c5120cbdc6244e3d10001eb27eea4dd3f80c331b3b6969fa434797d4edd50" + ); + assert_eq!( + format!("{}{}", hedera_der_prefix_public, hex::encode(public_key_bytes, false)), + "302a300506032b65700321007df3e1ab790b28de4706d36a7aa99a0e043cb3e2c3d6ec6686e4af7f638b0860" + ); + } +} + +#[test] +fn test_cardano_key() { + let mnemonic = "cost dash dress stove morning robust group affair stomach vacant route volume yellow salute laugh"; + let mnemonic_string = TWStringHelper::create(mnemonic); + + let seed_ptr = unsafe { tw_mnemonic_to_entropy(mnemonic_string.ptr()) }; + + let curve = Curve::Ed25519ExtendedCardano; + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let deriv_path = "m/1852'/1815'/0'/0/0"; + let path_string = TWStringHelper::create(deriv_path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + + let public_key_data = unsafe { tw_hd_node_public_key_data(derived_node_ptr) }; + let public_key_bytes = unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(public_key_bytes, false), + "fafa7eb4146220db67156a03a5f7a79c666df83eb31abbfbe77c85e06d40da3110f3245ddf9132ecef98c670272ef39c03a232107733d4a1d28cb53318df26faf4b8d5201961e68f2e177ba594101f513ee70fe70a41324e8ea8eb787ffda6f4bf2eea84515a4e16c4ff06c92381822d910b5cbf9e9c144e1fb76a6291af7276" + ); + + let invalid_deriv_path = "m/1852'/1815'/'/0/0"; + let invalid_path_string = TWStringHelper::create(invalid_deriv_path); + let invalid_derived_node_ptr = unsafe { + tw_hd_node_derive_from_path(hd_node, invalid_path_string.ptr(), pubkey_hasher as u32) + }; + assert!(invalid_derived_node_ptr.is_null()); +} + +#[test] +fn test_bip39_vectors() { + // BIP39 test vectors, from https://github.com/trezor/python-mnemonic/blob/master/vectors.json + let vectors: serde_json::Value = serde_json::from_str(&BIP39_TEST_VECTORS).unwrap(); + let english_vectors = vectors["english"].as_array().unwrap(); + + let curve: Curve = Curve::Secp256k1; + let base58_hasher = Hasher::Sha256d; + let version = 0x0488ade4; + + for v in english_vectors { + let seed = v[2].as_str().unwrap(); + let xprv = v[3].as_str().unwrap(); + + let seed_data = TWDataHelper::create(hex::decode(seed).unwrap()); + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_data.ptr(), curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let xprv_ptr = + unsafe { tw_hd_node_extended_private_key(hd_node, version, base58_hasher as u32) }; + let xprv_string = unsafe { + TWString::from_ptr_as_ref(xprv_ptr) + .unwrap() + .as_str() + .unwrap() + }; + assert_eq!(xprv_string, xprv); + } +} + +#[test] +fn test_extended_public_key_iost_ffi() { + let curve: Curve = Curve::Ed25519; + + let mnemonic = "often tobacco bread scare imitate song kind common bar forest yard wisdom"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + // BIP44 purpose and Bitcoin coin type + let purpose = 44; + let coin = 899; + + // XPUB + let pub_hd_version = 0x0488b21e; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let base58_hasher = Hasher::Sha256d; + + // // explicitly specify default account=0 + let path = format!("m/{}'/{}'/{}'", purpose, coin, 0); + let path_string = TWStringHelper::create(&path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + let derived_node = unsafe { TWHDNode::from_ptr_as_ref(derived_node_ptr).unwrap() }; + + let ext_pub_key = unsafe { + tw_hd_node_extended_public_key(derived_node, pub_hd_version, base58_hasher as u32) + }; + let ext_pub_key_string = unsafe { TWString::from_ptr_as_ref(ext_pub_key).unwrap() }; + let ext_pub_key_string = ext_pub_key_string.as_str().unwrap(); + assert_eq!(ext_pub_key_string, "xpub6CazMhni6xNtFaEeRqeaa2S3LyfrQWXk8YoEykEUyKpYyxqxG18HSo3e8Kkco5YkEddiCEF1pav6gXy71sGFKMux9rcdc8TCEfZG662hhxg"); +} + +#[test] +fn test_aeternity_key() { + let curve: Curve = Curve::Ed25519; + + let mnemonic = + "shoot island position soft burden budget tooth cruel issue economy destroy above"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/457'/0'/0'/0'"; + let path_string = TWStringHelper::create(path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + assert!(!derived_node_ptr.is_null()); + // let derived_node = unsafe { TWHDNode::from_ptr_as_ref(derived_node_ptr).unwrap() }; +} + +#[test] +fn test_binance_key() { + let curve: Curve = Curve::Secp256k1; + + let mnemonic = "rabbit tilt arm protect banner ill produce vendor april bike much identify pond upset front easily glass gallery address hair priority focus forest angle"; + let mnemonic_string = TWStringHelper::create(mnemonic); + let passphrase_string = TWStringHelper::create(""); + + let seed_ptr = unsafe { tw_mnemonic_to_seed(mnemonic_string.ptr(), passphrase_string.ptr()) }; + + let hd_node_ptr = unsafe { tw_hd_node_create_with_seed(seed_ptr, curve.to_raw()) }; + let hd_node = unsafe { TWHDNode::from_ptr_as_ref(hd_node_ptr).unwrap() }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(hd_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + assert_eq!( + hex::encode(private_key_bytes, true), + "0xfdf3a7c4962ac691f9fe4058521c7ea388be14f24d2340fe0a4a8105a60e666d" + ); + + let pubkey_hasher = Hasher::Sha256ripemd; + + let path = "m/44'/714'/0'/0/0"; + let path_string = TWStringHelper::create(path); + let derived_node_ptr = + unsafe { tw_hd_node_derive_from_path(hd_node, path_string.ptr(), pubkey_hasher as u32) }; + + let private_key_data = unsafe { tw_hd_node_private_key_data(derived_node_ptr) }; + let private_key_bytes = unsafe { TWData::from_ptr_as_ref(private_key_data).unwrap().to_vec() }; + + assert_eq!( + hex::encode(private_key_bytes, true), + "0x727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06" + ); +} diff --git a/rust/tw_crypto/tests/hd_node_public_ffi.rs b/rust/tw_crypto/tests/hd_node_public_ffi.rs new file mode 100644 index 00000000000..0fc6e1d749b --- /dev/null +++ b/rust/tw_crypto/tests/hd_node_public_ffi.rs @@ -0,0 +1,155 @@ +// Copyright © 2017-2023 Trust Wallet. +// +// This file is part of Trust. The full Trust copyright notice, including +// terms governing use, modification, and redistribution, is contained in the +// file LICENSE at the root of the source code distribution tree. + +use tw_crypto::ffi::crypto_hd_node_public::{ + tw_hd_node_public_create_with_extended_public_key, tw_hd_node_public_delete, + tw_hd_node_public_derive_from_path, tw_hd_node_public_public_key_data, +}; +use tw_encoding::hex; +use tw_hash::hasher::Hasher; +use tw_keypair::tw::Curve; +use tw_memory::ffi::{tw_data::TWData, RawPtrTrait}; +use tw_memory::test_utils::tw_string_helper::TWStringHelper; +use tw_misc::traits::ToBytesVec; + +#[test] +fn test_public_key_from_zpub() { + use tw_keypair::ecdsa::secp256k1::PublicKey; + + let zpub = "zpub6rNUNtxSa9Gxvm4Bdxf1MPMwrvkzwDx6vP96Hkzw3jiQKdg3fhXBStxjn12YixQB8h88B3RMSRscRstf9AEVaYr3MAqVBEWBDuEJU4PGaT9"; + let zpub_string = TWStringHelper::create(zpub); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + zpub_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let path = "m/0/0"; + let path_string = TWStringHelper::create(path); + + let hasher = Hasher::Sha256ripemd; + + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path(hd_node_ptr, path_string.ptr(), hasher as u32) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + assert!(!public_key_data.is_null()); + + let public_key_bytes = unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + let public_key = PublicKey::try_from(public_key_bytes.as_slice()).unwrap(); + + let public_key_hex = hex::encode(public_key.to_vec(), false); + assert_eq!( + public_key_hex, + "02df9ef2a7a5552765178b181e1e1afdefc7849985c7dfe9647706dd4fa40df6ac" + ); + + unsafe { tw_hd_node_public_delete(hd_node_ptr) }; +} + +#[test] +fn test_public_key_from_dpub() { + use tw_keypair::ecdsa::secp256k1::PublicKey; + + let zpub = "dpubZFUmm9oh5zmQkR2Tr2AXS4tCkTWg4B27SpCPFkapZrrAqgU1EwgEFgrmi6EnLGXhak86yDHhXPxFAnGU58W5S4e8NCKG1ASUVaxwRqqNdfP"; + let zpub_string = TWStringHelper::create(zpub); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + zpub_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Blake256d as u32, + ) + }; + + let path = "m/0/0"; + let path_string = TWStringHelper::create(path); + + let hasher = Hasher::Blake256ripemd; + + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path(hd_node_ptr, path_string.ptr(), hasher as u32) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + assert!(!public_key_data.is_null()); + + let public_key_bytes = unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + let public_key = PublicKey::try_from(public_key_bytes.as_slice()).unwrap(); + + let public_key_hex = hex::encode(public_key.to_vec(), false); + assert_eq!( + public_key_hex, + "035328794a9392d6618c0f8071d2ba25fecef85230d916c2ef17f578af70483103" + ); +} + +#[test] +fn test_public_key_from_extended_ethereum() { + let xpub = "xpub6C7LtZJgtz1BKXG9mExKUxYvX7HSF38UMMmGbpqNQw3DfYwAw8E6sH7VSVxFipvEEm2afSqTjoRgcLmycXX4zfxCWJ4HY73a9KdgvfHEQGB"; + let xpub_string = TWStringHelper::create(xpub); + + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + xpub_string.ptr(), + Curve::Secp256k1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + assert!(!hd_node_ptr.is_null()); + + let hasher = Hasher::Sha256ripemd; + let path = "m/0/1"; + let path_string = TWStringHelper::create(path); + + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path(hd_node_ptr, path_string.ptr(), hasher as u32) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + assert!(!public_key_data.is_null()); + + let public_key_bytes = unsafe { TWData::from_ptr_as_ref(public_key_data).unwrap().to_vec() }; + + let public_key_hex = hex::encode(public_key_bytes, false); + assert_eq!( + public_key_hex, + "024516c4aa5352035e1bb5be132694e1389a4ac37d32e5e717d35ee4c4dfab5132" + ); +} + +#[test] +fn test_public_key_from_zpub_nist() { + let zpub = "zpub6vBy1RjDYQ9EQZJYiWM1qvSdxKyjmEETobMBD9T9bwwmSGX1y4XrSDAKBZzHCjckGoh8gMEFmx3qyUEU2kcg3wMtUG5CpTtpqdzf8YShMLg"; + let zpub_string = TWStringHelper::create(zpub); + + // Create HDNode from extended private key + let hd_node_ptr = unsafe { + tw_hd_node_public_create_with_extended_public_key( + zpub_string.ptr(), + Curve::Nist256p1.to_raw(), + Hasher::Sha256d as u32, + ) + }; + + let path = "m/0/0"; + let path_string = TWStringHelper::create(path); + + let hasher = Hasher::Sha256ripemd; + + let derived_node_ptr = unsafe { + tw_hd_node_public_derive_from_path(hd_node_ptr, path_string.ptr(), hasher as u32) + }; + + let public_key_data = unsafe { tw_hd_node_public_public_key_data(derived_node_ptr) }; + assert!(!public_key_data.is_null()); +} diff --git a/rust/tw_hash/Cargo.toml b/rust/tw_hash/Cargo.toml index c9b8ab18c42..ddb71b89653 100644 --- a/rust/tw_hash/Cargo.toml +++ b/rust/tw_hash/Cargo.toml @@ -18,6 +18,7 @@ serde = { version = "1.0", features = ["derive"], optional = true } sha1 = "0.10.5" sha2 = "0.10.6" sha3 = "0.10.6" +strum_macros = "0.25" tw_encoding = { path = "../tw_encoding" } tw_memory = { path = "../tw_memory" } zeroize = "1.8.1" diff --git a/rust/tw_hash/src/hasher.rs b/rust/tw_hash/src/hasher.rs index badb1237472..9eb5d7048f3 100644 --- a/rust/tw_hash/src/hasher.rs +++ b/rust/tw_hash/src/hasher.rs @@ -2,12 +2,13 @@ // // Copyright © 2017 Trust Wallet. -use crate::blake::blake_256; +use crate::blake::{blake256_d, blake_256}; +use crate::groestl::groestl_512d; use crate::ripemd::{blake256_ripemd, sha256_ripemd}; use crate::sha2::{sha256, sha256_d}; use crate::sha3::keccak256; use crate::{H160, H256}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use tw_memory::Data; #[macro_export] @@ -81,25 +82,30 @@ pub trait StatefulHasher { /// /// Add hash types if necessary. For example, when add a new hasher to `registry.json`, /// otherwise use hash functions directly. -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)] +#[repr(u32)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, strum_macros::FromRepr)] pub enum Hasher { #[serde(rename = "sha256")] - Sha256, + Sha256 = 1, #[serde(rename = "keccak256")] - Keccak256, + Keccak256 = 4, + #[serde(rename = "blake256")] + Blake256 = 10, /// SHA256 hash of the SHA256 hash #[serde(rename = "sha256d")] - Sha256d, + Sha256d = 12, /// ripemd hash of the SHA256 hash #[serde(rename = "sha256ripemd")] - Sha256ripemd, - #[serde(rename = "blake256")] - Blake256, + Sha256ripemd = 13, + #[serde(rename = "blake256d")] + Blake256d = 15, /// ripemd hash of the BLAKE256 hash #[serde(rename = "blake256ripemd")] - Blake256ripemd, + Blake256ripemd = 16, + #[serde(rename = "groestl512d")] + Groestl512d = 17, #[serde(rename = "tapsighash")] - TapSighash, + TapSighash = 18, } impl StatefulHasher for Hasher { @@ -111,6 +117,8 @@ impl StatefulHasher for Hasher { Hasher::Sha256ripemd => sha256_ripemd(data), Hasher::Blake256 => blake_256(data), Hasher::Blake256ripemd => blake256_ripemd(data), + Hasher::Blake256d => blake256_d(data), + Hasher::Groestl512d => groestl_512d(data), Hasher::TapSighash => tapsighash(data), } } @@ -118,8 +126,13 @@ impl StatefulHasher for Hasher { /// Returns a corresponding hash len. fn hash_len(&self) -> usize { match self { - Hasher::Sha256 | Hasher::Keccak256 | Hasher::Sha256d | Hasher::Blake256 => H256::len(), + Hasher::Sha256 + | Hasher::Keccak256 + | Hasher::Sha256d + | Hasher::Blake256 + | Hasher::Blake256d => H256::len(), Hasher::Sha256ripemd | Hasher::Blake256ripemd => H160::len(), + Hasher::Groestl512d => H256::len(), Hasher::TapSighash => H256::len(), } } diff --git a/rust/tw_hash/src/hmac.rs b/rust/tw_hash/src/hmac.rs index 475c5bbdb7f..7bcd56edcd3 100644 --- a/rust/tw_hash/src/hmac.rs +++ b/rust/tw_hash/src/hmac.rs @@ -3,10 +3,12 @@ // Copyright © 2017 Trust Wallet. use hmac::{Hmac, Mac}; -use sha2::Sha256; +use sha2::{Sha256, Sha512}; type HmacSha256 = Hmac; +pub type HmacSha512 = Hmac; + pub fn hmac_sha256(key: &[u8], input: &[u8]) -> Vec { let mut mac = HmacSha256::new_from_slice(key).unwrap(); mac.update(input); diff --git a/rust/tw_keypair/src/ecdsa/canonical.rs b/rust/tw_keypair/src/ecdsa/canonical.rs index e335ee5c7de..f40da41b18a 100644 --- a/rust/tw_keypair/src/ecdsa/canonical.rs +++ b/rust/tw_keypair/src/ecdsa/canonical.rs @@ -24,6 +24,7 @@ use k256::sha2::digest::{FixedOutput, FixedOutputReset}; use k256::sha2::Digest; use rfc6979::{ByteArray, HmacDrbg}; use tw_hash::H256; +use tw_memory::ffi::c_byte_array::CByteArray; type CurveDigest = ::Digest; @@ -67,6 +68,37 @@ where Err(KeyPairError::SigningError) } +pub(crate) fn sign_canonical_ffi( + secret: &SigningKey, + hash_to_sign: H256, + canonical_checker: Option i32>, + transform_result: F, +) -> KeyPairResult> +where + F: FnOnce(Signature) -> Vec, + Scalar: SignPrimitive, + ::Uint: FieldBytesEncoding, +{ + let checker = move |sig: &Signature| { + if let Some(checker_fn) = canonical_checker { + // Convert signature to bytes and pass to the C function + let sig_bytes = sig.to_bytes(); + let sig_array = CByteArray::from(sig_bytes[..64].to_vec()); + + // Call the C function and check if it returns a positive value + unsafe { checker_fn(sig_bytes[64], sig_array.data()) > 0 } + } else { + // If no checker provided, accept all signatures + true + } + }; + + let mut sig = sign_with_canonical(secret, hash_to_sign, checker).map(transform_result)?; + // graphene adds 31 to the recovery id + sig[0] += 31; + Ok(sig) +} + fn ct_eq>(a: &ByteArray, b: &ByteArray) -> Choice { let mut ret = Choice::from(1); diff --git a/rust/tw_keypair/src/ecdsa/mod.rs b/rust/tw_keypair/src/ecdsa/mod.rs index dae3dd5bb7e..11f89c68564 100644 --- a/rust/tw_keypair/src/ecdsa/mod.rs +++ b/rust/tw_keypair/src/ecdsa/mod.rs @@ -8,7 +8,7 @@ use ecdsa::elliptic_curve::CurveArithmetic; use ecdsa::hazmat::DigestPrimitive; use ecdsa::PrimeCurve; -mod canonical; +pub mod canonical; pub mod der; pub mod nist256p1; pub mod secp256k1; diff --git a/rust/tw_keypair/src/ecdsa/nist256p1/private.rs b/rust/tw_keypair/src/ecdsa/nist256p1/private.rs index 0d2ede5bf83..71765d32b01 100644 --- a/rust/tw_keypair/src/ecdsa/nist256p1/private.rs +++ b/rust/tw_keypair/src/ecdsa/nist256p1/private.rs @@ -2,18 +2,22 @@ // // Copyright © 2017 Trust Wallet. +use std::str::FromStr; + use crate::ecdsa::nist256p1::public::PublicKey; use crate::ecdsa::nist256p1::Signature; -use crate::traits::SigningKeyTrait; +use crate::traits::{DerivableKeyTrait, SigningKeyTrait}; use crate::{KeyPairError, KeyPairResult}; -use p256::ecdsa::SigningKey; +use ecdsa::elliptic_curve::point::AffineCoordinates; +use p256::ecdsa::{SigningKey, VerifyingKey}; +use p256::{AffinePoint, ProjectivePoint}; use tw_encoding::hex; -use tw_hash::H256; +use tw_hash::{H256, H512}; use tw_misc::traits::ToBytesZeroizing; use zeroize::{ZeroizeOnDrop, Zeroizing}; /// Represents a `nist256p1` private key. -#[derive(ZeroizeOnDrop)] +#[derive(ZeroizeOnDrop, Clone)] pub struct PrivateKey { pub(crate) secret: SigningKey, } @@ -23,6 +27,21 @@ impl PrivateKey { pub fn public(&self) -> PublicKey { PublicKey::new(*self.secret.verifying_key()) } + + // See https://github.com/fioprotocol/fiojs/blob/master/src/ecc/key_private.js + pub fn ecies_shared_key(&self, pubkey: &PublicKey) -> H512 { + let shared_secret = diffie_hellman(&self.secret, &pubkey.public); + let hash = tw_hash::sha2::sha512(shared_secret.x().as_slice()); + H512::try_from(hash.as_slice()).expect("Expected 64 byte array sha512 hash") + } +} + +/// This method is inspired by [elliptic_curve::ecdh::diffie_hellman](https://github.com/RustCrypto/traits/blob/f0dbe44fea56d4c17e625ababacb580fec842137/elliptic-curve/src/ecdh.rs#L60-L70) +fn diffie_hellman(private: &SigningKey, public: &VerifyingKey) -> AffinePoint { + let public_point = ProjectivePoint::from(*public.as_affine()); + let secret_scalar = private.as_nonzero_scalar().as_ref(); + // Multiply the secret and public to get a shared secret affine point (x, y). + (public_point * secret_scalar).to_affine() } impl SigningKeyTrait for PrivateKey { @@ -56,9 +75,34 @@ impl<'a> TryFrom<&'a str> for PrivateKey { } } +impl FromStr for PrivateKey { + type Err = KeyPairError; + + fn from_str(hex: &str) -> Result { + Self::try_from(hex) + } +} + impl ToBytesZeroizing for PrivateKey { fn to_zeroizing_vec(&self) -> Zeroizing> { let secret = Zeroizing::new(self.secret.to_bytes()); Zeroizing::new(secret.as_slice().to_vec()) } } + +impl DerivableKeyTrait for PrivateKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(p256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InternalError)?; + + let derived_scalar = self.secret.as_nonzero_scalar().as_ref() + child_scalar.as_ref(); + + let secret = Option::::from(p256::NonZeroScalar::new(derived_scalar)) + .map(Into::into) + .ok_or(KeyPairError::InternalError)?; + + Ok(PrivateKey { secret }) + } +} diff --git a/rust/tw_keypair/src/ecdsa/nist256p1/public.rs b/rust/tw_keypair/src/ecdsa/nist256p1/public.rs index 6ac0ec429c7..86306c8ccc8 100644 --- a/rust/tw_keypair/src/ecdsa/nist256p1/public.rs +++ b/rust/tw_keypair/src/ecdsa/nist256p1/public.rs @@ -2,13 +2,19 @@ // // Copyright © 2017 Trust Wallet. +use std::cmp::Ordering; + use crate::ecdsa::nist256p1::{Signature, VerifySignature}; -use crate::traits::VerifyingKeyTrait; +use crate::traits::{DerivableKeyTrait, VerifyingKeyTrait}; use crate::{KeyPairError, KeyPairResult}; +use ecdsa::elliptic_curve::group::prime::PrimeCurveAffine; +use ecdsa::elliptic_curve::point::AffineCoordinates; use p256::ecdsa::signature::hazmat::PrehashVerifier; use p256::ecdsa::VerifyingKey; use tw_encoding::hex; +use tw_hash::hasher::{Hasher, StatefulHasher}; use tw_hash::{H256, H264, H520}; +use tw_memory::Data; use tw_misc::traits::ToBytesVec; /// Represents a `nist256p1` public key. @@ -49,6 +55,23 @@ impl PublicKey { H520::try_from(self.public.to_encoded_point(compressed).as_bytes()) .expect("Expected 65 byte array Public Key") } + + pub fn hash(&self, hasher: Hasher) -> Data { + hasher.hash(self.compressed().as_slice()) + } + + pub fn compare(&self, other: &PublicKey) -> Ordering { + let self_as_affine = self.public.as_affine(); + let other_as_affine = other.public.as_affine(); + let result = self_as_affine.x().cmp(&other_as_affine.x()); + if result != Ordering::Equal { + return result; + } + self_as_affine + .y_is_odd() + .unwrap_u8() + .cmp(&other_as_affine.y_is_odd().unwrap_u8()) + } } impl VerifyingKeyTrait for PublicKey { @@ -90,3 +113,19 @@ impl ToBytesVec for PublicKey { self.compressed().to_vec() } } + +impl DerivableKeyTrait for PublicKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(p256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InvalidPublicKey)?; + + let projective_point: p256::ProjectivePoint = self.public.as_affine().into(); + let child_point = projective_point + (p256::AffinePoint::generator() * *child_scalar); + let public = VerifyingKey::from_affine(child_point.into()) + .map_err(|_| KeyPairError::InternalError)?; + + Ok(PublicKey { public }) + } +} diff --git a/rust/tw_keypair/src/ecdsa/secp256k1/mod.rs b/rust/tw_keypair/src/ecdsa/secp256k1/mod.rs index dcc76c801e0..9f33f6e6991 100644 --- a/rust/tw_keypair/src/ecdsa/secp256k1/mod.rs +++ b/rust/tw_keypair/src/ecdsa/secp256k1/mod.rs @@ -143,22 +143,6 @@ mod tests { assert!(!private.public().verify(verify_sig, hash_to_sign)); } - #[test] - fn test_shared_key_hash() { - let private = PrivateKey::try_from( - "9cd3b16e10bd574fed3743d8e0de0b7b4e6c69f3245ab5a168ef010d22bfefa0", - ) - .unwrap(); - let public = PublicKey::try_from( - "02a18a98316b5f52596e75bfa5ca9fa9912edd0c989b86b73d41bb64c9c6adb992", - ) - .unwrap(); - let actual = private.shared_key_hash(&public); - let expected = - H256::from("ef2cf705af8714b35c0855030f358f2bee356ff3579cea2607b2025d80133c3a"); - assert_eq!(actual, expected); - } - #[test] fn test_public_key_recover() { let sign_bytes = H520::from("8720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba624d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de901"); diff --git a/rust/tw_keypair/src/ecdsa/secp256k1/private.rs b/rust/tw_keypair/src/ecdsa/secp256k1/private.rs index ec80de8b098..d71171b4d7f 100644 --- a/rust/tw_keypair/src/ecdsa/secp256k1/private.rs +++ b/rust/tw_keypair/src/ecdsa/secp256k1/private.rs @@ -2,20 +2,24 @@ // // Copyright © 2017 Trust Wallet. +use std::str::FromStr; + use crate::ecdsa::secp256k1::public::PublicKey; use crate::ecdsa::secp256k1::Signature; +use crate::traits::DerivableKeyTrait; use crate::traits::SigningKeyTrait; use crate::{KeyPairError, KeyPairResult}; +use ecdsa::elliptic_curve::point::AffineCoordinates; use k256::ecdsa::{SigningKey, VerifyingKey}; -use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::{AffinePoint, ProjectivePoint}; use tw_encoding::hex; use tw_hash::H256; +use tw_hash::H512; use tw_misc::traits::ToBytesZeroizing; use zeroize::{ZeroizeOnDrop, Zeroizing}; /// Represents a `secp256k1` private key. -#[derive(ZeroizeOnDrop)] +#[derive(ZeroizeOnDrop, Clone)] pub struct PrivateKey { pub(crate) secret: SigningKey, } @@ -26,17 +30,11 @@ impl PrivateKey { PublicKey::new(*self.secret.verifying_key()) } - /// Computes an EC Diffie-Hellman secret in constant time. - /// The method is ported from [TW::PrivateKey::getSharedKey](https://github.com/trustwallet/wallet-core/blob/830b1c5baaf90692196163999e4ee2063c5f4e49/src/PrivateKey.cpp#L175-L191). - pub fn shared_key_hash(&self, pubkey: &PublicKey) -> H256 { + // See https://github.com/fioprotocol/fiojs/blob/master/src/ecc/key_private.js + pub fn ecies_shared_key(&self, pubkey: &PublicKey) -> H512 { let shared_secret = diffie_hellman(&self.secret, &pubkey.public); - - // Get a compressed shared secret (33 bytes with a tag in front). - let compress = true; - let shared_secret_compressed = shared_secret.to_encoded_point(compress); - - let shared_secret_hash = tw_hash::sha2::sha256(shared_secret_compressed.as_bytes()); - H256::try_from(shared_secret_hash.as_slice()).expect("Expected 32 byte array sha256 hash") + let hash = tw_hash::sha2::sha512(shared_secret.x().as_slice()); + H512::try_from(hash.as_slice()).expect("Expected 64 byte array sha512 hash") } } @@ -79,9 +77,34 @@ impl<'a> TryFrom<&'a str> for PrivateKey { } } +impl FromStr for PrivateKey { + type Err = KeyPairError; + + fn from_str(hex: &str) -> Result { + Self::try_from(hex) + } +} + impl ToBytesZeroizing for PrivateKey { fn to_zeroizing_vec(&self) -> Zeroizing> { let secret = Zeroizing::new(self.secret.to_bytes()); Zeroizing::new(secret.as_slice().to_vec()) } } + +impl DerivableKeyTrait for PrivateKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(k256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InternalError)?; + + let derived_scalar = self.secret.as_nonzero_scalar().as_ref() + child_scalar.as_ref(); + + let secret = Option::::from(k256::NonZeroScalar::new(derived_scalar)) + .map(Into::into) + .ok_or(KeyPairError::InternalError)?; + + Ok(PrivateKey { secret }) + } +} diff --git a/rust/tw_keypair/src/ecdsa/secp256k1/public.rs b/rust/tw_keypair/src/ecdsa/secp256k1/public.rs index 73f61021069..49fb0030fdd 100644 --- a/rust/tw_keypair/src/ecdsa/secp256k1/public.rs +++ b/rust/tw_keypair/src/ecdsa/secp256k1/public.rs @@ -2,14 +2,20 @@ // // Copyright © 2017 Trust Wallet. +use std::cmp::Ordering; + use crate::ecdsa::secp256k1::{Signature, VerifySignature}; -use crate::traits::VerifyingKeyTrait; +use crate::traits::{DerivableKeyTrait, VerifyingKeyTrait}; use crate::{KeyPairError, KeyPairResult}; use der::Document; +use ecdsa::elliptic_curve::group::prime::PrimeCurveAffine; +use ecdsa::elliptic_curve::point::AffineCoordinates; use k256::ecdsa::signature::hazmat::PrehashVerifier; use k256::ecdsa::VerifyingKey; use tw_encoding::hex; +use tw_hash::hasher::{Hasher, StatefulHasher}; use tw_hash::{Hash, H256, H264, H512, H520}; +use tw_memory::Data; use tw_misc::traits::ToBytesVec; /// Represents a `secp256k1` public key. @@ -78,6 +84,24 @@ impl PublicKey { let doc = Document::try_from(&spki).unwrap(); doc.into_vec() } + + pub fn hash(&self, hasher: Hasher) -> Data { + hasher.hash(self.compressed().as_slice()) + } + + pub fn compare(&self, other: &PublicKey) -> Ordering { + let self_as_affine = self.public.as_affine(); + let other_as_affine = other.public.as_affine(); + let result = self_as_affine.x().cmp(&other_as_affine.x()); + if result == Ordering::Equal { + self_as_affine + .y_is_odd() + .unwrap_u8() + .cmp(&other_as_affine.y_is_odd().unwrap_u8()) + } else { + result + } + } } impl VerifyingKeyTrait for PublicKey { @@ -119,3 +143,19 @@ impl ToBytesVec for PublicKey { self.compressed().to_vec() } } + +impl DerivableKeyTrait for PublicKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(k256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InternalError)?; + + let projective_point: k256::ProjectivePoint = self.public.as_affine().into(); + let child_point = projective_point + (k256::AffinePoint::generator() * *child_scalar); + let public = VerifyingKey::from_affine(child_point.into()) + .map_err(|_| KeyPairError::InternalError)?; + + Ok(PublicKey { public }) + } +} diff --git a/rust/tw_keypair/src/ecdsa/signature.rs b/rust/tw_keypair/src/ecdsa/signature.rs index 0cb06a45a65..b70a14e698b 100644 --- a/rust/tw_keypair/src/ecdsa/signature.rs +++ b/rust/tw_keypair/src/ecdsa/signature.rs @@ -33,6 +33,16 @@ impl Signature { Signature { signature, v } } + pub(crate) fn new_from_bytes(sig: &[u8], rec_id: u8) -> KeyPairResult { + if sig.len() + 1 < Self::len() { + return Err(KeyPairError::InvalidSignature); + } + + let v = ecdsa::RecoveryId::from_byte(rec_id).ok_or(KeyPairError::InvalidSignature)?; + let signature = Self::signature_from_slices(&sig[Self::R_RANGE], &sig[Self::S_RANGE])?; + Ok(Self::new(signature, v)) + } + /// Returns the number of bytes for a serialized signature representation. pub const fn len() -> usize { Self::LEN @@ -90,6 +100,16 @@ impl Signature { dest } + pub fn vrs(&self) -> H520 { + let (r, s) = self.signature.split_bytes(); + + let mut dest = H520::default(); + dest[0] = self.v.to_byte(); + dest[1..33].copy_from_slice(r.as_slice()); + dest[33..65].copy_from_slice(s.as_slice()); + dest + } + pub fn to_der(&self) -> KeyPairResult { der::Signature::new(self.r(), self.s()) } diff --git a/rust/tw_keypair/src/ed25519/modifications/cardano/extended_private.rs b/rust/tw_keypair/src/ed25519/modifications/cardano/extended_private.rs index 6a2bd83124a..e4dc37cf582 100644 --- a/rust/tw_keypair/src/ed25519/modifications/cardano/extended_private.rs +++ b/rust/tw_keypair/src/ed25519/modifications/cardano/extended_private.rs @@ -12,22 +12,25 @@ use crate::ed25519::Hasher512; use crate::traits::SigningKeyTrait; use crate::{KeyPairError, KeyPairResult}; use std::ops::Range; +use std::str::FromStr; use tw_encoding::hex; use tw_hash::H256; use tw_misc::traits::ToBytesZeroizing; use zeroize::{ZeroizeOnDrop, Zeroizing}; /// Represents an `ed25519` extended private key that is used in Cardano blockchain. +#[derive(Clone)] pub struct ExtendedPrivateKey { /// The first half (96 bytes) of the extended secret. key: ExtendedSecretPart, /// The second half (96 bytes) of the extended secret. - second_key: ExtendedSecretPart, + second_key: Option>, } /// cbindgen:ignore impl ExtendedPrivateKey { /// The number of bytes in a serialized private key (192 bytes). + pub const SECRET_LEN: usize = ExtendedSecretPart::::LEN; pub const LEN: usize = ExtendedSecretPart::::LEN * 2; const KEY_RANGE: Range = 0..ExtendedSecretPart::::LEN; const SECOND_KEY_RANGE: Range = ExtendedSecretPart::::LEN..Self::LEN; @@ -35,13 +38,17 @@ impl ExtendedPrivateKey { /// Returns an associated Cardano extended `ed25519` public key. pub fn public(&self) -> ExtendedPublicKey { let key_public = PublicKey::with_expanded_secret_no_mangle(&self.key.expanded_key); - let second_key_public = - PublicKey::with_expanded_secret_no_mangle(&self.second_key.expanded_key); - let key = ExtendedPublicPart::new(key_public, self.key.chain_code); - let second_key = ExtendedPublicPart::new(second_key_public, self.second_key.chain_code); - ExtendedPublicKey::new(key, second_key) + if let Some(second_key) = &self.second_key { + let second_key_public = + PublicKey::with_expanded_secret_no_mangle(&second_key.expanded_key); + let second_key = ExtendedPublicPart::new(second_key_public, second_key.chain_code); + + ExtendedPublicKey::new(key, Some(second_key)) + } else { + ExtendedPublicKey::new(key, None) + } } } @@ -59,7 +66,9 @@ impl SigningKeyTrait for ExtendedPrivateKey { impl ToBytesZeroizing for ExtendedPrivateKey { fn to_zeroizing_vec(&self) -> Zeroizing> { let mut res = self.key.to_zeroizing_vec(); - res.extend_from_slice(self.second_key.to_zeroizing_vec().as_slice()); + if let Some(second_key) = &self.second_key { + res.extend_from_slice(second_key.to_zeroizing_vec().as_slice()); + } res } } @@ -68,13 +77,22 @@ impl<'a, H: Hasher512> TryFrom<&'a [u8]> for ExtendedPrivateKey { type Error = KeyPairError; fn try_from(bytes: &'a [u8]) -> Result { - if bytes.len() != Self::LEN { - return Err(KeyPairError::InvalidSecretKey); + if bytes.len() == Self::LEN { + let key = ExtendedSecretPart::try_from(&bytes[Self::KEY_RANGE])?; + let second_key = ExtendedSecretPart::try_from(&bytes[Self::SECOND_KEY_RANGE])?; + Ok(ExtendedPrivateKey { + key, + second_key: Some(second_key), + }) + } else if bytes.len() == Self::SECRET_LEN { + let key = ExtendedSecretPart::try_from(&bytes[Self::KEY_RANGE])?; + Ok(ExtendedPrivateKey { + key, + second_key: None, + }) + } else { + Err(KeyPairError::InvalidSecretKey) } - let key = ExtendedSecretPart::try_from(&bytes[Self::KEY_RANGE])?; - let second_key = ExtendedSecretPart::try_from(&bytes[Self::SECOND_KEY_RANGE])?; - - Ok(ExtendedPrivateKey { key, second_key }) } } @@ -87,7 +105,15 @@ impl<'a, H: Hasher512> TryFrom<&'a str> for ExtendedPrivateKey { } } -#[derive(ZeroizeOnDrop)] +impl FromStr for ExtendedPrivateKey { + type Err = KeyPairError; + + fn from_str(hex: &str) -> Result { + Self::try_from(hex) + } +} + +#[derive(ZeroizeOnDrop, Clone)] struct ExtendedSecretPart { secret: H256, extension: H256, diff --git a/rust/tw_keypair/src/ed25519/modifications/cardano/extended_public.rs b/rust/tw_keypair/src/ed25519/modifications/cardano/extended_public.rs index d3d82dba764..a9f4f596d38 100644 --- a/rust/tw_keypair/src/ed25519/modifications/cardano/extended_public.rs +++ b/rust/tw_keypair/src/ed25519/modifications/cardano/extended_public.rs @@ -18,18 +18,22 @@ pub struct ExtendedPublicKey { /// The first half of the public key (64 bytes). key: ExtendedPublicPart, /// The second half of the public key (64 bytes). - second_key: ExtendedPublicPart, + second_key: Option>, } /// cbindgen:ignore impl ExtendedPublicKey { /// The number of bytes in a serialized public key. + pub const PUBLIC_LEN: usize = ExtendedPublicPart::::LEN; pub const LEN: usize = ExtendedPublicPart::::LEN * 2; const KEY_RANGE: Range = 0..ExtendedPublicPart::::LEN; const SECOND_KEY_RANGE: Range = ExtendedPublicPart::::LEN..Self::LEN; /// Creates a public key with the given [`ExtendedPublicPart`] first and second keys. - pub(crate) fn new(key: ExtendedPublicPart, second_key: ExtendedPublicPart) -> Self { + pub(crate) fn new( + key: ExtendedPublicPart, + second_key: Option>, + ) -> Self { ExtendedPublicKey { key, second_key } } @@ -51,7 +55,9 @@ impl VerifyingKeyTrait for ExtendedPublicKey { impl ToBytesVec for ExtendedPublicKey { fn to_vec(&self) -> Vec { let mut res = self.key.to_vec(); - res.extend_from_slice(self.second_key.to_vec().as_slice()); + if let Some(second_key) = &self.second_key { + res.extend_from_slice(second_key.to_vec().as_slice()); + } res } } @@ -60,14 +66,22 @@ impl<'a, H: Hasher512> TryFrom<&'a [u8]> for ExtendedPublicKey { type Error = KeyPairError; fn try_from(bytes: &'a [u8]) -> Result { - if bytes.len() != Self::LEN { - return Err(KeyPairError::InvalidPublicKey); + if bytes.len() == Self::LEN { + let key = ExtendedPublicPart::try_from(&bytes[Self::KEY_RANGE])?; + let second_key = ExtendedPublicPart::try_from(&bytes[Self::SECOND_KEY_RANGE])?; + Ok(ExtendedPublicKey { + key, + second_key: Some(second_key), + }) + } else if bytes.len() == Self::PUBLIC_LEN { + let key = ExtendedPublicPart::try_from(&bytes[Self::KEY_RANGE])?; + Ok(ExtendedPublicKey { + key, + second_key: None, + }) + } else { + Err(KeyPairError::InvalidPublicKey) } - - let key = ExtendedPublicPart::try_from(&bytes[Self::KEY_RANGE])?; - let second_key = ExtendedPublicPart::try_from(&bytes[Self::SECOND_KEY_RANGE])?; - - Ok(ExtendedPublicKey { key, second_key }) } } diff --git a/rust/tw_keypair/src/ed25519/modifications/waves/private.rs b/rust/tw_keypair/src/ed25519/modifications/waves/private.rs index 4c6c68f5e46..bcbabb2b4b3 100644 --- a/rust/tw_keypair/src/ed25519/modifications/waves/private.rs +++ b/rust/tw_keypair/src/ed25519/modifications/waves/private.rs @@ -2,6 +2,8 @@ // // Copyright © 2017 Trust Wallet. +use std::str::FromStr; + use crate::ed25519::modifications::waves::public::PublicKey; use crate::ed25519::modifications::waves::signature::Signature; use crate::ed25519::{private::PrivateKey as StandardPrivateKey, Hasher512}; @@ -12,6 +14,7 @@ use tw_misc::traits::ToBytesZeroizing; use zeroize::Zeroizing; /// Represents an `ed25519` private key that is used in Waves blockchain. +#[derive(Clone)] pub struct PrivateKey { standard_key: StandardPrivateKey, } @@ -52,6 +55,14 @@ impl<'a, H: Hasher512> TryFrom<&'a str> for PrivateKey { } } +impl FromStr for PrivateKey { + type Err = KeyPairError; + + fn from_str(hex: &str) -> Result { + Self::try_from(hex) + } +} + impl ToBytesZeroizing for PrivateKey { fn to_zeroizing_vec(&self) -> Zeroizing> { self.standard_key.to_zeroizing_vec() diff --git a/rust/tw_keypair/src/ed25519/modifications/waves/public.rs b/rust/tw_keypair/src/ed25519/modifications/waves/public.rs index 1842f5e5cd3..a57d1e6b62c 100644 --- a/rust/tw_keypair/src/ed25519/modifications/waves/public.rs +++ b/rust/tw_keypair/src/ed25519/modifications/waves/public.rs @@ -13,6 +13,8 @@ use tw_encoding::hex; use tw_hash::H256; use tw_misc::traits::ToBytesVec; +use super::signature::PUBKEY_SIGN_MASK; + /// Represents an `ed25519` public key that is used in Waves blockchain. #[derive(Clone)] pub struct PublicKey { @@ -40,6 +42,13 @@ impl PublicKey { pub fn to_bytes(&self) -> H256 { self.curve25519_pk } + + pub fn to_standard_pubkey(&self) -> Option> { + let montgomery_point = MontgomeryPoint(self.curve25519_pk.take()); + let sign_bit = self.curve25519_pk[31] & PUBKEY_SIGN_MASK; + let edwards_point = montgomery_point.to_edwards(sign_bit)?; + Some(StandardPublicKey::::with_edwards_point(edwards_point)) + } } impl VerifyingKeyTrait for PublicKey { diff --git a/rust/tw_keypair/src/ed25519/modifications/waves/signature.rs b/rust/tw_keypair/src/ed25519/modifications/waves/signature.rs index 39613316940..5b15c7d7373 100644 --- a/rust/tw_keypair/src/ed25519/modifications/waves/signature.rs +++ b/rust/tw_keypair/src/ed25519/modifications/waves/signature.rs @@ -11,7 +11,7 @@ use tw_misc::traits::ToBytesVec; /// cbindgen:ignore /// Equals to 0x80. -const PUBKEY_SIGN_MASK: u8 = 0b1000_0000; +pub(crate) const PUBKEY_SIGN_MASK: u8 = 0b1000_0000; /// cbindgen:ignore /// Equals to 127. diff --git a/rust/tw_keypair/src/ed25519/private.rs b/rust/tw_keypair/src/ed25519/private.rs index ce0c2ef056f..c9cf6baf1f1 100644 --- a/rust/tw_keypair/src/ed25519/private.rs +++ b/rust/tw_keypair/src/ed25519/private.rs @@ -9,6 +9,7 @@ use crate::ed25519::Hasher512; use crate::traits::SigningKeyTrait; use crate::{KeyPairError, KeyPairResult}; use std::fmt; +use std::str::FromStr; use tw_encoding::hex; use tw_hash::H256; use tw_misc::traits::ToBytesZeroizing; @@ -70,6 +71,14 @@ impl<'a, H: Hasher512> TryFrom<&'a str> for PrivateKey { } } +impl FromStr for PrivateKey { + type Err = KeyPairError; + + fn from_str(hex: &str) -> Result { + Self::try_from(hex) + } +} + impl ToBytesZeroizing for PrivateKey { fn to_zeroizing_vec(&self) -> Zeroizing> { Zeroizing::new(self.secret.to_vec()) diff --git a/rust/tw_keypair/src/ffi/curve25519.rs b/rust/tw_keypair/src/ffi/curve25519.rs new file mode 100644 index 00000000000..0b8c4dba82f --- /dev/null +++ b/rust/tw_keypair/src/ffi/curve25519.rs @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#![allow(clippy::missing_safety_doc)] + +use crate::ed25519::waves::PublicKey as Curve25519PublicKey; +use tw_macros::tw_ffi; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; +use tw_misc::traits::ToBytesVec; +use tw_misc::try_or_else; + +#[tw_ffi(ty = static_function, class = TWCurve25519, name = PubkeyToEd25519)] +#[no_mangle] +pub unsafe extern "C" fn tw_curve25519_pubkey_to_ed25519( + pubkey: Nonnull, +) -> NullableMut { + let pubkey = TWData::from_ptr_as_ref(pubkey) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let pubkey = try_or_else!(Curve25519PublicKey::try_from(pubkey), std::ptr::null_mut); + let ed25519_pubkey = try_or_else!(pubkey.to_standard_pubkey(), std::ptr::null_mut); + TWData::from(ed25519_pubkey.to_vec()).into_ptr() +} diff --git a/rust/tw_keypair/src/ffi/ecdsa.rs b/rust/tw_keypair/src/ffi/ecdsa.rs new file mode 100644 index 00000000000..5a6c02dc549 --- /dev/null +++ b/rust/tw_keypair/src/ffi/ecdsa.rs @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#![allow(clippy::missing_safety_doc)] + +use crate::ecdsa::nist256p1::{ + PrivateKey as NISSecPrivateKey, PublicKey as NISTPublicKey, Signature as NISSignature, +}; +use crate::ecdsa::secp256k1::{ + PrivateKey as SECPrivateKey, PublicKey as SECPublicKey, Signature as SECSignature, +}; +use tw_hash::hasher::Hasher; +use tw_macros::tw_ffi; +use tw_memory::ffi::{tw_data::TWData, Nonnull, NullableMut, RawPtrTrait}; +use tw_misc::try_or_else; + +/// Converts an ECDSA signature to a DER-encoded signature. +/// +/// \param sig *non-null* pointer to a block of data corresponding to the signature. +/// \param is_secp256k1 whether the signature is a secp256k1 signature. +/// +/// \return DER-encoded signature. +#[tw_ffi(ty = static_function, class = TWECDSA, name = SigToDER)] +#[no_mangle] +pub unsafe extern "C" fn tw_ecdsa_sig_to_der( + sig: Nonnull, + is_secp256k1: bool, +) -> NullableMut { + let sig = TWData::from_ptr_as_ref(sig) + .map(|data| data.as_slice()) + .unwrap_or_default(); + if is_secp256k1 { + let sig = try_or_else!(SECSignature::try_from(sig), std::ptr::null_mut); + sig.to_der() + .map(|output| TWData::from(output.der_bytes()).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) + } else { + let sig = try_or_else!(NISSignature::try_from(sig), std::ptr::null_mut); + sig.to_der() + .map(|output| TWData::from(output.der_bytes()).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) + } +} + +/// Computes the hash of a public key. +/// +/// \param pubkey *non-null* pointer to a block of data corresponding to the public key. +/// \param is_secp256k1 whether the public key is a secp256k1 public key. +/// \param hasher hasher type. +/// \return hash of the public key. +#[tw_ffi(ty = static_function, class = TWECDSA, name = PubkeyHash)] +#[no_mangle] +pub unsafe extern "C" fn tw_ecdsa_pubkey_hash( + pubkey_data: Nonnull, + is_secp256k1: bool, + hasher: u32, +) -> NullableMut { + let pubkey_data = TWData::from_ptr_as_ref(pubkey_data) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let hasher = try_or_else!(Hasher::from_repr(hasher), std::ptr::null_mut); + let hash = if is_secp256k1 { + let pubkey = try_or_else!(SECPublicKey::try_from(pubkey_data), std::ptr::null_mut); + pubkey.hash(hasher) + } else { + let pubkey = try_or_else!(NISTPublicKey::try_from(pubkey_data), std::ptr::null_mut); + pubkey.hash(hasher) + }; + TWData::from(hash.to_vec()).into_ptr() +} + +/// Compares two ECDSA public keys. +/// +/// \param pubkey_data1 *non-null* pointer to a block of data corresponding to the first public key. +/// \param pubkey_data2 *non-null* pointer to a block of data corresponding to the second public key. +/// \param is_secp256k1 whether the public keys are secp256k1 public keys. +/// \return -2 if the public keys are invalid, otherwise the comparison result. +#[tw_ffi(ty = static_function, class = TWECDSA, name = PubkeyCompare)] +#[no_mangle] +pub unsafe extern "C" fn tw_ecdsa_pubkey_compare( + pubkey_data1: Nonnull, + pubkey_data2: Nonnull, + is_secp256k1: bool, +) -> i8 { + let pubkey_data1 = TWData::from_ptr_as_ref(pubkey_data1) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let pubkey_data2 = TWData::from_ptr_as_ref(pubkey_data2) + .map(|data| data.as_slice()) + .unwrap_or_default(); + if is_secp256k1 { + let pubkey1 = try_or_else!(SECPublicKey::try_from(pubkey_data1), || -2); + let pubkey2 = try_or_else!(SECPublicKey::try_from(pubkey_data2), || -2); + pubkey1.compare(&pubkey2) as i8 + } else { + let pubkey1 = try_or_else!(NISTPublicKey::try_from(pubkey_data1), || -2); + let pubkey2 = try_or_else!(NISTPublicKey::try_from(pubkey_data2), || -2); + pubkey1.compare(&pubkey2) as i8 + } +} + +/// Computes the shared key. +/// +/// \param private_key *non-null* pointer to a block of data corresponding to the private key. +/// \param pubkey_data *non-null* pointer to a block of data corresponding to the public key. +/// \param is_secp256k1 whether the private key is a secp256k1 private key. +/// \return the shared key. +#[tw_ffi(ty = static_function, class = TWECDSA, name = SharedKey)] +#[no_mangle] +pub unsafe extern "C" fn tw_ecdsa_shared_key( + private_key: Nonnull, + pubkey_data: Nonnull, + is_secp256k1: bool, +) -> NullableMut { + let private_key = TWData::from_ptr_as_ref(private_key) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let pubkey_data = TWData::from_ptr_as_ref(pubkey_data) + .map(|data| data.as_slice()) + .unwrap_or_default(); + let shared_key = if is_secp256k1 { + let private_key = try_or_else!(SECPrivateKey::try_from(private_key), std::ptr::null_mut); + let pubkey = try_or_else!(SECPublicKey::try_from(pubkey_data), std::ptr::null_mut); + private_key.ecies_shared_key(&pubkey) + } else { + let private_key = try_or_else!(NISSecPrivateKey::try_from(private_key), std::ptr::null_mut); + let pubkey = try_or_else!(NISTPublicKey::try_from(pubkey_data), std::ptr::null_mut); + private_key.ecies_shared_key(&pubkey) + }; + TWData::from(shared_key.to_vec()).into_ptr() +} diff --git a/rust/tw_keypair/src/ffi/mod.rs b/rust/tw_keypair/src/ffi/mod.rs index 33cdc647905..55cfa5ad735 100644 --- a/rust/tw_keypair/src/ffi/mod.rs +++ b/rust/tw_keypair/src/ffi/mod.rs @@ -4,5 +4,7 @@ pub mod asn; pub mod crypto_box; +pub mod curve25519; +pub mod ecdsa; pub mod privkey; pub mod pubkey; diff --git a/rust/tw_keypair/src/ffi/privkey.rs b/rust/tw_keypair/src/ffi/privkey.rs index 6451e9c958e..7fd5b41ee8a 100644 --- a/rust/tw_keypair/src/ffi/privkey.rs +++ b/rust/tw_keypair/src/ffi/privkey.rs @@ -31,11 +31,13 @@ impl AsRef for TWPrivateKey { pub unsafe extern "C" fn tw_private_key_create_with_data( input: *const u8, input_len: usize, + curve: u32, ) -> *mut TWPrivateKey { + let curve = try_or_else!(Curve::from_raw(curve), std::ptr::null_mut); let bytes_ref = CByteArrayRef::new(input, input_len); let bytes = try_or_else!(bytes_ref.to_vec(), std::ptr::null_mut); - PrivateKey::new(bytes) + PrivateKey::new(bytes, curve) .map(|private| TWPrivateKey(private).into_ptr()) // Return null if the private key is invalid. .unwrap_or_else(|_| std::ptr::null_mut()) @@ -72,6 +74,16 @@ pub unsafe extern "C" fn tw_private_key_size(data: *const TWPrivateKey) -> usize .unwrap_or_default() } +/// Returns the raw data of a given private-key. +/// +/// \param key *non-null* pointer to a private key. +/// \return C-compatible result with a C-compatible byte array. +#[no_mangle] +pub unsafe extern "C" fn tw_private_key_data(key: *mut TWPrivateKey) -> CByteArray { + let private = try_or_else!(TWPrivateKey::from_ptr_as_ref(key), CByteArray::default); + CByteArray::from(private.0.bytes().to_vec()) +} + /// Determines if the given private key is valid or not. /// /// \param key *non-null* byte array. @@ -101,9 +113,7 @@ pub unsafe extern "C" fn tw_private_key_sign( key: *mut TWPrivateKey, message: *const u8, message_len: usize, - curve: u32, ) -> CByteArray { - let curve = try_or_else!(Curve::from_raw(curve), CByteArray::default); let private = try_or_else!(TWPrivateKey::from_ptr_as_ref(key), CByteArray::default); let message_to_sign = try_or_else!( CByteArrayRef::new(message, message_len).as_slice(), @@ -111,7 +121,7 @@ pub unsafe extern "C" fn tw_private_key_sign( ); // Return an empty signature if an error occurs. - let sig = private.0.sign(message_to_sign, curve).unwrap_or_default(); + let sig = private.0.sign(message_to_sign).unwrap_or_default(); CByteArray::from(sig) } @@ -134,6 +144,58 @@ pub unsafe extern "C" fn tw_private_key_get_public_key_by_type( .unwrap_or_else(|_| std::ptr::null_mut()) } +/// Signs a digest using ECDSA with a canonical checker function. +/// +/// \param key *non-null* pointer to a Private key +/// \param digest *non-null* byte array containing the digest to sign. +/// \param digest_len the length of the `digest` array. +/// \param canonical_checker function pointer to check if signature is canonical. +/// \return Signature as a C-compatible result with a C-compatible byte array. +#[no_mangle] +pub unsafe extern "C" fn tw_private_key_sign_canonical( + key: *mut TWPrivateKey, + digest: *const u8, + digest_len: usize, + canonical_checker: Option i32>, +) -> CByteArray { + let private = try_or_else!(TWPrivateKey::from_ptr_as_ref(key), CByteArray::default); + let digest_to_sign = try_or_else!( + CByteArrayRef::new(digest, digest_len).as_slice(), + CByteArray::default + ); + + // Return an empty signature if an error occurs. + let sig = private + .0 + .sign_canonical(digest_to_sign, canonical_checker) + .unwrap_or_default(); + CByteArray::from(sig) +} + +/// Signs a digest using ECDSA as DER. +/// +/// \param key *non-null* pointer to a Private key +/// \param digest *non-null* byte array containing the digest to sign. +/// \param digest_len the length of the `digest` array. +/// \return Signature as a C-compatible result with a C-compatible byte array. +/// \note This function is only available for SECP256k1. +#[no_mangle] +pub unsafe extern "C" fn tw_private_key_sign_as_der( + key: *mut TWPrivateKey, + digest: *const u8, + digest_len: usize, +) -> CByteArray { + let private = try_or_else!(TWPrivateKey::from_ptr_as_ref(key), CByteArray::default); + let digest_to_sign = try_or_else!( + CByteArrayRef::new(digest, digest_len).as_slice(), + CByteArray::default + ); + + // Return an empty signature if an error occurs. + let sig = private.0.sign_as_der(digest_to_sign).unwrap_or_default(); + CByteArray::from(sig) +} + // #[no_mangle] // pub unsafe extern "C" fn tw_private_key_get_shared_key( // key: *mut TWPrivateKey, diff --git a/rust/tw_keypair/src/ffi/pubkey.rs b/rust/tw_keypair/src/ffi/pubkey.rs index 7f05f5f0fe9..1a3f9d2b239 100644 --- a/rust/tw_keypair/src/ffi/pubkey.rs +++ b/rust/tw_keypair/src/ffi/pubkey.rs @@ -41,6 +41,23 @@ pub unsafe extern "C" fn tw_public_key_create_with_data( .unwrap_or_else(|_| std::ptr::null_mut()) } +/// Determines if the given public key is valid or not. +/// +/// \param key *non-null* byte array. +/// \param key_len the length of the `key` array. +/// \param curve Eliptic curve of the public key. +/// \return true if the public key is valid, false otherwise. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_is_valid( + key: *const u8, + key_len: usize, + pubkey_type: u32, +) -> bool { + let pubkey_type = try_or_false!(PublicKeyType::from_raw(pubkey_type)); + let pub_key_bytes = try_or_false!(CByteArrayRef::new(key, key_len).to_vec()); + PublicKey::is_valid(pub_key_bytes, pubkey_type) +} + /// Delete the given public key. /// /// \param key *non-null* pointer to public key. @@ -82,21 +99,90 @@ pub unsafe extern "C" fn tw_public_key_data(key: *mut TWPublicKey) -> CByteArray CByteArray::from(public.0.to_bytes()) } -// #[no_mangle] -// pub unsafe extern "C" fn tw_public_key_is_valid( -// pubkey: *const u8, -// pubkey_len: usize, -// pubkey_type: u32, -// ) -> bool { -// let ty = match TWPublicKeyType::from_raw(pubkey_type) { -// Some(ty) => ty, -// None => return false, -// }; -// -// let pubkey_slice = match CByteArrayRef::new(pubkey, pubkey_len).as_slice() { -// Some(pubkey) => pubkey, -// None => return false, -// }; -// -// TWPublicKey::is_valid(pubkey_slice, ty) -// } +/// Returns the type of a given public-key. +/// +/// \param key *non-null* pointer to a public key. +/// \return C-compatible result with a C-compatible byte array. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_type(key: *mut TWPublicKey) -> u32 { + let public = try_or_else!(TWPublicKey::from_ptr_as_ref(key), || 0); + public.0.public_key_type() as u32 +} + +/// Returns the compressed data of a given public-key. +/// +/// \param key *non-null* pointer to a public key. +/// \return C-compatible result with a C-compatible byte array. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_compressed(key: *mut TWPublicKey) -> *mut TWPublicKey { + let public = try_or_else!(TWPublicKey::from_ptr_as_ref(key), std::ptr::null_mut); + public + .0 + .compressed() + .map(|public| TWPublicKey(public).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Returns the extended data of a given public-key. +/// +/// \param key *non-null* pointer to a public key. +/// \return C-compatible result with a C-compatible byte array. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_extended(key: *mut TWPublicKey) -> *mut TWPublicKey { + let public = try_or_else!(TWPublicKey::from_ptr_as_ref(key), std::ptr::null_mut); + public + .0 + .extended() + .map(|public| TWPublicKey(public).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Recover a public key from a signature and a message. +/// +/// \param sig *non-null* pointer to a block of data corresponding to the signature. +/// \param sig_len the length of the `sig` array. +/// \param msg *non-null* pointer to a block of data corresponding to the message. +/// \param msg_len the length of the `msg` array. +/// \return C-compatible result with a C-compatible pointer to the public key. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_recover_from_signature( + sig: *const u8, + sig_len: usize, + msg: *const u8, + msg_len: usize, + rec_id: u8, +) -> *mut TWPublicKey { + let sig = try_or_else!( + CByteArrayRef::new(sig, sig_len).as_slice(), + std::ptr::null_mut + ); + let msg = try_or_else!( + CByteArrayRef::new(msg, msg_len).as_slice(), + std::ptr::null_mut + ); + PublicKey::recover_from_signature(sig, msg, rec_id) + .map(|public| TWPublicKey(public).into_ptr()) + .unwrap_or_else(|_| std::ptr::null_mut()) +} + +/// Verify a signature as DER-encoded ECDSA signature. +/// +/// \param key *non-null* pointer to a public key. +/// \param sig *non-null* pointer to a block of data corresponding to the signature. +/// \param sig_len the length of the `sig` array. +/// \param msg *non-null* pointer to a block of data corresponding to the message. +/// \param msg_len the length of the `msg` array. +/// \return true if the signature and the message belongs to the given public key, otherwise false. +#[no_mangle] +pub unsafe extern "C" fn tw_public_key_verify_as_der( + key: *mut TWPublicKey, + sig: *const u8, + sig_len: usize, + msg: *const u8, + msg_len: usize, +) -> bool { + let public = try_or_false!(TWPublicKey::from_ptr_as_ref(key)); + let sig = try_or_false!(CByteArrayRef::new(sig, sig_len).as_slice()); + let msg = try_or_false!(CByteArrayRef::new(msg, msg_len).as_slice()); + public.0.verify_as_der(sig, msg) +} diff --git a/rust/tw_keypair/src/lib.rs b/rust/tw_keypair/src/lib.rs index 9a51090213d..0f185cfb57d 100644 --- a/rust/tw_keypair/src/lib.rs +++ b/rust/tw_keypair/src/lib.rs @@ -51,6 +51,7 @@ pub mod schnorr; pub mod starkex; pub mod traits; pub mod tw; +pub mod zilliqa_schnorr; #[cfg(feature = "test-utils")] pub mod test_utils; @@ -62,9 +63,12 @@ pub enum KeyPairError { InvalidSecretKey, InvalidPublicKey, InvalidSignature, + InvalidRecId, InvalidSignMessage, InvalidEncryptedMessage, SignatureVerifyError, SigningError, InternalError, + InvalidMessage, + UnsupportedCurve, } diff --git a/rust/tw_keypair/src/test_utils/tw_private_key_helper.rs b/rust/tw_keypair/src/test_utils/tw_private_key_helper.rs index 6c3c3bfc629..4250a64d4f4 100644 --- a/rust/tw_keypair/src/test_utils/tw_private_key_helper.rs +++ b/rust/tw_keypair/src/test_utils/tw_private_key_helper.rs @@ -12,16 +12,17 @@ pub struct TWPrivateKeyHelper { } impl TWPrivateKeyHelper { - pub fn with_bytes>(bytes: T) -> TWPrivateKeyHelper { + pub fn with_bytes>(bytes: T, curve: u32) -> TWPrivateKeyHelper { let priv_key_raw = CByteArray::from(bytes.into()); - let ptr = - unsafe { tw_private_key_create_with_data(priv_key_raw.data(), priv_key_raw.size()) }; + let ptr = unsafe { + tw_private_key_create_with_data(priv_key_raw.data(), priv_key_raw.size(), curve) + }; TWPrivateKeyHelper { ptr } } - pub fn with_hex(hex: &str) -> TWPrivateKeyHelper { + pub fn with_hex(hex: &str, curve: u32) -> TWPrivateKeyHelper { let priv_key_data = hex::decode(hex).unwrap(); - TWPrivateKeyHelper::with_bytes(priv_key_data) + TWPrivateKeyHelper::with_bytes(priv_key_data, curve) } pub fn ptr(&self) -> *mut TWPrivateKey { diff --git a/rust/tw_keypair/src/traits.rs b/rust/tw_keypair/src/traits.rs index 5ac9e30c773..5f78d89a82b 100644 --- a/rust/tw_keypair/src/traits.rs +++ b/rust/tw_keypair/src/traits.rs @@ -3,6 +3,7 @@ // Copyright © 2017 Trust Wallet. use crate::KeyPairResult; +use tw_hash::H256; use tw_misc::traits::{FromSlice, ToBytesVec, ToBytesZeroizing}; pub trait KeyPairTrait: FromSlice + SigningKeyTrait + VerifyingKeyTrait { @@ -31,3 +32,7 @@ pub trait VerifyingKeyTrait { /// Verifies if the given `hash` was signed using the private key. fn verify(&self, signature: Self::VerifySignature, message: Self::SigningMessage) -> bool; } + +pub trait DerivableKeyTrait: Sized { + fn derive_child(&self, other: H256) -> KeyPairResult; +} diff --git a/rust/tw_keypair/src/tw/mod.rs b/rust/tw_keypair/src/tw/mod.rs index 3e590dd0ed2..251d2d278f7 100644 --- a/rust/tw_keypair/src/tw/mod.rs +++ b/rust/tw_keypair/src/tw/mod.rs @@ -9,23 +9,34 @@ mod public; pub use private::PrivateKey; pub use public::PublicKey; +use zeroize::ZeroizeOnDrop; pub type Signature = Vec; #[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Deserialize, ZeroizeOnDrop)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub enum Curve { + #[serde(rename = "secp256k1")] Secp256k1 = 0, + #[serde(rename = "ed25519")] Ed25519 = 1, + #[serde(rename = "ed25519Blake2bNano")] Ed25519Blake2bNano = 2, /// Waves blockchain specific `curve25519`. + #[serde(rename = "curve25519Waves")] Curve25519Waves = 3, + #[serde(rename = "nist256p1")] Nist256p1 = 4, /// Cardano blockchain specific `ed25519` extended key. + #[serde(rename = "ed25519ExtendedCardano")] Ed25519ExtendedCardano = 5, + #[serde(rename = "starkex")] Starkex = 6, + #[serde(rename = "schnorr")] Schnorr = 7, + #[serde(rename = "zilliqaSchnorr")] + ZilliqaSchnorr = 8, } impl Curve { @@ -40,9 +51,24 @@ impl Curve { 5 => Some(Curve::Ed25519ExtendedCardano), 6 => Some(Curve::Starkex), 7 => Some(Curve::Schnorr), + 8 => Some(Curve::ZilliqaSchnorr), _ => None, } } + + pub fn to_raw(&self) -> u32 { + match self { + Curve::Secp256k1 => 0, + Curve::Ed25519 => 1, + Curve::Ed25519Blake2bNano => 2, + Curve::Curve25519Waves => 3, + Curve::Nist256p1 => 4, + Curve::Ed25519ExtendedCardano => 5, + Curve::Starkex => 6, + Curve::Schnorr => 7, + Curve::ZilliqaSchnorr => 8, + } + } } #[repr(C)] @@ -72,6 +98,8 @@ pub enum PublicKeyType { Starkex = 8, #[serde(rename = "schnorr")] Schnorr = 9, + #[serde(rename = "zilliqaSchnorr")] + ZilliqaSchnorr = 10, } impl PublicKeyType { @@ -88,6 +116,7 @@ impl PublicKeyType { 7 => Some(PublicKeyType::Ed25519ExtendedCardano), 8 => Some(PublicKeyType::Starkex), 9 => Some(PublicKeyType::Schnorr), + 10 => Some(PublicKeyType::ZilliqaSchnorr), _ => None, } } @@ -108,7 +137,8 @@ mod tests { (5, Some(Curve::Ed25519ExtendedCardano)), (6, Some(Curve::Starkex)), (7, Some(Curve::Schnorr)), - (8, None), + (8, Some(Curve::ZilliqaSchnorr)), + (9, None), ]; for (raw, expected) in tests { assert_eq!(Curve::from_raw(raw), expected); @@ -128,7 +158,8 @@ mod tests { (7, Some(PublicKeyType::Ed25519ExtendedCardano)), (8, Some(PublicKeyType::Starkex)), (9, Some(PublicKeyType::Schnorr)), - (10, None), + (10, Some(PublicKeyType::ZilliqaSchnorr)), + (11, None), ]; for (raw, expected) in tests { assert_eq!(PublicKeyType::from_raw(raw), expected); diff --git a/rust/tw_keypair/src/tw/private.rs b/rust/tw_keypair/src/tw/private.rs index 08cf8c18e80..8d44e3a8c92 100644 --- a/rust/tw_keypair/src/tw/private.rs +++ b/rust/tw_keypair/src/tw/private.rs @@ -2,13 +2,15 @@ // // Copyright © 2017 Trust Wallet. +use crate::ecdsa::canonical::sign_canonical_ffi; use crate::ecdsa::{nist256p1, secp256k1}; use crate::schnorr; use crate::traits::SigningKeyTrait; use crate::tw::{Curve, PublicKey, PublicKeyType}; +use crate::zilliqa_schnorr; use crate::{ed25519, starkex, KeyPairError, KeyPairResult}; use std::ops::Range; -use tw_hash::H256; +use tw_hash::{Hash, H256}; use tw_misc::traits::ToBytesVec; use zeroize::ZeroizeOnDrop; @@ -18,23 +20,24 @@ use zeroize::ZeroizeOnDrop; #[derive(ZeroizeOnDrop)] pub struct PrivateKey { bytes: Vec, + curve: Curve, } /// cbindgen:ignore impl PrivateKey { /// The number of bytes in a private key. - const SIZE: usize = 32; + pub(crate) const SIZE: usize = 32; const CARDANO_SIZE: usize = ed25519::cardano::ExtendedPrivateKey::LEN; const KEY_RANGE: Range = 0..Self::SIZE; const EXTENDED_CARDANO_RANGE: Range = 0..Self::CARDANO_SIZE; /// Validates the given `bytes` secret and creates a private key. - pub fn new(bytes: Vec) -> KeyPairResult { - if !Self::is_valid_general(&bytes) { + pub fn new(bytes: Vec, curve: Curve) -> KeyPairResult { + if !Self::is_valid_general(&bytes, &curve) { return Err(KeyPairError::InvalidSecretKey); } - Ok(PrivateKey { bytes }) + Ok(PrivateKey { bytes, curve }) } pub fn bytes(&self) -> &[u8] { @@ -59,9 +62,15 @@ impl PrivateKey { Ok(&self.bytes[Self::EXTENDED_CARDANO_RANGE]) } - /// Checks if the given `bytes` secret is valid in general (without a concrete curve). - pub fn is_valid_general(bytes: &[u8]) -> bool { - if bytes.len() != Self::SIZE && bytes.len() != Self::CARDANO_SIZE { + /// Checks if the given `bytes` secret is valid in general for the given `curve`. + pub fn is_valid_general(bytes: &[u8], curve: &Curve) -> bool { + let expected_len = if curve == &Curve::Ed25519ExtendedCardano { + Self::CARDANO_SIZE + } else { + Self::SIZE + }; + + if bytes.len() != expected_len { return false; } // Check for zero address. @@ -70,7 +79,7 @@ impl PrivateKey { /// Checks if the given `bytes` secret is valid. pub fn is_valid(bytes: &[u8], curve: Curve) -> bool { - if !Self::is_valid_general(bytes) { + if !Self::is_valid_general(bytes, &curve) { return false; } match curve { @@ -91,11 +100,14 @@ impl PrivateKey { }, Curve::Starkex => starkex::PrivateKey::try_from(&bytes[Self::KEY_RANGE]).is_ok(), Curve::Schnorr => schnorr::PrivateKey::try_from(&bytes[Self::KEY_RANGE]).is_ok(), + Curve::ZilliqaSchnorr => { + zilliqa_schnorr::PrivateKey::try_from(&bytes[Self::KEY_RANGE]).is_ok() + }, } } /// Signs a `message` with using the given elliptic curve. - pub fn sign(&self, message: &[u8], curve: Curve) -> KeyPairResult> { + pub fn sign(&self, message: &[u8]) -> KeyPairResult> { fn sign_impl(signing_key: Key, message: &[u8]) -> KeyPairResult> where Key: SigningKeyTrait, @@ -105,7 +117,7 @@ impl PrivateKey { signing_key.sign(hash_to_sign).map(|sig| sig.to_vec()) } - match curve { + match self.curve { Curve::Secp256k1 => sign_impl(self.to_secp256k1_privkey()?, message), Curve::Ed25519 => sign_impl(self.to_ed25519()?, message), Curve::Ed25519Blake2bNano => sign_impl(self.to_ed25519_blake2b()?, message), @@ -116,6 +128,38 @@ impl PrivateKey { }, Curve::Starkex => sign_impl(self.to_starkex_privkey()?, message), Curve::Schnorr => sign_impl(self.to_schnorr_privkey()?, message), + Curve::ZilliqaSchnorr => sign_impl(self.to_zilliqa_schnorr_privkey()?, message), + } + } + + pub fn sign_canonical( + &self, + message: &[u8], + canonical_checker: Option i32>, + ) -> KeyPairResult> { + let message_hash = + Hash::<32>::try_from(message).map_err(|_| KeyPairError::InvalidSignMessage)?; + + match self.curve { + Curve::Secp256k1 => { + let private_key = self.to_secp256k1_privkey()?; + sign_canonical_ffi( + &private_key.secret, + message_hash, + canonical_checker, + |sig| sig.vrs().to_vec(), + ) + }, + Curve::Nist256p1 => { + let private_key = self.to_nist256p1_privkey()?; + sign_canonical_ffi( + &private_key.secret, + message_hash, + canonical_checker, + |sig| sig.vrs().to_vec(), + ) + }, + _ => Err(KeyPairError::UnsupportedCurve), } } @@ -164,6 +208,10 @@ impl PrivateKey { let privkey = self.to_schnorr_privkey()?; Ok(PublicKey::Schnorr(privkey.public())) }, + PublicKeyType::ZilliqaSchnorr => { + let privkey = self.to_zilliqa_schnorr_privkey()?; + Ok(PublicKey::ZilliqaSchnorr(privkey.public())) + }, } } @@ -206,4 +254,27 @@ impl PrivateKey { fn to_schnorr_privkey(&self) -> KeyPairResult { schnorr::PrivateKey::try_from(self.key().as_slice()) } + + /// Tries to convert [`PrivateKey::key`] to [`zilliqa_schnorr::PrivateKey`]. + fn to_zilliqa_schnorr_privkey(&self) -> KeyPairResult { + zilliqa_schnorr::PrivateKey::try_from(self.key().as_slice()) + } + + /// Signs a digest using ECDSA as DER. + pub fn sign_as_der(&self, digest: &[u8]) -> KeyPairResult> { + match self.curve { + Curve::Secp256k1 => { + let private_key = self.to_secp256k1_privkey()?; + let hash_to_sign = + H256::try_from(digest).map_err(|_| KeyPairError::InvalidSignMessage)?; + let sig = private_key + .sign(hash_to_sign) + .map_err(|_| KeyPairError::InvalidSignature)?; + let der_sig = crate::ecdsa::der::Signature::new(sig.r(), sig.s()) + .map_err(|_| KeyPairError::InvalidSignature)?; + Ok(der_sig.der_bytes()) + }, + _ => Err(KeyPairError::UnsupportedCurve), + } + } } diff --git a/rust/tw_keypair/src/tw/public.rs b/rust/tw_keypair/src/tw/public.rs index 2ab54f8820a..3494abbd2a1 100644 --- a/rust/tw_keypair/src/tw/public.rs +++ b/rust/tw_keypair/src/tw/public.rs @@ -4,12 +4,16 @@ use crate::ecdsa::{nist256p1, secp256k1}; use crate::schnorr; -use crate::traits::VerifyingKeyTrait; +use crate::traits::{SigningKeyTrait, VerifyingKeyTrait}; use crate::tw::PublicKeyType; +use crate::zilliqa_schnorr; use crate::{ed25519, starkex, KeyPairError, KeyPairResult}; +use tw_hash::H256; use tw_misc::traits::ToBytesVec; use tw_misc::try_or_false; +use super::PrivateKey; + /// Represents a public key that can be used to verify signatures and messages. #[derive(Clone)] #[non_exhaustive] @@ -24,6 +28,7 @@ pub enum PublicKey { Ed25519ExtendedCardano(Box), Starkex(starkex::PublicKey), Schnorr(schnorr::PublicKey), + ZilliqaSchnorr(zilliqa_schnorr::PublicKey), } impl PublicKey { @@ -54,6 +59,12 @@ impl PublicKey { let pubkey = ed25519::sha512::PublicKey::try_from(bytes.as_slice())?; Ok(PublicKey::Ed25519(pubkey)) }, + PublicKeyType::Ed25519 + if ed25519::sha512::PublicKey::LEN + 1 == bytes.len() && bytes[0] == 0x01 => + { + let pubkey = ed25519::sha512::PublicKey::try_from(&bytes[1..])?; + Ok(PublicKey::Ed25519(pubkey)) + }, PublicKeyType::Ed25519Blake2b if ed25519::blake2b::PublicKey::LEN == bytes.len() => { let pubkey = ed25519::blake2b::PublicKey::try_from(bytes.as_slice())?; Ok(PublicKey::Ed25519Blake2b(pubkey)) @@ -76,6 +87,10 @@ impl PublicKey { let pubkey = schnorr::PublicKey::try_from(bytes.as_slice())?; Ok(PublicKey::Schnorr(pubkey)) }, + PublicKeyType::ZilliqaSchnorr => { + let pubkey = zilliqa_schnorr::PublicKey::try_from(bytes.as_slice())?; + Ok(PublicKey::ZilliqaSchnorr(pubkey)) + }, _ => Err(KeyPairError::InvalidPublicKey), } } @@ -114,6 +129,7 @@ impl PublicKey { }, PublicKey::Starkex(stark) => verify_impl(stark, sig, message), PublicKey::Schnorr(schnorr) => verify_impl(schnorr, sig, message), + PublicKey::ZilliqaSchnorr(zilliqa) => verify_impl(zilliqa, sig, message), } } @@ -130,6 +146,7 @@ impl PublicKey { PublicKey::Ed25519ExtendedCardano(cardano) => cardano.to_vec(), PublicKey::Starkex(stark) => stark.to_vec(), PublicKey::Schnorr(schnorr) => schnorr.to_vec(), + PublicKey::ZilliqaSchnorr(zilliqa) => zilliqa.to_vec(), } } @@ -171,6 +188,72 @@ impl PublicKey { PublicKey::Ed25519ExtendedCardano(_) => PublicKeyType::Ed25519ExtendedCardano, PublicKey::Starkex(_) => PublicKeyType::Starkex, PublicKey::Schnorr(_) => PublicKeyType::Schnorr, + PublicKey::ZilliqaSchnorr(_) => PublicKeyType::ZilliqaSchnorr, + } + } + + pub fn compressed(&self) -> KeyPairResult { + match self { + PublicKey::Secp256k1Extended(secp) => { + let bytes = secp.compressed().to_vec(); + PublicKey::new(bytes, PublicKeyType::Secp256k1) + }, + PublicKey::Nist256p1Extended(nist) => { + let bytes = nist.compressed().to_vec(); + PublicKey::new(bytes, PublicKeyType::Nist256p1) + }, + _ => Ok(self.clone()), + } + } + + pub fn extended(&self) -> KeyPairResult { + match self { + PublicKey::Secp256k1(secp) => { + let bytes = secp.uncompressed().to_vec(); + PublicKey::new(bytes, PublicKeyType::Secp256k1Extended) + }, + PublicKey::Nist256p1(nist) => { + let bytes = nist.uncompressed().to_vec(); + PublicKey::new(bytes, PublicKeyType::Nist256p1Extended) + }, + _ => Ok(self.clone()), + } + } + + pub fn recover_from_signature( + sig: &[u8], + message: &[u8], + rec_id: u8, + ) -> KeyPairResult { + if sig.len() < 2 * PrivateKey::SIZE { + return Err(KeyPairError::InvalidSignature); + } + if rec_id >= 4 { + return Err(KeyPairError::InvalidRecId); + } + if message.len() < PrivateKey::SIZE { + return Err(KeyPairError::InvalidMessage); + } + + let verify_sig = + ::Signature::new_from_bytes(sig, rec_id) + .map_err(|_| KeyPairError::InvalidSignature)?; + let message = H256::try_from(message).map_err(|_| KeyPairError::InvalidMessage)?; + let pubkey = secp256k1::PublicKey::recover(verify_sig, message)?; + Ok(PublicKey::Secp256k1Extended(pubkey)) + } + + pub fn verify_as_der(&self, sig: &[u8], message: &[u8]) -> bool { + match self { + PublicKey::Secp256k1(secp) | PublicKey::Secp256k1Extended(secp) => { + let der_sig = try_or_false!(crate::ecdsa::der::Signature::from_bytes(sig)); + let verify_sig = try_or_false!(secp256k1::VerifySignature::try_from( + der_sig.to_bytes().as_slice() + )); + let message = try_or_false!(H256::try_from(message)); + secp.verify(verify_sig, message) + }, + _ => false, } } } diff --git a/rust/tw_keypair/src/zilliqa_schnorr/mod.rs b/rust/tw_keypair/src/zilliqa_schnorr/mod.rs new file mode 100644 index 00000000000..c89022d56df --- /dev/null +++ b/rust/tw_keypair/src/zilliqa_schnorr/mod.rs @@ -0,0 +1,95 @@ +mod private; +mod public; +mod signature; + +pub use private::PrivateKey; +pub use public::PublicKey; +pub use signature::Signature; + +#[cfg(test)] +mod tests { + use super::*; + use crate::traits::{SigningKeyTrait, VerifyingKeyTrait}; + use crate::zilliqa_schnorr::public::VerifySignature; + use std::str::FromStr; + use tw_encoding::hex; + use tw_hash::sha2::sha256; + use tw_hash::sha3::keccak256; + use tw_hash::H256; + use tw_misc::traits::ToBytesVec; + + #[test] + fn test_public_key() { + let private_key = PrivateKey::from_str( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + ) + .unwrap(); + + let public_key = private_key.public(); + assert_eq!( + hex::encode(public_key.to_vec(), false), + "0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1" + ); + } + + #[test] + fn test_sign_zilliqa() { + let private_key = PrivateKey::from_str( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + ) + .unwrap(); + + let message = "hello schnorr"; + let message_data = message.as_bytes(); + let digest = sha256(message_data); + + let signature = private_key.sign(digest.to_vec()).unwrap(); + + assert_eq!( + hex::encode(signature.to_vec(), false), + "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853" + ); + } + + #[test] + fn test_verify_zilliqa() { + let private_key = PrivateKey::from_str( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + ) + .unwrap(); + + let public_key = private_key.public(); + + let message = "hello schnorr"; + let message_data = message.as_bytes(); + let digest = sha256(message_data); + + let signature = private_key.sign(digest.to_vec()).unwrap(); + + assert_eq!( + hex::encode(signature.to_vec(), false), + "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853" + ); + + let is_valid = public_key.verify(signature, digest.to_vec()); + assert!(is_valid); + } + + #[test] + fn test_verify_invalid() { + let private_key = PrivateKey::from_str( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + ) + .unwrap(); + + let signature_bytes = hex::decode("b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853").unwrap(); + let verify_sig = VerifySignature::try_from(signature_bytes.as_slice()).unwrap(); + + let hash_to_sign = keccak256(b"hello"); + let hash_to_sign = H256::try_from(hash_to_sign.as_slice()).unwrap(); + + assert!(!private_key + .public() + .verify(verify_sig, hash_to_sign.to_vec())); + } +} diff --git a/rust/tw_keypair/src/zilliqa_schnorr/private.rs b/rust/tw_keypair/src/zilliqa_schnorr/private.rs new file mode 100644 index 00000000000..e61ff8091ab --- /dev/null +++ b/rust/tw_keypair/src/zilliqa_schnorr/private.rs @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +use super::PublicKey; +use super::Signature; +use crate::ecdsa::canonical::generate_k; +use crate::traits::DerivableKeyTrait; +use crate::KeyPairResult; +use crate::{traits::SigningKeyTrait, KeyPairError}; +use ecdsa::elliptic_curve::PrimeField; +use ecdsa::hazmat::{bits2field, DigestPrimitive}; +use k256::elliptic_curve::bigint::ArrayEncoding; +use k256::elliptic_curve::Curve; +use k256::Secp256k1; +use k256::{ + elliptic_curve::{ops::Reduce, sec1::ToEncodedPoint}, + AffinePoint, Scalar, U256, +}; +use rfc6979::HmacDrbg; +use secp256k1::rand; +use sha2::{Digest, Sha256}; +use std::ops::Deref; +use std::str::FromStr; +use tw_encoding::hex; +use tw_hash::H256; +use tw_misc::traits::ToBytesZeroizing; +use zeroize::ZeroizeOnDrop; +use zeroize::Zeroizing; + +type CurveDigest = ::Digest; + +#[derive(Debug, Clone, ZeroizeOnDrop)] +/// secp256k1 (K-256) secret key. +pub struct PrivateKey(k256::SecretKey); + +impl PrivateKey { + /// Generates a random private key. + /// + /// # Example + /// ``` + /// use tw_keypair::zilliqa_schnorr::PrivateKey; + /// let private_key = PrivateKey::create_random(); + /// ``` + pub fn create_random() -> Self { + Self(k256::SecretKey::random(&mut rand::thread_rng())) + } + + /// Constructs a private key from a raw secret key. + pub fn from_slice(slice: &[u8]) -> Result { + Ok(Self( + k256::SecretKey::from_slice(slice).map_err(|_| KeyPairError::InvalidSecretKey)?, + )) + } + + /// Returns corresponding public key of the private key + pub fn public(&self) -> PublicKey { + PublicKey::new(self.0.public_key()) + } + + // Taken from https://github.com/Zilliqa/zilliqa-rs/blob/24a0e882bcab634b6e776d94709c1760841023d4/src/crypto/schnorr.rs#L20 + fn sign_inner(&self, k: Scalar, message: &[u8]) -> Option { + let public_key = self.public(); + + // 2. Compute the commitment Q = kG, where G is the base point. + let q = AffinePoint::GENERATOR * k; + + // 3. Compute the challenge r = H(Q, kpub, m) + let mut hasher = Sha256::new(); + hasher.update(q.to_encoded_point(true).to_bytes()); + hasher.update(public_key.to_encoded_point(true).to_bytes()); + hasher.update(message); + let r = >::reduce_bytes(&hasher.finalize()); + + // 4. If r = 0 mod(order), goto 1 + if r.is_zero().into() { + return None; + } + + // 5. Compute s = k - r*kpriv mod(order) + let s: Scalar = k - r.mul(&self.0.as_scalar_primitive().into()); + + // 6. If s = 0 goto 1. + if s.is_zero().into() { + return None; + } + + // 7. Signature on m is (r, s) + k256::ecdsa::Signature::from_scalars(r.to_bytes(), s.to_bytes()) + .map(|signature| Signature { signature }) + .ok() + } +} + +impl TryFrom<&[u8]> for PrivateKey { + type Error = KeyPairError; + + fn try_from(bytes: &[u8]) -> Result { + Self::from_slice(bytes) + } +} + +impl FromStr for PrivateKey { + type Err = KeyPairError; + + fn from_str(secret_key: &str) -> Result { + let bytes = hex::decode(secret_key).map_err(|_| KeyPairError::InvalidSecretKey)?; + Ok(Self( + k256::SecretKey::from_slice(&bytes).map_err(|_| KeyPairError::InvalidSecretKey)?, + )) + } +} + +impl Deref for PrivateKey { + type Target = k256::SecretKey; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ToBytesZeroizing for PrivateKey { + fn to_zeroizing_vec(&self) -> Zeroizing> { + let secret = Zeroizing::new(self.0.to_bytes()); + Zeroizing::new(secret.as_slice().to_vec()) + } +} + +impl SigningKeyTrait for PrivateKey { + type SigningMessage = Vec; + type Signature = Signature; + + // Taken from https://github.com/Zilliqa/zilliqa-rs/blob/24a0e882bcab634b6e776d94709c1760841023d4/src/crypto/schnorr.rs#L20 + fn sign(&self, message: Self::SigningMessage) -> KeyPairResult { + let priv_scalar = self.0.as_scalar_primitive(); + let entropy_input = &priv_scalar.to_bytes(); + + let message_hash = sha2::Sha256::digest(message.as_slice()); + let nonce = bits2field::(message_hash.as_slice()) + .map_err(|_| KeyPairError::InvalidSignMessage)?; + let n = Secp256k1::ORDER.to_be_byte_array(); + let additional_data = &[]; + + let mut hmac_drbg = + HmacDrbg::>::new(entropy_input, &nonce, additional_data); + + for _ in 0..10000 { + let k = generate_k(&mut hmac_drbg, &n); + let k_scalar = Scalar::from_repr(k).unwrap(); + + if let Some(signature) = self.sign_inner(k_scalar, message.as_slice()) { + return Ok(signature); + } + } + + Err(KeyPairError::SigningError) + } +} + +impl DerivableKeyTrait for PrivateKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(k256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InternalError)?; + + let derived_scalar = self.0.to_nonzero_scalar().as_ref() + child_scalar.as_ref(); + + let secret = Option::::from(k256::NonZeroScalar::new(derived_scalar)) + .map(Into::into) + .ok_or(KeyPairError::InternalError)?; + + Ok(PrivateKey(secret)) + } +} + +#[cfg(test)] +mod tests { + use super::{PrivateKey, PublicKey}; + use crate::traits::VerifyingKeyTrait; + use k256::{elliptic_curve::PrimeField, FieldBytes, Scalar}; + use tw_encoding::hex; + + #[test] + fn signing() { + // From https://github.com/Zilliqa/zilliqa-js/blob/226b371eaac78ed80e7b40b93189b6a97086bdf5/packages/zilliqa-js-crypto/test/schnorr.spec.ts#L23. + let cases = [ + ( + "A7F1D92A82C8D8FE434D98558CE2B347171198542F112D0558F56BD68807999248336241F30D23E55F30D1C8ED610C4B0235398184B814A29CB45A672ACAE548E9C5F1B0C4158AE59B4D39F6F7E8A105D3FEEDA5D5F3D9E45BFA6CC351E220AE0CE106986D61FF34A11E19FD3650E9B7818FC33A1E0FC02C44557AC8AB50C9B2DEB2F6B5E24C4FDD9F8867BDCE1FF261008E7897970E346207D75E47A158298E5BA2F56246869CC42E362A02731264E60687EF5309D108534F51F8658FB4F080B7CB19EE9AEBD718CC4FA27C8C37DFC1ADA5D133D13ABE03F021E9B1B78CCBD82F7FF2B38C6D48D01E481B2D4FAF7171805FD7F2D39EF4C4F19B9496E81DAB8193B3737E1B27D9C43957166441B93515E8F03C95D8E8CE1E1864FAAD68DDFC5932130109390B0F1FE5CA716805F8362E98DCCAADC86ADBED25801A9A9DCFA6264319DDAFE83A89C51F3C6D199D38DE10E660C37BE872C3F2B31660DE8BC95902B9103262CDB941F77376F5D3DBB7A3D5A387797FC4819A035ECA704CEDB37110EE7F206B0C8805AAEBF4963E7C4708CE8D4E092366E71792A8A3B2BBCDEE321B3E15380C541EF0930888969F7457AFE18588826A419D58311C1784B5484EECDB393F6A0ACA11B91DF0866B500B8DEE501FD7EB9BCE09A17D74124B4605ADFC0777BED9816D8D7E8488544A18D8045CB3283B0A752B881B5F500FADB59010E63D", + "039E43C9810E6CC09F46AAD38E716DAE3191629534967DC457D3A687D2E2CDDC6A", + "0F494B8312E8D257E51730C78F8FE3B47B6840C59AAAEC7C2EBE404A2DE8B25A", + "532B2267C4A3054F380B3357339BDFB379E88366FE61B42ACA05F69BC3F6F54E", + "3AF3D288E830E96FF8ED0769F45ABDA774CD989E2AE32EF9E985C8505F14FF98", + "E191EB14A70B5B53ADA45AFFF4A04578F5D8BB2B1C8A22985EA159B53826CDE7", + ), + ( + "1B664F8BDA2DBF33CB6BE21C8EB3ECA9D9D5BF144C08E9577ED0D1E5E560875109B340980580473DBC2E689A3BE838E77A0A3348FE960EC9BF81DA36F1868CA5D24788FA4C0C778BF0D12314285495636516CF40861B3D737FD35DBB591C5B5D25916EB1D86176B14E0E67D2D03957F0CF6C87834BF328540588360BA7C7C5F88541634FB7BADE5F94FF671D1FEBDCBDA116D2DA779038ED7679896C29198B2657B58C50EA054F644F4129C8BA8D8D544B727633DD40754398046796E038626FEF9237CE5B615BC08677EE5ABFBD85F73F7F8868CB1B5FBA4C1309F16061AA133821FBE2A758D2BBE6AA040A940D41B7D3B869CEE945150AA4A40E6FF719EEC24B2681CD5CE06B50273436584066046656D5EFED7315759189D68815DDB9E5F8D7FD53B6EC096616A773B9421F6704CED36EF4E484BA0C6C5A4855C71C33A54AC82BE803E5CFD175779FC444B7E6AA9001EEFABEBC0CF99754887C7B0A27AFDDC415F8A02C5AF1EFEA26AD1E5D92B1E29A8FAF5B2186C3094F4A137BCFAA65D7B274214DB64C86F3085B24938E1832FB310A6F064181E298D23062ABC817BA173023C8C04C5C3A1ECBF4AF72372B381FF69865C8F0E3C70B931C45A7419B3C441842EBFACC3D070AC3B433CD120B6E85B72DADCF40B23B173C34F6BE1B1901F6621F1497B085CF8E999D986EF8FF3A889A0238979983A8686F69E10EF9249A87", + "0245DC2911EDC02F2774E0A40FBEB0112EA60BF513F9EC50889D59FC94C97EC18F", + "8D566BB87EF69FFDA622E0A59FBAAFE57F486CE65844343A5D9B97DE9C4F619A", + "948AFFFF6E068CA2F2757BFD6085D6E4C3084B038E5533C5927ECB19EA0D329C", + "DFEE66E2C4799E73F0F778126A23032608408C27C2E7B3FA45A626BB9BDEB53C", + "75445CC9DBFE4E7BC64E020FA22CACFA4C40D5AA84DD6AEF661564FCA9746C40", + ), + ( + "3444C8501F19A8A78670F748FA401C4020AE086D7157A3837EC721DEF0D6E095928C5B78ED9B95560CE33D5B22778BE66DCEF2D21878D481DFF41A4DEDCAFDCAEAB4BD78629D7EC40FD26F1DD954CA84A3B53B84E9903056E840837A1390F37BB8ADE799DAC1E465D811916547EB4B6A163082E9833634A1224C54F681B8DC70A792C0CB4671D4970CCC80E2168CE920CC8FA07B1F90E9898D16019913ED5B8EE8A8DE7AB6F7895601FD20E49FD73E6F5D24C0D97E67871539F0E4E32CCB6677AFF03356D1F3790945E94039E51A63B3C840B74E3053D95CA71C0D3AC20A9065828D30AB5BFB6188A8F291FB1EB4E1EED03E2F5F558C00D8E3084120DEEB8BFE908429B36A896A45D624E79372CC18DF37DB2D20C9726D4FEF7BECF220138B53BC54C2DA461A9955AFF33F2F93DD96464BF3E883FC5750BDBE79BC2F82427F41DE42659AC4B111D7CEF8085003469DF8C9D3541480C6841707CE4C8F3D003AF982AD35C2733D0FA3B1EE52A6DAB36203D99AEC179A565B5050F480235C3BC560AA28EF5DD5525BFA254E584A86FDBD4BCC5B56551BAD00255CB72F806D7F3C533321B0864007AFBA4E0FF9638517FA8D788F52766F3A28C57C428BFDD4234AA760CE8044DF1E1FBA58E8B1D9C5A79D2AC4592FC31702F7E83351D2160C09C5CEA554F2C93A61C040E225612DF2B550900B097E18638350E3BA15C9AD53CE1861", + "02237627FE7374061FBD80AEA842DCE76D9206F0DDC7B319F3B30FA75DBD4F009A", + "009755F442D66585A10B80A49850C77764AD029D1BEA73F4DA45AB331306E6E5", + "2D78C77B736AD0A00FDF60695C01E96520656C13DC890A5B864672C6CED1C49A", + "4B73D4D919D7B4DEF330391899EA02023851CABE044E34E18EAE3E10588CECCD", + "D5DE85C4BDEA5910DC36AEF5660774D65291322C1E87FDA0D00C864E8C5FED29", + ), + ]; + for (message, public_key, secret_key, k, r, s) in cases { + let k = + Scalar::from_repr(FieldBytes::clone_from_slice(&hex::decode(k).unwrap())).unwrap(); + let message = hex::decode(message).unwrap(); + let secret_key = secret_key.parse::().unwrap(); + let public_key = public_key.parse::().unwrap(); + + let signature = secret_key.sign_inner(k, &message).unwrap(); + + assert_eq!(signature.signature.r().to_string(), r); + assert_eq!(signature.signature.s().to_string(), s); + + assert!(public_key.verify(signature, message)); + } + } +} diff --git a/rust/tw_keypair/src/zilliqa_schnorr/public.rs b/rust/tw_keypair/src/zilliqa_schnorr/public.rs new file mode 100644 index 00000000000..269c9fc81fc --- /dev/null +++ b/rust/tw_keypair/src/zilliqa_schnorr/public.rs @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +use crate::traits::{DerivableKeyTrait, VerifyingKeyTrait}; +use crate::{KeyPairError, KeyPairResult}; +use ecdsa::elliptic_curve::group::prime::PrimeCurveAffine; +use k256::{ + elliptic_curve::{ops::Reduce, sec1::ToEncodedPoint, Group}, + AffinePoint, Scalar, U256, +}; +use sha2::{Digest, Sha256}; +use std::fmt::Display; +use std::ops::Deref; +use std::str::FromStr; +use tw_encoding::hex; +use tw_hash::H256; +use tw_misc::traits::ToBytesVec; + +pub type VerifySignature = super::Signature; + +/// secp256k1 (K-256) public key. +#[derive(Debug, Clone)] +pub struct PublicKey(k256::PublicKey); + +impl PublicKey { + /// Creates a new public key. + pub fn new(pk: k256::PublicKey) -> Self { + Self(pk) + } +} + +impl TryFrom<&[u8]> for PublicKey { + type Error = KeyPairError; + + fn try_from(bytes: &[u8]) -> Result { + Ok(Self( + k256::PublicKey::from_sec1_bytes(bytes).map_err(|_| KeyPairError::InvalidPublicKey)?, + )) + } +} + +impl FromStr for PublicKey { + type Err = KeyPairError; + + /// Parse a string into a public key + /// + /// # Example + /// ``` + /// use tw_keypair::zilliqa_schnorr::PublicKey; + /// let public_key: PublicKey = "03bfad0f0b53cff5213b5947f3ddd66acee8906aba3610c111915aecc84092e052" + /// .parse() + /// .unwrap(); + /// assert_eq!( + /// public_key.to_string(), + /// "03bfad0f0b53cff5213b5947f3ddd66acee8906aba3610c111915aecc84092e052" + /// ); + /// ``` + fn from_str(public_key: &str) -> Result { + let bytes = hex::decode(public_key).map_err(|_| KeyPairError::InvalidPublicKey)?; + Ok(Self( + k256::PublicKey::from_sec1_bytes(&bytes).map_err(|_| KeyPairError::InvalidPublicKey)?, + )) + } +} + +impl Deref for PublicKey { + type Target = k256::PublicKey; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Display for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + hex::encode(self.to_sec1_bytes(), false).to_lowercase() + ) + } +} + +impl ToBytesVec for PublicKey { + fn to_vec(&self) -> Vec { + self.0.to_sec1_bytes().to_vec() + } +} + +impl VerifyingKeyTrait for PublicKey { + type SigningMessage = Vec; + type VerifySignature = VerifySignature; + + // Taken from https://github.com/Zilliqa/zilliqa-rs/blob/24a0e882bcab634b6e776d94709c1760841023d4/src/crypto/schnorr.rs#L50 + fn verify(&self, signature: Self::VerifySignature, message: Self::SigningMessage) -> bool { + let (r, s) = signature.split_scalars(); + + // 2. Compute Q = sG + r*kpub + let q = (AffinePoint::GENERATOR * *s) + (*self.as_affine() * *r); + + // 3. If Q = 0 (the neutral point), return 0; + if q.is_identity().into() { + return false; + } + + // 4. r' = H(Q, kpub, m) + let mut hasher = Sha256::new(); + hasher.update(q.to_encoded_point(true).to_bytes()); + hasher.update(self.to_encoded_point(true).to_bytes()); + hasher.update(message); + let r_dash = >::reduce_bytes(&hasher.finalize()); + + // 5. Return r' == r + if r_dash != *r { + return false; + } + + true + } +} + +impl DerivableKeyTrait for PublicKey { + fn derive_child(&self, other: H256) -> KeyPairResult { + let child_scalar = Option::::from(k256::NonZeroScalar::from_repr( + other.take().into(), + )) + .ok_or(KeyPairError::InternalError)?; + + let projective_point: k256::ProjectivePoint = self.0.as_affine().into(); + let child_point = projective_point + (k256::AffinePoint::generator() * *child_scalar); + let public = k256::PublicKey::from_affine(child_point.into()) + .map_err(|_| KeyPairError::InternalError)?; + + Ok(PublicKey(public)) + } +} diff --git a/rust/tw_keypair/src/zilliqa_schnorr/signature.rs b/rust/tw_keypair/src/zilliqa_schnorr/signature.rs new file mode 100644 index 00000000000..ce5158fd737 --- /dev/null +++ b/rust/tw_keypair/src/zilliqa_schnorr/signature.rs @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +use crate::KeyPairError; +use k256::NonZeroScalar; +use tw_misc::traits::ToBytesVec; + +pub struct Signature { + pub(crate) signature: k256::ecdsa::Signature, +} + +impl Signature { + pub fn new(signature: k256::ecdsa::Signature) -> Self { + Self { signature } + } + + pub(crate) fn split_scalars(&self) -> (NonZeroScalar, NonZeroScalar) { + self.signature.split_scalars() + } +} + +impl<'a> TryFrom<&'a [u8]> for Signature { + type Error = KeyPairError; + + fn try_from(sig: &'a [u8]) -> Result { + let signature = + k256::ecdsa::Signature::from_slice(sig).map_err(|_| KeyPairError::InvalidSignature)?; + Ok(Signature::new(signature)) + } +} + +impl ToBytesVec for Signature { + fn to_vec(&self) -> Vec { + self.signature.to_bytes().to_vec() + } +} diff --git a/rust/tw_keypair/tests/ed25519_waves_tests.rs b/rust/tw_keypair/tests/ed25519_waves_tests.rs index c231ee362b1..1e55445100b 100644 --- a/rust/tw_keypair/tests/ed25519_waves_tests.rs +++ b/rust/tw_keypair/tests/ed25519_waves_tests.rs @@ -6,7 +6,9 @@ use serde::Deserialize; use tw_encoding::hex::{self, as_hex}; use tw_hash::{H256, H512}; use tw_keypair::ed25519::waves::KeyPair; +use tw_keypair::ffi::curve25519::tw_curve25519_pubkey_to_ed25519; use tw_keypair::traits::{KeyPairTrait, SigningKeyTrait, VerifyingKeyTrait}; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; use tw_misc::traits::ToBytesZeroizing; /// The tests were generated in C++ using the `trezor-crypto` library. @@ -62,3 +64,17 @@ fn test_ed25519_waves_priv_to_pub() { assert_eq!(public.to_bytes(), test.public); } } + +#[test] +fn test_tw_curve25519_pubkey_to_ed25519() { + let pubkey = "559a50cb45a9a8e8d4f83295c354725990164d10bb505275d1a3086c08fb935d"; + let pubkey_data = hex::decode(pubkey).unwrap(); + let tw_pubkey = TWDataHelper::create(pubkey_data); + + let hash = TWDataHelper::wrap(unsafe { tw_curve25519_pubkey_to_ed25519(tw_pubkey.ptr()) }); + + assert_eq!( + hex::encode(hash.to_vec().unwrap(), false), + "ff84c4bfc095df25b01e48807715856d95af93d88c5b57f30cb0ce567ca4ce56" + ); +} diff --git a/rust/tw_keypair/tests/nist256p1_tests.rs b/rust/tw_keypair/tests/nist256p1_tests.rs index 570f98d4fe0..6024dd47792 100644 --- a/rust/tw_keypair/tests/nist256p1_tests.rs +++ b/rust/tw_keypair/tests/nist256p1_tests.rs @@ -3,10 +3,13 @@ // Copyright © 2017 Trust Wallet. use serde::Deserialize; -use tw_encoding::hex::as_hex; +use tw_encoding::hex::{self, as_hex}; use tw_hash::{H256, H264, H520}; use tw_keypair::ecdsa::nist256p1::{PrivateKey, PublicKey, VerifySignature}; +use tw_keypair::ffi::ecdsa::{tw_ecdsa_pubkey_hash, tw_ecdsa_sig_to_der}; use tw_keypair::traits::VerifyingKeyTrait; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; +use tw_misc::traits::ToBytesVec; /// The tests were generated in C++ using the `trezor-crypto` library. const NIST256P1_VERIFY: &str = include_str!("nist256p1_verify.json"); @@ -53,3 +56,76 @@ fn test_nist256p1_priv_to_pub() { assert_eq!(actual_public, test.public); } } + +#[test] +fn test_nist256p1_pubkey_compare() { + let p1 = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; + let p2 = "03d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1ee"; + let p3 = "0305947c8564734b0e634531c405a0b6488e2cb9bcde5eddefcf3f008f0c048115"; + + let pubkey1 = PublicKey::try_from(hex::decode(p1).unwrap().as_slice()).unwrap(); + let pubkey2 = PublicKey::try_from(hex::decode(p2).unwrap().as_slice()).unwrap(); + let pubkey3 = PublicKey::try_from(hex::decode(p3).unwrap().as_slice()).unwrap(); + + let mut pubkeys = vec![pubkey1, pubkey2, pubkey3]; + pubkeys.sort_by(|a, b| a.compare(b)); + assert_eq!(hex::encode(pubkeys[0].to_vec(), false), p3); + assert_eq!(hex::encode(pubkeys[1].to_vec(), false), p1); + assert_eq!(hex::encode(pubkeys[2].to_vec(), false), p2); +} + +#[test] +fn test_nist256p1_shared_key() { + let private_key = PrivateKey::try_from( + hex::decode("bca2a4e7db34577e1193d6b6312244a246832228598c91fd5123cba52c182979") + .unwrap() + .as_slice(), + ) + .unwrap(); + let public_key = PublicKey::try_from( + hex::decode("031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486") + .unwrap() + .as_slice(), + ) + .unwrap(); + let shared_key = private_key.ecies_shared_key(&public_key); + assert_eq!(hex::encode(shared_key, false), "d5277ff8bda8bd043a663583019b9b4397b58c69a7fdbb9c39e6525eb99e5183f9a82cd4ce9f75d81ebc61ced5c763d612a9f8dc255ba4aea25675d882a8e514"); +} + +#[test] +fn test_tw_sig_to_der() { + let signature = "6cc8a52ea475c5ab090bb91f62e1e3e9831450b6941d30ed0600a08acec014db65e7ecee3a3e1f95a53054a03f16f0e44f1d0aa3a44b87a4664819a0f5c0f38800"; + let signature_data = hex::decode(signature).unwrap(); + let tw_signature = TWDataHelper::create(signature_data); + + let signature = TWDataHelper::wrap(unsafe { tw_ecdsa_sig_to_der(tw_signature.ptr(), false) }); + + assert_eq!( + hex::encode(signature.to_vec().unwrap(), false), + "304402206cc8a52ea475c5ab090bb91f62e1e3e9831450b6941d30ed0600a08acec014db022065e7ecee3a3e1f95a53054a03f16f0e44f1d0aa3a44b87a4664819a0f5c0f388" + ); +} + +#[test] +fn test_tw_invalid_sig_to_der() { + let signature = "6ccd"; + let signature_data = hex::decode(signature).unwrap(); + let tw_signature = TWDataHelper::create(signature_data); + + let signature = TWDataHelper::wrap(unsafe { tw_ecdsa_sig_to_der(tw_signature.ptr(), false) }); + assert_eq!(signature.is_null(), true); +} + +#[test] +fn test_tw_pubkey_hash() { + let pubkey = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; + let pubkey_data = hex::decode(pubkey).unwrap(); + let tw_pubkey = TWDataHelper::create(pubkey_data); + + let hash = TWDataHelper::wrap(unsafe { tw_ecdsa_pubkey_hash(tw_pubkey.ptr(), false, 1) }); + + assert_eq!( + hex::encode(hash.to_vec().unwrap(), false), + "fc5f90ded54731474b8bb18ee579f77ad93427486a888d23a1af92719bcf5640" + ); +} diff --git a/rust/tw_keypair/tests/private_key_ffi_tests.rs b/rust/tw_keypair/tests/private_key_ffi_tests.rs index 8a03928ecfd..e6716336468 100644 --- a/rust/tw_keypair/tests/private_key_ffi_tests.rs +++ b/rust/tw_keypair/tests/private_key_ffi_tests.rs @@ -7,28 +7,24 @@ use tw_hash::sha2::sha256; use tw_hash::sha3::keccak256; use tw_hash::H256; use tw_keypair::ffi::privkey::{ - tw_private_key_create_with_data, tw_private_key_get_public_key_by_type, - tw_private_key_is_valid, tw_private_key_sign, + tw_private_key_bytes, tw_private_key_create_with_data, tw_private_key_data, + tw_private_key_get_public_key_by_type, tw_private_key_is_valid, tw_private_key_sign, + tw_private_key_sign_as_der, tw_private_key_size, }; use tw_keypair::ffi::pubkey::{tw_public_key_data, tw_public_key_delete, tw_public_key_verify}; use tw_keypair::test_utils::tw_private_key_helper::TWPrivateKeyHelper; use tw_keypair::test_utils::tw_public_key_helper::TWPublicKeyHelper; use tw_keypair::tw::{Curve, PublicKeyType}; use tw_memory::ffi::c_byte_array::CByteArray; +use tw_memory::ffi::tw_data::tw_data_create_with_bytes; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; fn test_sign(curve: Curve, secret: &str, msg: &str, expected_sign: &str) { - let tw_privkey = TWPrivateKeyHelper::with_hex(secret); + let tw_privkey = TWPrivateKeyHelper::with_hex(secret, curve.to_raw()); let msg = hex::decode(msg).unwrap(); let msg_raw = CByteArray::from(msg); - let actual = unsafe { - tw_private_key_sign( - tw_privkey.ptr(), - msg_raw.data(), - msg_raw.size(), - curve as u32, - ) - .into_vec() - }; + let actual = + unsafe { tw_private_key_sign(tw_privkey.ptr(), msg_raw.data(), msg_raw.size()).into_vec() }; let expected = hex::decode(expected_sign).unwrap(); assert_eq!(actual, expected); } @@ -37,23 +33,39 @@ fn test_sign(curve: Curve, secret: &str, msg: &str, expected_sign: &str) { fn test_tw_private_key_create() { let tw_privkey = TWPrivateKeyHelper::with_hex( "ef2cf705af8714b35c0855030f358f2bee356ff3579cea2607b2025d80133c3a", + Curve::Secp256k1.to_raw(), ); assert!(!tw_privkey.is_null()); + let bytes = unsafe { tw_private_key_bytes(tw_privkey.ptr()) }; + let size = unsafe { tw_private_key_size(tw_privkey.ptr()) }; + let tw_data = TWDataHelper::wrap(unsafe { tw_data_create_with_bytes(bytes, size) }); + assert_eq!( + hex::encode(tw_data.to_vec().unwrap(), false), + "ef2cf705af8714b35c0855030f358f2bee356ff3579cea2607b2025d80133c3a" + ); + + let data = unsafe { tw_private_key_data(tw_privkey.ptr()) }; + assert_eq!( + hex::encode(unsafe { data.into_vec() }, false), + "ef2cf705af8714b35c0855030f358f2bee356ff3579cea2607b2025d80133c3a" + ); + // Invalid hex. - let tw_privkey = TWPrivateKeyHelper::with_bytes(*b"123"); + let tw_privkey = TWPrivateKeyHelper::with_bytes(*b"123", Curve::Secp256k1.to_raw()); assert!(tw_privkey.is_null()); // Zero private key. let tw_privkey = TWPrivateKeyHelper::with_hex( "0000000000000000000000000000000000000000000000000000000000000000", + Curve::Secp256k1.to_raw(), ); assert!(tw_privkey.is_null()); } #[test] fn test_tw_private_key_delete_null() { - unsafe { tw_private_key_create_with_data(std::ptr::null_mut(), 0) }; + unsafe { tw_private_key_create_with_data(std::ptr::null_mut(), 0, Curve::Secp256k1.to_raw()) }; } #[test] @@ -117,17 +129,12 @@ fn test_tw_private_key_sign_starkex() { fn test_tw_private_key_sign_invalid_hash() { let tw_privkey = TWPrivateKeyHelper::with_hex( "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), ); let hash = hex::decode("0xf86a808509c7652400830130b9946b175474e89094c44da98b954eedeac495271d0f80b844a9059cbb0000000000000000000000005322b34c88ed0691971bf52a7047448f0f4efc840000000000000000000000000000000000000000000000001bc16d674ec80000808080").unwrap(); let hash_raw = CByteArray::from(hash); let actual = unsafe { - tw_private_key_sign( - tw_privkey.ptr(), - hash_raw.data(), - hash_raw.size(), - Curve::Secp256k1 as u32, - ) - .into_vec() + tw_private_key_sign(tw_privkey.ptr(), hash_raw.data(), hash_raw.size()).into_vec() }; assert!(actual.is_empty()); } @@ -136,16 +143,9 @@ fn test_tw_private_key_sign_invalid_hash() { fn test_tw_private_key_sign_null_hash() { let tw_privkey = TWPrivateKeyHelper::with_hex( "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), ); - let actual = unsafe { - tw_private_key_sign( - tw_privkey.ptr(), - std::ptr::null(), - 0, - Curve::Secp256k1 as u32, - ) - .into_vec() - }; + let actual = unsafe { tw_private_key_sign(tw_privkey.ptr(), std::ptr::null(), 0).into_vec() }; assert!(actual.is_empty()); } @@ -164,6 +164,7 @@ fn test_tw_private_key_get_public_key_by_type() { let tw_privkey = TWPrivateKeyHelper::with_hex( "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), ); assert!(!tw_privkey.is_null()); @@ -181,31 +182,25 @@ fn test_tw_private_key_get_public_key_by_type() { #[test] fn test_tw_private_key_is_valid() { - fn is_valid(privkey_bytes: Vec) -> bool { + fn is_valid(privkey_bytes: Vec, curve: Curve) -> bool { let privkey_raw = CByteArray::from(privkey_bytes); - unsafe { - tw_private_key_is_valid( - privkey_raw.data(), - privkey_raw.size(), - Curve::Secp256k1 as u32, - ) - } + unsafe { tw_private_key_is_valid(privkey_raw.data(), privkey_raw.size(), curve.to_raw()) } } // Non-zero private key. let privkey_bytes = H256::from("0000000000000000000000000000000000000000000000000000000000000001"); - assert!(is_valid(privkey_bytes.into_vec())); + assert!(is_valid(privkey_bytes.into_vec(), Curve::Secp256k1)); // Cardano private key. let privkey_bytes = hex::decode("089b68e458861be0c44bf9f7967f05cc91e51ede86dc679448a3566990b7785bd48c330875b1e0d03caaed0e67cecc42075dce1c7a13b1c49240508848ac82f603391c68824881ae3fc23a56a1a75ada3b96382db502e37564e84a5413cfaf1290dbd508e5ec71afaea98da2df1533c22ef02a26bb87b31907d0b2738fb7785b38d53aa68fc01230784c9209b2b2a2faf28491b3b1f1d221e63e704bbd0403c4154425dfbb01a2c5c042da411703603f89af89e57faae2946e2a5c18b1c5ca0e").unwrap(); - assert!(is_valid(privkey_bytes)); + assert!(is_valid(privkey_bytes, Curve::Ed25519ExtendedCardano)); // Zero private key. let privkey_bytes = H256::from("0000000000000000000000000000000000000000000000000000000000000000"); - assert!(!is_valid(privkey_bytes.into_vec())); + assert!(!is_valid(privkey_bytes.into_vec(), Curve::Secp256k1)); } // `schnorr` generates unique signatures based on auxiliary random. @@ -214,18 +209,11 @@ fn test_tw_private_key_sign_schnorr() { let secret = "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79"; let msg = "99b7098e8150cde90f3ec00280815d3069f81c7cdb6d83bbe2b897b1afbe7cd6"; - let tw_privkey = TWPrivateKeyHelper::with_hex(secret); + let tw_privkey = TWPrivateKeyHelper::with_hex(secret, Curve::Schnorr.to_raw()); let msg = hex::decode(msg).unwrap(); let msg_raw = CByteArray::from(msg); - let signature = unsafe { - tw_private_key_sign( - tw_privkey.ptr(), - msg_raw.data(), - msg_raw.size(), - Curve::Schnorr as u32, - ) - .into_vec() - }; + let signature = + unsafe { tw_private_key_sign(tw_privkey.ptr(), msg_raw.data(), msg_raw.size()).into_vec() }; let signature_data = CByteArray::from(signature); @@ -247,3 +235,63 @@ fn test_tw_private_key_sign_schnorr() { }; assert!(is_valid, "Error verifying a schnorr signature"); } + +#[test] +fn test_tw_private_key_sign_as_der() { + let tw_privkey = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), + ); + assert!(!tw_privkey.is_null()); + + let message = "hello"; + let message_data = message.as_bytes(); + let digest = keccak256(message_data); + let digest_raw = CByteArray::from(digest.to_vec()); + + let signature = unsafe { + tw_private_key_sign_as_der(tw_privkey.ptr(), digest_raw.data(), digest_raw.size()) + .into_vec() + }; + + assert_eq!( + hex::encode(signature, false), + "30450221008720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba6202204d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de9" + ); +} + +#[test] +fn test_tw_private_key_sign_zilliqa() { + let tw_privkey = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::ZilliqaSchnorr.to_raw(), + ); + assert!(!tw_privkey.is_null()); + + let message = "hello schnorr"; + let message_data = message.as_bytes(); + let digest = sha256(message_data); + let digest_raw = CByteArray::from(digest.to_vec()); + + let signature = unsafe { + tw_private_key_sign(tw_privkey.ptr(), digest_raw.data(), digest_raw.size()).into_vec() + }; + + assert_eq!( + hex::encode(signature, false), + "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853" + ); +} + +#[test] +fn test_private_key_is_valid() { + let private_key_hex = "0x4646464646464646464646464646464646464646464646464646464646464646"; + let bytes = hex::decode(private_key_hex).unwrap(); + let bytes_ptr = bytes.as_ptr(); + let bytes_len = bytes.len(); + + let is_valid = + unsafe { tw_private_key_is_valid(bytes_ptr, bytes_len, Curve::Secp256k1.to_raw()) }; + + assert!(is_valid); +} diff --git a/rust/tw_keypair/tests/public_key_ffi_tests.rs b/rust/tw_keypair/tests/public_key_ffi_tests.rs index 9195ed66f5d..bdf163c5b58 100644 --- a/rust/tw_keypair/tests/public_key_ffi_tests.rs +++ b/rust/tw_keypair/tests/public_key_ffi_tests.rs @@ -5,10 +5,20 @@ use tw_encoding::hex; use tw_hash::sha2::sha256; use tw_hash::sha3::keccak256; -use tw_keypair::ffi::pubkey::{tw_public_key_delete, tw_public_key_verify}; +use tw_keypair::ffi::ecdsa::{tw_ecdsa_pubkey_compare, tw_ecdsa_shared_key}; +use tw_keypair::ffi::privkey::{ + tw_private_key_get_public_key_by_type, tw_private_key_sign, tw_private_key_sign_as_der, +}; +use tw_keypair::ffi::pubkey::{ + tw_public_key_compressed, tw_public_key_data, tw_public_key_delete, tw_public_key_extended, + tw_public_key_is_valid, tw_public_key_recover_from_signature, tw_public_key_type, + tw_public_key_verify, tw_public_key_verify_as_der, +}; +use tw_keypair::test_utils::tw_private_key_helper::TWPrivateKeyHelper; use tw_keypair::test_utils::tw_public_key_helper::TWPublicKeyHelper; -use tw_keypair::tw::PublicKeyType; +use tw_keypair::tw::{Curve, PublicKeyType}; use tw_memory::ffi::c_byte_array::CByteArray; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; fn test_verify(ty: PublicKeyType, public: &str, msg: &str, sign: &str) { let tw_public = TWPublicKeyHelper::with_hex(public, ty); @@ -38,6 +48,8 @@ fn test_tw_public_key_create_by_type() { PublicKeyType::Secp256k1, ); assert!(!tw_public.is_null()); + let ty = unsafe { tw_public_key_type(tw_public.ptr()) }; + assert_eq!(ty, PublicKeyType::Secp256k1 as u32); // Compressed pubkey with '03' prefix. let tw_public = TWPublicKeyHelper::with_hex( @@ -45,12 +57,16 @@ fn test_tw_public_key_create_by_type() { PublicKeyType::Secp256k1, ); assert!(!tw_public.is_null()); + let ty = unsafe { tw_public_key_type(tw_public.ptr()) }; + assert_eq!(ty, PublicKeyType::Secp256k1 as u32); let tw_public = TWPublicKeyHelper::with_hex( "0499c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c166b489a4b7c491e7688e6ebea3a71fc3a1a48d60f98d5ce84c93b65e423fde91", PublicKeyType::Secp256k1Extended, ); assert!(!tw_public.is_null()); + let ty = unsafe { tw_public_key_type(tw_public.ptr()) }; + assert_eq!(ty, PublicKeyType::Secp256k1Extended as u32); // Pass an extended pubkey, but Secp256k1 type. let tw_public = TWPublicKeyHelper::with_hex( @@ -58,6 +74,8 @@ fn test_tw_public_key_create_by_type() { PublicKeyType::Secp256k1, ); assert!(tw_public.is_null()); + let ty = unsafe { tw_public_key_type(tw_public.ptr()) }; + assert_eq!(ty, PublicKeyType::Secp256k1 as u32); // Pass a compressed pubkey, but Secp256k1Extended type. let tw_public = TWPublicKeyHelper::with_hex( @@ -65,6 +83,8 @@ fn test_tw_public_key_create_by_type() { PublicKeyType::Secp256k1Extended, ); assert!(tw_public.is_null()); + let ty = unsafe { tw_public_key_type(tw_public.ptr()) }; + assert_eq!(ty, PublicKeyType::Secp256k1 as u32); } #[test] @@ -120,3 +140,273 @@ fn test_tw_public_key_verify_ed25519_extended_cardano() { let sign = "375df53b6a4931dcf41e062b1c64288ed4ff3307f862d5c1b1c71964ce3b14c99422d0fdfeb2807e9900a26d491d5e8a874c24f98eec141ed694d7a433a90f08"; test_verify(PublicKeyType::Ed25519ExtendedCardano, public, &msg, sign); } + +#[test] +fn test_tw_public_key_compressed_extended() { + let tw_privkey = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), + ); + assert!(!tw_privkey.is_null()); + + let tw_pubkey = unsafe { + TWPublicKeyHelper::wrap(tw_private_key_get_public_key_by_type( + tw_privkey.ptr(), + PublicKeyType::Secp256k1 as u32, + )) + }; + assert!(!tw_pubkey.is_null()); + + unsafe { + assert_eq!( + tw_public_key_type(tw_pubkey.ptr()), + PublicKeyType::Secp256k1 as u32 + ); + } + + let tw_extended = unsafe { TWPublicKeyHelper::wrap(tw_public_key_extended(tw_pubkey.ptr())) }; + assert!(!tw_extended.is_null()); + + unsafe { + assert_eq!( + tw_public_key_type(tw_extended.ptr()), + PublicKeyType::Secp256k1Extended as u32 + ); + } + + let tw_compressed = + unsafe { TWPublicKeyHelper::wrap(tw_public_key_compressed(tw_extended.ptr())) }; + assert!(!tw_compressed.is_null()); + + unsafe { + assert_eq!( + tw_public_key_type(tw_compressed.ptr()), + PublicKeyType::Secp256k1 as u32 + ); + } +} + +#[test] +fn test_tw_public_key_recover() { + let message = + hex::decode("de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb11432").unwrap(); + let signature = hex::decode("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef80").unwrap(); + + let message_raw = CByteArray::from(message); + let signature_raw = CByteArray::from(signature); + + let tw_public_key = unsafe { + TWPublicKeyHelper::wrap(tw_public_key_recover_from_signature( + signature_raw.data(), + signature_raw.size(), + message_raw.data(), + message_raw.size(), + 0x01, + )) + }; + + assert!(!tw_public_key.is_null()); + + unsafe { + assert_eq!( + tw_public_key_type(tw_public_key.ptr()), + PublicKeyType::Secp256k1Extended as u32 + ); + + let public_key_data = tw_public_key_data(tw_public_key.ptr()); + let public_key_hex = hex::encode(public_key_data.into_vec(), false); + + assert_eq!( + public_key_hex, + "0456d8089137b1fd0d890f8c7d4a04d0fd4520a30b19518ee87bd168ea12ed8090329274c4c6c0d9df04515776f2741eeffc30235d596065d718c3973e19711ad0" + ); + } +} + +#[test] +fn test_tw_public_key_verify_as_der() { + let tw_privkey = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::Secp256k1.to_raw(), + ); + assert!(!tw_privkey.is_null()); + + let message = "Hello"; + let message_data = message.as_bytes(); + let digest = keccak256(message_data); + let digest_raw = CByteArray::from(digest.to_vec()); + + // Sign the digest using DER format + let signature = unsafe { + tw_private_key_sign_as_der(tw_privkey.ptr(), digest_raw.data(), digest_raw.size()) + .into_vec() + }; + let signature_raw = CByteArray::from(signature); + + // Get the public key + let tw_public_key = unsafe { + TWPublicKeyHelper::wrap(tw_private_key_get_public_key_by_type( + tw_privkey.ptr(), + PublicKeyType::Secp256k1Extended as u32, + )) + }; + + // Verify the DER signature + let is_valid_der = unsafe { + tw_public_key_verify_as_der( + tw_public_key.ptr(), + signature_raw.data(), + signature_raw.size(), + digest_raw.data(), + digest_raw.size(), + ) + }; + assert!(is_valid_der, "DER signature verification failed"); + + // Regular verification should fail with DER signature + let is_valid_regular = unsafe { + tw_public_key_verify( + tw_public_key.ptr(), + signature_raw.data(), + signature_raw.size(), + digest_raw.data(), + digest_raw.size(), + ) + }; + assert!( + !is_valid_regular, + "Regular verification should fail with DER signature" + ); +} + +#[test] +fn test_tw_public_key_verify_zilliqa() { + let tw_privkey = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + Curve::ZilliqaSchnorr.to_raw(), + ); + assert!(!tw_privkey.is_null()); + + let message = "hello schnorr"; + let message_data = message.as_bytes(); + let digest = sha256(message_data); + let digest_raw = CByteArray::from(digest.to_vec()); + + // Sign the digest using Zilliqa format + let signature = unsafe { + tw_private_key_sign(tw_privkey.ptr(), digest_raw.data(), digest_raw.size()).into_vec() + }; + let signature_raw = CByteArray::from(signature.clone()); + + // Get the public key + let tw_public_key = unsafe { + TWPublicKeyHelper::wrap(tw_private_key_get_public_key_by_type( + tw_privkey.ptr(), + PublicKeyType::ZilliqaSchnorr as u32, + )) + }; + + // Verify the Zilliqa signature + let is_valid = unsafe { + tw_public_key_verify( + tw_public_key.ptr(), + signature_raw.data(), + signature_raw.size(), + digest_raw.data(), + digest_raw.size(), + ) + }; + assert!(is_valid, "Zilliqa signature verification failed"); + + // Check the expected signature + assert_eq!( + hex::encode(signature, false), + "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853" + ); +} + +#[test] +fn test_public_key_is_valid() { + let public_key_hex = "0xbeff0e5d6f6e6e6d573d3044f3e2bfb353400375dc281da3337468d4aa527908"; + let bytes = hex::decode(public_key_hex).unwrap(); + let bytes_ptr = bytes.as_ptr(); + let bytes_len = bytes.len(); + + let is_valid = + unsafe { tw_public_key_is_valid(bytes_ptr, bytes_len, PublicKeyType::Ed25519 as u32) }; + + assert!(is_valid); +} + +#[test] +fn test_zillqa_schnorr_public_key_is_valid() { + let public_key_hex = "034ae47910d58b9bde819c3cffa8de4441955508db00aa2540db8e6bf6e99abc1b"; + let bytes = hex::decode(public_key_hex).unwrap(); + let bytes_ptr = bytes.as_ptr(); + let bytes_len = bytes.len(); + + let is_valid = unsafe { + tw_public_key_is_valid(bytes_ptr, bytes_len, PublicKeyType::ZilliqaSchnorr as u32) + }; + + assert!(is_valid); +} + +#[test] +fn test_secp256k1_shared_key_ffi() { + let private_key = TWDataHelper::create( + hex::decode("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90").unwrap(), + ); + let public_key = TWDataHelper::create( + hex::decode("024edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10").unwrap(), + ); + let shared_key = TWDataHelper::wrap(unsafe { + tw_ecdsa_shared_key(private_key.ptr(), public_key.ptr(), true) + }); + assert_eq!(hex::encode(shared_key.to_vec().unwrap(), false), "a71b4ec5a9577926a1d2aa1d9d99327fd3b68f6a1ea597200a0d890bd3331df300a2d49fec0b2b3e6969ce9263c5d6cf47c191c1ef149373ecc9f0d98116b598"); +} + +#[test] +fn test_nist256p1_shared_key_ffi() { + let private_key = TWDataHelper::create( + hex::decode("bca2a4e7db34577e1193d6b6312244a246832228598c91fd5123cba52c182979").unwrap(), + ); + let public_key = TWDataHelper::create( + hex::decode("031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486").unwrap(), + ); + let shared_key = TWDataHelper::wrap(unsafe { + tw_ecdsa_shared_key(private_key.ptr(), public_key.ptr(), false) + }); + assert_eq!(hex::encode(shared_key.to_vec().unwrap(), false), "d5277ff8bda8bd043a663583019b9b4397b58c69a7fdbb9c39e6525eb99e5183f9a82cd4ce9f75d81ebc61ced5c763d612a9f8dc255ba4aea25675d882a8e514"); +} + +#[test] +fn test_nist256p1_pubkey_compare() { + let public_key_1 = TWDataHelper::create( + hex::decode("031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486").unwrap(), + ); + let public_key_2 = TWDataHelper::create( + hex::decode("03d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1ee").unwrap(), + ); + let public_key_3 = TWDataHelper::create( + hex::decode("0305947c8564734b0e634531c405a0b6488e2cb9bcde5eddefcf3f008f0c048115").unwrap(), + ); + let result = unsafe { tw_ecdsa_pubkey_compare(public_key_1.ptr(), public_key_2.ptr(), false) }; + assert_eq!(result, -1); + let result = unsafe { tw_ecdsa_pubkey_compare(public_key_1.ptr(), public_key_3.ptr(), false) }; + assert_eq!(result, 1); + let result = unsafe { tw_ecdsa_pubkey_compare(public_key_2.ptr(), public_key_3.ptr(), false) }; + assert_eq!(result, 1); +} + +#[test] +fn test_secp256k1_pubkey_compare() { + let public_key_1 = TWDataHelper::create( + hex::decode("02a18a98316b5f52596e75bfa5ca9fa9912edd0c989b86b73d41bb64c9c6adb992").unwrap(), + ); + let public_key_2 = TWDataHelper::create( + hex::decode("0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1").unwrap(), + ); + let result = unsafe { tw_ecdsa_pubkey_compare(public_key_1.ptr(), public_key_2.ptr(), true) }; + assert_eq!(result, 1); +} diff --git a/rust/tw_keypair/tests/secp256k1_tests.rs b/rust/tw_keypair/tests/secp256k1_tests.rs index 9e56c024862..76886161e8a 100644 --- a/rust/tw_keypair/tests/secp256k1_tests.rs +++ b/rust/tw_keypair/tests/secp256k1_tests.rs @@ -3,10 +3,14 @@ // Copyright © 2017 Trust Wallet. use serde::Deserialize; +use tw_encoding::hex; use tw_encoding::hex::as_hex; use tw_hash::{H256, H520}; -use tw_keypair::ecdsa::secp256k1::{KeyPair, VerifySignature}; +use tw_keypair::ecdsa::secp256k1::{KeyPair, PrivateKey, PublicKey, VerifySignature}; +use tw_keypair::ffi::ecdsa::{tw_ecdsa_pubkey_hash, tw_ecdsa_sig_to_der}; use tw_keypair::traits::{SigningKeyTrait, VerifyingKeyTrait}; +use tw_memory::test_utils::tw_data_helper::TWDataHelper; +use tw_misc::traits::ToBytesVec; /// The tests were generated in C++ using the `trezor-crypto` library. const SECP256K1_SIGN: &str = include_str!("secp256k1_sign.json"); @@ -33,3 +37,73 @@ fn test_secp256k1_sign_verify() { assert!(keypair.verify(verify_sign, test.hash)); } } + +#[test] +fn test_secp256k1_pubkey_compare() { + let p1 = "02a18a98316b5f52596e75bfa5ca9fa9912edd0c989b86b73d41bb64c9c6adb992"; + let p2 = "0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1"; + + let pubkey1 = PublicKey::try_from(hex::decode(p1).unwrap().as_slice()).unwrap(); + let pubkey2 = PublicKey::try_from(hex::decode(p2).unwrap().as_slice()).unwrap(); + + let mut pubkeys = vec![pubkey1, pubkey2]; + pubkeys.sort_by(|a, b| a.compare(b)); + assert_eq!(hex::encode(pubkeys[0].to_vec(), false), p2); + assert_eq!(hex::encode(pubkeys[1].to_vec(), false), p1); +} + +#[test] +fn test_secp256k1_shared_key() { + let private_key = PrivateKey::try_from( + hex::decode("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90") + .unwrap() + .as_slice(), + ) + .unwrap(); + let public_key = PublicKey::try_from( + hex::decode("024edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10") + .unwrap() + .as_slice(), + ) + .unwrap(); + let shared_key = private_key.ecies_shared_key(&public_key); + assert_eq!(hex::encode(shared_key, false), "a71b4ec5a9577926a1d2aa1d9d99327fd3b68f6a1ea597200a0d890bd3331df300a2d49fec0b2b3e6969ce9263c5d6cf47c191c1ef149373ecc9f0d98116b598"); +} + +#[test] +fn test_tw_sig_to_der() { + let signature = "882d92979f3fd4df2b19eecea6b4ca3104898774e83506d934736a80697a19366f4fde413d1fcf73adc00dd3938be427cea62a2aa166eab209703a3f63bd77fc00"; + let signature_data = hex::decode(signature).unwrap(); + let tw_signature = TWDataHelper::create(signature_data); + + let signature = TWDataHelper::wrap(unsafe { tw_ecdsa_sig_to_der(tw_signature.ptr(), true) }); + + assert_eq!( + hex::encode(signature.to_vec().unwrap(), false), + "3045022100882d92979f3fd4df2b19eecea6b4ca3104898774e83506d934736a80697a193602206f4fde413d1fcf73adc00dd3938be427cea62a2aa166eab209703a3f63bd77fc" + ); +} + +#[test] +fn test_tw_invalid_sig_to_der() { + let signature = "6ccd"; + let signature_data = hex::decode(signature).unwrap(); + let tw_signature = TWDataHelper::create(signature_data); + + let signature = TWDataHelper::wrap(unsafe { tw_ecdsa_sig_to_der(tw_signature.ptr(), false) }); + assert_eq!(signature.is_null(), true); +} + +#[test] +fn test_tw_pubkey_hash() { + let pubkey = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; + let pubkey_data = hex::decode(pubkey).unwrap(); + let tw_pubkey = TWDataHelper::create(pubkey_data); + + let hash = TWDataHelper::wrap(unsafe { tw_ecdsa_pubkey_hash(tw_pubkey.ptr(), true, 1) }); + + assert_eq!( + hex::encode(hash.to_vec().unwrap(), false), + "fc5f90ded54731474b8bb18ee579f77ad93427486a888d23a1af92719bcf5640" + ); +} diff --git a/rust/tw_keypair/tests/tw_keypair_starkex_tests.rs b/rust/tw_keypair/tests/tw_keypair_starkex_tests.rs index 9fe872ad797..411f46b8eef 100644 --- a/rust/tw_keypair/tests/tw_keypair_starkex_tests.rs +++ b/rust/tw_keypair/tests/tw_keypair_starkex_tests.rs @@ -13,7 +13,7 @@ fn test_starkex_tw_private_key() { let pubkey_bytes = hex::decode("02a4c7332c55d6c1c510d24272d1db82878f2302f05b53bcc38695ed5f78fffd").unwrap(); - let privkey = PrivateKey::new(privkey_bytes.clone()).unwrap(); + let privkey = PrivateKey::new(privkey_bytes.clone(), Curve::Starkex).unwrap(); assert_eq!(privkey.key().into_vec(), privkey_bytes); let public = privkey @@ -29,8 +29,8 @@ fn test_starkex_tw_private_key_sign() { let hash_to_sign = hex::decode("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76").unwrap(); - let privkey = PrivateKey::new(privkey_bytes).unwrap(); - let actual = privkey.sign(&hash_to_sign, Curve::Starkex).unwrap(); + let privkey = PrivateKey::new(privkey_bytes.clone(), Curve::Starkex).unwrap(); + let actual = privkey.sign(&hash_to_sign).unwrap(); let expected = H512::from("061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a"); assert_eq!(actual, expected.into_vec()); } diff --git a/rust/tw_tests/tests/chains/ton/ton_message_signer.rs b/rust/tw_tests/tests/chains/ton/ton_message_signer.rs index 523188947fa..3a0b4265985 100644 --- a/rust/tw_tests/tests/chains/ton/ton_message_signer.rs +++ b/rust/tw_tests/tests/chains/ton/ton_message_signer.rs @@ -2,7 +2,7 @@ // // Copyright © 2017 Trust Wallet. -use tw_keypair::test_utils::tw_private_key_helper::TWPrivateKeyHelper; +use tw_keypair::{test_utils::tw_private_key_helper::TWPrivateKeyHelper, tw::Curve}; use tw_memory::test_utils::tw_string_helper::TWStringHelper; use wallet_core_rs::ffi::ton::message_signer::tw_ton_message_signer_sign_message; @@ -10,6 +10,7 @@ use wallet_core_rs::ffi::ton::message_signer::tw_ton_message_signer_sign_message fn test_ton_wallet_create_state_init() { let private_key = TWPrivateKeyHelper::with_hex( "112d4e2e700a468f1eae699329202f1ee671d6b665caa2d92dea038cf3868c18", + Curve::Ed25519.to_raw(), ); assert!(!private_key.is_null()); let message = TWStringHelper::create("Hello world"); diff --git a/rust/tw_tests/tests/coin_address_derivation_test.rs b/rust/tw_tests/tests/coin_address_derivation_test.rs index 026b260128c..068bbdaeb06 100644 --- a/rust/tw_tests/tests/coin_address_derivation_test.rs +++ b/rust/tw_tests/tests/coin_address_derivation_test.rs @@ -16,13 +16,14 @@ use tw_memory::test_utils::tw_string_helper::TWStringHelper; #[test] fn test_coin_address_derivation() { - let private_key = TWPrivateKeyHelper::with_hex( - "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", - ); - for coin in CoinType::iter() { let coin_item = get_coin_item(coin).unwrap(); + let private_key = TWPrivateKeyHelper::with_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", + coin_item.curve.to_raw(), + ); + // Skip unsupported blockchains. if !coin_item.blockchain.is_supported() { continue; diff --git a/rust/wallet_core_rs/Cargo.toml b/rust/wallet_core_rs/Cargo.toml index c66a335b140..bacaf4b68f2 100644 --- a/rust/wallet_core_rs/Cargo.toml +++ b/rust/wallet_core_rs/Cargo.toml @@ -13,6 +13,7 @@ default = [ "bitcoin", "ethereum", "keypair", + "crypto", "solana", "ton", "utils", @@ -21,6 +22,7 @@ any-coin = ["tw_any_coin"] bitcoin = ["tw_bitcoin", "tw_coin_registry"] ethereum = ["tw_ethereum", "tw_coin_registry"] keypair = ["tw_keypair"] +crypto = ["tw_crypto"] solana = ["tw_solana"] ton = ["tw_ton"] utils = [ @@ -41,6 +43,7 @@ tw_encoding = { path = "../tw_encoding", optional = true } tw_ethereum = { path = "../chains/tw_ethereum", optional = true } tw_hash = { path = "../tw_hash", optional = true } tw_keypair = { path = "../tw_keypair", optional = true } +tw_crypto = { path = "../tw_crypto", optional = true } tw_memory = { path = "../tw_memory", optional = true } tw_number = { path = "../tw_number", optional = true } tw_macros = { path = "../tw_macros" } diff --git a/rust/wallet_core_rs/cbindgen.toml b/rust/wallet_core_rs/cbindgen.toml index 6697f798a56..43458d4b26d 100644 --- a/rust/wallet_core_rs/cbindgen.toml +++ b/rust/wallet_core_rs/cbindgen.toml @@ -11,6 +11,7 @@ extra_bindings = [ "tw_encoding", "tw_hash", "tw_keypair", + "tw_crypto", "tw_memory", ] include = [ @@ -18,5 +19,6 @@ include = [ "tw_encoding", "tw_hash", "tw_keypair", + "tw_crypto", "tw_memory", ] diff --git a/rust/wallet_core_rs/src/lib.rs b/rust/wallet_core_rs/src/lib.rs index f26f8e9364e..449bb15050e 100644 --- a/rust/wallet_core_rs/src/lib.rs +++ b/rust/wallet_core_rs/src/lib.rs @@ -6,6 +6,8 @@ pub extern crate tw_any_coin; #[cfg(feature = "bitcoin")] pub extern crate tw_bitcoin; +#[cfg(feature = "crypto")] +pub extern crate tw_crypto; #[cfg(feature = "utils")] pub extern crate tw_encoding; #[cfg(feature = "utils")] diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 02bfe6e2ad5..1c4fa3e2448 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -28,7 +28,7 @@ set (CMAKE_C_STANDARD_REQUIRED ON) # ${WALLET_CORE}/src -- internal TrustWalletCore files, for signer protobuf messages # ${WALLET_CORE}/build/local/include) -- for protobuf includes include_directories (${CMAKE_SOURCE_DIR} ${WALLET_CORE}/include ${WALLET_CORE}/src ${WALLET_CORE}/build/local/include) -link_directories (${WALLET_CORE}/build ${WALLET_CORE}/build/trezor-crypto ${WALLET_CORE}/build/local/lib ${WALLET_CORE}/rust/target/release) +link_directories (${WALLET_CORE}/build ${WALLET_CORE}/build/local/lib ${WALLET_CORE}/rust/target/release) find_library(WALLET_CORE_LIB_FILE TrustWalletCore PATH ${WALLET_CORE}/build) if (NOT WALLET_CORE_LIB_FILE) @@ -76,4 +76,4 @@ SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINK_FLAGS}") add_executable (sample sample.cpp) # link with our library, and default platform libraries -target_link_libraries (sample PUBLIC TrustWalletCore ${WALLET_CORE_RS_LIB_FILE} TrezorCrypto protobuf pthread ${PLATFORM_LIBS}) +target_link_libraries (sample PUBLIC TrustWalletCore ${WALLET_CORE_RS_LIB_FILE} protobuf pthread ${PLATFORM_LIBS}) diff --git a/samples/cpp/README.md b/samples/cpp/README.md index 5998b7c59d7..628f2a3f48e 100644 --- a/samples/cpp/README.md +++ b/samples/cpp/README.md @@ -23,7 +23,7 @@ and [Build Instructions](https://developer.trustwallet.com/wallet-core/building) You need to download and build WalletCore yourself (there is no official binary distribution). -The dependencies TrezorCrypto and protobuf are also needed, these also come with WalletCore. +The dependency protobuf is also needed, this also comes with WalletCore. You need to [build](https://developer.trustwallet.com/wallet-core/building) the library. diff --git a/samples/go/core/bitcoin.go b/samples/go/core/bitcoin.go index b9b0d218298..56223db74a8 100644 --- a/samples/go/core/bitcoin.go +++ b/samples/go/core/bitcoin.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include // #include // #include diff --git a/samples/go/core/coin.go b/samples/go/core/coin.go index f1dd5dc94d9..aced3e60fbd 100644 --- a/samples/go/core/coin.go +++ b/samples/go/core/coin.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include // #include import "C" diff --git a/samples/go/core/datavector.go b/samples/go/core/datavector.go index 04a4e4bd520..60cade5449e 100644 --- a/samples/go/core/datavector.go +++ b/samples/go/core/datavector.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include import "C" import "tw/types" diff --git a/samples/go/core/mnemonic.go b/samples/go/core/mnemonic.go index a1968b864b9..5414117568c 100644 --- a/samples/go/core/mnemonic.go +++ b/samples/go/core/mnemonic.go @@ -1,8 +1,8 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm -// #include +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm +// #include import "C" import "tw/types" diff --git a/samples/go/core/publicKey.go b/samples/go/core/publicKey.go index bf70a64622f..b97a4faa874 100644 --- a/samples/go/core/publicKey.go +++ b/samples/go/core/publicKey.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include import "C" diff --git a/samples/go/core/transaction.go b/samples/go/core/transaction.go index 8aa9e1a900c..f5633fb238a 100644 --- a/samples/go/core/transaction.go +++ b/samples/go/core/transaction.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include // #include import "C" diff --git a/samples/go/core/transactionHelper.go b/samples/go/core/transactionHelper.go index df2a78c64dd..2b9b87d2640 100644 --- a/samples/go/core/transactionHelper.go +++ b/samples/go/core/transactionHelper.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include import "C" import "tw/types" diff --git a/samples/go/core/wallet.go b/samples/go/core/wallet.go index ee95b763631..a002fa62383 100644 --- a/samples/go/core/wallet.go +++ b/samples/go/core/wallet.go @@ -1,7 +1,7 @@ package core // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include // #include // #include diff --git a/samples/go/dev-console/native/cgo.go b/samples/go/dev-console/native/cgo.go index b393d457f7a..2c497614aa4 100644 --- a/samples/go/dev-console/native/cgo.go +++ b/samples/go/dev-console/native/cgo.go @@ -1,7 +1,7 @@ package native // #cgo CFLAGS: -I packaged/include -// #cgo LDFLAGS: -lTrustWalletCore -lstdc++ -lm -lprotobuf -lwallet_core_rs -lTrezorCrypto +// #cgo LDFLAGS: -lTrustWalletCore -lstdc++ -lm -lprotobuf -lwallet_core_rs // // // #cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/packaged/lib -L${SRCDIR}/packaged/lib diff --git a/samples/go/dev-console/native/twmnemonic.go b/samples/go/dev-console/native/twmnemonic.go index f159a1a486a..3d20c1b003f 100644 --- a/samples/go/dev-console/native/twmnemonic.go +++ b/samples/go/dev-console/native/twmnemonic.go @@ -1,6 +1,6 @@ package native -// #include +// #include import "C" func IsMnemonicValid(mn string) bool { diff --git a/samples/go/dev-console/prepare.sh b/samples/go/dev-console/prepare.sh index ff2a4f6af3a..2555093d9f3 100755 --- a/samples/go/dev-console/prepare.sh +++ b/samples/go/dev-console/prepare.sh @@ -6,6 +6,5 @@ ninja cp libTrustWalletCore.a ../native/packaged/lib/ cp libprotobuf.a ../native/packaged/lib cp ../../../../build/local/lib/libwallet_core_rs.a ../native/packaged/lib -cp trezor-crypto/libTrezorCrypto.a ../native/packaged/lib cd - cp -R ../../../include native/packaged/ diff --git a/samples/go/types/twdata.go b/samples/go/types/twdata.go index 5bc9fa90f77..df61b9b0310 100644 --- a/samples/go/types/twdata.go +++ b/samples/go/types/twdata.go @@ -1,7 +1,7 @@ package types // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include import "C" diff --git a/samples/go/types/twstring.go b/samples/go/types/twstring.go index b61c52c565a..4df40d7d076 100644 --- a/samples/go/types/twstring.go +++ b/samples/go/types/twstring.go @@ -1,7 +1,7 @@ package types // #cgo CFLAGS: -I../../../include -// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm +// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -lTrustWalletCore -lwallet_core_rs -lprotobuf -lstdc++ -lm // #include import "C" diff --git a/samples/rust/README.md b/samples/rust/README.md index 237b65b34ae..f9923b9584a 100644 --- a/samples/rust/README.md +++ b/samples/rust/README.md @@ -20,7 +20,7 @@ cargo run - The app links with the wallet-core library (C/C++). - The `walletcore_iface.rs` file contains the interface definitions in Rust. -- Links with `TrustWalletCore`, `TrezorCrypto`, `protobuf`, and the platform libc (`c++` or `stdc++`). Build/link parameters are in `build.rs`. +- Links with `TrustWalletCore`, `protobuf`, and the platform libc (`c++` or `stdc++`). Build/link parameters are in `build.rs`. - Rust proto files are created during the build process, from the `.proto` files in wallet-core, into subfolder `src/wc_proto` (see `build.rs`). diff --git a/samples/rust/src/build.rs b/samples/rust/src/build.rs index d027e03a745..ea5e6e734ab 100644 --- a/samples/rust/src/build.rs +++ b/samples/rust/src/build.rs @@ -9,7 +9,7 @@ use std::path::Path; static WALLET_CORE_PROJECT_DIR: &str = "../.."; // libs to link with, in reverse dependency order -static LIBS: [&str; 4] = ["TrustWalletCore", "TrezorCrypto", "protobuf", "wallet_core_rs"]; +static LIBS: [&str; 3] = ["TrustWalletCore", "protobuf", "wallet_core_rs"]; fn main() { // Generate protobuf interface files @@ -35,7 +35,6 @@ fn main() { println!("Protobuf codegen to {} ready", out_dir); println!("cargo:rustc-link-search=native={}/build", WALLET_CORE_PROJECT_DIR); - println!("cargo:rustc-link-search=native={}/build/trezor-crypto", WALLET_CORE_PROJECT_DIR); println!("cargo:rustc-link-search=native={}/build/local/lib", WALLET_CORE_PROJECT_DIR); println!("cargo:rustc-link-search=native={}/rust/target/release", WALLET_CORE_PROJECT_DIR); diff --git a/src/Bech32Address.cpp b/src/Bech32Address.cpp index 8394773b635..dae0f08b513 100644 --- a/src/Bech32Address.cpp +++ b/src/Bech32Address.cpp @@ -5,7 +5,6 @@ #include "Bech32Address.h" #include "Bech32.h" #include "Data.h" -#include using namespace TW; diff --git a/src/Bitcoin/CashAddress.cpp b/src/Bitcoin/CashAddress.cpp index 1f98d5fb48c..4c9326911e0 100644 --- a/src/Bitcoin/CashAddress.cpp +++ b/src/Bitcoin/CashAddress.cpp @@ -5,8 +5,9 @@ #include "CashAddress.h" #include "../Coin.h" -#include -#include +#include "../cash_addr.h" +#include "../Hash.h" +#include #include #include @@ -83,7 +84,14 @@ CashAddress::CashAddress(std::string hrp, const PublicKey& publicKey) } std::array payload{}; payload[0] = 0; - ecdsa_get_pubkeyhash(publicKey.bytes.data(), HASHER_SHA2_RIPEMD, payload.data() + 1); + auto data = TWDataCreateWithBytes(publicKey.bytes.data(), publicKey.bytes.size()); + auto result = TWECDSAPubkeyHash(data, true, Hash::HasherSha256ripemd); + TWDataDelete(data); + if (result == nullptr) { + throw std::invalid_argument("Invalid public key hash"); + } + std::copy(TWDataBytes(result), TWDataBytes(result) + TWDataSize(result), payload.begin() + 1); + TWDataDelete(result); size_t outlen = 0; auto success = cash_addr_to_data(bytes.data(), &outlen, payload.data(), 21) != 0; diff --git a/src/Bitcoin/MessageSigner.cpp b/src/Bitcoin/MessageSigner.cpp index af8a6565322..3fb1107b203 100644 --- a/src/Bitcoin/MessageSigner.cpp +++ b/src/Bitcoin/MessageSigner.cpp @@ -52,7 +52,7 @@ std::string MessageSigner::signMessage(const PrivateKey& privateKey, const std:: throw std::invalid_argument("Address does not match key"); } const auto messageHash = messageToHash(message); - const auto signature = privateKey.sign(messageHash, TWCurveSECP256k1); + const auto signature = privateKey.sign(messageHash); // The V value: add 31 (or 27 for compressed), and move to the first byte const byte v = signature[SignatureRSLength] + PublicKey::SignatureVOffset + (compressed ? 4ul : 0ul); diff --git a/src/Bitcoin/SegwitAddress.cpp b/src/Bitcoin/SegwitAddress.cpp index 70ec462d391..c72d55b11c6 100644 --- a/src/Bitcoin/SegwitAddress.cpp +++ b/src/Bitcoin/SegwitAddress.cpp @@ -5,8 +5,8 @@ #include "SegwitAddress.h" #include "../Bech32.h" - -#include +#include "../Hash.h" +#include namespace TW::Bitcoin { @@ -34,8 +34,15 @@ SegwitAddress::SegwitAddress(const PublicKey& publicKey, std::string hrp) throw std::invalid_argument("SegwitAddress needs a compressed SECP256k1 public key."); } witnessProgram.resize(20); - ecdsa_get_pubkeyhash(publicKey.compressed().bytes.data(), HASHER_SHA2_RIPEMD, - witnessProgram.data()); + auto compressed = publicKey.compressed(); + auto data = TWDataCreateWithBytes(compressed.bytes.data(), compressed.bytes.size()); + auto result = TWECDSAPubkeyHash(data, true, Hash::HasherSha256ripemd); + TWDataDelete(data); + if (result == nullptr) { + throw std::invalid_argument("Invalid public key hash"); + } + std::copy(TWDataBytes(result), TWDataBytes(result) + TWDataSize(result), witnessProgram.begin()); + TWDataDelete(result); } std::tuple SegwitAddress::decode(const std::string& addr) { diff --git a/src/EOS/Address.cpp b/src/EOS/Address.cpp index 72e6d52d2ed..6c9333c508f 100644 --- a/src/EOS/Address.cpp +++ b/src/EOS/Address.cpp @@ -5,8 +5,7 @@ #include "Address.h" #include "../Base58.h" #include "../BinaryCoding.h" - -#include +#include "../Hash.h" #include @@ -35,36 +34,30 @@ bool Address::isValid(const Data& bytes, EOS::Type type) { /// IMPORTANT: THERE ARE NO SIZE CHECKS. THE BUFFER IS ASSUMED /// TO HAVE PublicKeyDataSize bytes. uint32_t Address::createChecksum(const Data& bytes, Type type) { - // create our own checksum and compare the two - uint8_t hash[RIPEMD160_DIGEST_LENGTH]; - RIPEMD160_CTX ctx; - ripemd160_Init(&ctx); - - // add the bytes to the hash input - ripemd160_Update(&ctx, bytes.data(), PublicKeyDataSize); - - // append the prefix to the hash input as well in case of modern types + Data hashInput; + append(hashInput, Data(bytes.begin(), bytes.begin() + PublicKeyDataSize)); + switch (type) { case Type::Legacy: // no extra input break; - case Type::ModernK1: - ripemd160_Update(&ctx, - (const uint8_t*)Modern::K1::prefix.c_str(), - static_cast(Modern::K1::prefix.size())); + case Type::ModernK1: { + auto startK1 = (const uint8_t*)Modern::K1::prefix.c_str(); + auto endK1 = startK1 + static_cast(Modern::K1::prefix.size()); + append(hashInput, Data(startK1, endK1)); break; + } - case Type::ModernR1: - ripemd160_Update(&ctx, - (const uint8_t*)Modern::R1::prefix.c_str(), - static_cast(Modern::R1::prefix.size())); + case Type::ModernR1: { + auto startR1 = (const uint8_t*)Modern::R1::prefix.c_str(); + auto endR1 = startR1 + static_cast(Modern::R1::prefix.size()); + append(hashInput, Data(startR1, endR1)); break; } + } - // finalize the hash - ripemd160_Final(&ctx, hash); - - return decode32LE(hash); + auto hash = Hash::ripemd(hashInput.data(), hashInput.size()); + return decode32LE(hash.data()); } /// Extracts and verifies the key data from a base58 string. diff --git a/src/EOS/Signer.cpp b/src/EOS/Signer.cpp index 1c1286e17c4..4a4bc8ffe95 100644 --- a/src/EOS/Signer.cpp +++ b/src/EOS/Signer.cpp @@ -5,9 +5,6 @@ #include "Signer.h" #include "Asset.h" #include "PackedTransaction.h" - -#include - namespace TW::EOS { Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept { @@ -88,7 +85,7 @@ TW::Data Signer::serializeTx(const Transaction& transaction) const noexcept { } // canonical check for EOS -int Signer::isCanonical([[maybe_unused]] uint8_t by, uint8_t sig[64]) { +int Signer::isCanonical([[maybe_unused]] uint8_t by, const uint8_t sig[64]) { // clang-format off return !(sig[0] & 0x80) && !(sig[0] == 0 && !(sig[1] & 0x80)) diff --git a/src/EOS/Signer.h b/src/EOS/Signer.h index 0eef641f9a2..5667515ec84 100644 --- a/src/EOS/Signer.h +++ b/src/EOS/Signer.h @@ -36,7 +36,7 @@ class Signer { /// Serialize the transaction. Data serializeTx(const Transaction& transaction) const noexcept; - static int isCanonical(uint8_t by, uint8_t sig[64]); + static int isCanonical(uint8_t by, const uint8_t sig[64]); Transaction buildTx(const Proto::SigningInput& input) const; Data buildUnsignedTx(const Proto::SigningInput& input) noexcept; diff --git a/src/EOS/Transaction.cpp b/src/EOS/Transaction.cpp index f5ae6608f46..96fe968dcd2 100644 --- a/src/EOS/Transaction.cpp +++ b/src/EOS/Transaction.cpp @@ -5,8 +5,7 @@ #include "../Base58.h" #include "../HexCoding.h" #include "Transaction.h" - -#include +#include "../Hash.h" #include #include @@ -43,10 +42,7 @@ std::string Signature::string() const noexcept { buffer.push_back(static_cast(c)); } - Data hash; - hash.resize(RIPEMD160_DIGEST_LENGTH); - - ripemd160(buffer.data(), static_cast(buffer.size()), hash.data()); + auto hash = Hash::ripemd(buffer.data(), buffer.size()); // drop the subPrefix and append the checksum to the bufer buffer.resize(DataSize); diff --git a/src/Encrypt.cpp b/src/Encrypt.cpp index a3a3c8a78a0..09c0d153310 100644 --- a/src/Encrypt.cpp +++ b/src/Encrypt.cpp @@ -4,104 +4,83 @@ #include "Encrypt.h" #include "Data.h" -#include #include #include #include -namespace TW::Encrypt { +#include "rust/Wrapper.h" +#include "TrustWalletCore/Generated/TWCrypto.h" -size_t paddingSize(size_t origSize, size_t blockSize, TWAESPaddingMode paddingMode) { - if (origSize % blockSize == 0) { - // even blocks - if (paddingMode == TWAESPaddingModePKCS7) { - return blockSize; - } - return 0; - } - // non-even - return blockSize - origSize % blockSize; -} +namespace TW::Encrypt { Data AESCBCEncrypt(const Data& key, const Data& data, Data& iv, TWAESPaddingMode paddingMode) { - aes_encrypt_ctx ctx; - if (aes_encrypt_key(key.data(), static_cast(key.size()), &ctx) == EXIT_FAILURE) { - throw std::invalid_argument("Invalid key"); - } + Rust::TWDataWrapper dataWrapper = data; + Rust::TWDataWrapper ivWrapper = iv; + Rust::TWDataWrapper keyWrapper = key; - // Message is padded to round block size, or by a full padding block if even - const size_t blockSize = AES_BLOCK_SIZE; - const auto padding = paddingSize(data.size(), blockSize, paddingMode); - const auto resultSize = data.size() + padding; - Data result(resultSize); - size_t idx; - for (idx = 0; idx < resultSize - blockSize; idx += blockSize) { - aes_cbc_encrypt(data.data() + idx, result.data() + idx, blockSize, iv.data(), &ctx); - } - // last block - if (idx < resultSize) { - uint8_t padded[blockSize] = {0}; - if (paddingMode == TWAESPaddingModePKCS7) { - std::memset(padded, static_cast(padding), blockSize); - } - std::memcpy(padded, data.data() + idx, data.size() - idx); - aes_cbc_encrypt(padded, result.data() + idx, blockSize, iv.data(), &ctx); + Rust::TWDataWrapper res = Rust::tw_aes_encrypt_cbc( + keyWrapper.get(), + dataWrapper.get(), + ivWrapper.get(), + paddingMode + ); + auto resData = res.toDataOrDefault(); + if (resData.empty()) { + throw std::runtime_error("Invalid aes cbc encrypt"); } - - return result; + return resData; } Data AESCBCDecrypt(const Data& key, const Data& data, Data& iv, TWAESPaddingMode paddingMode) { - const size_t blockSize = AES_BLOCK_SIZE; - if (data.size() % blockSize != 0) { - throw std::invalid_argument("Invalid data size"); - } - assert((data.size() % blockSize) == 0); + Rust::TWDataWrapper dataWrapper = data; + Rust::TWDataWrapper ivWrapper = iv; + Rust::TWDataWrapper keyWrapper = key; - aes_decrypt_ctx ctx; - if (aes_decrypt_key(key.data(), static_cast(key.size()), &ctx) != EXIT_SUCCESS) { - throw std::invalid_argument("Invalid key"); + Rust::TWDataWrapper res = Rust::tw_aes_decrypt_cbc( + keyWrapper.get(), + dataWrapper.get(), + ivWrapper.get(), + paddingMode + ); + auto resData = res.toDataOrDefault(); + if (resData.empty()) { + throw std::runtime_error("Invalid aes cbc decrypt"); } - - Data result(data.size()); - for (std::size_t i = 0; i < data.size(); i += blockSize) { - aes_cbc_decrypt(data.data() + i, result.data() + i, blockSize, iv.data(), &ctx); - } - - if (paddingMode == TWAESPaddingModePKCS7 && result.size() > 0) { - // need to remove padding - assert(result.size() > 0); - const byte paddingSize = result[result.size() - 1]; - if (paddingSize <= result.size()) { - // remove last paddingSize number of bytes - const size_t unpaddedSize = result.size() - paddingSize; - Data resultUnpadded = TW::data(result.data(), unpaddedSize); - return resultUnpadded; - } - } - return result; + return resData; } Data AESCTREncrypt(const Data& key, const Data& data, Data& iv) { - aes_encrypt_ctx ctx; - if (aes_encrypt_key(key.data(), static_cast(key.size()), &ctx) != EXIT_SUCCESS) { - throw std::invalid_argument("Invalid key"); - } + Rust::TWDataWrapper dataWrapper = data; + Rust::TWDataWrapper ivWrapper = iv; + Rust::TWDataWrapper keyWrapper = key; - Data result(data.size()); - aes_ctr_encrypt(data.data(), result.data(), static_cast(data.size()), iv.data(), aes_ctr_cbuf_inc, &ctx); - return result; + Rust::TWDataWrapper res = Rust::tw_aes_encrypt_ctr( + keyWrapper.get(), + dataWrapper.get(), + ivWrapper.get() + ); + auto resData = res.toDataOrDefault(); + if (resData.empty()) { + throw std::runtime_error("Invalid aes ctr encrypt"); + } + return resData; } Data AESCTRDecrypt(const Data& key, const Data& data, Data& iv) { - aes_encrypt_ctx ctx; - if (aes_encrypt_key(key.data(), static_cast(key.size()), &ctx) != EXIT_SUCCESS) { - throw std::invalid_argument("Invalid key"); - } + Rust::TWDataWrapper dataWrapper = data; + Rust::TWDataWrapper ivWrapper = iv; + Rust::TWDataWrapper keyWrapper = key; - Data result(data.size()); - aes_ctr_decrypt(data.data(), result.data(), static_cast(data.size()), iv.data(), aes_ctr_cbuf_inc, &ctx); - return result; + Rust::TWDataWrapper res = Rust::tw_aes_decrypt_ctr( + keyWrapper.get(), + dataWrapper.get(), + ivWrapper.get() + ); + auto resData = res.toDataOrDefault(); + if (resData.empty()) { + throw std::runtime_error("Invalid aes ctr decrypt"); + } + return resData; } } // namespace TW::Encrypt diff --git a/src/Everscale/Messages.cpp b/src/Everscale/Messages.cpp index 47d2b4d72a2..4d42921d2de 100644 --- a/src/Everscale/Messages.cpp +++ b/src/Everscale/Messages.cpp @@ -65,7 +65,7 @@ MessageData createSignedMessage(PublicKey& publicKey, PrivateKey& key, bool boun auto payloadCell = payloadCopy.intoCell(); Data data(payloadCell->hash.begin(), payloadCell->hash.end()); - auto signature = key.sign(data, TWCurveED25519); + auto signature = key.sign(data); payload.prependRaw(signature, static_cast(signature.size()) * 8); auto header = std::make_shared(InitData(publicKey).computeAddr(WorkchainType::Basechain)); diff --git a/src/FIO/Address.cpp b/src/FIO/Address.cpp index abfc1046846..314a9f2c7cd 100644 --- a/src/FIO/Address.cpp +++ b/src/FIO/Address.cpp @@ -5,9 +5,7 @@ #include "Address.h" #include "../Base58.h" #include "../BinaryCoding.h" - -#include - +#include "../Hash.h" #include using namespace TW; @@ -34,18 +32,8 @@ bool Address::isValid(const Data& bytes) { /// Creates a checksum of PublicKeyDataSize bytes at the buffer uint32_t Address::createChecksum(const Data& bytes) { - // create checksum and compare - uint8_t hash[RIPEMD160_DIGEST_LENGTH]; - RIPEMD160_CTX ctx; - ripemd160_Init(&ctx); - - // add the bytes to the hash input - ripemd160_Update(&ctx, bytes.data(), PublicKey::secp256k1Size); - - // finalize the hash - ripemd160_Final(&ctx, hash); - - return decode32LE(hash); + auto hash = Hash::ripemd(bytes.data(), PublicKey::secp256k1Size); + return decode32LE(hash.data()); } /// Decode and verifies the key data from a base58 string. diff --git a/src/FIO/Encryption.cpp b/src/FIO/Encryption.cpp index ee2c2b54c6c..08dc09f49dc 100644 --- a/src/FIO/Encryption.cpp +++ b/src/FIO/Encryption.cpp @@ -3,6 +3,7 @@ // Copyright © 2017 Trust Wallet. #include "Encryption.h" +#include "rand.h" #include "../Base64.h" #include "../Encrypt.h" @@ -10,12 +11,11 @@ #include "../HexCoding.h" #include "../PrivateKey.h" #include "../PublicKey.h" - -#include -#include -#include +#include "../Utils.h" +#include #include + #include namespace TW::FIO { @@ -87,22 +87,14 @@ Data Encryption::checkDecrypt(const Data& secret, const Data& message) { Data Encryption::getSharedSecret(const PrivateKey& privateKey1, const PublicKey& publicKey2) { // See https://github.com/fioprotocol/fiojs/blob/master/src/ecc/key_private.js - - curve_point KBP; - [[maybe_unused]] int read_res = ecdsa_read_pubkey(&secp256k1, publicKey2.bytes.data(), &KBP); - assert(read_res); - - bignum256 privBN; - bn_read_be(privateKey1.bytes.data(), &privBN); - - curve_point P; - point_multiply(&secp256k1, &privBN, &KBP, &P); - - Data S(32); - bn_write_be(&P.x, S.data()); - - // SHA512 used in ECIES - return Hash::sha512(S); + + auto privateKey = wrapTWData(TWDataCreateWithBytes(privateKey1.bytes.data(), privateKey1.bytes.size())); + auto publicKey = wrapTWData(TWDataCreateWithBytes(publicKey2.bytes.data(), publicKey2.bytes.size())); + auto sharedKey = wrapTWData(TWECDSASharedKey(privateKey.get(), publicKey.get(), true)); + if (sharedKey == nullptr) { + throw std::invalid_argument("Invalid shared key"); + } + return dataFromTWData(sharedKey); } Data Encryption::encrypt(const PrivateKey& privateKey1, const PublicKey& publicKey2, const Data& message, const Data& iv) { diff --git a/src/FIO/Signer.cpp b/src/FIO/Signer.cpp index 0e90e84df30..7652d7772fd 100644 --- a/src/FIO/Signer.cpp +++ b/src/FIO/Signer.cpp @@ -12,9 +12,6 @@ #include "../proto/Common.pb.h" #include "TransactionBuilder.h" -#include -#include - #include namespace TW::FIO { @@ -42,7 +39,7 @@ Proto::SigningOutput Signer::compile(const Proto::SigningInput& input, const Dat Data Signer::signData(const PrivateKey& privKey, const Data& data) { Data hash = Hash::sha256(data); - Data signature = privKey.sign(hash, TWCurveSECP256k1, isCanonical); + Data signature = privKey.sign(hash, isCanonical); return signature; } @@ -62,7 +59,7 @@ bool Signer::verify(const PublicKey& pubKey, const Data& data, const Data& signa } // canonical check for FIO, both R and S length is 32 -int Signer::isCanonical([[maybe_unused]] uint8_t by, uint8_t sig[64]) { +int Signer::isCanonical([[maybe_unused]] uint8_t by, const uint8_t sig[64]) { return !(sig[0] & 0x80) && !(sig[0] == 0 && !(sig[1] & 0x80)) && !(sig[32] & 0x80) diff --git a/src/FIO/Signer.h b/src/FIO/Signer.h index 72b3d7b7098..e18494ad815 100644 --- a/src/FIO/Signer.h +++ b/src/FIO/Signer.h @@ -34,7 +34,7 @@ class Signer { /// Verify a signature, used in testing static bool verify(const PublicKey& pubKey, const Data& data, const Data& signature); - static int isCanonical(uint8_t by, uint8_t sig[64]); + static int isCanonical(uint8_t by, const uint8_t sig[64]); }; } // namespace TW::FIO diff --git a/src/Filecoin/Signer.cpp b/src/Filecoin/Signer.cpp index 8db3a82cebd..2a946863192 100644 --- a/src/Filecoin/Signer.cpp +++ b/src/Filecoin/Signer.cpp @@ -47,7 +47,7 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept { Data Signer::sign(const PrivateKey& privateKey, Transaction& transaction) noexcept { Data toSign = Hash::blake2b(transaction.cid(), 32); - auto signature = privateKey.sign(toSign, TWCurveSECP256k1); + auto signature = privateKey.sign(toSign); return Data(signature.begin(), signature.end()); } diff --git a/src/Groestlcoin/Address.cpp b/src/Groestlcoin/Address.cpp index 74253e2799b..ea1657681d6 100644 --- a/src/Groestlcoin/Address.cpp +++ b/src/Groestlcoin/Address.cpp @@ -6,7 +6,9 @@ #include "Base58.h" #include -#include +#include "../Hash.h" +#include "../Utils.h" +#include namespace TW::Groestlcoin { @@ -50,7 +52,13 @@ Address::Address(const PublicKey& publicKey, uint8_t prefix) { throw std::invalid_argument("Groestlcoin::Address needs a compressed SECP256k1 public key."); } bytes[0] = prefix; - ecdsa_get_pubkeyhash(publicKey.bytes.data(), HASHER_SHA2_RIPEMD, bytes.data() + 1); + auto data = wrapTWData(TWDataCreateWithBytes(publicKey.bytes.data(), publicKey.bytes.size())); + auto result = wrapTWData(TWECDSAPubkeyHash(data.get(), true, Hash::HasherSha256ripemd)); + if (result == nullptr) { + throw std::invalid_argument("Invalid public key hash"); + } + auto resultData = dataFromTWData(result); + std::copy(resultData.begin(), resultData.end(), bytes.begin() + 1); } std::string Address::string() const { diff --git a/src/HDWallet.cpp b/src/HDWallet.cpp index a329f6634da..d94a67b7f21 100644 --- a/src/HDWallet.cpp +++ b/src/HDWallet.cpp @@ -16,28 +16,16 @@ #include #include -#include - -#include -#include -#include -#include +#include "Generated/HDNode.h" +#include +#include "Generated/HDNodePublic.h" +#include #include #include using namespace TW; -namespace { - -uint32_t fingerprint(HDNode* node, Hash::Hasher hasher); -std::string serialize(const HDNode* node, uint32_t fingerprint, uint32_t version, bool use_public, Hash::Hasher hasher); -bool deserialize(const std::string& extended, TWCurve curve, Hash::Hasher hasher, HDNode* node); -const char* curveName(TWCurve curve); -} // namespace - -const int MnemonicBufLength = Mnemonic::MaxWords * (BIP39_MAX_WORD_LENGTH + 3) + 20; // some extra slack - template HDWallet::HDWallet(const Data& seed) { std::copy_n(seed.begin(), seedSize, this->seed.begin()); @@ -47,28 +35,20 @@ template void HDWallet::updateSeedAndEntropy([[maybe_unused]] bool check) { assert(!check || Mnemonic::isValid(mnemonic)); // precondition - // generate seed from mnemonic - mnemonic_to_seed(mnemonic.c_str(), passphrase.c_str(), seed.data(), nullptr); - - // generate entropy bits from mnemonic - Data entropyRaw((Mnemonic::MaxWords * Mnemonic::BitsPerWord) / 8); - // entropy is truncated to fully bytes, 4 bytes for each 3 words (=33 bits) - auto entropyBytes = mnemonic_to_bits(mnemonic.c_str(), entropyRaw.data()) / 33 * 4; - // copy to truncate - entropy = data(entropyRaw.data(), entropyBytes); + auto seedData = Mnemonic::toSeed(mnemonic, passphrase); + std::copy_n(seedData.begin(), seedSize, seed.begin()); + entropy = Mnemonic::toEntropy(mnemonic); + assert(!check || entropy.size() > 10); } template HDWallet::HDWallet(int strength, const std::string& passphrase) : passphrase(passphrase) { - char buf[MnemonicBufLength]; - const char* mnemonic_chars = mnemonic_generate(strength, buf, MnemonicBufLength); - if (mnemonic_chars == nullptr) { + mnemonic = Mnemonic::generate(strength); + if (mnemonic.empty()) { throw std::invalid_argument("Invalid strength"); } - mnemonic = mnemonic_chars; - TW::memzero(buf, MnemonicBufLength); updateSeedAndEntropy(); } @@ -85,13 +65,10 @@ HDWallet::HDWallet(const std::string& mnemonic, const std::string& pas template HDWallet::HDWallet(const Data& entropy, const std::string& passphrase) : passphrase(passphrase) { - char buf[MnemonicBufLength]; - const char* mnemonic_chars = mnemonic_from_data(entropy.data(), static_cast(entropy.size()), buf, MnemonicBufLength); - if (mnemonic_chars == nullptr) { + mnemonic = Mnemonic::generateFromData(entropy); + if (mnemonic.empty()) { throw std::invalid_argument("Invalid mnemonic data"); } - mnemonic = mnemonic_chars; - TW::memzero(buf, MnemonicBufLength); updateSeedAndEntropy(); } @@ -103,102 +80,60 @@ HDWallet::~HDWallet() { } template -static HDNode getMasterNode(const HDWallet& wallet, TWCurve curve) { - const auto privateKeyType = PrivateKey::getType(curve); - HDNode node; - switch (privateKeyType) { - case TWPrivateKeyTypeCardano: { - // Derives the root Cardano HDNode from a passphrase and the entropy encoded in - // a BIP-0039 mnemonic using the Icarus derivation (V2) scheme - const auto entropy = wallet.getEntropy(); - uint8_t secret[CARDANO_SECRET_LENGTH]; - secret_from_entropy_cardano_icarus((const uint8_t*)"", 0, entropy.data(), int(entropy.size()), secret, nullptr); - hdnode_from_secret_cardano(secret, &node); - TW::memzero(secret, CARDANO_SECRET_LENGTH); - break; - } - case TWPrivateKeyTypeDefault: - default: - hdnode_from_seed(wallet.getSeed().data(), HDWallet::mSeedSize, curveName(curve), &node); - break; +static TWHDNode* getMasterNode(const HDWallet& wallet, TWCurve curve) { + TWData* seedData = nullptr; + if (curve == TWCurveED25519ExtendedCardano) { + seedData = TWDataCreateWithBytes(wallet.getEntropy().data(), wallet.getEntropy().size()); + } else { + seedData = TWDataCreateWithBytes(wallet.getSeed().data(), wallet.getSeed().size()); } + auto node = TWHDNodeCreateWithSeed(seedData, curve); + TWDataDelete(seedData); return node; } template -static HDNode getNode(const HDWallet& wallet, TWCurve curve, const DerivationPath& derivationPath) { - const auto privateKeyType = PrivateKey::getType(curve); +static TWHDNode* getNode(const HDWallet& wallet, TWCurve curve, const DerivationPath& derivationPath, TW::Hash::Hasher hasher) { auto node = getMasterNode(wallet, curve); - for (auto& index : derivationPath.indices) { - switch (privateKeyType) { - case TWPrivateKeyTypeCardano: - hdnode_private_ckd_cardano(&node, index.derivationIndex()); - break; - case TWPrivateKeyTypeDefault: - default: - hdnode_private_ckd(&node, index.derivationIndex()); - break; - } + if (node == nullptr) { + return nullptr; } - return node; + auto derivationPathString = TWStringCreateWithUTF8Bytes(derivationPath.string().c_str()); + auto childNode = TWHDNodeDeriveFromPath(node, derivationPathString, hasher); + TWStringDelete(derivationPathString); + TWHDNodeDelete(node); + return childNode; } template PrivateKey HDWallet::getMasterKey(TWCurve curve) const { - auto node = getMasterNode(*this, curve); - auto data = Data(node.private_key, node.private_key + PrivateKey::_size); - return PrivateKey(data, curve); -} - -template -PrivateKey HDWallet::getMasterKeyExtension(TWCurve curve) const { - auto node = getMasterNode(*this, curve); - auto data = Data(node.private_key_extension, node.private_key_extension + PrivateKey::_size); + auto node = getMasterNode(*this, curve); + if (node == nullptr) { + throw std::invalid_argument("Invalid master node"); + } + auto privateKeyData = TWHDNodePrivateKeyData(node); + TWHDNodeDelete(node); + auto data = Data(TWDataBytes(privateKeyData), TWDataBytes(privateKeyData) + TWDataSize(privateKeyData)); + TWDataDelete(privateKeyData); return PrivateKey(data, curve); } -template -DerivationPath HDWallet::cardanoStakingDerivationPath(const DerivationPath& path) { - DerivationPath stakingPath = path; - stakingPath.indices[3].value = 2; - stakingPath.indices[4].value = 0; - return stakingPath; -} - template PrivateKey HDWallet::getKeyByCurve(TWCurve curve, const DerivationPath& derivationPath) const { - const auto privateKeyType = PrivateKey::getType(curve); - auto node = getNode(*this, curve, derivationPath); - switch (privateKeyType) { - case TWPrivateKeyTypeCardano: { - if (derivationPath.indices.size() < 4 || derivationPath.indices[3].value > 1) { - // invalid derivation path - return PrivateKey(Data(PrivateKey::cardanoKeySize), curve); - } - const DerivationPath stakingPath = cardanoStakingDerivationPath(derivationPath); - - auto pkData = Data(node.private_key, node.private_key + PrivateKey::_size); - auto extData = Data(node.private_key_extension, node.private_key_extension + PrivateKey::_size); - auto chainCode = Data(node.chain_code, node.chain_code + PrivateKey::_size); - - // repeat with staking path - const auto node2 = getNode(*this, curve, stakingPath); - auto pkData2 = Data(node2.private_key, node2.private_key + PrivateKey::_size); - auto extData2 = Data(node2.private_key_extension, node2.private_key_extension + PrivateKey::_size); - auto chainCode2 = Data(node2.chain_code, node2.chain_code + PrivateKey::_size); - - TW::memzero(&node); - return PrivateKey(pkData, extData, chainCode, pkData2, extData2, chainCode2, curve); + auto curveToUse = curve == TWCurveStarkex ? TWCurveSECP256k1 : curve; + auto node = getNode(*this, curveToUse, derivationPath, Hash::HasherSha256ripemd); + if (node == nullptr) { + throw std::invalid_argument("Invalid derivation path"); } - case TWPrivateKeyTypeDefault: - default: - // default path - auto data = Data(node.private_key, node.private_key + PrivateKey::_size); - TW::memzero(&node); - if (curve == TWCurveStarkex) { - return ImmutableX::getPrivateKeyFromEthPrivKey(PrivateKey(data, curve)); - } - return PrivateKey(data, curve); + auto privateKeyData = TWHDNodePrivateKeyData(node); + TWHDNodeDelete(node); + auto data = Data(TWDataBytes(privateKeyData), TWDataBytes(privateKeyData) + TWDataSize(privateKeyData)); + TWDataDelete(privateKeyData); + auto privateKey = PrivateKey(data, curveToUse); + if (curve == TWCurveStarkex) { + return ImmutableX::getPrivateKeyFromEthPrivKey(privateKey); + } else { + return privateKey; } } @@ -218,7 +153,15 @@ template std::string HDWallet::getRootKey(TWCoinType coin, TWHDVersion version) const { const auto curve = TWCoinTypeCurve(coin); auto node = getMasterNode(*this, curve); - return serialize(&node, 0, version, false, base58Hasher(coin)); + if (node == nullptr) { + return "Unsupported curve"; + } + auto extendedPrivateKey = TWHDNodeExtendedPrivateKey(node, version, TW::base58Hasher(coin)); + TWHDNodeDelete(node); + auto* bytes = TWStringUTF8Bytes(extendedPrivateKey); + std::string result(bytes); + TWStringDelete(extendedPrivateKey); + return result; } template @@ -240,11 +183,17 @@ std::string HDWallet::getExtendedPrivateKeyAccount(TWPurpose purpose, const auto curve = TWCoinTypeCurve(coin); const auto path = TW::derivationPath(coin, derivation); - auto derivationPath = DerivationPath({DerivationPathIndex(purpose, true), DerivationPathIndex(path.coin(), true)}); - auto node = getNode(*this, curve, derivationPath); - auto fingerprintValue = fingerprint(&node, publicKeyHasher(coin)); - hdnode_private_ckd(&node, account + 0x80000000); - return serialize(&node, fingerprintValue, version, false, base58Hasher(coin)); + auto derivationPath = DerivationPath({DerivationPathIndex(purpose, true), DerivationPathIndex(path.coin(), true), DerivationPathIndex(account, true)}); + auto node = getNode(*this, curve, derivationPath, TW::publicKeyHasher(coin)); + if (node == nullptr) { + return "Invalid derivation path"; + } + auto extendedPrivateKey = TWHDNodeExtendedPrivateKey(node, version, TW::base58Hasher(coin)); + TWHDNodeDelete(node); + auto* bytes = TWStringUTF8Bytes(extendedPrivateKey); + std::string result(bytes); + TWStringDelete(extendedPrivateKey); + return result; } template @@ -255,64 +204,75 @@ std::string HDWallet::getExtendedPublicKeyAccount(TWPurpose purpose, T const auto curve = TWCoinTypeCurve(coin); const auto path = TW::derivationPath(coin, derivation); - auto derivationPath = DerivationPath({DerivationPathIndex(purpose, true), DerivationPathIndex(path.coin(), true)}); - auto node = getNode(*this, curve, derivationPath); - auto fingerprintValue = fingerprint(&node, publicKeyHasher(coin)); - hdnode_private_ckd(&node, account + 0x80000000); - hdnode_fill_public_key(&node); - return serialize(&node, fingerprintValue, version, true, base58Hasher(coin)); + auto derivationPath = DerivationPath({DerivationPathIndex(purpose, true), DerivationPathIndex(path.coin(), true), DerivationPathIndex(account, true)}); + auto node = getNode(*this, curve, derivationPath, TW::publicKeyHasher(coin)); + if (node == nullptr) { + return "Invalid derivation path"; + } + auto extendedPublicKey = TWHDNodeExtendedPublicKey(node, version, TW::base58Hasher(coin)); + TWHDNodeDelete(node); + auto* bytes = TWStringUTF8Bytes(extendedPublicKey); + std::string result(bytes); + TWStringDelete(extendedPublicKey); + return result; } template std::optional HDWallet::getPublicKeyFromExtended(const std::string& extended, TWCoinType coin, const DerivationPath& path) { const auto curve = TW::curve(coin); - const auto hasher = TW::base58Hasher(coin); - - auto node = HDNode{}; - if (!deserialize(extended, curve, hasher, &node)) { + auto extendedString = TWStringCreateWithUTF8Bytes(extended.c_str()); + auto node = TWHDNodePublicCreateWithExtendedPublicKey(extendedString, curve, TW::base58Hasher(coin)); + TWStringDelete(extendedString); + if (node == nullptr) { return {}; } - if (node.curve->params == nullptr) { + auto childPath = DerivationPath({DerivationPathIndex(path.change(), false), DerivationPathIndex(path.address(), false)}); + auto childPathString = TWStringCreateWithUTF8Bytes(childPath.string().c_str()); + auto childNode = TWHDNodePublicDeriveFromPath(node, childPathString, TW::publicKeyHasher(coin)); + TWHDNodePublicDelete(node); + TWStringDelete(childPathString); + if (childNode == nullptr) { return {}; } - hdnode_public_ckd(&node, path.change()); - hdnode_public_ckd(&node, path.address()); - hdnode_fill_public_key(&node); - // These public key type are not applicable. Handled above, as node.curve->params is null - assert(curve != TWCurveED25519 && curve != TWCurveED25519Blake2bNano && curve != TWCurveED25519ExtendedCardano && curve != TWCurveCurve25519); + auto pubkeyData = TWHDNodePublicPublicKeyData(childNode); + TWHDNodePublicDelete(childNode); + auto data = Data(TWDataBytes(pubkeyData), TWDataBytes(pubkeyData) + TWDataSize(pubkeyData)); + TWDataDelete(pubkeyData); TWPublicKeyType keyType = TW::publicKeyType(coin); - if (curve == TWCurveSECP256k1) { - auto pubkey = PublicKey(Data(node.public_key, node.public_key + 33), TWPublicKeyTypeSECP256k1); - if (keyType == TWPublicKeyTypeSECP256k1Extended) { - return pubkey.extended(); - } else { - return pubkey; - } - } else if (curve == TWCurveNIST256p1) { - auto pubkey = PublicKey(Data(node.public_key, node.public_key + 33), TWPublicKeyTypeNIST256p1); - if (keyType == TWPublicKeyTypeNIST256p1Extended) { - return pubkey.extended(); - } else { - return pubkey; - } + if (keyType == TWPublicKeyTypeSECP256k1Extended) { + auto pubkey = PublicKey(data, TWPublicKeyTypeSECP256k1); + return pubkey.extended(); + } else if (keyType == TWPublicKeyTypeNIST256p1Extended) { + auto pubkey = PublicKey(data, TWPublicKeyTypeNIST256p1); + return pubkey.extended(); + } else { + return PublicKey(data, keyType); } - return {}; } template std::optional HDWallet::getPrivateKeyFromExtended(const std::string& extended, TWCoinType coin, const DerivationPath& path) { const auto curve = TW::curve(coin); - const auto hasher = TW::base58Hasher(coin); - - auto node = HDNode{}; - if (!deserialize(extended, curve, hasher, &node)) { + auto extendedString = TWStringCreateWithUTF8Bytes(extended.c_str()); + auto node = TWHDNodeCreateWithExtendedPrivateKey(extendedString, curve, TW::base58Hasher(coin)); + TWStringDelete(extendedString); + if (node == nullptr) { return {}; } - hdnode_private_ckd(&node, path.change()); - hdnode_private_ckd(&node, path.address()); - - return PrivateKey(Data(node.private_key, node.private_key + 32), curve); + auto childPath = DerivationPath({DerivationPathIndex(path.change(), false), DerivationPathIndex(path.address(), false)}); + auto childPathString = TWStringCreateWithUTF8Bytes(childPath.string().c_str()); + auto childNode = TWHDNodeDeriveFromPath(node, childPathString, TW::publicKeyHasher(coin)); + TWHDNodeDelete(node); + TWStringDelete(childPathString); + if (childNode == nullptr) { + return {}; + } + auto privkeyData = TWHDNodePrivateKeyData(childNode); + TWHDNodeDelete(childNode); + auto data = Data(TWDataBytes(privkeyData), TWDataBytes(privkeyData) + TWDataSize(privkeyData)); + TWDataDelete(privkeyData); + return PrivateKey(data, curve); } template @@ -322,87 +282,6 @@ PrivateKey HDWallet::bip32DeriveRawSeed(TWCoinType coin, const Data& s return wallet.getKeyByCurve(curve, path); } -namespace { - -uint32_t fingerprint(HDNode* node, Hash::Hasher hasher) { - hdnode_fill_public_key(node); - auto digest = Hash::hash(hasher, node->public_key, 33); - return ((uint32_t)digest[0] << 24) + (digest[1] << 16) + (digest[2] << 8) + digest[3]; -} - -std::string serialize(const HDNode* node, uint32_t fingerprint, uint32_t version, bool use_public, Hash::Hasher hasher) { - Data node_data; - node_data.reserve(78); - - encode32BE(version, node_data); - node_data.push_back(static_cast(node->depth)); - encode32BE(fingerprint, node_data); - encode32BE(node->child_num, node_data); - node_data.insert(node_data.end(), node->chain_code, node->chain_code + 32); - if (use_public) { - node_data.insert(node_data.end(), node->public_key, node->public_key + 33); - } else { - node_data.push_back(0); - node_data.insert(node_data.end(), node->private_key, node->private_key + 32); - } - - return Base58::encodeCheck(node_data, Rust::Base58Alphabet::Bitcoin, hasher); -} - -bool deserialize(const std::string& extended, TWCurve curve, Hash::Hasher hasher, HDNode* node) { - TW::memzero(node); - const char* curveNameStr = curveName(curve); - if (curveNameStr == nullptr || std::string(curveNameStr).empty()) { - return false; - } - node->curve = get_curve_by_name(curveNameStr); - assert(node->curve != nullptr); - - const auto node_data = Base58::decodeCheck(extended, Rust::Base58Alphabet::Bitcoin, hasher); - if (node_data.size() != 78) { - return false; - } - - uint32_t version = decode32BE(node_data.data()); - if (TWHDVersionIsPublic(static_cast(version))) { - std::copy(node_data.begin() + 45, node_data.begin() + 45 + 33, node->public_key); - } else if (TWHDVersionIsPrivate(static_cast(version))) { - if (node_data[45]) { // invalid data - return false; - } - std::copy(node_data.begin() + 46, node_data.begin() + 46 + 32, node->private_key); - } else { - return false; // invalid version - } - node->depth = node_data[4]; - node->child_num = decode32BE(node_data.data() + 9); - std::copy(node_data.begin() + 13, node_data.begin() + 13 + 32, node->chain_code); - return true; -} - -const char* curveName(TWCurve curve) { - switch (curve) { - case TWCurveStarkex: - case TWCurveSECP256k1: - return SECP256K1_NAME; - case TWCurveED25519: - return ED25519_NAME; - case TWCurveED25519Blake2bNano: - return ED25519_BLAKE2B_NANO_NAME; - case TWCurveED25519ExtendedCardano: - return ED25519_CARDANO_NAME; - case TWCurveNIST256p1: - return NIST256P1_NAME; - case TWCurveCurve25519: - return CURVE25519_NAME; - case TWCurveNone: - default: - return ""; - } -} - -} // namespace - namespace TW { template class HDWallet<32>; template class HDWallet<64>; diff --git a/src/HDWallet.h b/src/HDWallet.h index 7cff0fbcb2e..96d417f383b 100644 --- a/src/HDWallet.h +++ b/src/HDWallet.h @@ -74,9 +74,6 @@ class HDWallet { /// Returns master key. PrivateKey getMasterKey(TWCurve curve) const; - /// Returns the master private key extension (32 byte). - PrivateKey getMasterKeyExtension(TWCurve curve) const; - /// Returns the private key with the given derivation. PrivateKey getKey(const TWCoinType coin, TWDerivation derivation) const; diff --git a/src/Harmony/Signer.cpp b/src/Harmony/Signer.cpp index 8a1cb459306..8d84778f3c7 100644 --- a/src/Harmony/Signer.cpp +++ b/src/Harmony/Signer.cpp @@ -23,7 +23,7 @@ std::tuple Signer::values(const uint256_t& chai std::tuple Signer::sign(const uint256_t& chainID, const PrivateKey& privateKey, const Data& hash) noexcept { - auto signature = privateKey.sign(hash, TWCurveSECP256k1); + auto signature = privateKey.sign(hash); return values(chainID, signature); } diff --git a/src/Hedera/Signer.cpp b/src/Hedera/Signer.cpp index 13d2a93f9e0..4020a452aaf 100644 --- a/src/Hedera/Signer.cpp +++ b/src/Hedera/Signer.cpp @@ -67,7 +67,7 @@ static inline Proto::SigningOutput sign(const proto::TransactionBody& body, cons auto protoOutput = Proto::SigningOutput(); Data encoded; auto encodedBody = data(body.SerializeAsString()); - auto signedBody = privateKey.sign(encodedBody, TWCurveED25519); + auto signedBody = privateKey.sign(encodedBody); auto sigMap = proto::SignatureMap(); auto* sigPair = sigMap.add_sigpair(); sigPair->set_ed25519(signedBody.data(), signedBody.size()); diff --git a/src/Icon/Address.cpp b/src/Icon/Address.cpp index 15eaf1d7a02..d50321ef586 100644 --- a/src/Icon/Address.cpp +++ b/src/Icon/Address.cpp @@ -5,8 +5,7 @@ #include "Address.h" #include "../HexCoding.h" - -#include +#include "../Hash.h" namespace TW::Icon { @@ -43,8 +42,7 @@ Address::Address(const std::string& string) { Address::Address(const PublicKey& publicKey, enum AddressType type) : type(type) { - auto hash = std::array(); - sha3_256(publicKey.bytes.data() + 1, publicKey.bytes.size() - 1, hash.data()); + auto hash = Hash::sha3_256(publicKey.bytes.data() + 1, publicKey.bytes.size() - 1); std::copy(hash.end() - Address::size, hash.end(), bytes.begin()); } diff --git a/src/Keystore/AESParameters.cpp b/src/Keystore/AESParameters.cpp index f2156144a6c..857c51e62bb 100644 --- a/src/Keystore/AESParameters.cpp +++ b/src/Keystore/AESParameters.cpp @@ -5,8 +5,7 @@ #include "AESParameters.h" #include "../HexCoding.h" - -#include +#include "rand.h" using namespace TW; diff --git a/src/Keystore/EncryptionParameters.cpp b/src/Keystore/EncryptionParameters.cpp index db34105c024..620d077b578 100644 --- a/src/Keystore/EncryptionParameters.cpp +++ b/src/Keystore/EncryptionParameters.cpp @@ -6,10 +6,9 @@ #include "../Hash.h" -#include -#include -#include #include +#include +#include "TrustWalletCore/Generated/TWCrypto.h" using namespace TW; @@ -37,6 +36,95 @@ static const auto kdfParams = "kdfparams"; static const auto mac = "mac"; } // namespace CodingKeys +static Data rustScrypt(const Data& password, const ScryptParameters& params) { + Rust::TWDataWrapper passwordData = password; + Rust::TWDataWrapper saltData = params.salt; + + Rust::TWDataWrapper res = Rust::crypto_scrypt( + passwordData.get(), + saltData.get(), + params.n, + params.r, + params.p, + params.desiredKeyLength + ); + auto data = res.toDataOrDefault(); + if (data.empty()) { + throw std::runtime_error("Invalid scrypt parameters"); + } + return data; +} + +static Data rustPbkdf2(const Data& password, const PBKDF2Parameters& params) { + Rust::TWDataWrapper passwordData = password; + Rust::TWDataWrapper saltData = params.salt; + + Rust::TWDataWrapper res = Rust::tw_pbkdf2_hmac_sha256( + passwordData.get(), + saltData.get(), + params.iterations, + params.desiredKeyLength + ); + auto data = res.toDataOrDefault(); + if (data.empty()) { + throw std::runtime_error("Invalid pbkdf2 parameters"); + } + return data; +} +template +static Data rustAesOperation(const Data& data, const Data& iv, const Data& key, CryptoFunc cryptoFunc, const char* errorMsg) { + Rust::TWDataWrapper dataWrapper = data; + Rust::TWDataWrapper ivWrapper = iv; + Rust::TWDataWrapper keyWrapper = key; + + Rust::TWDataWrapper res = cryptoFunc( + keyWrapper.get(), + dataWrapper.get(), + ivWrapper.get() + ); + auto resData = res.toDataOrDefault(); + if (resData.empty()) { + throw std::runtime_error(errorMsg); + } + return resData; +} + +static Data rustAesCtrEncrypt128(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_encrypt_ctr_128, "Invalid aes ctr encrypt 128"); +} + +static Data rustAesCtrDecrypt128(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_decrypt_ctr_128, "Invalid aes ctr decrypt 128"); +} + +static Data rustAesCtrEncrypt192(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_encrypt_ctr_192, "Invalid aes ctr encrypt 192"); +} + +static Data rustAesCtrDecrypt192(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_decrypt_ctr_192, "Invalid aes ctr decrypt 192"); +} + +static Data rustAesCtrEncrypt256(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_encrypt_ctr_256, "Invalid aes ctr encrypt 256"); +} + +static Data rustAesCtrDecrypt256(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, Rust::tw_aes_decrypt_ctr_256, "Invalid aes ctr decrypt 256"); +} + +static Data rustAesCbcEncrypt(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, + [](auto d, auto i, auto k) { return Rust::tw_aes_encrypt_cbc(d, i, k, TWAESPaddingModePKCS7); }, + "Invalid aes cbc encrypt"); +} + +static Data rustAesCbcDecrypt(const Data& data, const Data& iv, const Data& key) { + return rustAesOperation(data, iv, key, + [](auto d, auto i, auto k) { return Rust::tw_aes_decrypt_cbc(d, i, k, TWAESPaddingModePKCS7); }, + "Invalid aes cbc decrypt"); +} + EncryptionParameters::EncryptionParameters(const nlohmann::json& json) { auto cipher = json[CodingKeys::cipher].get(); cipherParams = AESParameters::AESParametersFromJson(json[CodingKeys::cipherParams], cipher); @@ -68,32 +156,23 @@ nlohmann::json EncryptionParameters::json() const { EncryptedPayload::EncryptedPayload(const Data& password, const Data& data, const EncryptionParameters& params) : params(std::move(params)), _mac() { auto scryptParams = std::get(this->params.kdfParams); - auto derivedKey = Data(scryptParams.desiredKeyLength); - scrypt(reinterpret_cast(password.data()), password.size(), scryptParams.salt.data(), - scryptParams.salt.size(), scryptParams.n, scryptParams.r, scryptParams.p, derivedKey.data(), - scryptParams.desiredKeyLength); + auto derivedKey = rustScrypt(password, scryptParams); - aes_encrypt_ctx ctx; - auto result = 0; switch(this->params.cipherParams.mCipherEncryption) { case TWStoredKeyEncryptionAes128Ctr: - case TWStoredKeyEncryptionAes128Cbc: - result = aes_encrypt_key128(derivedKey.data(), &ctx); + encrypted = rustAesCtrEncrypt128(data, this->params.cipherParams.iv, derivedKey); break; case TWStoredKeyEncryptionAes192Ctr: - result = aes_encrypt_key192(derivedKey.data(), &ctx); + encrypted = rustAesCtrEncrypt192(data, this->params.cipherParams.iv, derivedKey); break; case TWStoredKeyEncryptionAes256Ctr: - result = aes_encrypt_key256(derivedKey.data(), &ctx); + encrypted = rustAesCtrEncrypt256(data, this->params.cipherParams.iv, derivedKey); + break; + case TWStoredKeyEncryptionAes128Cbc: + encrypted = rustAesCbcEncrypt(data, this->params.cipherParams.iv, derivedKey); break; } - assert(result == EXIT_SUCCESS); - if (result == EXIT_SUCCESS) { - Data iv = this->params.cipherParams.iv; - encrypted = Data(data.size()); - aes_ctr_encrypt(data.data(), encrypted.data(), static_cast(data.size()), iv.data(), aes_ctr_cbuf_inc, &ctx); - _mac = computeMAC(derivedKey.end() - params.getKeyBytesSize(), derivedKey.end(), encrypted); - } + _mac = computeMAC(derivedKey.end() - params.getKeyBytesSize(), derivedKey.end(), encrypted); } EncryptedPayload::~EncryptedPayload() { @@ -106,16 +185,10 @@ Data EncryptedPayload::decrypt(const Data& password) const { auto mac = Data(); if (auto* scryptParams = std::get_if(¶ms.kdfParams); scryptParams) { - derivedKey.resize(scryptParams->defaultDesiredKeyLength); - scrypt(password.data(), password.size(), scryptParams->salt.data(), - scryptParams->salt.size(), scryptParams->n, scryptParams->r, scryptParams->p, derivedKey.data(), - scryptParams->defaultDesiredKeyLength); + derivedKey = rustScrypt(password, *scryptParams); mac = computeMAC(derivedKey.end() - params.getKeyBytesSize(), derivedKey.end(), encrypted); } else if (auto* pbkdf2Params = std::get_if(¶ms.kdfParams); pbkdf2Params) { - derivedKey.resize(pbkdf2Params->defaultDesiredKeyLength); - pbkdf2_hmac_sha256(password.data(), static_cast(password.size()), pbkdf2Params->salt.data(), - static_cast(pbkdf2Params->salt.size()), pbkdf2Params->iterations, derivedKey.data(), - pbkdf2Params->defaultDesiredKeyLength); + derivedKey = rustPbkdf2(password, *pbkdf2Params); mac = computeMAC(derivedKey.end() - params.getKeyBytesSize(), derivedKey.end(), encrypted); } else { throw DecryptionError::unsupportedKDF; @@ -127,24 +200,19 @@ Data EncryptedPayload::decrypt(const Data& password) const { Data decrypted(encrypted.size()); Data iv = params.cipherParams.iv; - const auto encryption = params.cipherParams.mCipherEncryption; - if (encryption == TWStoredKeyEncryptionAes128Ctr || encryption == TWStoredKeyEncryptionAes256Ctr) { - aes_encrypt_ctx ctx; - [[maybe_unused]] auto result = aes_encrypt_key(derivedKey.data(), params.getKeyBytesSize(), &ctx); - assert(result != EXIT_FAILURE); - - aes_ctr_decrypt(encrypted.data(), decrypted.data(), static_cast(encrypted.size()), iv.data(), - aes_ctr_cbuf_inc, &ctx); - } else if (encryption == TWStoredKeyEncryptionAes128Cbc) { - aes_decrypt_ctx ctx; - [[maybe_unused]] auto result = aes_decrypt_key(derivedKey.data(), params.getKeyBytesSize(), &ctx); - assert(result != EXIT_FAILURE); - - for (auto i = 0ul; i < encrypted.size(); i += params.getKeyBytesSize()) { - aes_cbc_decrypt(encrypted.data() + i, decrypted.data() + i, params.getKeyBytesSize(), iv.data(), &ctx); - } - } else { - throw DecryptionError::unsupportedCipher; + switch (params.cipherParams.mCipherEncryption) { + case TWStoredKeyEncryptionAes128Ctr: + decrypted = rustAesCtrDecrypt128(encrypted, iv, derivedKey); + break; + case TWStoredKeyEncryptionAes192Ctr: + decrypted = rustAesCtrDecrypt192(encrypted, iv, derivedKey); + break; + case TWStoredKeyEncryptionAes256Ctr: + decrypted = rustAesCtrDecrypt256(encrypted, iv, derivedKey); + break; + case TWStoredKeyEncryptionAes128Cbc: + decrypted = rustAesCbcDecrypt(encrypted, iv, derivedKey); + break; } return decrypted; diff --git a/src/Keystore/PBKDF2Parameters.cpp b/src/Keystore/PBKDF2Parameters.cpp index e965e7bba16..be7a9868568 100644 --- a/src/Keystore/PBKDF2Parameters.cpp +++ b/src/Keystore/PBKDF2Parameters.cpp @@ -3,8 +3,7 @@ // Copyright © 2017 Trust Wallet. #include "PBKDF2Parameters.h" - -#include +#include "rand.h" using namespace TW; diff --git a/src/Keystore/ScryptParameters.cpp b/src/Keystore/ScryptParameters.cpp index 4ec194dd5e8..5bfbf090058 100644 --- a/src/Keystore/ScryptParameters.cpp +++ b/src/Keystore/ScryptParameters.cpp @@ -4,8 +4,8 @@ #include "ScryptParameters.h" -#include #include +#include "rand.h" using namespace TW; diff --git a/src/Keystore/StoredKey.cpp b/src/Keystore/StoredKey.cpp index 31ed44c0933..845c4be8734 100644 --- a/src/Keystore/StoredKey.cpp +++ b/src/Keystore/StoredKey.cpp @@ -10,7 +10,7 @@ #include "PrivateKey.h" #include -#include +#include "memzero.h" #include #include @@ -62,7 +62,7 @@ StoredKey StoredKey::createWithPrivateKeyAddDefaultAddress(const std::string& na const auto derivationPath = TW::derivationPath(coin); const auto pubKeyType = TW::publicKeyType(coin); const auto pubKey = PrivateKey(privateKeyData, TWCoinTypeCurve(coin)).getPublicKey(pubKeyType); - const auto address = TW::deriveAddress(coin, PrivateKey(privateKeyData)); + const auto address = TW::deriveAddress(coin, PrivateKey(privateKeyData, TWCoinTypeCurve(coin))); key.accounts.emplace_back(address, coin, TWDerivationDefault, derivationPath, hex(pubKey.bytes), ""); return key; } @@ -280,12 +280,12 @@ void StoredKey::fixAddresses(const Data& password) { } break; case StoredKeyType::privateKey: { - auto key = PrivateKey(payload.decrypt(password)); for (auto& account : accounts) { if (!account.address.empty() && !account.publicKey.empty() && TW::validateAddress(account.coin, account.address)) { continue; } + auto key = PrivateKey(payload.decrypt(password), TWCoinTypeCurve(account.coin)); updateAddressForAccount(key, account); } } break; diff --git a/src/Mnemonic.cpp b/src/Mnemonic.cpp index a6e9a2227cd..a4fef987981 100644 --- a/src/Mnemonic.cpp +++ b/src/Mnemonic.cpp @@ -4,8 +4,7 @@ #include "Mnemonic.h" -#include -#include +#include "rust/Wrapper.h" #include #include @@ -17,60 +16,49 @@ namespace TW { const int Mnemonic::SuggestMaxCount = 10; +std::string Mnemonic::generate(uint32_t strength) { + const Rust::TWStringWrapper result = Rust::tw_mnemonic_generate(strength); + return result.toStringOrDefault(); +} + +std::string Mnemonic::generateFromData(const Data& data) { + const Rust::TWDataWrapper dataRustData = data; + const Rust::TWStringWrapper result = Rust::tw_mnemonic_generate_from_data(dataRustData.get()); + return result.toStringOrDefault(); +} + bool Mnemonic::isValid(const std::string& mnemonic) { - return mnemonic_check(mnemonic.c_str()) != 0; + const Rust::TWStringWrapper mnemonicRustStr = mnemonic; + return Rust::tw_mnemonic_is_valid(mnemonicRustStr.get()); } -inline const char* const* mnemonicWordlist() { return wordlist; } +std::string Mnemonic::getWord(uint32_t index) { + const Rust::TWStringWrapper result = Rust::tw_mnemonic_get_word(index); + return result.toStringOrDefault(); +} bool Mnemonic::isValidWord(const std::string& word) { - const char* wordC = word.c_str(); - const auto len = word.length(); - // Although this operation is not security-critical, we aim for constant-time operation here as well - // (i.e., no early exit on match) - auto found = false; - for (const char* const* w = mnemonicWordlist(); *w != nullptr; ++w) { - if (std::string(*w).size() == len && strncmp(*w, wordC, len) == 0) { - found = true; - } - } - return found; + const Rust::TWStringWrapper wordRustStr = word; + return Rust::tw_mnemonic_is_valid_word(wordRustStr.get()); } std::string Mnemonic::suggest(const std::string& prefix) { - if (prefix.size() == 0) { - return ""; - } - assert(prefix.size() >= 1); - // lowercase prefix - std::string prefixLo = prefix; - std::transform(prefixLo.begin(), prefixLo.end(), prefixLo.begin(), - [](unsigned char c){ return std::tolower(c); }); - const char* prefixLoC = prefixLo.c_str(); + const Rust::TWStringWrapper prefixRustStr = prefix; + const Rust::TWStringWrapper result = Rust::tw_mnemonic_suggest(prefixRustStr.get()); + return result.toStringOrDefault(); +} - std::vector result; - for (const char* const* word = mnemonicWordlist(); *word != nullptr; ++word) { - // check first letter match (optimization) - if ((*word)[0] == prefixLo[0]) { - if (strncmp(*word, prefixLoC, prefixLo.length()) == 0) { - // we have a match - result.emplace_back(*word); - if (result.size() >= SuggestMaxCount) { - break; // enough results - } - } - } - } +Data Mnemonic::toSeed(const std::string& mnemonic, const std::string& passphrase) { + const Rust::TWStringWrapper mnemonicRustStr = mnemonic; + const Rust::TWStringWrapper passphraseRustStr = passphrase; + const Rust::TWDataWrapper result = Rust::tw_mnemonic_to_seed(mnemonicRustStr.get(), passphraseRustStr.get()); + return result.toDataOrDefault(); +} - // convert results to one string - std::string resultString; - for (auto& word: result) { - if (resultString.length() > 0) { - resultString += " "; - } - resultString += word; - } - return resultString; +Data Mnemonic::toEntropy(const std::string& mnemonic) { + const Rust::TWStringWrapper mnemonicRustStr = mnemonic; + const Rust::TWDataWrapper result = Rust::tw_mnemonic_to_entropy(mnemonicRustStr.get()); + return result.toDataOrDefault(); } } // namespace TW diff --git a/src/Mnemonic.h b/src/Mnemonic.h index dc6fc4ff2d6..3efb39ad187 100644 --- a/src/Mnemonic.h +++ b/src/Mnemonic.h @@ -4,6 +4,7 @@ #pragma once +#include "Data.h" #include namespace TW { @@ -16,6 +17,10 @@ class Mnemonic { static constexpr int BitsPerWord = 11; // each word encodes this many bits (there are 2^11=2048 different words) public: + static std::string generate(uint32_t strength); + + static std::string generateFromData(const Data& data); + /// Determines whether a BIP39 English mnemonic phrase is valid. // E.g. for a valid mnemonic: "credit expect life fade cover suit response wash pear what skull force" static bool isValid(const std::string& mnemonic); @@ -23,6 +28,8 @@ class Mnemonic { /// Determines whether word is a valid BIP39 English menemonic word. static bool isValidWord(const std::string& word); + static std::string getWord(uint32_t index); + /// Return BIP39 English words that match the given prefix. // - A single string is returned, with space-separated list of words (or single word or empty string) // (Why not array? To simplify the cross-language interfaces) @@ -38,6 +45,10 @@ class Mnemonic { // - 'a'-> 'abandon ability able about above absent absorb abstract absurd abuse' static std::string suggest(const std::string& prefix); + static Data toSeed(const std::string& mnemonic, const std::string& passphrase); + + static Data toEntropy(const std::string& mnemonic); + static const int SuggestMaxCount; }; diff --git a/src/NULS/Address.cpp b/src/NULS/Address.cpp index d71d4279341..5aba91e1cf9 100644 --- a/src/NULS/Address.cpp +++ b/src/NULS/Address.cpp @@ -3,11 +3,13 @@ // Copyright © 2017 Trust Wallet. #include "Address.h" -#include +#include +#include "../Hash.h" #include "../Base58.h" #include "../BinaryCoding.h" #include "../HexCoding.h" +#include "../Utils.h" using namespace TW; @@ -59,7 +61,13 @@ Address::Address(const TW::PublicKey& publicKey, bool isMainnet) { } // Address Type bytes[2] = addressType; - ecdsa_get_pubkeyhash(publicKey.bytes.data(), HASHER_SHA2_RIPEMD, bytes.begin() + 3); + auto data = wrapTWData(TWDataCreateWithBytes(publicKey.bytes.data(), publicKey.bytes.size())); + auto result = wrapTWData(TWECDSAPubkeyHash(data.get(), true, Hash::HasherSha256ripemd)); + if (result == nullptr) { + throw std::invalid_argument("Invalid public key hash"); + } + auto resultData = dataFromTWData(result); + std::copy(resultData.begin(), resultData.end(), bytes.begin() + 3); bytes[23] = checksum(bytes); } diff --git a/src/NULS/Signer.cpp b/src/NULS/Signer.cpp index 51b44385159..6bb550ff52e 100644 --- a/src/NULS/Signer.cpp +++ b/src/NULS/Signer.cpp @@ -3,12 +3,13 @@ // Copyright © 2017 Trust Wallet. #include "Signer.h" -#include #include "Address.h" #include "BinaryCoding.h" #include "../Hash.h" #include "../PrivateKey.h" +#include "../Utils.h" +#include using namespace TW; @@ -196,10 +197,15 @@ Data Signer::buildSignedTx(const std::vector publicKeys, std::copy(publicKeys[i].begin(), publicKeys[i].end(), std::back_inserter(transactionSignature)); - std::array tempSigBytes; - size_t size = ecdsa_sig_to_der(signatures[i].data(), tempSigBytes.data()); + auto sig = wrapTWData(TWDataCreateWithBytes(signatures[i].data(), signatures[i].size())); + auto der = wrapTWData(TWECDSASigToDER(sig.get(), true)); + if (der == nullptr) { + throw std::invalid_argument("Invalid signature"); + } + auto signature = Data{}; - std::copy(tempSigBytes.begin(), tempSigBytes.begin() + size, std::back_inserter(signature)); + auto derData = dataFromTWData(der); + std::copy(derData.begin(), derData.end(), std::back_inserter(signature)); encodeVarInt(signature.size(), transactionSignature); std::copy(signature.begin(), signature.end(), std::back_inserter(transactionSignature)); diff --git a/src/Nano/Address.cpp b/src/Nano/Address.cpp index beb05b919be..c0a3fd4c653 100644 --- a/src/Nano/Address.cpp +++ b/src/Nano/Address.cpp @@ -4,27 +4,69 @@ // Copyright © 2017 Trust Wallet. #include "Address.h" -#include +#include "../Hash.h" +#include "../Base32.h" #include namespace TW::Nano { +static const char* BASE32_ALPHABET_NANO = "13456789abcdefghijkmnopqrstuwxyz"; + +const size_t CHECKSUM_LEN = 5; +const size_t PADDING_LEN = 3; +const size_t ADDRESS_BASE_LENGTH = 60; +const size_t PUBLIC_KEY_LEN = 32; +const size_t RAW_LEN = PADDING_LEN + PUBLIC_KEY_LEN + CHECKSUM_LEN; + const std::string kPrefixNano{"nano_"}; const std::string kPrefixXrb{"xrb_"}; +bool isValidInternal(const std::string& address, const std::string& prefix, uint8_t* publicKey) { + if (address.length() != prefix.length() + ADDRESS_BASE_LENGTH) { + return false; + } + + // Validate that the prefix matches + if (address.substr(0, prefix.length()) != prefix) { + return false; + } + + // Try to decode the address + std::string encoded = "1111" + address.substr(prefix.length()); + + Data raw; + raw.resize(RAW_LEN); + if (!Base32::decode(encoded, raw, BASE32_ALPHABET_NANO)) { + return false; + } + + // Validate the checksum + Data checksum = Hash::blake2b( + Data(raw.begin() + PADDING_LEN, raw.begin() + PADDING_LEN + PUBLIC_KEY_LEN), + CHECKSUM_LEN + ); + + // Compare checksums + for (size_t i = 0; i < CHECKSUM_LEN; i++) { + if (raw[40 - CHECKSUM_LEN + i] != checksum[CHECKSUM_LEN - (i + 1)]) { + return false; + } + } + + if (publicKey != nullptr) { + std::copy(raw.begin() + PADDING_LEN, raw.begin() + PADDING_LEN + 32, publicKey); + } + + return true; +} + bool Address::isValid(const std::string& address) { bool valid = false; - valid = nano_validate_address( - kPrefixNano.c_str(), kPrefixNano.length(), - address.c_str(), address.length(), - nullptr); + valid = isValidInternal(address, kPrefixNano, nullptr); if (!valid) { - valid = nano_validate_address( - kPrefixXrb.c_str(), kPrefixXrb.length(), - address.c_str(), address.length(), - nullptr); + valid = isValidInternal(address, kPrefixXrb, nullptr); } return valid; @@ -33,16 +75,10 @@ bool Address::isValid(const std::string& address) { Address::Address(const std::string& address) { bool valid = false; - valid = nano_validate_address( - kPrefixNano.c_str(), kPrefixNano.length(), - address.c_str(), address.length(), - bytes.data()); + valid = isValidInternal(address, kPrefixNano, bytes.data()); if (!valid) { - valid = nano_validate_address( - kPrefixXrb.c_str(), kPrefixXrb.length(), - address.c_str(), address.length(), - bytes.data()); + valid = isValidInternal(address, kPrefixXrb, bytes.data()); } // Ensure address is valid @@ -61,16 +97,15 @@ Address::Address(const PublicKey& publicKey) { } std::string Address::string() const { - std::array out = {0}; - - size_t count = nano_get_address( - bytes.data(), - kPrefixNano.c_str(), kPrefixNano.length(), - out.data(), out.size()); - // closing \0 - assert(count < out.size()); - out[count] = 0; - return {out.data()}; + Data bytesAsData; + bytesAsData.assign(bytes.begin(), bytes.end()); + auto hash = Hash::blake2b(bytesAsData, CHECKSUM_LEN); + bytesAsData.insert(bytesAsData.begin(), PADDING_LEN, 0); + bytesAsData.insert(bytesAsData.end(), hash.rbegin(), hash.rend()); + + auto result = Base32::encode(bytesAsData, BASE32_ALPHABET_NANO); + result.replace(0, kPrefixNano.length()-1, kPrefixNano); + return result; } } // namespace TW::Nano diff --git a/src/Nervos/Transaction.cpp b/src/Nervos/Transaction.cpp index ca65efa723e..800071110c5 100644 --- a/src/Nervos/Transaction.cpp +++ b/src/Nervos/Transaction.cpp @@ -197,7 +197,7 @@ Common::Proto::SigningError Transaction::signWitnesses(const PrivateKey& private } auto messageHash = Hash::blake2b(message, 32, Constants::gHashPersonalization); - auto signature = privateKey.sign(messageHash, TWCurveSECP256k1); + auto signature = privateKey.sign(messageHash); if (signature.empty()) { // Error: Failed to sign return Common::Proto::Error_signing; diff --git a/src/Nimiq/Address.cpp b/src/Nimiq/Address.cpp index 46ab1bb1f5e..7653cfd03c1 100644 --- a/src/Nimiq/Address.cpp +++ b/src/Nimiq/Address.cpp @@ -5,8 +5,7 @@ #include "Address.h" #include "../Base32.h" - -#include +#include "../Hash.h" #include @@ -87,8 +86,7 @@ Address::Address(const std::vector& data) { } Address::Address(const PublicKey& publicKey) { - auto hash = std::array(); - tc_blake2b(publicKey.bytes.data(), 32, hash.data(), hash.size()); + auto hash = Hash::blake2b(publicKey.bytes.data(), publicKey.bytes.size()); std::copy(hash.begin(), hash.begin() + Address::size, bytes.begin()); } diff --git a/src/Nimiq/Signer.cpp b/src/Nimiq/Signer.cpp index fb4e6b55269..69d31b656c5 100644 --- a/src/Nimiq/Signer.cpp +++ b/src/Nimiq/Signer.cpp @@ -3,7 +3,6 @@ // Copyright © 2017 Trust Wallet. #include "Signer.h" -#include #include @@ -34,7 +33,7 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept { void Signer::sign(const PrivateKey& privateKey, Transaction& transaction) const noexcept { auto preImage = transaction.getPreImage(); - auto signature = privateKey.sign(preImage, TWCurveED25519); + auto signature = privateKey.sign(preImage); std::copy(signature.begin(), signature.end(), transaction.signature.begin()); } diff --git a/src/Ontology/Address.cpp b/src/Ontology/Address.cpp index 6cf098eb111..b2897237a41 100644 --- a/src/Ontology/Address.cpp +++ b/src/Ontology/Address.cpp @@ -7,8 +7,7 @@ #include "ParamsBuilder.h" #include "../Hash.h" - -#include +#include "../Base58.h" #include #include @@ -29,8 +28,7 @@ Address::Address(const std::string& b58Address) { if (!Address::isValid(b58Address)) { throw std::runtime_error("Invalid base58 encode address."); } - Data addressWithVersion(size + 1); - base58_decode_check(b58Address.c_str(), HASHER_SHA2D, addressWithVersion.data(), size + 1); + const auto addressWithVersion = Base58::decodeCheck(b58Address, Rust::Base58Alphabet::Bitcoin, Hash::HasherSha256d); std::copy(addressWithVersion.begin() + 1, addressWithVersion.end(), _data.begin()); } @@ -54,21 +52,16 @@ bool Address::isValid(const std::string& b58Address) noexcept { if (b58Address.length() != 34) { return false; } - Data addressWithVersion(size + 1); - auto len = - base58_decode_check(b58Address.c_str(), HASHER_SHA2D, addressWithVersion.data(), size + 1); - return len == size + 1; + const auto addressWithVersion = + Base58::decodeCheck(b58Address, Rust::Base58Alphabet::Bitcoin, Hash::HasherSha256d); + return addressWithVersion.size() == size + 1; } std::string Address::string() const { std::vector encodeData(size + 1); encodeData[0] = version; std::copy(_data.begin(), _data.end(), encodeData.begin() + 1); - size_t b58StrSize = 34; - std::string b58Str(b58StrSize, ' '); - base58_encode_check(encodeData.data(), (int)encodeData.size(), HASHER_SHA2D, &b58Str[0], - (int)b58StrSize + 1); - return b58Str; + return Base58::encodeCheck(encodeData, Rust::Base58Alphabet::Bitcoin, Hash::HasherSha256d); } } // namespace TW::Ontology diff --git a/src/Ontology/ParamsBuilder.cpp b/src/Ontology/ParamsBuilder.cpp index 7c529aa0080..beed82f2d1f 100644 --- a/src/Ontology/ParamsBuilder.cpp +++ b/src/Ontology/ParamsBuilder.cpp @@ -5,14 +5,13 @@ #include "ParamsBuilder.h" #include "Data.h" #include "OpCode.h" - -#include -#include -#include +#include "../Utils.h" #include #include +#include + namespace TW::Ontology { void ParamsBuilder::buildNeoVmParam(ParamsBuilder& builder, const NeoVmParamValue& param) { @@ -207,14 +206,10 @@ Data ParamsBuilder::fromMultiPubkey(uint8_t m, const std::vector& pubKeys) builder.push(m); auto sortedPubKeys = pubKeys; std::sort(sortedPubKeys.begin(), sortedPubKeys.end(), [](Data& o1, Data& o2) -> int { - curve_point p1, p2; - ecdsa_read_pubkey(&nist256p1, o1.data(), &p1); - ecdsa_read_pubkey(&nist256p1, o2.data(), &p2); - auto result = bn_is_less(&p1.x, &p2.x); - if (result != 0) { - return result; - } - return bn_is_less(&p1.y, &p2.y); + auto pubkey1 = wrapTWData(TWDataCreateWithBytes(o1.data(), o1.size())); + auto pubkey2 = wrapTWData(TWDataCreateWithBytes(o2.data(), o2.size())); + auto result = TWECDSAPubkeyCompare(pubkey1.get(), pubkey2.get(), false); + return result < 0; }); for (auto const& pk : sortedPubKeys) { builder.push(pk); diff --git a/src/Ontology/Signer.cpp b/src/Ontology/Signer.cpp index 48cf1bab857..bb3141bc6eb 100644 --- a/src/Ontology/Signer.cpp +++ b/src/Ontology/Signer.cpp @@ -56,7 +56,7 @@ void Signer::sign(Transaction& tx) const { if (tx.sigVec.size() >= Transaction::sigVecLimit) { throw std::runtime_error("the number of transaction signatures should not be over 16."); } - auto signature = getPrivateKey().sign(tx.txHash(), TWCurveNIST256p1); + auto signature = getPrivateKey().sign(tx.txHash()); signature.pop_back(); tx.sigVec.emplace_back(publicKey, signature, 1); } @@ -65,7 +65,7 @@ void Signer::addSign(Transaction& tx) const { if (tx.sigVec.size() >= Transaction::sigVecLimit) { throw std::runtime_error("the number of transaction signatures should not be over 16."); } - auto signature = getPrivateKey().sign(tx.txHash(), TWCurveNIST256p1); + auto signature = getPrivateKey().sign(tx.txHash()); signature.pop_back(); tx.sigVec.emplace_back(publicKey, signature, 1); } diff --git a/src/PrivateKey.cpp b/src/PrivateKey.cpp index 98e05e500bc..4534cd21b48 100644 --- a/src/PrivateKey.cpp +++ b/src/PrivateKey.cpp @@ -7,52 +7,12 @@ #include "HexCoding.h" #include "PublicKey.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include using namespace TW; -Data rust_get_public_from_private(const Data& key, TWPublicKeyType public_type) { - auto* privkey = Rust::tw_private_key_create_with_data(key.data(), key.size()); - if (privkey == nullptr) { - return {}; - } - Data toReturn; - - auto* pubkey = Rust::tw_private_key_get_public_key_by_type(privkey, static_cast(public_type)); - if (pubkey == nullptr) { - Rust::tw_private_key_delete(privkey); - return {}; - } - - Rust::CByteArrayWrapper res = Rust::tw_public_key_data(pubkey); - - Rust::tw_public_key_delete(pubkey); - Rust::tw_private_key_delete(privkey); - return res.data; -} - -Data rust_private_key_sign(const Data& key, const Data& hash, TWCurve curve) { - auto* priv = Rust::tw_private_key_create_with_data(key.data(), key.size()); - if (priv == nullptr) { - return {}; - } - Rust::CByteArrayWrapper res = Rust::tw_private_key_sign(priv, hash.data(), hash.size(), static_cast(curve)); - Rust::tw_private_key_delete(priv); - return res.data; -} - bool PrivateKey::isValid(const Data& data) { // Check length if (data.size() != _size && data.size() != cardanoKeySize) { @@ -70,39 +30,7 @@ bool PrivateKey::isValid(const Data& data) { } bool PrivateKey::isValid(const Data& data, TWCurve curve) { - // check size - bool valid = isValid(data); - if (!valid) { - return false; - } - - const ecdsa_curve* ec_curve = nullptr; - switch (curve) { - case TWCurveSECP256k1: - ec_curve = &secp256k1; - break; - case TWCurveNIST256p1: - ec_curve = &nist256p1; - break; - case TWCurveED25519: - case TWCurveED25519Blake2bNano: - case TWCurveED25519ExtendedCardano: - case TWCurveCurve25519: - case TWCurveNone: - default: - break; - } - - if (ec_curve != nullptr) { - bignum256 k; - bn_read_be(data.data(), &k); - if (!bn_is_less(&k, &ec_curve->order)) { - memzero(&k, sizeof(k)); - return false; - }; - } - - return true; + return Rust::tw_private_key_is_valid(data.data(), data.size(), static_cast(curve)); } TWPrivateKeyType PrivateKey::getType(TWCurve curve) noexcept { @@ -114,34 +42,17 @@ TWPrivateKeyType PrivateKey::getType(TWCurve curve) noexcept { } } - PrivateKey::PrivateKey(const Data& data) { - if (!isValid(data)) { - throw std::invalid_argument("Invalid private key data"); - } - bytes = data; - } - PrivateKey::PrivateKey(const Data& data, TWCurve curve) { if (!isValid(data, curve)) { throw std::invalid_argument("Invalid private key data"); } bytes = data; _curve = curve; -} - -PrivateKey::PrivateKey( - const Data& key1, const Data& extension1, const Data& chainCode1, - const Data& key2, const Data& extension2, const Data& chainCode2) { - if (key1.size() != _size || extension1.size() != _size || chainCode1.size() != _size || - key2.size() != _size || extension2.size() != _size || chainCode2.size() != _size) { - throw std::invalid_argument("Invalid private key or extended key data"); + auto* privkey = Rust::tw_private_key_create_with_data(data.data(), data.size(), static_cast(curve)); + if (privkey == nullptr) { + throw std::invalid_argument("Invalid private key"); } - bytes = key1; - append(bytes, extension1); - append(bytes, chainCode1); - append(bytes, key2); - append(bytes, extension2); - append(bytes, chainCode2); + _impl = Rust::wrapTWPrivateKey(privkey); } PrivateKey::PrivateKey( @@ -159,211 +70,37 @@ PrivateKey::PrivateKey( append(bytes, extension2); append(bytes, chainCode2); _curve = curve; -} - -PublicKey PrivateKey::getPublicKey(TWPublicKeyType type) const { - Data result; - switch (type) { - case TWPublicKeyTypeSECP256k1: - result.resize(PublicKey::secp256k1Size); - ecdsa_get_public_key33(&secp256k1, key().data(), result.data()); - break; - case TWPublicKeyTypeSECP256k1Extended: - result.resize(PublicKey::secp256k1ExtendedSize); - ecdsa_get_public_key65(&secp256k1, key().data(), result.data()); - break; - case TWPublicKeyTypeNIST256p1: - result.resize(PublicKey::secp256k1Size); - ecdsa_get_public_key33(&nist256p1, key().data(), result.data()); - break; - case TWPublicKeyTypeNIST256p1Extended: - result.resize(PublicKey::secp256k1ExtendedSize); - ecdsa_get_public_key65(&nist256p1, key().data(), result.data()); - break; - case TWPublicKeyTypeED25519: - result.resize(PublicKey::ed25519Size); - ed25519_publickey(key().data(), result.data()); - break; - case TWPublicKeyTypeED25519Blake2b: - result.resize(PublicKey::ed25519Size); - ed25519_publickey_blake2b(key().data(), result.data()); - break; - case TWPublicKeyTypeED25519Cardano: { - // must be double extended key - if (bytes.size() != cardanoKeySize) { - throw std::invalid_argument("Invalid extended key"); - } - Data pubKey(PublicKey::ed25519Size); - - // first key - ed25519_publickey_ext(key().data(), pubKey.data()); - append(result, pubKey); - // copy chainCode - append(result, chainCode()); - - // second key - ed25519_publickey_ext(secondKey().data(), pubKey.data()); - append(result, pubKey); - append(result, secondChainCode()); - } break; - - case TWPublicKeyTypeCURVE25519: { - result.resize(PublicKey::ed25519Size); - PublicKey ed25519PublicKey = getPublicKey(TWPublicKeyTypeED25519); - ed25519_pk_to_curve25519(result.data(), ed25519PublicKey.bytes.data()); - break; - } - - case TWPublicKeyTypeStarkex: { - result = rust_get_public_from_private(this->bytes, type); - break; - } - } - return PublicKey(result, type); -} - -int ecdsa_sign_digest_checked(const ecdsa_curve* curve, const uint8_t* priv_key, const uint8_t* digest, size_t digest_size, uint8_t* sig, uint8_t* pby, int (*is_canonical)(uint8_t by, uint8_t sig[64])) { - if (digest_size < 32) { - return -1; - } - assert(digest_size >= 32); - return ecdsa_sign_digest(curve, priv_key, digest, sig, pby, is_canonical); -} - -Data PrivateKey::sign(const Data& digest, TWCurve curve) const { - if (_curve.has_value() && _curve.value() != curve) { - throw std::invalid_argument("Specified curve is different from the curve of the private key"); - } - Data result; - bool success = false; - switch (curve) { - case TWCurveSECP256k1: { - result.resize(65); - success = ecdsa_sign_digest_checked(&secp256k1, key().data(), digest.data(), digest.size(), result.data(), result.data() + 64, nullptr) == 0; - } break; - case TWCurveED25519: { - result.resize(64); - ed25519_sign(digest.data(), digest.size(), key().data(), result.data()); - success = true; - } break; - case TWCurveED25519Blake2bNano: { - result.resize(64); - ed25519_sign_blake2b(digest.data(), digest.size(), key().data(), result.data()); - success = true; - } break; - case TWCurveED25519ExtendedCardano: { - result.resize(64); - ed25519_sign_ext(digest.data(), digest.size(), key().data(), extension().data(), result.data()); - success = true; - } break; - case TWCurveCurve25519: { - result.resize(64); - const auto publicKey = getPublicKey(TWPublicKeyTypeED25519); - ed25519_sign(digest.data(), digest.size(), key().data(), result.data()); - const auto sign_bit = publicKey.bytes[31] & 0x80; - result[63] = result[63] & 127; - result[63] |= sign_bit; - success = true; - } break; - case TWCurveNIST256p1: { - result.resize(65); - success = ecdsa_sign_digest_checked(&nist256p1, key().data(), digest.data(), digest.size(), result.data(), result.data() + 64, nullptr) == 0; - } break; - case TWCurveStarkex: { - result = rust_private_key_sign(key(), digest, curve); - success = result.size() == 64; - } break; - case TWCurveNone: - default: - break; - } - - if (!success) { - return {}; - } - return result; -} - -Data PrivateKey::sign(const Data& digest, int (*canonicalChecker)(uint8_t by, uint8_t sig[64])) const { - if (!_curve.has_value()) { - throw std::invalid_argument("Curve is not set"); + auto* privkey = Rust::tw_private_key_create_with_data(bytes.data(), bytes.size(), static_cast(curve)); + if (privkey == nullptr) { + throw std::invalid_argument("Invalid private key"); } - return sign(digest, _curve.value(), canonicalChecker); + _impl = Rust::wrapTWPrivateKey(privkey); } -Data PrivateKey::sign(const Data& digest, TWCurve curve, int (*canonicalChecker)(uint8_t by, uint8_t sig[64])) const { - if (_curve.has_value() && _curve.value() != curve) { - throw std::invalid_argument("Specified curve is different from the curve of the private key"); - } - Data result; - bool success = false; - switch (curve) { - case TWCurveSECP256k1: { - result.resize(65); - success = ecdsa_sign_digest_checked(&secp256k1, key().data(), digest.data(), digest.size(), result.data() + 1, result.data(), canonicalChecker) == 0; - } break; - case TWCurveED25519: // not supported - case TWCurveED25519Blake2bNano: // not supported - case TWCurveED25519ExtendedCardano: // not supported - case TWCurveCurve25519: // not supported - break; - case TWCurveNIST256p1: { - result.resize(65); - success = ecdsa_sign_digest_checked(&nist256p1, key().data(), digest.data(), digest.size(), result.data() + 1, result.data(), canonicalChecker) == 0; - } break; - case TWCurveNone: - default: - break; - } - - if (!success) { - return {}; +PublicKey PrivateKey::getPublicKey(TWPublicKeyType type) const { + auto* pubkey = Rust::tw_private_key_get_public_key_by_type(_impl.get(), static_cast(type)); + if (pubkey == nullptr) { + return PublicKey(Data(), type); } - - // graphene adds 31 to the recovery id - result[0] += 31; - return result; + return PublicKey(Rust::wrapTWPublicKey(pubkey)); } Data PrivateKey::sign(const Data& digest) const { - if (!_curve.has_value()) { - throw std::invalid_argument("Curve is not set"); - } - return sign(digest, _curve.value()); + Rust::CByteArrayWrapper res = Rust::tw_private_key_sign(_impl.get(), digest.data(), digest.size()); + return res.data; } -Data PrivateKey::signAsDER(const Data& digest) const { - if (_curve.has_value() && _curve.value() != TWCurveSECP256k1) { - throw std::invalid_argument("DER signature is only supported for SECP256k1"); - } - Data sig(64); - bool success = - ecdsa_sign_digest(&secp256k1, key().data(), digest.data(), sig.data(), nullptr, nullptr) == 0; - if (!success) { - return {}; - } - - Data resultBytes(72); - size_t size = ecdsa_sig_to_der(sig.data(), resultBytes.data()); - - auto result = Data{}; - std::copy(resultBytes.begin(), resultBytes.begin() + size, std::back_inserter(result)); - return result; +Data PrivateKey::sign(const Data& digest, int (*canonicalChecker)(uint8_t by, const uint8_t sig[64])) const { + Rust::CByteArrayWrapper res = Rust::tw_private_key_sign_canonical(_impl.get(), digest.data(), digest.size(), canonicalChecker); + return res.data; } -Data PrivateKey::signZilliqa(const Data& message) const { - if (_curve.has_value() && _curve.value() != TWCurveSECP256k1) { - throw std::invalid_argument("Zilliqa signature is only supported for SECP256k1"); - } - Data sig(64); - bool success = zil_schnorr_sign(&secp256k1, key().data(), message.data(), static_cast(message.size()), sig.data()) == 0; - - if (!success) { - return {}; - } - return sig; +Data PrivateKey::signAsDER(const Data& digest) const { + Rust::CByteArrayWrapper res = Rust::tw_private_key_sign_as_der(_impl.get(), digest.data(), digest.size()); + return res.data; } void PrivateKey::cleanup() { memzero(bytes.data(), bytes.size()); + _impl = nullptr; } diff --git a/src/PrivateKey.h b/src/PrivateKey.h index ba0e5ebcff9..34f6a07d469 100644 --- a/src/PrivateKey.h +++ b/src/PrivateKey.h @@ -43,29 +43,15 @@ class PrivateKey { // obtain private key type used by the curve/coin static TWPrivateKeyType getType(TWCurve curve) noexcept; - /// Initializes a private key with an array of bytes. Size must be exact (normally 32, or 192 for extended) - /// @deprecated Use PrivateKey(const Data& data, TWCurve curve) instead - explicit PrivateKey(const Data& data); - /// Initializes a private key with an array of bytes and a curve. /// Size of the data must be exact (normally 32, or 192 for extended) /// Signing functions will throw an exception if the provided curve is different from the one specified. explicit PrivateKey(const Data& data, TWCurve curve); - /// Initializes a private key from a string of bytes. - /// @deprecated Use PrivateKey(const std::string& data, TWCurve curve) instead - explicit PrivateKey(const std::string& data) : PrivateKey(TW::data(data)) {} - /// Initializes a private key from a string of bytes and a curve. /// Signing functions will throw an exception if the provided curve is different from the one specified. explicit PrivateKey(const std::string& data, TWCurve curve) : PrivateKey(TW::data(data), curve) {} - /// Initializes a Cardano style key - /// @deprecated Use PrivateKey(const Data& bytes1, const Data& extension1, const Data& chainCode1, const Data& bytes2, const Data& extension2, const Data& chainCode2, TWCurve curve) instead - explicit PrivateKey( - const Data& bytes1, const Data& extension1, const Data& chainCode1, - const Data& bytes2, const Data& extension2, const Data& chainCode2); - /// Initializes a Cardano style key with a specified curve. /// Signing functions will throw an exception if the provided curve is different from the one specified. explicit PrivateKey( @@ -84,38 +70,27 @@ class PrivateKey { /// Returns the public key for this private key. PublicKey getPublicKey(enum TWPublicKeyType type) const; - /// Signs a digest using the given ECDSA curve. - /// If constructed with a curve, an exception will be thrown if the curve does not match the one specified. - /// @deprecated Use sign(const Data& digest) instead - Data sign(const Data& digest, TWCurve curve) const; - /// Signs a digest using the given ECDSA curve at the time of construction. /// IF constructed without a curve, an exception will be thrown. Data sign(const Data& digest) const; /// Signs a digest using the given ECDSA curve and prepends the recovery id (a la graphene) /// Only a sig that passes canonicalChecker is returned - /// If constructed with a curve, an exception will be thrown if the curve does not match the one specified. - /// @deprecated Use sign(const Data& digest, int(*canonicalChecker)(uint8_t by, uint8_t sig[64])) instead - Data sign(const Data& digest, TWCurve curve, int(*canonicalChecker)(uint8_t by, uint8_t sig[64])) const; - - /// Signs a digest using the given ECDSA curve and prepends the recovery id (a la graphene) - /// Only a sig that passes canonicalChecker is returned - Data sign(const Data& digest, int (*canonicalChecker)(uint8_t by, uint8_t sig[64])) const; + Data sign(const Data& digest, int (*canonicalChecker)(uint8_t by, const uint8_t sig[64])) const; /// Signs a digest using the given ECDSA curve. The result is encoded with /// DER. /// If constructed with a curve, an exception will be thrown if the curve does not match SECP256k1. Data signAsDER(const Data& digest) const; - /// Signs a digest using given ECDSA curve, returns Zilliqa schnorr signature - /// If constructed with a curve, an exception will be thrown if the curve does not match SECP256k1. - Data signZilliqa(const Data& message) const; - /// Cleanup contents (fill with 0s), called before destruction void cleanup(); + + /// Returns the curve used by the private key. + TWCurve curve() const { return _curve; } private: - std::optional _curve = std::nullopt; + TWCurve _curve; + std::shared_ptr _impl; }; } // namespace TW diff --git a/src/PublicKey.cpp b/src/PublicKey.cpp index d9789e6bc06..5ebb3a604cc 100644 --- a/src/PublicKey.cpp +++ b/src/PublicKey.cpp @@ -6,15 +6,9 @@ #include "PrivateKey.h" #include "Data.h" #include "rust/bindgen/WalletCoreRSBindgen.h" +#include "rust/Wrapper.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "memzero.h" #include @@ -23,29 +17,7 @@ namespace TW { /// Determines if a collection of bytes makes a valid public key of the /// given type. bool PublicKey::isValid(const Data& data, enum TWPublicKeyType type) { - const auto size = data.size(); - if (size == 0) { - return false; - } - switch (type) { - case TWPublicKeyTypeED25519: - return size == ed25519Size || (size == ed25519Size + 1 && data[0] == 0x01); - case TWPublicKeyTypeCURVE25519: - case TWPublicKeyTypeED25519Blake2b: - return size == ed25519Size; - case TWPublicKeyTypeED25519Cardano: - return size == cardanoKeySize; - case TWPublicKeyTypeSECP256k1: - case TWPublicKeyTypeNIST256p1: - return size == secp256k1Size && (data[0] == 0x02 || data[0] == 0x03); - case TWPublicKeyTypeSECP256k1Extended: - case TWPublicKeyTypeNIST256p1Extended: - return size == secp256k1ExtendedSize && data[0] == 0x04; - case TWPublicKeyTypeStarkex: - return size == starkexSize; - default: - return false; - } + return Rust::tw_public_key_is_valid(data.data(), data.size(), static_cast(type)); } /// Initializes a public key with a collection of bytes. @@ -56,79 +28,36 @@ PublicKey::PublicKey(const Data& data, enum TWPublicKeyType type) if (!isValid(data, type)) { throw std::invalid_argument("Invalid public key data"); } - switch (type) { - case TWPublicKeyTypeStarkex: - case TWPublicKeyTypeSECP256k1: - case TWPublicKeyTypeNIST256p1: - case TWPublicKeyTypeSECP256k1Extended: - case TWPublicKeyTypeNIST256p1Extended: - bytes.reserve(data.size()); - std::copy(std::begin(data), std::end(data), std::back_inserter(bytes)); - break; - - case TWPublicKeyTypeED25519: - case TWPublicKeyTypeCURVE25519: - bytes.reserve(ed25519Size); - if (data.size() == ed25519Size + 1) { - std::copy(std::begin(data) + 1, std::end(data), std::back_inserter(bytes)); - } else { - std::copy(std::begin(data), std::end(data), std::back_inserter(bytes)); - } - break; - case TWPublicKeyTypeED25519Blake2b: - bytes.reserve(ed25519Size); - assert(data.size() == ed25519Size); // ensured by isValid() above - std::copy(std::begin(data), std::end(data), std::back_inserter(bytes)); - break; - case TWPublicKeyTypeED25519Cardano: - bytes.reserve(cardanoKeySize); - std::copy(std::begin(data), std::end(data), std::back_inserter(bytes)); + auto* pubkey = Rust::tw_public_key_create_with_data(data.data(), data.size(), static_cast(type)); + if (pubkey == nullptr) { + throw std::invalid_argument("Invalid public key"); } + _impl = Rust::wrapTWPublicKey(pubkey); + Rust::CByteArrayWrapper pubkeyData = Rust::tw_public_key_data(_impl.get()); + bytes = pubkeyData.data; +} + +PublicKey::PublicKey(std::shared_ptr _impl) + : _impl(_impl) { + Rust::CByteArrayWrapper pubkeyData = Rust::tw_public_key_data(_impl.get()); + bytes = pubkeyData.data; + type = static_cast(Rust::tw_public_key_type(_impl.get())); } PublicKey PublicKey::compressed() const { - if (type != TWPublicKeyTypeSECP256k1Extended && type != TWPublicKeyTypeNIST256p1Extended) { + auto compressedPubKey = Rust::tw_public_key_compressed(_impl.get()); + if (compressedPubKey == nullptr) { return *this; } - - Data newBytes(secp256k1Size); - assert(bytes.size() >= 65); - newBytes[0] = 0x02 | (bytes[64] & 0x01); - - assert(type == TWPublicKeyTypeSECP256k1Extended || type == TWPublicKeyTypeNIST256p1Extended); - switch (type) { - case TWPublicKeyTypeSECP256k1Extended: - std::copy(bytes.begin() + 1, bytes.begin() + secp256k1Size, newBytes.begin() + 1); - return PublicKey(newBytes, TWPublicKeyTypeSECP256k1); - - case TWPublicKeyTypeNIST256p1Extended: - default: - std::copy(bytes.begin() + 1, bytes.begin() + secp256k1Size, newBytes.begin() + 1); - return PublicKey(newBytes, TWPublicKeyTypeNIST256p1); - } + return PublicKey(Rust::wrapTWPublicKey(compressedPubKey)); } PublicKey PublicKey::extended() const { - Data newBytes(secp256k1ExtendedSize); - switch (type) { - case TWPublicKeyTypeSECP256k1: - ecdsa_uncompress_pubkey(&secp256k1, bytes.data(), newBytes.data()); - return PublicKey(newBytes, TWPublicKeyTypeSECP256k1Extended); - case TWPublicKeyTypeSECP256k1Extended: - return *this; - case TWPublicKeyTypeNIST256p1: - ecdsa_uncompress_pubkey(&nist256p1, bytes.data(), newBytes.data()); - return PublicKey(newBytes, TWPublicKeyTypeNIST256p1Extended); - case TWPublicKeyTypeNIST256p1Extended: - return *this; - case TWPublicKeyTypeED25519: - case TWPublicKeyTypeCURVE25519: - case TWPublicKeyTypeED25519Blake2b: - case TWPublicKeyTypeED25519Cardano: - return *this; - default: + auto extendedPubKey = Rust::tw_public_key_extended(_impl.get()); + if (extendedPubKey == nullptr) { return *this; } + return PublicKey(Rust::wrapTWPublicKey(extendedPubKey)); } bool rust_public_key_verify(const Data& key, TWPublicKeyType type, const Data& sig, const Data& msgHash) { @@ -142,73 +71,11 @@ bool rust_public_key_verify(const Data& key, TWPublicKeyType type, const Data& s } bool PublicKey::verify(const Data& signature, const Data& message) const { - switch (type) { - case TWPublicKeyTypeSECP256k1: - case TWPublicKeyTypeSECP256k1Extended: - return ecdsa_verify_digest(&secp256k1, bytes.data(), signature.data(), message.data()) == 0; - case TWPublicKeyTypeNIST256p1: - case TWPublicKeyTypeNIST256p1Extended: - return ecdsa_verify_digest(&nist256p1, bytes.data(), signature.data(), message.data()) == 0; - case TWPublicKeyTypeED25519: - return ed25519_sign_open(message.data(), message.size(), bytes.data(), signature.data()) == 0; - case TWPublicKeyTypeED25519Blake2b: - return ed25519_sign_open_blake2b(message.data(), message.size(), bytes.data(), signature.data()) == 0; - case TWPublicKeyTypeED25519Cardano: { - const auto key = subData(bytes, 0, ed25519Size); - return ed25519_sign_open(message.data(), message.size(), key.data(), signature.data()) == 0; - } - case TWPublicKeyTypeCURVE25519: { - auto ed25519PublicKey = Data(); - ed25519PublicKey.resize(PublicKey::ed25519Size); - curve25519_pk_to_ed25519(ed25519PublicKey.data(), bytes.data()); - - ed25519PublicKey[31] &= 0x7F; - ed25519PublicKey[31] |= signature[63] & 0x80; - - // remove sign bit - auto verifyBuffer = Data(); - append(verifyBuffer, signature); - verifyBuffer[63] &= 127; - return ed25519_sign_open(message.data(), message.size(), ed25519PublicKey.data(), verifyBuffer.data()) == 0; - } - case TWPublicKeyTypeStarkex: - return rust_public_key_verify(bytes, type, signature, message); - default: - throw std::logic_error("Not yet implemented"); - } + return Rust::tw_public_key_verify(_impl.get(), signature.data(), signature.size(), message.data(), message.size()); } bool PublicKey::verifyAsDER(const Data& signature, const Data& message) const { - switch (type) { - case TWPublicKeyTypeSECP256k1: - case TWPublicKeyTypeSECP256k1Extended: { - Data sig(64); - int ret = ecdsa_sig_from_der(signature.data(), signature.size(), sig.data()); - if (ret) { - return false; - } - return ecdsa_verify_digest(&secp256k1, bytes.data(), sig.data(), message.data()) == 0; - } - - default: - return false; - } -} - -bool PublicKey::verifyZilliqa(const Data& signature, const Data& message) const { - switch (type) { - case TWPublicKeyTypeSECP256k1: - case TWPublicKeyTypeSECP256k1Extended: - return zil_schnorr_verify(&secp256k1, bytes.data(), signature.data(), message.data(), static_cast(message.size())) == 0; - case TWPublicKeyTypeNIST256p1: - case TWPublicKeyTypeNIST256p1Extended: - case TWPublicKeyTypeED25519: - case TWPublicKeyTypeED25519Blake2b: - case TWPublicKeyTypeED25519Cardano: - case TWPublicKeyTypeCURVE25519: - default: - return false; - } + return Rust::tw_public_key_verify_as_der(_impl.get(), signature.data(), signature.size(), message.data(), message.size()); } Data PublicKey::hash(const Data& prefix, Hash::Hasher hasher, bool skipTypeByte) const { @@ -223,20 +90,11 @@ Data PublicKey::hash(const Data& prefix, Hash::Hasher hasher, bool skipTypeByte) } PublicKey PublicKey::recoverRaw(const Data& signatureRS, byte recId, const Data& messageDigest) { - if (signatureRS.size() < 2 * PrivateKey::_size) { - throw std::invalid_argument("signature too short"); - } - if (recId >= 4) { - throw std::invalid_argument("Invalid recId (>=4)"); - } - if (messageDigest.size() < PrivateKey::_size) { - throw std::invalid_argument("digest too short"); - } - TW::Data result(secp256k1SignatureSize); - if (auto ret = ecdsa_recover_pub_from_sig(&secp256k1, result.data(), signatureRS.data(), messageDigest.data(), recId); ret != 0) { - throw std::invalid_argument("recover failed " + std::to_string(ret)); + auto* pubkey = Rust::tw_public_key_recover_from_signature(signatureRS.data(), signatureRS.size(), messageDigest.data(), messageDigest.size(), recId); + if (pubkey == nullptr) { + throw std::invalid_argument("Recover failed"); } - return PublicKey(result, TWPublicKeyTypeSECP256k1Extended); + return PublicKey(Rust::wrapTWPublicKey(pubkey)); } PublicKey PublicKey::recover(const Data& signature, const Data& messageDigest) { @@ -255,9 +113,12 @@ bool PublicKey::isValidED25519() const { if (type != TWPublicKeyTypeED25519) { return false; } - assert(bytes.size() == ed25519Size); - ge25519 r; - return ge25519_unpack_negative_vartime(&r, bytes.data()) != 0; + return _impl != nullptr; +} + +void PublicKey::cleanup() { + memzero(bytes.data(), bytes.size()); + _impl = nullptr; } } // namespace TW diff --git a/src/PublicKey.h b/src/PublicKey.h index 6a1e3d17855..5304d614d45 100644 --- a/src/PublicKey.h +++ b/src/PublicKey.h @@ -8,6 +8,7 @@ #include "Hash.h" #include +#include "rust/Wrapper.h" #include #include @@ -55,6 +56,11 @@ class PublicKey { /// \throws std::invalid_argument if the data is not a valid public key. explicit PublicKey(const Data& data, enum TWPublicKeyType type); + /// Initializes a public key with a Rust implementation. + explicit PublicKey(std::shared_ptr impl); + + virtual ~PublicKey() { cleanup(); } + /// Determines if this is a compressed public key. bool isCompressed() const { return type != TWPublicKeyTypeSECP256k1Extended && type != TWPublicKeyTypeNIST256p1Extended; @@ -71,10 +77,7 @@ class PublicKey { /// Verifies a signature in DER format. bool verifyAsDER(const Data& signature, const Data& message) const; - - /// Verifies a Zilliqa schnorr signature for the provided message. - bool verifyZilliqa(const Data& signature, const Data& message) const; - + /// Computes the public key hash. /// /// The public key hash is computed by applying the hasher to the public key @@ -97,6 +100,11 @@ class PublicKey { /// Check if this key makes a valid ED25519 key (it is on the curve) bool isValidED25519() const; + + /// Cleanup contents (fill with 0s), called before destruction + void cleanup(); +private: + std::shared_ptr _impl; }; inline bool operator==(const PublicKey& lhs, const PublicKey& rhs) { diff --git a/src/StarkEx/MessageSigner.cpp b/src/StarkEx/MessageSigner.cpp index 967bc0bf7e0..02257e76d55 100644 --- a/src/StarkEx/MessageSigner.cpp +++ b/src/StarkEx/MessageSigner.cpp @@ -9,7 +9,7 @@ namespace TW::StarkEx { std::string MessageSigner::signMessage(const TW::PrivateKey& privateKey, const std::string& message) { auto digest = parse_hex(message, true); - return hex(privateKey.sign(digest, TWCurveStarkex)); + return hex(privateKey.sign(digest)); } bool MessageSigner::verifyMessage(const PublicKey& publicKey, const std::string& message, const std::string& signature) noexcept { diff --git a/src/Stellar/Address.cpp b/src/Stellar/Address.cpp index dbf2261388e..fab5894328f 100644 --- a/src/Stellar/Address.cpp +++ b/src/Stellar/Address.cpp @@ -7,7 +7,7 @@ #include "../Base32.h" #include "../HexCoding.h" -#include +#include"memzero.h" #include #include diff --git a/src/Tezos/Address.cpp b/src/Tezos/Address.cpp index f079b45ce96..0a630451320 100644 --- a/src/Tezos/Address.cpp +++ b/src/Tezos/Address.cpp @@ -11,8 +11,6 @@ #include "../Hash.h" #include "../HexCoding.h" -#include - namespace TW::Tezos { /// Address prefixes. diff --git a/src/Tezos/BinaryCoding.cpp b/src/Tezos/BinaryCoding.cpp index 6be3edd6442..8b13242a76d 100644 --- a/src/Tezos/BinaryCoding.cpp +++ b/src/Tezos/BinaryCoding.cpp @@ -8,7 +8,6 @@ #include "../PublicKey.h" #include "../PrivateKey.h" -#include #include namespace TW::Tezos { diff --git a/src/Tezos/MessageSigner.cpp b/src/Tezos/MessageSigner.cpp index 25234f170ed..fc687d7b1d8 100644 --- a/src/Tezos/MessageSigner.cpp +++ b/src/Tezos/MessageSigner.cpp @@ -38,7 +38,7 @@ std::string MessageSigner::formatMessage(const std::string& message, const std:: } std::string MessageSigner::signMessage(const PrivateKey& privateKey, const std::string& message) { - auto signature = privateKey.sign(Hash::blake2b(parse_hex(message), 32), TWCurveED25519); + auto signature = privateKey.sign(Hash::blake2b(parse_hex(message), 32)); return Base58::encodeCheck(concat(gEdSigPrefix, signature)); } diff --git a/src/Tron/MessageSigner.cpp b/src/Tron/MessageSigner.cpp index 32af140daf0..41411fb8390 100644 --- a/src/Tron/MessageSigner.cpp +++ b/src/Tron/MessageSigner.cpp @@ -21,7 +21,7 @@ Data generateMessage(const std::string& message) { std::string MessageSigner::signMessage(const PrivateKey& privateKey, const std::string& message) { auto signableMessage = generateMessage(message); - auto data = privateKey.sign(signableMessage, TWCurveSECP256k1); + auto data = privateKey.sign(signableMessage); data[64] += 27; return hex(data); } diff --git a/src/Utils.h b/src/Utils.h new file mode 100644 index 00000000000..2d74f9e67a2 --- /dev/null +++ b/src/Utils.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#pragma once + +#include +#include +#include "Data.h" + +inline std::shared_ptr wrapTWData(TWData* data) { + return std::shared_ptr(data, TWDataDelete); +} + +inline TW::Data dataFromTWData(const std::shared_ptr& data) { + return TW::Data(TWDataBytes(data.get()), TWDataBytes(data.get()) + TWDataSize(data.get())); +} diff --git a/src/Zilliqa/Signer.cpp b/src/Zilliqa/Signer.cpp index 6db4930d251..cb6c295fb28 100644 --- a/src/Zilliqa/Signer.cpp +++ b/src/Zilliqa/Signer.cpp @@ -91,9 +91,9 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept { auto output = Proto::SigningOutput(); Address address; const auto preImage = Signer::getPreImage(input, address); - const auto key = PrivateKey(Data(input.private_key().begin(), input.private_key().end()), TWCurveSECP256k1); - const auto pubKey = key.getPublicKey(TWPublicKeyTypeSECP256k1); - const auto signature = key.signZilliqa(preImage); + const auto key = PrivateKey(Data(input.private_key().begin(), input.private_key().end()), TWCurveZILLIQASchnorr); + const auto pubKey = key.getPublicKey(TWPublicKeyTypeZILLIQASchnorr); + const auto signature = key.sign(preImage); const auto transaction = input.transaction(); // build json diff --git a/trezor-crypto/crypto/cash_addr.c b/src/cash_addr.cpp similarity index 94% rename from trezor-crypto/crypto/cash_addr.c rename to src/cash_addr.cpp index 271f556678d..502fb967e9b 100644 --- a/trezor-crypto/crypto/cash_addr.c +++ b/src/cash_addr.cpp @@ -19,11 +19,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include -#include -#include - -#include +#include +#include +#include +#include +#include "cash_addr.h" #define MAX_CASHADDR_SIZE 129 #define MAX_BASE32_SIZE 104 @@ -32,7 +32,7 @@ #define CHECKSUM_SIZE 8 uint64_t cashaddr_polymod_step(uint64_t pre) { - uint8_t b = pre >> 35; + uint8_t b = (uint8_t)(pre >> 35); return ((pre & 0x7FFFFFFFFULL) << 5) ^ (-((b >> 0) & 1) & 0x98f2bc8e61ULL) ^ (-((b >> 1) & 1) & 0x79b76d99e2ULL) ^ (-((b >> 2) & 1) & 0xf33e5fb3c4ULL) ^ @@ -60,7 +60,7 @@ int cash_encode(char* output, const char* hrp, const uint8_t* data, if (ch < 33 || ch > 126) { return 0; } - *(output++) = ch; + *(output++) = (char)ch; chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); ++i; } @@ -88,7 +88,7 @@ int cash_encode(char* output, const char* hrp, const uint8_t* data, int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) { uint64_t chk = 1; size_t i = 0; - size_t input_len = strlen(input); + size_t input_len = std::string(input).size(); size_t hrp_len = 0; int have_lower = 0, have_upper = 0; if (input_len < CHECKSUM_SIZE || input_len > MAX_CASHADDR_SIZE) { @@ -117,7 +117,7 @@ int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) { have_upper = 1; ch = (ch - 'A') + 'a'; } - hrp[i] = ch; + hrp[i] = (char)ch; chk = cashaddr_polymod_step(chk) ^ (ch & 0x1f); } hrp[i] = 0; @@ -132,7 +132,7 @@ int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) { } chk = cashaddr_polymod_step(chk) ^ v; if (i + CHECKSUM_SIZE < input_len) { - data[i - (1 + hrp_len)] = v; + data[i - (1 + hrp_len)] = (uint8_t)v; } ++i; } @@ -152,12 +152,12 @@ static int convert_bits(uint8_t* out, size_t* outlen, int outbits, bits += inbits; while (bits >= outbits) { bits -= outbits; - out[(*outlen)++] = (val >> bits) & maxv; + out[(*outlen)++] = (uint8_t)((val >> bits) & maxv); } } if (pad) { if (bits) { - out[(*outlen)++] = (val << (outbits - bits)) & maxv; + out[(*outlen)++] = (uint8_t)((val << (outbits - bits)) & maxv); } } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { return 0; diff --git a/trezor-crypto/include/TrezorCrypto/cash_addr.h b/src/cash_addr.h similarity index 100% rename from trezor-crypto/include/TrezorCrypto/cash_addr.h rename to src/cash_addr.h diff --git a/src/interface/TWAES.cpp b/src/interface/TWAES.cpp deleted file mode 100644 index 7b63e735015..00000000000 --- a/src/interface/TWAES.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include - -#include <../../src/Encrypt.h> - -using namespace TW; - -TWData *_Nullable TWAESEncryptCBC(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv, enum TWAESPaddingMode mode) { - try { - Data encrypted = Encrypt::AESCBCEncrypt(*((Data*)key), *((Data*)data), *((Data*)iv), mode); - return TWDataCreateWithData(&encrypted); - } catch (...) { - return nullptr; - } -} - -TWData *_Nullable TWAESDecryptCBC(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv, enum TWAESPaddingMode mode) { - try { - Data decrypted = Encrypt::AESCBCDecrypt(*((Data*)key), *((Data*)data), *((Data*)iv), mode); - return TWDataCreateWithData(&decrypted); - } catch (...) { - return nullptr; - } -} - -TWData *_Nullable TWAESEncryptCTR(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv) { - try { - Data encrypted = Encrypt::AESCTREncrypt(*((Data*)key), *((Data*)data), *((Data*)iv)); - return TWDataCreateWithData(&encrypted); - } catch (...) { - return nullptr; - } -} - -TWData *_Nullable TWAESDecryptCTR(TWData *_Nonnull key, TWData *_Nonnull data, TWData *_Nonnull iv) { - try { - Data decrypted = Encrypt::AESCTRDecrypt(*((Data*)key), *((Data*)data), *((Data*)iv)); - return TWDataCreateWithData(&decrypted); - } catch (...) { - return nullptr; - } -} diff --git a/src/interface/TWBitcoinAddress.cpp b/src/interface/TWBitcoinAddress.cpp index e81dd75a32d..48831a5983f 100644 --- a/src/interface/TWBitcoinAddress.cpp +++ b/src/interface/TWBitcoinAddress.cpp @@ -5,7 +5,6 @@ #include "../Base58.h" #include "../Bitcoin/Address.h" -#include #include #include diff --git a/src/interface/TWHDWallet.cpp b/src/interface/TWHDWallet.cpp index bce0e819a6b..da690924693 100644 --- a/src/interface/TWHDWallet.cpp +++ b/src/interface/TWHDWallet.cpp @@ -60,7 +60,10 @@ TWData *_Nonnull TWHDWalletEntropy(struct TWHDWallet *_Nonnull wallet) { return TWDataCreateWithBytes(wallet->impl.getEntropy().data(), wallet->impl.getEntropy().size()); } -struct TWPrivateKey *_Nonnull TWHDWalletGetMasterKey(struct TWHDWallet *_Nonnull wallet, TWCurve curve) { +struct TWPrivateKey *_Nullable TWHDWalletGetMasterKey(struct TWHDWallet *_Nonnull wallet, TWCurve curve) { + if (curve == TWCurveED25519ExtendedCardano) { + return nullptr; + } return new TWPrivateKey{ wallet->impl.getMasterKey(curve) }; } diff --git a/src/interface/TWHash.cpp b/src/interface/TWHash.cpp index a6a5528627d..b2e33318f1d 100644 --- a/src/interface/TWHash.cpp +++ b/src/interface/TWHash.cpp @@ -7,10 +7,6 @@ #include "Data.h" #include "BinaryCoding.h" -#include -#include -#include -#include #include @@ -82,13 +78,10 @@ TWData* _Nonnull TWHashSHA256SHA256(TWData* _Nonnull data) { } TWData *_Nonnull TWHashBlake2bPersonal(TWData *_Nonnull data, TWData * _Nonnull personal, size_t outlen) { - auto resultBytes = TW::Data(outlen); - auto dataBytes = TWDataBytes(data); auto personalBytes = TWDataBytes(personal); auto personalSize = TWDataSize(personal); - tc_blake2b_Personal(dataBytes, static_cast(TWDataSize(data)), personalBytes, personalSize, resultBytes.data(), outlen); - auto result = TWDataCreateWithBytes(resultBytes.data(), outlen); - return result; + const auto result = Hash::blake2b(reinterpret_cast(TWDataBytes(data)), TWDataSize(data), outlen, Data(personalBytes, personalBytes + personalSize)); + return TWDataCreateWithBytes(result.data(), result.size()); } TWData* _Nonnull TWHashSHA256RIPEMD(TWData* _Nonnull data) { diff --git a/src/interface/TWMnemonic.cpp b/src/interface/TWMnemonic.cpp deleted file mode 100644 index e5694b3c9a4..00000000000 --- a/src/interface/TWMnemonic.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include - -#include "../Mnemonic.h" - -using namespace TW; - -bool TWMnemonicIsValid(TWString *_Nonnull mnemonic) { - return Mnemonic::isValid(TWStringUTF8Bytes(mnemonic)); -} - -bool TWMnemonicIsValidWord(TWString *_Nonnull word) { - return Mnemonic::isValidWord(TWStringUTF8Bytes(word)); -} - -TWString* _Nonnull TWMnemonicSuggest(TWString *_Nonnull prefix) { - auto result = Mnemonic::suggest(std::string(TWStringUTF8Bytes(prefix))); - return TWStringCreateWithUTF8Bytes(result.c_str()); -} diff --git a/src/interface/TWPBKDF2.cpp b/src/interface/TWPBKDF2.cpp deleted file mode 100644 index 3fae3225482..00000000000 --- a/src/interface/TWPBKDF2.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include -#include -#include - -#include "Data.h" - -using namespace TW; - -TWData* _Nullable TWPBKDF2HmacSha256(TWData* _Nonnull password, TWData* _Nonnull salt, - uint32_t iterations, uint32_t dkLen) { - - Data key(dkLen); - int passLen = static_cast(TWDataSize(password)); - int saltLen = static_cast(TWDataSize(salt)); - pbkdf2_hmac_sha256( - TWDataBytes(password), - passLen, - TWDataBytes(salt), - saltLen, - iterations, - key.data(), - dkLen - ); - return TWDataCreateWithData(&key); -} - -TWData* _Nullable TWPBKDF2HmacSha512(TWData* _Nonnull password, TWData* _Nonnull salt, - uint32_t iterations, uint32_t dkLen) { - Data key(dkLen); - int passLen = static_cast(TWDataSize(password)); - int saltLen = static_cast(TWDataSize(salt)); - pbkdf2_hmac_sha512( - TWDataBytes(password), - passLen, - TWDataBytes(salt), - saltLen, - iterations, - key.data(), - dkLen - ); - return TWDataCreateWithData(&key); -} diff --git a/src/interface/TWPrivateKey.cpp b/src/interface/TWPrivateKey.cpp index 37483dca65d..26eb71a92f3 100644 --- a/src/interface/TWPrivateKey.cpp +++ b/src/interface/TWPrivateKey.cpp @@ -2,12 +2,10 @@ // // Copyright © 2017 Trust Wallet. +#include "rand.h" #include "../PrivateKey.h" #include "../PublicKey.h" -#include -#include -#include #include #include @@ -15,10 +13,10 @@ using namespace TW; -struct TWPrivateKey *TWPrivateKeyCreate() { +struct TWPrivateKey *TWPrivateKeyCreate(enum TWCurve curve) { Data bytes(PrivateKey::_size); random_buffer(bytes.data(), PrivateKey::_size); - if (!PrivateKey::isValid(bytes)) { + if (!PrivateKey::isValid(bytes, curve)) { // Under no circumstance return an invalid private key. We'd rather // crash. This also captures cases where the random generator fails // since we initialize the array to zeros, which is an invalid private @@ -26,21 +24,21 @@ struct TWPrivateKey *TWPrivateKeyCreate() { std::terminate(); } - return new TWPrivateKey{ PrivateKey(std::move(bytes)) }; + return new TWPrivateKey{ PrivateKey(std::move(bytes), curve) }; } -struct TWPrivateKey *_Nullable TWPrivateKeyCreateWithData(TWData *_Nonnull data) { +struct TWPrivateKey *_Nullable TWPrivateKeyCreateWithData(TWData *_Nonnull data, enum TWCurve curve) { auto dataSize = TWDataSize(data); Data bytes(dataSize); TWDataCopyBytes(data, 0, dataSize, bytes.data()); - if (!PrivateKey::isValid(bytes)) { + if (!PrivateKey::isValid(bytes, curve)) { return nullptr; } - return new TWPrivateKey{ PrivateKey(std::move(bytes)) }; + return new TWPrivateKey{ PrivateKey(std::move(bytes), curve) }; } struct TWPrivateKey *_Nullable TWPrivateKeyCreateCopy(struct TWPrivateKey *_Nonnull key) { - return new TWPrivateKey{ PrivateKey(key->impl.bytes) }; + return new TWPrivateKey{ PrivateKey(key->impl.bytes, key->impl.curve()) }; } void TWPrivateKeyDelete(struct TWPrivateKey *_Nonnull pk) { @@ -88,19 +86,17 @@ struct TWPublicKey *_Nonnull TWPrivateKeyGetPublicKeyCurve25519(struct TWPrivate return TWPrivateKeyGetPublicKeyByType(pk, TWPublicKeyTypeCURVE25519); } -TWData *TWPrivateKeySign(struct TWPrivateKey *_Nonnull pk, TWData *_Nonnull digest, enum TWCurve curve) { - const auto& d = *reinterpret_cast(digest); - auto result = pk->impl.sign(d, curve); - if (result.empty()) { - return nullptr; - } else { - return TWDataCreateWithBytes(result.data(), result.size()); - } +struct TWPublicKey *_Nonnull TWPrivateKeyGetPublicKeySchnorr(struct TWPrivateKey *_Nonnull pk) { + return TWPrivateKeyGetPublicKeyByType(pk, TWPublicKeyTypeSchnorr); } -TWData* TWPrivateKeySignAsDER(struct TWPrivateKey* pk, TWData* digest) { - auto& d = *reinterpret_cast(digest); - auto result = pk->impl.signAsDER(d); +struct TWPublicKey *_Nonnull TWPrivateKeyGetPublicKeyZilliqaSchnorr(struct TWPrivateKey *_Nonnull pk) { + return TWPrivateKeyGetPublicKeyByType(pk, TWPublicKeyTypeZILLIQASchnorr); +} + +TWData *TWPrivateKeySign(struct TWPrivateKey *_Nonnull pk, TWData *_Nonnull digest) { + const auto& d = *reinterpret_cast(digest); + auto result = pk->impl.sign(d); if (result.empty()) { return nullptr; } else { @@ -108,10 +104,9 @@ TWData* TWPrivateKeySignAsDER(struct TWPrivateKey* pk, TWData* digest) { } } -TWData *TWPrivateKeySignZilliqaSchnorr(struct TWPrivateKey *_Nonnull pk, TWData *_Nonnull message) { - const auto& msg = *reinterpret_cast(message); - auto result = pk->impl.signZilliqa(msg); - +TWData *TWPrivateKeySignAsDER(struct TWPrivateKey *_Nonnull pk, TWData *_Nonnull digest) { + const auto& d = *reinterpret_cast(digest); + auto result = pk->impl.signAsDER(d); if (result.empty()) { return nullptr; } else { diff --git a/src/interface/TWPublicKey.cpp b/src/interface/TWPublicKey.cpp index 6459b947a05..e220dec45c6 100644 --- a/src/interface/TWPublicKey.cpp +++ b/src/interface/TWPublicKey.cpp @@ -7,9 +7,6 @@ #include "../HexCoding.h" #include "../PublicKey.h" -#include -#include - using TW::PublicKey; struct TWPublicKey *_Nullable TWPublicKeyCreateWithData(TWData *_Nonnull data, enum TWPublicKeyType type) { @@ -58,12 +55,6 @@ bool TWPublicKeyVerifyAsDER(struct TWPublicKey *_Nonnull pk, TWData *_Nonnull si return pk->impl.verifyAsDER(s, m); } -bool TWPublicKeyVerifyZilliqaSchnorr(struct TWPublicKey *_Nonnull pk, TWData *_Nonnull signature, TWData *_Nonnull message) { - const auto& s = *reinterpret_cast(signature); - const auto& m = *reinterpret_cast(message); - return pk->impl.verifyZilliqa(s, m); -} - enum TWPublicKeyType TWPublicKeyKeyType(struct TWPublicKey *_Nonnull publicKey) { return publicKey->impl.type; } diff --git a/src/interface/TWSegwitAddress.cpp b/src/interface/TWSegwitAddress.cpp index 5d74bdb3716..e473a2b2123 100644 --- a/src/interface/TWSegwitAddress.cpp +++ b/src/interface/TWSegwitAddress.cpp @@ -4,7 +4,6 @@ #include "../Bitcoin/SegwitAddress.h" -#include #include #include #include diff --git a/src/interface/TWString.cpp b/src/interface/TWString.cpp index 3641660b8d8..a3a2389c128 100644 --- a/src/interface/TWString.cpp +++ b/src/interface/TWString.cpp @@ -4,7 +4,7 @@ #include -#include +#include "memzero.h" #include TWString *_Nonnull TWStringCreateWithUTF8Bytes(const char *_Nonnull bytes) { diff --git a/src/memory/memzero_wrapper.h b/src/memory/memzero_wrapper.h index 71af4291e78..c1062501032 100644 --- a/src/memory/memzero_wrapper.h +++ b/src/memory/memzero_wrapper.h @@ -8,7 +8,7 @@ #include -#include +#include "memzero.h" namespace TW { diff --git a/trezor-crypto/crypto/memzero.c b/src/memzero.c similarity index 100% rename from trezor-crypto/crypto/memzero.c rename to src/memzero.c diff --git a/trezor-crypto/include/TrezorCrypto/memzero.h b/src/memzero.h similarity index 100% rename from trezor-crypto/include/TrezorCrypto/memzero.h rename to src/memzero.h diff --git a/trezor-crypto/crypto/rand.c b/src/rand.cpp similarity index 85% rename from trezor-crypto/crypto/rand.c rename to src/rand.cpp index 9f22a0a5812..48b63d3ad23 100644 --- a/trezor-crypto/crypto/rand.c +++ b/src/rand.cpp @@ -21,23 +21,24 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include "rand.h" #include #include #include #include +#include // [wallet-core] uint32_t __attribute__((weak)) random32(void) { int randomData = open("/dev/urandom", O_RDONLY); if (randomData < 0) { - return 0; + throw std::runtime_error("Failed to open /dev/urandom"); } uint32_t result; if (read(randomData, &result, sizeof(result)) < 0) { - return 0; + throw std::runtime_error("Failed to read from /dev/urandom"); } close(randomData); @@ -48,10 +49,10 @@ uint32_t __attribute__((weak)) random32(void) { void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) { int randomData = open("/dev/urandom", O_RDONLY); if (randomData < 0) { - return; + throw std::runtime_error("Failed to open /dev/urandom"); } if (read(randomData, buf, len) < 0) { - return; + throw std::runtime_error("Failed to read from /dev/urandom"); } close(randomData); } diff --git a/trezor-crypto/include/TrezorCrypto/rand.h b/src/rand.h similarity index 100% rename from trezor-crypto/include/TrezorCrypto/rand.h rename to src/rand.h diff --git a/swift/Sources/KeyStore.swift b/swift/Sources/KeyStore.swift index 0b6c3368d77..58c8d78e7a0 100644 --- a/swift/Sources/KeyStore.swift +++ b/swift/Sources/KeyStore.swift @@ -138,10 +138,11 @@ public final class KeyStore { return try self.import(mnemonic: mnemonic, name: name, encryptPassword: newPassword, coins: coins) } - guard let privateKey = PrivateKey(data: data) else { + let coin = coins.first ?? .ethereum + guard let privateKey = PrivateKey(data: data, curve: coin.curve) else { throw Error.invalidKey } - return try self.import(privateKey: privateKey, name: name, password: newPassword, coin: coins.first ?? .ethereum) + return try self.import(privateKey: privateKey, name: name, password: newPassword, coin: coin) } private func checkMnemonic(_ data: Data) -> String? { diff --git a/swift/Tests/Addresses/BitcoinAddressTests.swift b/swift/Tests/Addresses/BitcoinAddressTests.swift index da079e80027..56d7bca0b10 100644 --- a/swift/Tests/Addresses/BitcoinAddressTests.swift +++ b/swift/Tests/Addresses/BitcoinAddressTests.swift @@ -44,7 +44,7 @@ class BitcoinAddressTests: XCTestCase { func testFromPrivateKey() { let data = Data(hexString: "f7b5f7a8090c5c93cd2d6d01383c9286b221ea78d8bef3e482f0c5cdde653e68")! - let privateKey = PrivateKey(data: data)! + let privateKey = PrivateKey(data: data, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let address = BitcoinAddress.compatibleAddress(publicKey: publicKey, prefix: CoinType.bitcoin.p2shPrefix) @@ -53,7 +53,7 @@ class BitcoinAddressTests: XCTestCase { func testFromPrivateKeyUncompressed() { let data = Data(hexString: "f7b5f7a8090c5c93cd2d6d01383c9286b221ea78d8bef3e482f0c5cdde653e68")! - let privateKey = PrivateKey(data: data)! + let privateKey = PrivateKey(data: data, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let address = BitcoinAddress.compatibleAddress(publicKey: publicKey, prefix: CoinType.bitcoin.p2shPrefix) @@ -62,7 +62,7 @@ class BitcoinAddressTests: XCTestCase { func testFromPrivateKeySegwitAddress() { let data = Data(hexString: "28071bf4e2b0340db41b807ed8a5514139e5d6427ff9d58dbd22b7ed187103a4")! - let privateKey = PrivateKey(data: data)! + let privateKey = PrivateKey(data: data, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let address = BitcoinAddress(publicKey: publicKey, prefix: CoinType.bitcoin.p2pkhPrefix)! @@ -228,7 +228,7 @@ class BitcoinAddressTests: XCTestCase { } func testBitcoinDeriveAddress() { - let privateKey = PrivateKey(data: Data(hexString: "4646464646464646464646464646464646464646464646464646464646464646")!)! + let privateKey = PrivateKey(data: Data(hexString: "4646464646464646464646464646464646464646464646464646464646464646")!, curve: CoinType.bitcoin.curve)! let address = CoinType.bitcoin.deriveAddress(privateKey: privateKey) XCTAssertEqual("bc1qhkfq3zahaqkkzx5mjnamwjsfpq2jk7z00ppggv", address.description) } diff --git a/swift/Tests/Addresses/NEOAddressTests.swift b/swift/Tests/Addresses/NEOAddressTests.swift index fffdc401277..59a5822a457 100644 --- a/swift/Tests/Addresses/NEOAddressTests.swift +++ b/swift/Tests/Addresses/NEOAddressTests.swift @@ -25,7 +25,7 @@ class NEOAddressTests: XCTestCase { } func testFromPrivateKey() { - let privateKey = PrivateKey(data: Data(hexString: "4cbd05e59cbe5faba43bbf5a15fdaf27ad72c232f8d88d987c6b3d4d98300af5")!)! + let privateKey = PrivateKey(data: Data(hexString: "4cbd05e59cbe5faba43bbf5a15fdaf27ad72c232f8d88d987c6b3d4d98300af5")!, curve: CoinType.neo.curve)! let address = AnyAddress(publicKey: privateKey.getPublicKeyNist256p1(), coin: .neo) XCTAssertEqual(address.description, "AH11LGtFk6VU9Z7suuM5eNpho1bAoE5Gbz") } diff --git a/swift/Tests/Addresses/OntologyAddressTests.swift b/swift/Tests/Addresses/OntologyAddressTests.swift index 760465b3ecd..d8b3c1d6b67 100644 --- a/swift/Tests/Addresses/OntologyAddressTests.swift +++ b/swift/Tests/Addresses/OntologyAddressTests.swift @@ -25,7 +25,7 @@ class OntologyAddressTests: XCTestCase { } func testFromPrivateKey() { - let privateKey = PrivateKey(data: Data(hexString: "4cbd05e59cbe5faba43bbf5a15fdaf27ad72c232f8d88d987c6b3d4d98300af5")!)! + let privateKey = PrivateKey(data: Data(hexString: "4cbd05e59cbe5faba43bbf5a15fdaf27ad72c232f8d88d987c6b3d4d98300af5")!, curve: CoinType.ontology.curve)! let address = AnyAddress(publicKey: privateKey.getPublicKeyNist256p1(), coin: .ontology) XCTAssertEqual(address.description, "AH11LGtFk6VU9Z7suuM5eNpho1bAoE5Gbz") } diff --git a/swift/Tests/Addresses/TronAddressTests.swift b/swift/Tests/Addresses/TronAddressTests.swift index cc2b3a6773f..722c33a303b 100644 --- a/swift/Tests/Addresses/TronAddressTests.swift +++ b/swift/Tests/Addresses/TronAddressTests.swift @@ -8,7 +8,7 @@ import XCTest class TronAddressTests: XCTestCase { func testFromPrivateKey() { - let privateKey = PrivateKey(data: Data(hexString: "2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")!)! + let privateKey = PrivateKey(data: Data(hexString: "2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")!, curve: CoinType.tron.curve)! let address = CoinType.tron.deriveAddress(privateKey: privateKey) @@ -16,7 +16,7 @@ class TronAddressTests: XCTestCase { } func testFromPublicKey() { - let privateKey = PrivateKey(data: Data(hexString: "BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835")!)! + let privateKey = PrivateKey(data: Data(hexString: "BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835")!, curve: CoinType.tron.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) XCTAssertEqual("THRF3GuPnvvPzKoaT8pJex5XHmo8NNbCb3", AnyAddress(publicKey: publicKey, coin: .tron).description) diff --git a/swift/Tests/Blockchains/AcalaEVMTests.swift b/swift/Tests/Blockchains/AcalaEVMTests.swift index dd4577c23a1..af9d42fbf44 100644 --- a/swift/Tests/Blockchains/AcalaEVMTests.swift +++ b/swift/Tests/Blockchains/AcalaEVMTests.swift @@ -7,7 +7,7 @@ import XCTest class AcalaEVMTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!)! + let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!, curve: CoinType.acalaEVM.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .acalaEVM) let expected = AnyAddress(string: "0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", coin: .acalaEVM)! diff --git a/swift/Tests/Blockchains/AcalaTests.swift b/swift/Tests/Blockchains/AcalaTests.swift index 4ef108e7f2c..2afc9695041 100644 --- a/swift/Tests/Blockchains/AcalaTests.swift +++ b/swift/Tests/Blockchains/AcalaTests.swift @@ -10,7 +10,7 @@ class AcalaTests: XCTestCase { let genesisHash = Data(hexString: "0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c")! func testAddress() { - let key = PrivateKey(data: Data(hexString: "0x9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!)! + let key = PrivateKey(data: Data(hexString: "0x9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!, curve: CoinType.acala.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .acala) let addressFromString = AnyAddress(string: "269ZCS3WLGydTN8ynhyhZfzJrXkePUcdhwgLQs6TWFs5wVL5", coin: .acala)! @@ -21,7 +21,7 @@ class AcalaTests: XCTestCase { func testSigning() { // real key in 1p test - let key = PrivateKey(data: Data(hexString: "9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!)! + let key = PrivateKey(data: Data(hexString: "9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!, curve: CoinType.acala.curve)! let input = PolkadotSigningInput.with { $0.genesisHash = genesisHash diff --git a/swift/Tests/Blockchains/AgoricTests.swift b/swift/Tests/Blockchains/AgoricTests.swift index a35e0ed4948..d16d35114e0 100644 --- a/swift/Tests/Blockchains/AgoricTests.swift +++ b/swift/Tests/Blockchains/AgoricTests.swift @@ -8,7 +8,7 @@ import XCTest class AgoricTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73")!)! + let key = PrivateKey(data: Data(hexString: "037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73")!, curve: CoinType.agoric.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .agoric) let addressFromString = AnyAddress(string: "agoric18zvvgk6j3eq5wd7mqxccgt20gz2w94cy88aek5", coin: .agoric)! @@ -18,7 +18,7 @@ class AgoricTests: XCTestCase { } func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73")!)! + let privateKey = PrivateKey(data: Data(hexString: "037048190544fa57651452f477c096de4f3073e7835cf3845b04602563a73f73")!, curve: CoinType.agoric.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .agoric) diff --git a/swift/Tests/Blockchains/AionTests.swift b/swift/Tests/Blockchains/AionTests.swift index 89c731de13f..948d4123866 100644 --- a/swift/Tests/Blockchains/AionTests.swift +++ b/swift/Tests/Blockchains/AionTests.swift @@ -8,7 +8,7 @@ import XCTest class AionTests: XCTestCase { func testAddress() { - let privateKey = PrivateKey(data: Data(hexString: "db33ffdf82c7ba903daf68d961d3c23c20471a8ce6b408e52d579fd8add80cc9")!)! + let privateKey = PrivateKey(data: Data(hexString: "db33ffdf82c7ba903daf68d961d3c23c20471a8ce6b408e52d579fd8add80cc9")!, curve: CoinType.aion.curve)! let publicKey = privateKey.getPublicKeyEd25519() let address = AnyAddress(publicKey: publicKey, coin: .aion) XCTAssertEqual(address.description, "0xa0d2312facea71b740679c926d040c9056a65a4bfa2ddd18ec160064f82909e7") diff --git a/swift/Tests/Blockchains/AlgorandTests.swift b/swift/Tests/Blockchains/AlgorandTests.swift index 7c03fbb1a07..a8e081280a3 100644 --- a/swift/Tests/Blockchains/AlgorandTests.swift +++ b/swift/Tests/Blockchains/AlgorandTests.swift @@ -8,7 +8,7 @@ import XCTest class AlgorandTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "a6c4394041e64fe93d889386d7922af1b9a87f12e433762759608e61434d6cf7")!)! + let key = PrivateKey(data: Data(hexString: "a6c4394041e64fe93d889386d7922af1b9a87f12e433762759608e61434d6cf7")!, curve: CoinType.algorand.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .algorand) let addressFromString = AnyAddress(string: "ADIYK65L3XR5ODNNCUIQVEET455L56MRKJHRBX5GU4TZI2752QIWK4UL5A", coin: .algorand)! diff --git a/swift/Tests/Blockchains/AvalancheTests.swift b/swift/Tests/Blockchains/AvalancheTests.swift index cc0da61aaae..32ae197680d 100644 --- a/swift/Tests/Blockchains/AvalancheTests.swift +++ b/swift/Tests/Blockchains/AvalancheTests.swift @@ -8,7 +8,7 @@ import XCTest class AvalancheTests: XCTestCase { func testCChainAddress() { - let key = PrivateKey(data: Data(hexString: "98cb077f972feb0481f1d894f272c6a1e3c15e272a1658ff716444f465200070")!)! + let key = PrivateKey(data: Data(hexString: "98cb077f972feb0481f1d894f272c6a1e3c15e272a1658ff716444f465200070")!, curve: CoinType.avalancheCChain.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .avalancheCChain) let addressETH = AnyAddress(publicKey: pubkey, coin: .ethereum) diff --git a/swift/Tests/Blockchains/BandChainTests.swift b/swift/Tests/Blockchains/BandChainTests.swift index 60fb141add8..9c450b3da38 100644 --- a/swift/Tests/Blockchains/BandChainTests.swift +++ b/swift/Tests/Blockchains/BandChainTests.swift @@ -6,7 +6,7 @@ import WalletCore import XCTest class BandChainTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!)! + let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!, curve: CoinType.bandChain.curve)! func testAddress() { let address = CoinType.bandChain.deriveAddress(privateKey: privateKey) diff --git a/swift/Tests/Blockchains/BinanceChainTests.swift b/swift/Tests/Blockchains/BinanceChainTests.swift index 8f16331ee46..69fa9750bd5 100644 --- a/swift/Tests/Blockchains/BinanceChainTests.swift +++ b/swift/Tests/Blockchains/BinanceChainTests.swift @@ -7,7 +7,7 @@ import WalletCore class BinanceChainTests: XCTestCase { - let testKey = PrivateKey(data: Data(hexString: "eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d")!)! + let testKey = PrivateKey(data: Data(hexString: "eeba3f6f2db26ced519a3d4c43afff101db957a21d54d25dc7fd235c404d7a5d")!, curve: .secp256k1)! func testAddress() { let publicKey = PublicKey(data: Data(hexString: "0x026a35920088d98c3888ca68c53dfc93f4564602606cbb87f0fe5ee533db38e502")!, type: .secp256k1)! @@ -36,7 +36,7 @@ class BinanceChainTests: XCTestCase { } func testSignSendOrder() { - let privateKey = PrivateKey(data: Data(hexString: "95949f757db1f57ca94a5dff23314accbe7abee89597bf6a3c7382c84d7eb832")!)! + let privateKey = PrivateKey(data: Data(hexString: "95949f757db1f57ca94a5dff23314accbe7abee89597bf6a3c7382c84d7eb832")!, curve: .secp256k1)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let token = BinanceSendOrder.Token.with { diff --git a/swift/Tests/Blockchains/BinanceSmartChainTests.swift b/swift/Tests/Blockchains/BinanceSmartChainTests.swift index a1d82e098e8..4fdb63ad66d 100644 --- a/swift/Tests/Blockchains/BinanceSmartChainTests.swift +++ b/swift/Tests/Blockchains/BinanceSmartChainTests.swift @@ -8,7 +8,7 @@ import XCTest class BinanceSmartChainTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06")!)! + let key = PrivateKey(data: Data(hexString: "727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06")!, curve: CoinType.smartChain.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .smartChain) let expected = AnyAddress(string: "0xf3d468DBb386aaD46E92FF222adDdf872C8CC064", coin: .smartChain)! diff --git a/swift/Tests/Blockchains/BitcoinDiamondTests.swift b/swift/Tests/Blockchains/BitcoinDiamondTests.swift index 1afbbdc18f2..78aecf1ecab 100644 --- a/swift/Tests/Blockchains/BitcoinDiamondTests.swift +++ b/swift/Tests/Blockchains/BitcoinDiamondTests.swift @@ -7,7 +7,7 @@ import XCTest class BitcoinDiamondTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee")!)! + let key = PrivateKey(data: Data(hexString: "d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee")!, curve: CoinType.bitcoinDiamond.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .bitcoinDiamond) let addressFromString = AnyAddress(string: "1G15VvshDxwFTnahZZECJfFwEkq9fP79o8", coin: .bitcoinDiamond)! @@ -17,7 +17,7 @@ class BitcoinDiamondTests: XCTestCase { } func testSign() { - let key = PrivateKey(data: Data(hexString: "d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee")!)! + let key = PrivateKey(data: Data(hexString: "d2b9f2846d3adcead910ee0124a3ba7ae29e8a4729787d27f9bea1f532928eee")!, curve: CoinType.bitcoinDiamond.curve)! let script = BitcoinScript.lockScriptForAddress(address: "1G15VvshDxwFTnahZZECJfFwEkq9fP79o8", coin: .bitcoinDiamond) let utxos = [ diff --git a/swift/Tests/Blockchains/BitcoinTests.swift b/swift/Tests/Blockchains/BitcoinTests.swift index 3ae42d7d925..18b904b6327 100644 --- a/swift/Tests/Blockchains/BitcoinTests.swift +++ b/swift/Tests/Blockchains/BitcoinTests.swift @@ -16,7 +16,7 @@ class BitcoinTransactionSignerTests: XCTestCase { let dustAmount = 546 as Int64 let txId = Data.reverse(hexString: "8ec895b4d30adb01e38471ca1019bfc8c3e5fbd1f28d9e7b5653260d89989008") - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let utxo0 = BitcoinV2Input.with { @@ -88,7 +88,7 @@ class BitcoinTransactionSignerTests: XCTestCase { // Now spend just created `797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1` commit output. let txIdCommit = Data.reverse(hexString: "797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1") - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let utxo0 = BitcoinV2Input.with { @@ -152,7 +152,7 @@ class BitcoinTransactionSignerTests: XCTestCase { let txIdReveal = Data.reverse(hexString: "7046dc2689a27e143ea2ad1039710885147e9485ab6453fa7e87464aa7dd3eca") let txIdForFee = Data.reverse(hexString: "797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1") - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let bobAddress = "bc1qazgc2zhu2kmy42py0vs8d7yff67l3zgpwfzlpk" @@ -302,7 +302,7 @@ class BitcoinTransactionSignerTests: XCTestCase { func testSignP2SH_P2WPKH() { let address = "3LGoLac9mtCwDy2q8PYyvwL8kMyrCWCYQW" let lockScript = BitcoinScript.lockScriptForAddress(address: address, coin: .bitcoin) - let key = PrivateKey(data: Data(hexString: "e240ef3419d038577e48426c8c37c3c13bec1a0ed3f5270b82e7377bc48699dd")!)! + let key = PrivateKey(data: Data(hexString: "e240ef3419d038577e48426c8c37c3c13bec1a0ed3f5270b82e7377bc48699dd")!, curve: CoinType.bitcoin.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let utxos = [ BitcoinUnspentTransaction.with { @@ -351,7 +351,7 @@ class BitcoinTransactionSignerTests: XCTestCase { // compressed WIF, real key is 5KCr let wif = "L4BeKzm3AHDUMkxLRVKTSVxkp6Hz9FcMQPh18YCKU1uioXfovzwP" let decoded = Base58.decode(string: wif)! - let key = PrivateKey(data: decoded[1 ..< 33])! + let key = PrivateKey(data: decoded[1 ..< 33], curve: CoinType.bitcoin.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) // shortcut methods only support compressed public key @@ -420,7 +420,7 @@ class BitcoinTransactionSignerTests: XCTestCase { func testPlanPsbtThorSwap() throws { let privateKeyBytes = Data(hexString: "f00ffbe44c5c2838c13d2778854ac66b75e04eb6054f0241989e223223ad5e55")! - let privateKey = PrivateKey(data: privateKeyBytes)! + let privateKey = PrivateKey(data: privateKeyBytes, curve: CoinType.bitcoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let psbt = Data(hexString: "70736274ff0100bc0200000001147010db5fbcf619067c1090fec65c131443fbc80fb4aaeebe940e44206098c60000000000ffffffff0360ea000000000000160014f22a703617035ef7f490743d50f26ae08c30d0a70000000000000000426a403d3a474149412e41544f4d3a636f736d6f7331737377797a666d743675396a373437773537753438746778646575393573757a666c6d7175753a303a743a35303e12000000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d000000000001011f6603010000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d00000000")! diff --git a/swift/Tests/Blockchains/BitconCashTests.swift b/swift/Tests/Blockchains/BitconCashTests.swift index 406dc3026af..d00008da5a9 100644 --- a/swift/Tests/Blockchains/BitconCashTests.swift +++ b/swift/Tests/Blockchains/BitconCashTests.swift @@ -60,7 +60,7 @@ class BitcoinCashTests: XCTestCase { func testSign() throws { let utxoTxId = "050d00e2e18ef13969606f1ceee290d3f49bd940684ce39898159352952b8ce2" - let privateKey = PrivateKey(data: Data(hexString: "7fdafb9db5bc501f2096e7d13d331dc7a75d9594af3d251313ba8b6200f4e384")!)! + let privateKey = PrivateKey(data: Data(hexString: "7fdafb9db5bc501f2096e7d13d331dc7a75d9594af3d251313ba8b6200f4e384")!, curve: CoinType.bitcoinCash.curve)! let address = CoinType.bitcoinCash.deriveAddress(privateKey: privateKey) let utxo = BitcoinUnspentTransaction.with { $0.outPoint.hash = Data.reverse(hexString: utxoTxId) // reverse of UTXO tx id, Bitcoin internal expects network byte order diff --git a/swift/Tests/Blockchains/BluzelleTests.swift b/swift/Tests/Blockchains/BluzelleTests.swift index 78d32c8843f..c76f86e62de 100644 --- a/swift/Tests/Blockchains/BluzelleTests.swift +++ b/swift/Tests/Blockchains/BluzelleTests.swift @@ -9,7 +9,7 @@ class BluzelleAddressTests: XCTestCase { func testAddressPublicKey() { let privateKeyData = Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")! - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.bluzelle.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let expectedAddress = "bluzelle1jf9aaj9myrzsnmpdr7twecnaftzmku2myvn4dg" @@ -86,7 +86,7 @@ class BluzelleSignerTests: XCTestCase { func testSigningMessage() { // Submitted Realworld tx for the following test : https://bigdipper.net.bluzelle.com/transactions/B3A7F30539CCDF72D210BC995FAF65B43F9BE04FA9F8AFAE0EC969660744002F - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.bluzelle.curve)! let sendCoinsMessage = CosmosMessage.Send.with { $0.fromAddress = myAddress diff --git a/swift/Tests/Blockchains/CardanoTests.swift b/swift/Tests/Blockchains/CardanoTests.swift index 4acef413ba3..ff82eba88cf 100644 --- a/swift/Tests/Blockchains/CardanoTests.swift +++ b/swift/Tests/Blockchains/CardanoTests.swift @@ -7,7 +7,7 @@ import XCTest class CardanoTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "e8c8c5b2df13f3abed4e6b1609c808e08ff959d7e6fc3d849e3f2880550b574437aa559095324d78459b9bb2da069da32337e1cc5da78f48e1bd084670107f3110f3245ddf9132ecef98c670272ef39c03a232107733d4a1d28cb53318df26fae0d152bb611cb9ff34e945e4ff627e6fba81da687a601a879759cd76530b5744424db69a75edd4780a5fbc05d1a3c84ac4166ff8e424808481dd8e77627ce5f5bf2eea84515a4e16c4ff06c92381822d910b5cbf9e9c144e1fb76a6291af7276")!)! + let key = PrivateKey(data: Data(hexString: "e8c8c5b2df13f3abed4e6b1609c808e08ff959d7e6fc3d849e3f2880550b574437aa559095324d78459b9bb2da069da32337e1cc5da78f48e1bd084670107f3110f3245ddf9132ecef98c670272ef39c03a232107733d4a1d28cb53318df26fae0d152bb611cb9ff34e945e4ff627e6fba81da687a601a879759cd76530b5744424db69a75edd4780a5fbc05d1a3c84ac4166ff8e424808481dd8e77627ce5f5bf2eea84515a4e16c4ff06c92381822d910b5cbf9e9c144e1fb76a6291af7276")!, curve: CoinType.cardano.curve)! let pubkey = key.getPublicKeyEd25519Cardano() let address = AnyAddress(publicKey: pubkey, coin: .cardano) let addressFromString = AnyAddress(string: "addr1qxxe304qg9py8hyyqu8evfj4wln7dnms943wsugpdzzsxnkvvjljtzuwxvx0pnwelkcruy95ujkq3aw6rl0vvg32x35qc92xkq", coin: .cardano)! @@ -64,7 +64,7 @@ class CardanoTests: XCTestCase { /// Successfully broadcasted: /// https://cardanoscan.io/transaction/0203ce2c91f59f169a26e9ef91254639d2b7911afac9c7c0ae64539f88ba46a5 func testSignTransferFromLegacy() throws { - let privateKey = PrivateKey(data: Data(hexString: "98f266d1aac660179bc2f456033941238ee6b2beb8ed0f9f34c9902816781f5a9903d1d395d6ab887b65ea5e344ef09b449507c21a75f0ce8c59d0ed1c6764eba7f484aa383806735c46fd769c679ee41f8952952036a6e2338ada940b8a91f4e890ca4eb6bec44bf751b5a843174534af64d6ad1f44e0613db78a7018781f5aa151d2997f52059466b715d8eefab30a78b874ae6ef4931fa58bb21ef8ce2423d46f19d0fbf75afb0b9a24e31d533f4fd74cee3b56e162568e8defe37123afc4")!)! + let privateKey = PrivateKey(data: Data(hexString: "98f266d1aac660179bc2f456033941238ee6b2beb8ed0f9f34c9902816781f5a9903d1d395d6ab887b65ea5e344ef09b449507c21a75f0ce8c59d0ed1c6764eba7f484aa383806735c46fd769c679ee41f8952952036a6e2338ada940b8a91f4e890ca4eb6bec44bf751b5a843174534af64d6ad1f44e0613db78a7018781f5aa151d2997f52059466b715d8eefab30a78b874ae6ef4931fa58bb21ef8ce2423d46f19d0fbf75afb0b9a24e31d533f4fd74cee3b56e162568e8defe37123afc4")!, curve: CoinType.cardano.curve)! let publicKey = privateKey.getPublicKeyEd25519Cardano() let byronAddress = Cardano.getByronAddress(publicKey: publicKey) diff --git a/swift/Tests/Blockchains/ConfluxeSpaceTests.swift b/swift/Tests/Blockchains/ConfluxeSpaceTests.swift index 77751907f35..3d7e8428a92 100644 --- a/swift/Tests/Blockchains/ConfluxeSpaceTests.swift +++ b/swift/Tests/Blockchains/ConfluxeSpaceTests.swift @@ -7,7 +7,7 @@ import XCTest class ConfluxeSpaceTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!)! + let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!, curve: CoinType.confluxeSpace.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .confluxeSpace) let expected = AnyAddress(string: "0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", coin: .confluxeSpace)! diff --git a/swift/Tests/Blockchains/CosmosTests.swift b/swift/Tests/Blockchains/CosmosTests.swift index 90cfd33423c..c20aae7ff03 100644 --- a/swift/Tests/Blockchains/CosmosTests.swift +++ b/swift/Tests/Blockchains/CosmosTests.swift @@ -22,7 +22,7 @@ class CosmosAddressTests: XCTestCase { class CosmosSignerTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005")!)! + let privateKey = PrivateKey(data: Data(hexString: "80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005")!, curve: CoinType.cosmos.curve)! func testSigningTransaction() { let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) @@ -95,7 +95,7 @@ class CosmosSignerTests: XCTestCase { $0.sequence = 5 $0.messages = [message] $0.fee = fee - $0.privateKey = PrivateKey(data: Data(hexString: "c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc")!)!.data + $0.privateKey = PrivateKey(data: Data(hexString: "c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc")!, curve: CoinType.cosmos.curve)!.data } let output: CosmosSigningOutput = AnySigner.sign(input: input, coin: .cosmos) @@ -129,7 +129,7 @@ class CosmosSignerTests: XCTestCase { $0.sequence = 4 $0.messages = [message] $0.fee = fee - $0.privateKey = PrivateKey(data: Data(hexString: "c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc")!)!.data + $0.privateKey = PrivateKey(data: Data(hexString: "c7764249cdf77f8f1d840fa8af431579e5e41cf1af937e1e23afa22f3f4f0ccc")!, curve: CoinType.cosmos.curve)!.data } let output: CosmosSigningOutput = AnySigner.sign(input: input, coin: .cosmos) @@ -223,7 +223,7 @@ class CosmosSignerTests: XCTestCase { } func testIbcTransfer() { - let privateKey = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!)! + let privateKey = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!, curve: CoinType.cosmos.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .cosmos) diff --git a/swift/Tests/Blockchains/CryptoorgTests.swift b/swift/Tests/Blockchains/CryptoorgTests.swift index 9f781e24982..199aab0da72 100644 --- a/swift/Tests/Blockchains/CryptoorgTests.swift +++ b/swift/Tests/Blockchains/CryptoorgTests.swift @@ -7,7 +7,7 @@ import XCTest class CryptoorgTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e")!)! + let key = PrivateKey(data: Data(hexString: "7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e")!, curve: CoinType.cosmos.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .cryptoOrg) let addressFromString = AnyAddress(string: "cro1z53wwe7md6cewz9sqwqzn0aavpaun0gw39h3rd", coin: .cryptoOrg)! @@ -16,7 +16,7 @@ class CryptoorgTests: XCTestCase { XCTAssertEqual(address.description, addressFromString.description) } - let privateKey = PrivateKey(data: Data(hexString: "200e439e39cf1aad465ee3de6166247f914cbc0f823fc2dd48bf16dcd556f39d")!)! + let privateKey = PrivateKey(data: Data(hexString: "200e439e39cf1aad465ee3de6166247f914cbc0f823fc2dd48bf16dcd556f39d")!, curve: CoinType.cosmos.curve)! func testSign() { let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) diff --git a/swift/Tests/Blockchains/DashTests.swift b/swift/Tests/Blockchains/DashTests.swift index 94ebddfccc1..d55d1e09d6b 100644 --- a/swift/Tests/Blockchains/DashTests.swift +++ b/swift/Tests/Blockchains/DashTests.swift @@ -7,7 +7,7 @@ import XCTest class DashAddressTests: XCTestCase { func testAddress() { - let privateKey = PrivateKey(data: Data(hexString: "4b45e94800b9a2c3a45296f8de718bf9577cbe444773c39508d7f957355c759c")!)! + let privateKey = PrivateKey(data: Data(hexString: "4b45e94800b9a2c3a45296f8de718bf9577cbe444773c39508d7f957355c759c")!, curve: CoinType.dash.curve)! let address = CoinType.dash.deriveAddress(privateKey: privateKey) XCTAssertEqual(address, "Xw7HTXGY3TFeA3ZsVuMRrYh96GtwWb4hQb") diff --git a/swift/Tests/Blockchains/DecredTests.swift b/swift/Tests/Blockchains/DecredTests.swift index e13b23dcfad..736b0fda94f 100644 --- a/swift/Tests/Blockchains/DecredTests.swift +++ b/swift/Tests/Blockchains/DecredTests.swift @@ -31,7 +31,7 @@ class DecredTests: XCTestCase { func testSign() { // https://mainnet.decred.org/tx/bcc5228e9d956918984d1853c31d7edcd862f8a7fca20ded114d93f8a74ad32a - let key = PrivateKey(data: Data(hexString: "ba005cd605d8a02e3d5dfd04234cef3a3ee4f76bfbad2722d1fb5af8e12e6764")!)! + let key = PrivateKey(data: Data(hexString: "ba005cd605d8a02e3d5dfd04234cef3a3ee4f76bfbad2722d1fb5af8e12e6764")!, curve: CoinType.decred.curve)! let txHash = Data.reverse(hexString: "5015d14dcfd78998cfa13e0325798a74d95bbe75f167a49467303f70dde9bffd") let utxoAddress = CoinType.decred.deriveAddress(privateKey: key) @@ -73,7 +73,7 @@ class DecredTests: XCTestCase { func testSignV2() { // https://dcrdata.decred.org/tx/0934163f403cf9d256447890fed972e1f8b66309ecd41dec8a4dcfb657906a68 let privateKeyData = Data(hexString: "99ed469e6b7d9f188962940d9d0f9fd8582c6c37e52394348f177ff0526b8a03")! - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.decred.curve)! let senderAddress = CoinType.decred.deriveAddress(privateKey: privateKey) let toAddress = "Dsofok7qyhDLVRXcTqYdFgmGsUFSiHonbWH" diff --git a/swift/Tests/Blockchains/DydxTests.swift b/swift/Tests/Blockchains/DydxTests.swift index a464c834c8a..2192f355e96 100644 --- a/swift/Tests/Blockchains/DydxTests.swift +++ b/swift/Tests/Blockchains/DydxTests.swift @@ -7,7 +7,7 @@ import XCTest class DydxTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!)! + let key = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!, curve: CoinType.dydx.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .dydx) let addressFromString = AnyAddress(string: "dydx1mry47pkga5tdswtluy0m8teslpalkdq0hc72uz", coin: .dydx)! diff --git a/swift/Tests/Blockchains/ECashTests.swift b/swift/Tests/Blockchains/ECashTests.swift index 7f07d59b0ba..ea7e6b460b1 100644 --- a/swift/Tests/Blockchains/ECashTests.swift +++ b/swift/Tests/Blockchains/ECashTests.swift @@ -60,7 +60,7 @@ class ECashTests: XCTestCase { func testSign() throws { let utxoTxId = "050d00e2e18ef13969606f1ceee290d3f49bd940684ce39898159352952b8ce2" - let privateKey = PrivateKey(data: Data(hexString: "7fdafb9db5bc501f2096e7d13d331dc7a75d9594af3d251313ba8b6200f4e384")!)! + let privateKey = PrivateKey(data: Data(hexString: "7fdafb9db5bc501f2096e7d13d331dc7a75d9594af3d251313ba8b6200f4e384")!, curve: CoinType.ecash.curve)! let address = CoinType.ecash.deriveAddress(privateKey: privateKey) let utxo = BitcoinUnspentTransaction.with { $0.outPoint.hash = Data.reverse(hexString: utxoTxId) // reverse of UTXO tx id, Bitcoin internal expects network byte order diff --git a/swift/Tests/Blockchains/EthereumTests.swift b/swift/Tests/Blockchains/EthereumTests.swift index 9d5e73a326a..f706e6baae7 100644 --- a/swift/Tests/Blockchains/EthereumTests.swift +++ b/swift/Tests/Blockchains/EthereumTests.swift @@ -274,7 +274,7 @@ class EthereumTests: XCTestCase { } func testMessageAndVerifySignerImmutableX() { - let privateKey = PrivateKey(data: Data(hexString: "3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84")!)! + let privateKey = PrivateKey(data: Data(hexString: "3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84")!, curve: CoinType.ethereum.curve)! let msg = "Only sign this request if you’ve initiated an action with Immutable X.\n\nFor internal use:\nbd717ba31dca6e0f3f136f7c4197babce5f09a9f25176044c0b3112b1b6017a3" let signature = EthereumMessageSigner.signMessageImmutableX(privateKey: privateKey, message: msg) XCTAssertEqual(signature, "32cd5a58f3419fc5db672e3d57f76199b853eda0856d491b38f557b629b0a0814ace689412bf354a1af81126d2749207dffae8ae8845160f33948a6b787e17ee01") @@ -283,7 +283,7 @@ class EthereumTests: XCTestCase { } func testMessageAndVerifySignerLegacy() { - let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!)! + let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!, curve: CoinType.ethereum.curve)! let msg = "Foo" let signature = EthereumMessageSigner.signMessage(privateKey: privateKey, message: msg) XCTAssertEqual(signature, "21a779d499957e7fd39392d49a079679009e60e492d9654a148829be43d2490736ec72bc4a5644047d979c3cf4ebe2c1c514044cf436b063cb89fc6676be71101b") @@ -292,7 +292,7 @@ class EthereumTests: XCTestCase { } func testMessageAndVerifySignerEip155() { - let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!)! + let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!, curve: CoinType.ethereum.curve)! let msg = "Foo" let signature = EthereumMessageSigner.signMessageEip155(privateKey: privateKey, message: msg, chainId: 0) XCTAssertEqual(signature, "21a779d499957e7fd39392d49a079679009e60e492d9654a148829be43d2490736ec72bc4a5644047d979c3cf4ebe2c1c514044cf436b063cb89fc6676be711023") @@ -301,7 +301,7 @@ class EthereumTests: XCTestCase { } func testMessageAndVerifySigner712Legacy() { - let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!)! + let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!, curve: CoinType.ethereum.curve)! let msg = """ { "types": { @@ -336,7 +336,7 @@ class EthereumTests: XCTestCase { } func testMessageAndVerifySigner712Eip155() { - let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!)! + let privateKey = PrivateKey(data: Data(hexString: "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")!, curve: CoinType.ethereum.curve)! let msg = """ { "types": { diff --git a/swift/Tests/Blockchains/EverscaleTests.swift b/swift/Tests/Blockchains/EverscaleTests.swift index 2fc44ddf7b5..838ece5b2f1 100644 --- a/swift/Tests/Blockchains/EverscaleTests.swift +++ b/swift/Tests/Blockchains/EverscaleTests.swift @@ -7,7 +7,7 @@ import XCTest class EverscaleTests: XCTestCase { func testAddressFromPrivateKey() { - let privateKey = PrivateKey(data: Data(hexString: "15d126cb1a84acdbcd1d9c3f6975968c2beb18cc43c95849d4b0226e1c8552aa")!)! + let privateKey = PrivateKey(data: Data(hexString: "15d126cb1a84acdbcd1d9c3f6975968c2beb18cc43c95849d4b0226e1c8552aa")!, curve: CoinType.everscale.curve)! let publicKey = privateKey.getPublicKeyEd25519() let address = AnyAddress(publicKey: publicKey, coin: .everscale) XCTAssertEqual(address.description, "0:0c39661089f86ec5926ea7d4ee4223d634ba4ed6dcc2e80c7b6a8e6d59f79b04") diff --git a/swift/Tests/Blockchains/FIOTests.swift b/swift/Tests/Blockchains/FIOTests.swift index 4a35e145ea8..bbcbfbe25a4 100644 --- a/swift/Tests/Blockchains/FIOTests.swift +++ b/swift/Tests/Blockchains/FIOTests.swift @@ -21,7 +21,7 @@ class FIOTests: XCTestCase { } func testAddressFromKey() { - let key = PrivateKey(data: Data(hexString: "ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854")!)! + let key = PrivateKey(data: Data(hexString: "ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854")!, curve: CoinType.fio.curve)! let address = AnyAddress(publicKey: key.getPublicKeySecp256k1(compressed: true), coin: .fio) XCTAssertEqual(address.description, "FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o") @@ -29,7 +29,7 @@ class FIOTests: XCTestCase { func testRegisterFioAddress() { let chainId = Data(hexString: "4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77")! - let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!)! + let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!, curve: CoinType.fio.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: publicKey, coin: .fio) @@ -66,7 +66,7 @@ class FIOTests: XCTestCase { func testAddPubAddress() { let chainId = Data(hexString: "4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77")! - let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!)! + let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!, curve: CoinType.fio.curve)! let chainParams = FIOChainParams.with { $0.chainID = chainId @@ -105,7 +105,7 @@ class FIOTests: XCTestCase { func testTransfer() { let chainId = Data(hexString: "4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77")! - let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!)! + let privateKey = PrivateKey(data: Data(hexString: "ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")!, curve: CoinType.fio.curve)! let chainParams = FIOChainParams.with { $0.chainID = chainId diff --git a/swift/Tests/Blockchains/FilecoinTests.swift b/swift/Tests/Blockchains/FilecoinTests.swift index 2998bdfec56..35d524742be 100644 --- a/swift/Tests/Blockchains/FilecoinTests.swift +++ b/swift/Tests/Blockchains/FilecoinTests.swift @@ -8,14 +8,14 @@ import WalletCore class FilecoinTests: XCTestCase { func testCreateAddress() { - let privateKey = PrivateKey(data: Data(hexString: "1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe")!)! + let privateKey = PrivateKey(data: Data(hexString: "1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe")!, curve: CoinType.filecoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: publicKey, coin: .filecoin) XCTAssertEqual(address.description, "f1z4a36sc7mfbv4z3qwutblp2flycdui3baffytbq") } func testCreateDelegatedAddress() { - let privateKey = PrivateKey(data: Data(hexString: "825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a")!)! + let privateKey = PrivateKey(data: Data(hexString: "825d2bb32965764a98338139412c7591ed54c951dd65504cd8ddaeaa0fea7b2a")!, curve: CoinType.filecoin.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: publicKey, filecoinAddressType: .delegated) XCTAssertEqual(address.description, "f410fvak24cyg3saddajborn6idt7rrtfj2ptauk5pbq") diff --git a/swift/Tests/Blockchains/GroestlcoinTests.swift b/swift/Tests/Blockchains/GroestlcoinTests.swift index 5490f79e1b3..634aaae64af 100644 --- a/swift/Tests/Blockchains/GroestlcoinTests.swift +++ b/swift/Tests/Blockchains/GroestlcoinTests.swift @@ -7,12 +7,12 @@ import XCTest class GroestlcoinTests: XCTestCase { func testAddress() { - let privateKey1 = PrivateKey(data: Data(hexString: "3c3385ddc6fd95ba7282051aeb440bc75820b8c10db5c83c052d7586e3e98e84")!)! + let privateKey1 = PrivateKey(data: Data(hexString: "3c3385ddc6fd95ba7282051aeb440bc75820b8c10db5c83c052d7586e3e98e84")!, curve: CoinType.groestlcoin.curve)! let publicKey1 = privateKey1.getPublicKeySecp256k1(compressed: true) let legacyAddress = GroestlcoinAddress(publicKey: publicKey1, prefix: CoinType.groestlcoin.p2pkhPrefix) XCTAssertEqual(GroestlcoinAddress(string: "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM")!.description, legacyAddress.description) - let privateKey2 = PrivateKey(data: Data(hexString: "8c59c0a6f433a961109d4fd485c4562f87e0f1ad0ece32e1db406a84c5028391")!)! + let privateKey2 = PrivateKey(data: Data(hexString: "8c59c0a6f433a961109d4fd485c4562f87e0f1ad0ece32e1db406a84c5028391")!, curve: CoinType.groestlcoin.curve)! let publicKey2 = privateKey2.getPublicKeySecp256k1(compressed: true) let bech32Address = SegwitAddress(hrp: .groestlcoin, publicKey: publicKey2) XCTAssertEqual(SegwitAddress(string: "grs1qsjpmsmm4x34wlt6kk4zef9u0jtculguktwgwg4")!.description, bech32Address.description) diff --git a/swift/Tests/Blockchains/IconTests.swift b/swift/Tests/Blockchains/IconTests.swift index 3e19c5d48bb..afe5c0e9706 100644 --- a/swift/Tests/Blockchains/IconTests.swift +++ b/swift/Tests/Blockchains/IconTests.swift @@ -21,7 +21,7 @@ class IconTests: XCTestCase { } func testFromPrivateKey() { - let privateKey = PrivateKey(data: Data(hexString: "94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f")!)! + let privateKey = PrivateKey(data: Data(hexString: "94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f")!, curve: CoinType.icon.curve)! let address = AnyAddress(publicKey: privateKey.getPublicKeySecp256k1(compressed: false), coin: .icon) XCTAssertEqual(address.description, "hx98c0832ca5bd8e8bf355ca9491888aa9725c2c48") } @@ -32,7 +32,7 @@ class IconTests: XCTestCase { } func testSigning() { - let privateKey = PrivateKey(data: Data(hexString: "2d42994b2f7735bbc93a3e64381864d06747e574aa94655c516f9ad0a74eed79")!)! + let privateKey = PrivateKey(data: Data(hexString: "2d42994b2f7735bbc93a3e64381864d06747e574aa94655c516f9ad0a74eed79")!, curve: CoinType.icon.curve)! let input = IconSigningInput.with { $0.fromAddress = "hxbe258ceb872e08851f1f59694dac2558708ece11" $0.toAddress = "hx5bfdb090f43a808005ffc27c25b213145e80b7cd" diff --git a/swift/Tests/Blockchains/InternetComputerTests.swift b/swift/Tests/Blockchains/InternetComputerTests.swift index e4942450abf..fc90e82dfb3 100644 --- a/swift/Tests/Blockchains/InternetComputerTests.swift +++ b/swift/Tests/Blockchains/InternetComputerTests.swift @@ -11,7 +11,7 @@ class InternetComputerTests: XCTestCase { func testAddress() { // TODO: Check and finalize implementation - let key = PrivateKey(data: Data(hexString: "ee42eaada903e20ef6e5069f0428d552475c1ea7ed940842da6448f6ef9d48e7")!)! + let key = PrivateKey(data: Data(hexString: "ee42eaada903e20ef6e5069f0428d552475c1ea7ed940842da6448f6ef9d48e7")!, curve: CoinType.internetComputer.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .internetComputer) let addressFromString = AnyAddress(string: "2f25874478d06cf68b9833524a6390d0ba69c566b02f46626979a3d6a4153211", coin: .internetComputer)! @@ -21,7 +21,7 @@ class InternetComputerTests: XCTestCase { } func testSign() { - let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!)! + let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!, curve: CoinType.internetComputer.curve)! let input = InternetComputerSigningInput.with { $0.privateKey = key.data $0.transaction = InternetComputerTransaction.with { @@ -39,7 +39,7 @@ class InternetComputerTests: XCTestCase { } func testSignWithInvalidToAccountIdentifier() { - let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!)! + let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!, curve: CoinType.internetComputer.curve)! let input = InternetComputerSigningInput.with { $0.privateKey = key.data $0.transaction = InternetComputerTransaction.with { @@ -57,7 +57,7 @@ class InternetComputerTests: XCTestCase { } func testSignWithInvalidAmount() { - let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!)! + let key = PrivateKey(data: Data(hexString: "227102911bb99ce7285a55f952800912b7d22ebeeeee59d77fc33a5d7c7080be")!, curve: CoinType.internetComputer.curve)! let input = InternetComputerSigningInput.with { $0.privateKey = key.data $0.transaction = InternetComputerTransaction.with { diff --git a/swift/Tests/Blockchains/IoTeXTests.swift b/swift/Tests/Blockchains/IoTeXTests.swift index 017df545223..16cd34966a1 100644 --- a/swift/Tests/Blockchains/IoTeXTests.swift +++ b/swift/Tests/Blockchains/IoTeXTests.swift @@ -7,7 +7,7 @@ import WalletCore class IoTeXTests: XCTestCase { func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748")!)! + let privateKey = PrivateKey(data: Data(hexString: "0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748")!, curve: CoinType.ioTeX.curve)! let input = IoTeXSigningInput.with { $0.version = 1 diff --git a/swift/Tests/Blockchains/KavaTests.swift b/swift/Tests/Blockchains/KavaTests.swift index 1b23b5e3632..0d5ab0913ca 100644 --- a/swift/Tests/Blockchains/KavaTests.swift +++ b/swift/Tests/Blockchains/KavaTests.swift @@ -7,7 +7,7 @@ import WalletCore class KavaTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!)! + let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!, curve: CoinType.kava.curve)! func testAddress() { let address = CoinType.kava.deriveAddress(privateKey: privateKey) diff --git a/swift/Tests/Blockchains/KuCoinCommunityChainTests.swift b/swift/Tests/Blockchains/KuCoinCommunityChainTests.swift index 6faee34cac3..b751ad9656c 100644 --- a/swift/Tests/Blockchains/KuCoinCommunityChainTests.swift +++ b/swift/Tests/Blockchains/KuCoinCommunityChainTests.swift @@ -8,7 +8,7 @@ import XCTest class KuCoinCommunityChainTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "33b85056aabab539bcb68540735ecf054e38bc58b29b751530e2b54ecb4ca564")!)! + let key = PrivateKey(data: Data(hexString: "33b85056aabab539bcb68540735ecf054e38bc58b29b751530e2b54ecb4ca564")!, curve: CoinType.kuCoinCommunityChain.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .kuCoinCommunityChain) let addressFromString = AnyAddress(string: "0xE5cA667d795685E9915E5F4b4254ca832eEB398B", coin: .kuCoinCommunityChain)! diff --git a/swift/Tests/Blockchains/KusamaTests.swift b/swift/Tests/Blockchains/KusamaTests.swift index b881a2451fb..0f1d5f1242b 100644 --- a/swift/Tests/Blockchains/KusamaTests.swift +++ b/swift/Tests/Blockchains/KusamaTests.swift @@ -20,7 +20,7 @@ class KusamaTests: XCTestCase { } func testAddress() { - let key = PrivateKey(data: Data(hexString: "0x85fca134b3fe3fd523d8b528608d803890e26c93c86dc3d97b8d59c7b3540c97")!)! + let key = PrivateKey(data: Data(hexString: "0x85fca134b3fe3fd523d8b528608d803890e26c93c86dc3d97b8d59c7b3540c97")!, curve: CoinType.kusama.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .kusama) let addressFromString = AnyAddress(string: "HewiDTQv92L2bVtkziZC8ASxrFUxr6ajQ62RXAnwQ8FDVmg", coin: .kusama)! diff --git a/swift/Tests/Blockchains/LitecoinTests.swift b/swift/Tests/Blockchains/LitecoinTests.swift index f4087fe1a04..7fb92ca4cdf 100644 --- a/swift/Tests/Blockchains/LitecoinTests.swift +++ b/swift/Tests/Blockchains/LitecoinTests.swift @@ -7,18 +7,20 @@ import XCTest class LitecoinTests: XCTestCase { func testAddress() { - let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!)! + let curve = CoinType.litecoin.curve + + let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!, curve: curve)! let publicKey1 = privateKey1.getPublicKeySecp256k1(compressed: true) let legacyAddress = BitcoinAddress(publicKey: publicKey1, prefix: CoinType.litecoin.p2pkhPrefix)! XCTAssertEqual(BitcoinAddress(string: "LV7LV7Z4bWDEjYkfx9dQo6k6RjGbXsg6hS")!.description, legacyAddress.description) - let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!)! + let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!, curve: curve)! let publicKey2 = privateKey2.getPublicKeySecp256k1(compressed: true) let compatibleAddress = BitcoinAddress.compatibleAddress(publicKey: publicKey2, prefix: CoinType.litecoin.p2shPrefix) XCTAssertEqual(BitcoinAddress(string: "M8eTgzhoFTErAjkGa6cyBomcHfxAprbDgD")!.description, compatibleAddress.description) - let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!)! + let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!, curve: curve)! let publicKey3 = privateKey3.getPublicKeySecp256k1(compressed: true) let bech32Address = SegwitAddress(hrp: .litecoin, publicKey: publicKey3) XCTAssertEqual(SegwitAddress(string: "ltc1qytnqzjknvv03jwfgrsmzt0ycmwqgl0asjnaxwu")!.description, bech32Address.description) diff --git a/swift/Tests/Blockchains/MonacoinTests.swift b/swift/Tests/Blockchains/MonacoinTests.swift index b08d139ab98..8d40a76fe1a 100644 --- a/swift/Tests/Blockchains/MonacoinTests.swift +++ b/swift/Tests/Blockchains/MonacoinTests.swift @@ -7,18 +7,18 @@ import XCTest class MonacoinTests: XCTestCase { func testAddress() { - let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!)! + let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!, curve: CoinType.monacoin.curve)! let publicKey1 = privateKey1.getPublicKeySecp256k1(compressed: true) let legacyAddress = BitcoinAddress(publicKey: publicKey1, prefix: CoinType.monacoin.p2pkhPrefix)! XCTAssertEqual(BitcoinAddress(string: "MHnYTL9e1s8zNR2qzzJ3mMHfgjnUzyMscd")!.description, legacyAddress.description) - let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!)! + let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!, curve: CoinType.monacoin.curve)! let publicKey2 = privateKey2.getPublicKeySecp256k1(compressed: true) let compatibleAddress = BitcoinAddress.compatibleAddress(publicKey: publicKey2, prefix: CoinType.monacoin.p2shPrefix) XCTAssertEqual(BitcoinAddress(string: "P9LUcYCEoMZEFuShhCHZcS8YSCEtGsMQ7u")!.description, compatibleAddress.description) - let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!)! + let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!, curve: CoinType.monacoin.curve)! let publicKey3 = privateKey3.getPublicKeySecp256k1(compressed: true) let bech32Address = SegwitAddress(hrp: .monacoin, publicKey: publicKey3) XCTAssertEqual(SegwitAddress(string: "mona1qytnqzjknvv03jwfgrsmzt0ycmwqgl0asju3qmd")!.description, bech32Address.description) diff --git a/swift/Tests/Blockchains/MultiversXTests.swift b/swift/Tests/Blockchains/MultiversXTests.swift index 2084f8b551d..39556f6081d 100644 --- a/swift/Tests/Blockchains/MultiversXTests.swift +++ b/swift/Tests/Blockchains/MultiversXTests.swift @@ -14,7 +14,7 @@ class MultiversXTests: XCTestCase { let carolBech32 = "erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8" func testAddress() { - let key = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let key = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .multiversX) let addressFromString = AnyAddress(string: aliceBech32, coin: .multiversX)! @@ -24,7 +24,7 @@ class MultiversXTests: XCTestCase { } func testSignGenericAction() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.genericAction = MultiversXGenericAction.with { @@ -52,7 +52,7 @@ class MultiversXTests: XCTestCase { } func testSignGenericActionWithGuardian() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.genericAction = MultiversXGenericAction.with { @@ -82,7 +82,7 @@ class MultiversXTests: XCTestCase { } func testSignGenericActionWithRelayer() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.genericAction = MultiversXGenericAction.with { @@ -112,7 +112,7 @@ class MultiversXTests: XCTestCase { func testSignGenericActionUndelegate() { // Successfully broadcasted https://explorer.multiversx.com/transactions/3301ae5a6a77f0ab9ceb5125258f12539a113b0c6787de76a5c5867f2c515d65 - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.genericAction = MultiversXGenericAction.with { @@ -141,7 +141,7 @@ class MultiversXTests: XCTestCase { func testSignGenericActionDelegate() { // Successfully broadcasted https://explorer.multiversx.com/transactions/e5007662780f8ed677b37b156007c24bf60b7366000f66ec3525cfa16a4564e7 - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.genericAction = MultiversXGenericAction.with { @@ -169,7 +169,7 @@ class MultiversXTests: XCTestCase { } func testSignEGLDTransfer() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.egldTransfer = MultiversXEGLDTransfer.with { @@ -193,7 +193,7 @@ class MultiversXTests: XCTestCase { } func testSignEGLDTransferWithGuardian() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.egldTransfer = MultiversXEGLDTransfer.with { @@ -218,7 +218,7 @@ class MultiversXTests: XCTestCase { } func testSignESDTTransfer() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.esdtTransfer = MultiversXESDTTransfer.with { @@ -244,7 +244,7 @@ class MultiversXTests: XCTestCase { } func testSignESDTNFTTransfer() { - let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!)! + let privateKey = PrivateKey(data: Data(hexString: aliceSeedHex)!, curve: CoinType.multiversX.curve)! let input = MultiversXSigningInput.with { $0.esdtnftTransfer = MultiversXESDTNFTTransfer.with { diff --git a/swift/Tests/Blockchains/NEARTests.swift b/swift/Tests/Blockchains/NEARTests.swift index e145db8c625..bf3fc950dc4 100644 --- a/swift/Tests/Blockchains/NEARTests.swift +++ b/swift/Tests/Blockchains/NEARTests.swift @@ -45,7 +45,7 @@ class NEARTests: XCTestCase { func testSigningTransaction() { // swiftlint:disable:next line_length - let privateKey = PrivateKey(data: Base58.decodeNoCheck(string: "3hoMW1HvnRLSFCLZnvPzWeoGwtdHzke34B2cTHM8rhcbG3TbuLKtShTv3DvyejnXKXKBiV7YPkLeqUHN1ghnqpFv")!.subdata(in: 0..<32))! + let privateKey = PrivateKey(data: Base58.decodeNoCheck(string: "3hoMW1HvnRLSFCLZnvPzWeoGwtdHzke34B2cTHM8rhcbG3TbuLKtShTv3DvyejnXKXKBiV7YPkLeqUHN1ghnqpFv")!.subdata(in: 0..<32), curve: CoinType.near.curve)! let input = NEARSigningInput.with { $0.signerID = "test.near" diff --git a/swift/Tests/Blockchains/NEOTests.swift b/swift/Tests/Blockchains/NEOTests.swift index 21b881831ff..cf020762b0b 100644 --- a/swift/Tests/Blockchains/NEOTests.swift +++ b/swift/Tests/Blockchains/NEOTests.swift @@ -8,7 +8,7 @@ import XCTest class NEOTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB")!)! + let key = PrivateKey(data: Data(hexString: "2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB")!, curve: CoinType.neo.curve)! let pubkey = key.getPublicKeyNist256p1() let address = AnyAddress(publicKey: pubkey, coin: .neo) let addressFromString = AnyAddress(string: "AQCSMB3oSDA1dHPn6GXN6KB4NHmdo1fX41", coin: .neo) @@ -94,11 +94,7 @@ class NEOTests: XCTestCase { // https://testnet-explorer.o3.network/transactions/0x7b138c753c24f474d0f70af30a9d79756e0ee9c1f38c12ed07fbdf6fc5132eaf - XCTAssertEqual("8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf122956bc88746dc666759a2d67f120fe3ce1659f916d22a91e0b02421d3bddbd1232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", + XCTAssertEqual("8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", result) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // XCTAssertEqual("8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac", - // result) } } diff --git a/swift/Tests/Blockchains/NULSTests.swift b/swift/Tests/Blockchains/NULSTests.swift index 458162f164b..0fe52c5ea7f 100644 --- a/swift/Tests/Blockchains/NULSTests.swift +++ b/swift/Tests/Blockchains/NULSTests.swift @@ -8,7 +8,7 @@ import XCTest class NULSTests: XCTestCase { func testAddress() { - let privateKey = PrivateKey(data: Data(hexString: "0xa1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")!)! + let privateKey = PrivateKey(data: Data(hexString: "0xa1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")!, curve: CoinType.nuls.curve)! let pubkey = privateKey.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .nuls) let addressFromString = AnyAddress(string: "NULSd6HghWa4CN5qdxqMwYVikQxRZyj57Jn4L", coin: .nuls)! diff --git a/swift/Tests/Blockchains/NativeInjectiveTests.swift b/swift/Tests/Blockchains/NativeInjectiveTests.swift index f8686ff84bb..6e89f972817 100644 --- a/swift/Tests/Blockchains/NativeInjectiveTests.swift +++ b/swift/Tests/Blockchains/NativeInjectiveTests.swift @@ -8,7 +8,7 @@ import XCTest class NativeInjectiveTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1")!)! + let key = PrivateKey(data: Data(hexString: "9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1")!, curve: CoinType.nativeInjective.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .nativeInjective) let addressFromString = AnyAddress(string: "inj13u6g7vqgw074mgmf2ze2cadzvkz9snlwcrtq8a", coin: .nativeInjective)! @@ -17,7 +17,7 @@ class NativeInjectiveTests: XCTestCase { } func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1")!)! + let privateKey = PrivateKey(data: Data(hexString: "9ee18daf8e463877aaf497282abc216852420101430482a28e246c179e2c5ef1")!, curve: CoinType.nativeInjective.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let fromAddress = AnyAddress(publicKey: publicKey, coin: .nativeInjective) diff --git a/swift/Tests/Blockchains/NativeZetaChainTests.swift b/swift/Tests/Blockchains/NativeZetaChainTests.swift index 5c5a8650098..bb05234c76c 100644 --- a/swift/Tests/Blockchains/NativeZetaChainTests.swift +++ b/swift/Tests/Blockchains/NativeZetaChainTests.swift @@ -7,7 +7,7 @@ import XCTest class NativeZetaChainTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed")!)! + let key = PrivateKey(data: Data(hexString: "8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed")!, curve: CoinType.nativeZetaChain.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .nativeZetaChain) let addressFromString = AnyAddress(string: "zeta14py36sx57ud82t9yrks9z6hdsrpn5x6kmxs0ne", coin: .nativeZetaChain)! @@ -16,7 +16,7 @@ class NativeZetaChainTests: XCTestCase { } func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed")!)! + let privateKey = PrivateKey(data: Data(hexString: "8d2a3bd62d300a148c89dc8635f87b7a24a951bd1c4e78675fe40e1a640d46ed")!, curve: CoinType.nativeZetaChain.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let fromAddress = AnyAddress(publicKey: publicKey, coin: .nativeZetaChain) diff --git a/swift/Tests/Blockchains/NebulasTests.swift b/swift/Tests/Blockchains/NebulasTests.swift index 7cfe7e63747..1549e3719d6 100644 --- a/swift/Tests/Blockchains/NebulasTests.swift +++ b/swift/Tests/Blockchains/NebulasTests.swift @@ -10,7 +10,7 @@ import WalletCore class NebulasTests: XCTestCase { func testAddressFromPublicKey() { - let privateKey = PrivateKey(data: Data(hexString: "d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b")!)! + let privateKey = PrivateKey(data: Data(hexString: "d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b")!, curve: CoinType.nebulas.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: publicKey, coin: .nebulas) @@ -28,7 +28,7 @@ class NebulasTests: XCTestCase { $0.amount = Data(hexString: "98a7d9b8314c0000")! //11000000000000000000ULL $0.payload = "" $0.timestamp = Data(hexString: "5cfc84ca")! //1560052938 - $0.privateKey = PrivateKey(data: Data(hexString: "d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b")!)!.data + $0.privateKey = PrivateKey(data: Data(hexString: "d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b")!, curve: CoinType.nebulas.curve)!.data } let output: NebulasSigningOutput = AnySigner.sign(input: input, coin: .nebulas) XCTAssertEqual(output.algorithm, 1) diff --git a/swift/Tests/Blockchains/NervosTests.swift b/swift/Tests/Blockchains/NervosTests.swift index c1716b0775f..8bbd395e8b5 100644 --- a/swift/Tests/Blockchains/NervosTests.swift +++ b/swift/Tests/Blockchains/NervosTests.swift @@ -16,7 +16,7 @@ class NervosTests: XCTestCase { func testAddress() throws { - let key = PrivateKey(data: Data(hexString: "8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb")!)! + let key = PrivateKey(data: Data(hexString: "8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb")!, curve: CoinType.nervos.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .nervos) let addressFromString = AnyAddress(string: "ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqwyk5x9erg8furras980hksatlslfaktks7epf25", coin: .nervos)! diff --git a/swift/Tests/Blockchains/OasisTests.swift b/swift/Tests/Blockchains/OasisTests.swift index 994d0aff619..dce8b3d1220 100644 --- a/swift/Tests/Blockchains/OasisTests.swift +++ b/swift/Tests/Blockchains/OasisTests.swift @@ -9,7 +9,7 @@ class OasisTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")!)! + let key = PrivateKey(data: Data(hexString: "4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")!, curve: CoinType.oasis.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .oasis) let addressFromString = AnyAddress(string: "oasis1qzawzy5kaa2xgphenf3r0f5enpr3mx5dps559yxm", coin: .oasis)! @@ -19,7 +19,7 @@ class OasisTests: XCTestCase { } func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "0x4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")!)! + let privateKey = PrivateKey(data: Data(hexString: "0x4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")!, curve: CoinType.oasis.curve)! let input = OasisSigningInput.with { $0.privateKey = privateKey.data $0.transfer = OasisTransferMessage.with { diff --git a/swift/Tests/Blockchains/OntologyTests.swift b/swift/Tests/Blockchains/OntologyTests.swift index a81c6744980..cdf1b2adda1 100644 --- a/swift/Tests/Blockchains/OntologyTests.swift +++ b/swift/Tests/Blockchains/OntologyTests.swift @@ -52,10 +52,7 @@ class OntologyTests: XCTestCase { let output: OntologySigningOutput = AnySigner.sign(input: input, coin: .ontology) let result = output.encoded.hexString - XCTAssertEqual("00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb7cff28ddaf7f1048822c0ca21a0c4926323a2497875b963f3b8cbd3717aa6e7c2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // XCTAssertEqual("00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aacd6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) + XCTAssertEqual("00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6ebb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aacd6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) } func testSignOngTransfer() { @@ -75,10 +72,7 @@ class OntologyTests: XCTestCase { let output: OntologySigningOutput = AnySigner.sign(input: input, coin: .ontology) let result = output.encoded.hexString - XCTAssertEqual("00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f73b8ab199a4d757b4c7b9ed46c4ff8cfa8aefaa90b7fb6485e358034448cba752321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d743b078bd4e21bb4404c0182a32ee05260e22454dffb34dacccf458dfbee6d32db232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // XCTAssertEqual("00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b00730143800049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) + XCTAssertEqual("00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94abac41aaf3ead76586a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efad62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b00730143800049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", result) } } diff --git a/swift/Tests/Blockchains/OsmosisTests.swift b/swift/Tests/Blockchains/OsmosisTests.swift index 45fc92bc3e8..f59c17174b3 100644 --- a/swift/Tests/Blockchains/OsmosisTests.swift +++ b/swift/Tests/Blockchains/OsmosisTests.swift @@ -7,7 +7,7 @@ import XCTest class OsmosisTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!)! + let key = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!, curve: CoinType.osmosis.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .osmosis) let addressFromString = AnyAddress(string: "osmo1mky69cn8ektwy0845vec9upsdphktxt0en97f5", coin: .osmosis)! @@ -17,7 +17,7 @@ class OsmosisTests: XCTestCase { } func testSigningTransaction() { - let privateKey = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!)! + let privateKey = PrivateKey(data: Data(hexString: "8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")!, curve: CoinType.osmosis.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .osmosis) diff --git a/swift/Tests/Blockchains/PactusTests.swift b/swift/Tests/Blockchains/PactusTests.swift index 933bdeaebea..9ee073327f9 100644 --- a/swift/Tests/Blockchains/PactusTests.swift +++ b/swift/Tests/Blockchains/PactusTests.swift @@ -10,7 +10,7 @@ class PactusTests: XCTestCase { override func setUp() { super.setUp() - privateKey = PrivateKey(data: Data(hexString: "4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6")!)! + privateKey = PrivateKey(data: Data(hexString: "4e51f1f3721f644ac7a193be7f5e7b8c2abaa3467871daf4eacb5d3af080e5d6")!, curve: CoinType.pactus.curve)! } func testAddress() { diff --git a/swift/Tests/Blockchains/PolkadotTests.swift b/swift/Tests/Blockchains/PolkadotTests.swift index fe1d96c74d8..0197a7b349b 100644 --- a/swift/Tests/Blockchains/PolkadotTests.swift +++ b/swift/Tests/Blockchains/PolkadotTests.swift @@ -22,7 +22,7 @@ class PolkadotTests: XCTestCase { } func testAddress() { - let key = PrivateKey(data: Data(hexString: "0xd65ed4c1a742699b2e20c0c1f1fe780878b1b9f7d387f934fe0a7dc36f1f9008")!)! + let key = PrivateKey(data: Data(hexString: "0xd65ed4c1a742699b2e20c0c1f1fe780878b1b9f7d387f934fe0a7dc36f1f9008")!, curve: CoinType.polkadot.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .polkadot) let addressFromString = AnyAddress(string: "12twBQPiG5yVSf3jQSBkTAKBKqCShQ5fm33KQhH3Hf6VDoKW", coin: .polkadot)! @@ -138,7 +138,7 @@ class PolkadotTests: XCTestCase { func testChillAndUnbond() { // real key in 1p test - let key = PrivateKey(data: Data(hexString: "298fcced2b497ed48367261d8340f647b3fca2d9415d57c2e3c5ef90482a2266")!)! + let key = PrivateKey(data: Data(hexString: "298fcced2b497ed48367261d8340f647b3fca2d9415d57c2e3c5ef90482a2266")!, curve: CoinType.polkadot.curve)! let input = PolkadotSigningInput.with { $0.genesisHash = genesisHash @@ -164,7 +164,7 @@ class PolkadotTests: XCTestCase { func testAcalaSigning() { // real key in 1p test - let key = PrivateKey(data: Data(hexString: "9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!)! + let key = PrivateKey(data: Data(hexString: "9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")!, curve: CoinType.polkadot.curve)! let acalaGenesisHash = Data(hexString: "0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c")! diff --git a/swift/Tests/Blockchains/PolygonTests.swift b/swift/Tests/Blockchains/PolygonTests.swift index 5c0e06fff09..9493a1c3456 100644 --- a/swift/Tests/Blockchains/PolygonTests.swift +++ b/swift/Tests/Blockchains/PolygonTests.swift @@ -7,11 +7,11 @@ import XCTest class PolygonTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!)! + let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!, curve: CoinType.polygon.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .polygon) let expected = AnyAddress(string: "0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", coin: .polygon)! XCTAssertEqual(address.description, expected.description) } -} \ No newline at end of file +} diff --git a/swift/Tests/Blockchains/PolymeshTests.swift b/swift/Tests/Blockchains/PolymeshTests.swift index bbd695266b7..f323ede9b85 100644 --- a/swift/Tests/Blockchains/PolymeshTests.swift +++ b/swift/Tests/Blockchains/PolymeshTests.swift @@ -11,7 +11,7 @@ class PolymeshTests: XCTestCase { let testKey1 = Data(hexString: "0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4")! func testAddress() { - let key = PrivateKey(data: Data(hexString: "0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4")!)! + let key = PrivateKey(data: Data(hexString: "0x790a0a01ec2e7c7db4abcaffc92ce70a960ef9ad3021dbe3bf327c1c6343aee4")!, curve: CoinType.polymesh.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .polymesh) let addressFromString = AnyAddress(string: "2EANwBfNsFu9KV8JsW5sbhF6ft8bzvw5EW1LCrgHhrqtK6Ys", coin: .polymesh)! diff --git a/swift/Tests/Blockchains/QtumTests.swift b/swift/Tests/Blockchains/QtumTests.swift index 1c9fdaf3da1..0b1303a96b2 100644 --- a/swift/Tests/Blockchains/QtumTests.swift +++ b/swift/Tests/Blockchains/QtumTests.swift @@ -7,13 +7,13 @@ import XCTest class QtumTests: XCTestCase { func testAddress() { - let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!)! + let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!, curve: CoinType.qtum.curve)! let publicKey1 = privateKey1.getPublicKeySecp256k1(compressed: true) let legacyAddress = BitcoinAddress(publicKey: publicKey1, prefix: CoinType.qtum.p2pkhPrefix)! XCTAssertEqual(BitcoinAddress(string: "QWVNLCXwhJqzut9YCLxbeMTximr2hmw7Vr")!.description, legacyAddress.description) - let privateKey2 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!)! + let privateKey2 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!, curve: CoinType.qtum.curve)! let publicKey2 = privateKey2.getPublicKeySecp256k1(compressed: true) let bech32Address = SegwitAddress(hrp: .qtum, publicKey: publicKey2) XCTAssertEqual(SegwitAddress(string: "qc1qytnqzjknvv03jwfgrsmzt0ycmwqgl0as6uywkk")!.description, bech32Address.description) diff --git a/swift/Tests/Blockchains/RippleTests.swift b/swift/Tests/Blockchains/RippleTests.swift index d4f9cf22689..d4be1f0d5ee 100644 --- a/swift/Tests/Blockchains/RippleTests.swift +++ b/swift/Tests/Blockchains/RippleTests.swift @@ -7,7 +7,7 @@ import WalletCore class RippleTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "9c3d42d0515f0406ed350ab2abf3eaf761f8907802469b64052ac17e2250ae13")!)! + let key = PrivateKey(data: Data(hexString: "9c3d42d0515f0406ed350ab2abf3eaf761f8907802469b64052ac17e2250ae13")!, curve: CoinType.xrp.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .xrp) diff --git a/swift/Tests/Blockchains/ScrollTests.swift b/swift/Tests/Blockchains/ScrollTests.swift index c890debc03e..b63c3ee51e2 100644 --- a/swift/Tests/Blockchains/ScrollTests.swift +++ b/swift/Tests/Blockchains/ScrollTests.swift @@ -7,7 +7,7 @@ import XCTest class ScrollTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!)! + let key = PrivateKey(data: Data(hexString: "828c4c48c2cef521f0251920891ed79e871faa24f64f43cde83d07bc99f8dbf0")!, curve: CoinType.scroll.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .scroll) let expected = AnyAddress(string: "0xe32DC46bfBF78D1eada7b0a68C96903e01418D64", coin: .scroll)! diff --git a/swift/Tests/Blockchains/SecretTests.swift b/swift/Tests/Blockchains/SecretTests.swift index 2acf4b61247..1af042b0505 100644 --- a/swift/Tests/Blockchains/SecretTests.swift +++ b/swift/Tests/Blockchains/SecretTests.swift @@ -7,7 +7,7 @@ import XCTest class SecretTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada")!)! + let key = PrivateKey(data: Data(hexString: "87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada")!, curve: CoinType.secret.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .secret) let addressFromString = AnyAddress(string: "secret18mdrja40gfuftt5yx6tgj0fn5lurplezyp894y", coin: .secret)! @@ -17,7 +17,7 @@ class SecretTests: XCTestCase { } func testSigningTransaction() { - let privateKey = PrivateKey(data: Data(hexString: "87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada")!)! + let privateKey = PrivateKey(data: Data(hexString: "87201512d132ef7a1e57f9e24905fbc24300bd73f676b5716182be5f3e39dada")!, curve: CoinType.secret.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .secret) diff --git a/swift/Tests/Blockchains/SmartBitcoinCashTests.swift b/swift/Tests/Blockchains/SmartBitcoinCashTests.swift index 5385549a3b8..d478345c99c 100644 --- a/swift/Tests/Blockchains/SmartBitcoinCashTests.swift +++ b/swift/Tests/Blockchains/SmartBitcoinCashTests.swift @@ -8,7 +8,7 @@ import XCTest class SmartBitcoinCashTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "155cbd57319f3d938977b4c18000473eb3c432c4e31b667b63e88559c497d82d")!)! + let key = PrivateKey(data: Data(hexString: "155cbd57319f3d938977b4c18000473eb3c432c4e31b667b63e88559c497d82d")!, curve: CoinType.smartBitcoinCash.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .smartBitcoinCash) let addressFromString = AnyAddress(string: "0x8bFC9477684987dcAf0970b9bce5E3D9267C99C0", coin: .smartBitcoinCash)! diff --git a/swift/Tests/Blockchains/SolanaTests.swift b/swift/Tests/Blockchains/SolanaTests.swift index e84ced805eb..e02b9ae8131 100644 --- a/swift/Tests/Blockchains/SolanaTests.swift +++ b/swift/Tests/Blockchains/SolanaTests.swift @@ -10,7 +10,7 @@ class SolanaTests: XCTestCase { let privateKeyData = Data(Base58.decodeNoCheck( string: "A7psj2GW7ZMdY4E5hJq14KMeYg7HFjULSsWSrTXZLvYr")!) func testAddressFromPrivateKey() { - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.solana.curve)! let publicKey = privateKey.getPublicKeyEd25519() let address = AnyAddress(publicKey: publicKey, coin: .solana) XCTAssertEqual(address.description, "7v91N7iZ9mNicL8WfG6cgSCKyRXydQjLh6UYBWwm6y1Q") diff --git a/swift/Tests/Blockchains/StargazeTests.swift b/swift/Tests/Blockchains/StargazeTests.swift index 16bc5f5c3c0..bc67e73ee2b 100644 --- a/swift/Tests/Blockchains/StargazeTests.swift +++ b/swift/Tests/Blockchains/StargazeTests.swift @@ -7,7 +7,7 @@ import XCTest class StargazeTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!)! + let key = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!, curve: CoinType.stargaze.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .stargaze) let addressFromString = AnyAddress(string: "stars1mry47pkga5tdswtluy0m8teslpalkdq02a8nhy", coin: .stargaze)! @@ -17,7 +17,7 @@ class StargazeTests: XCTestCase { } func testSignCW721() { - let privateKey = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!)! + let privateKey = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!, curve: CoinType.stargaze.curve)! let txMessage = "{\"transfer_nft\": {\"recipient\": \"stars1kd5q7qejlqz94kpmd9pvr4v2gzgnca3lvt6xnp\",\"token_id\": \"1209\"}}"; let wasmMsg = CosmosMessage.WasmExecuteContractGeneric.with { @@ -63,7 +63,7 @@ class StargazeTests: XCTestCase { } func testSign() { - let privateKey = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!)! + let privateKey = PrivateKey(data: Data(hexString: "a498a9ee41af9bab5ef2a8be63d5c970135c3c109e70efc8c56c534e6636b433")!, curve: CoinType.stargaze.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .stargaze) diff --git a/swift/Tests/Blockchains/StarkExTests.swift b/swift/Tests/Blockchains/StarkExTests.swift index 56dd47f5839..078245d9305 100644 --- a/swift/Tests/Blockchains/StarkExTests.swift +++ b/swift/Tests/Blockchains/StarkExTests.swift @@ -7,7 +7,7 @@ import WalletCore class StarkExTests: XCTestCase { func testMessageAndVerifySigner() { - let privateKey = PrivateKey(data: Data(hexString: "04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de")!)! + let privateKey = PrivateKey(data: Data(hexString: "04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de")!, curve: .starkex)! let msg = "463a2240432264a3aa71a5713f2a4e4c1b9e12bbb56083cd56af6d878217cf" let signature = StarkExMessageSigner.signMessage(privateKey: privateKey, message: msg) XCTAssertEqual(signature, "04cf5f21333dd189ada3c0f2a51430d733501a9b1d5e07905273c1938cfb261e05b6013d74adde403e8953743a338c8d414bb96bf69d2ca1a91a85ed2700a528") diff --git a/swift/Tests/Blockchains/StellarTests.swift b/swift/Tests/Blockchains/StellarTests.swift index 159d1575fdb..d6be712bad8 100644 --- a/swift/Tests/Blockchains/StellarTests.swift +++ b/swift/Tests/Blockchains/StellarTests.swift @@ -8,7 +8,7 @@ import WalletCore class StellarTests: XCTestCase { func testAddressFromPrivateKey() { - let key = PrivateKey(data: Data(hexString: "59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")!)! + let key = PrivateKey(data: Data(hexString: "59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")!, curve: CoinType.stellar.curve)! let pubkey = key.getPublicKeyEd25519() let address = AnyAddress(publicKey: pubkey, coin: .stellar) diff --git a/swift/Tests/Blockchains/SyscoinTests.swift b/swift/Tests/Blockchains/SyscoinTests.swift index 9668e7de5de..7b4cfa53114 100644 --- a/swift/Tests/Blockchains/SyscoinTests.swift +++ b/swift/Tests/Blockchains/SyscoinTests.swift @@ -7,18 +7,18 @@ import XCTest class SyscoinTests: XCTestCase { func testAddress() { - let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!)! + let privateKey1 = PrivateKey(data: Data(hexString: "a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730")!, curve: CoinType.syscoin.curve)! let publicKey1 = privateKey1.getPublicKeySecp256k1(compressed: true) let legacyAddress = BitcoinAddress(publicKey: publicKey1, prefix: CoinType.syscoin.p2pkhPrefix)! XCTAssertEqual(BitcoinAddress(string: "SXBPFk2PFDAP13qyKSdC4yptsJ8kJRAT3T")!.description, legacyAddress.description) - let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!)! + let privateKey2 = PrivateKey(data: Data(hexString: "f6ee7e6c9bd2f4dc8f0db0dc4679de06c998afc42d825edf7966dd4488b0aa1f")!, curve: CoinType.syscoin.curve)! let publicKey2 = privateKey2.getPublicKeySecp256k1(compressed: true) let compatibleAddress = BitcoinAddress.compatibleAddress(publicKey: publicKey2, prefix: CoinType.syscoin.p2shPrefix) XCTAssertEqual(BitcoinAddress(string: "32SKP7HqJLPRNEUNUDddNAXCxyMinjbX8g")!.description, compatibleAddress.description) - let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!)! + let privateKey3 = PrivateKey(data: Data(hexString: "55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625")!, curve: CoinType.syscoin.curve)! let publicKey3 = privateKey3.getPublicKeySecp256k1(compressed: true) let bech32Address = SegwitAddress(hrp: .syscoin, publicKey: publicKey3) XCTAssertEqual(SegwitAddress(string: "sys1qytnqzjknvv03jwfgrsmzt0ycmwqgl0as7lkcf7")!.description, bech32Address.description) diff --git a/swift/Tests/Blockchains/THORChainTests.swift b/swift/Tests/Blockchains/THORChainTests.swift index a0ae0db1d45..5f584ddc446 100644 --- a/swift/Tests/Blockchains/THORChainTests.swift +++ b/swift/Tests/Blockchains/THORChainTests.swift @@ -20,7 +20,7 @@ class THORChainAddressTests: XCTestCase { class THORChainSignerTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e")!)! + let privateKey = PrivateKey(data: Data(hexString: "7105512f0c020a1dd759e14b865ec0125f59ac31e34d7a2807a228ed50cb343e")!, curve: CoinType.thorchain.curve)! func testJsonModeSigning() { let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) diff --git a/swift/Tests/Blockchains/TerraClassicTests.swift b/swift/Tests/Blockchains/TerraClassicTests.swift index 66ab6f11816..ceb05b6c020 100644 --- a/swift/Tests/Blockchains/TerraClassicTests.swift +++ b/swift/Tests/Blockchains/TerraClassicTests.swift @@ -7,7 +7,7 @@ import WalletCore class TerraClassicTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!)! + let privateKey = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!, curve: CoinType.terra.curve)! func testAddress() { let address = CoinType.terra.deriveAddress(privateKey: privateKey) @@ -452,7 +452,7 @@ class TerraClassicTests: XCTestCase { } func testSigningWasmTerraTransferTxProtobuf() { - let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!)! + let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!, curve: CoinType.terra.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .terra) @@ -500,9 +500,9 @@ class TerraClassicTests: XCTestCase { } func testSigningWasmTerraGenericProtobuf() { - let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!)! - let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) - let fromAddress = AnyAddress(publicKey: publicKey, coin: .terra) + let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!, curve: CoinType.terra.curve)! + let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) + let fromAddress = AnyAddress(publicKey: publicKey, coin: .terra) let wasmGenericMessage = CosmosMessage.WasmTerraExecuteContractGeneric.with { $0.senderAddress = fromAddress.description @@ -549,7 +549,7 @@ class TerraClassicTests: XCTestCase { } func testSigningWasmTerraGenericWithCoins() { - let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!)! + let privateKey = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!, curve: CoinType.terra.curve)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) let fromAddress = AnyAddress(publicKey: publicKey, coin: .terra) diff --git a/swift/Tests/Blockchains/TerraTests.swift b/swift/Tests/Blockchains/TerraTests.swift index af8b1d0e593..c04caaf49a1 100644 --- a/swift/Tests/Blockchains/TerraTests.swift +++ b/swift/Tests/Blockchains/TerraTests.swift @@ -7,9 +7,9 @@ import WalletCore class TerraTests: XCTestCase { - let privateKey80e8 = PrivateKey(data: Data(hexString: "80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005")!)! // terra1hsk6jryyqjfhp5dhc55tc9jtckygx0ep37hdd2 - let privateKeycf08 = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!)! // terra18wukp84dq227wu4mgh0jm6n9nlnj6rs82pp9wf - let privateKey1037 = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!)! + let privateKey80e8 = PrivateKey(data: Data(hexString: "80e81ea269e66a0a05b11236df7919fb7fbeedba87452d667489d7403a02f005")!, curve: CoinType.terra.curve)! // terra1hsk6jryyqjfhp5dhc55tc9jtckygx0ep37hdd2 + let privateKeycf08 = PrivateKey(data: Data(hexString: "cf08ee8493e6f6a53f9721b9045576e80f371c0e36d08fdaf78b27a7afd8e616")!, curve: CoinType.terra.curve)! // terra18wukp84dq227wu4mgh0jm6n9nlnj6rs82pp9wf + let privateKey1037 = PrivateKey(data: Data(hexString: "1037f828ca313f4c9e120316e8e9ff25e17f07fe66ba557d5bc5e2eeb7cba8f6")!, curve: CoinType.terra.curve)! func testAddress() { let address = CoinType.terraV2.deriveAddress(privateKey: privateKey1037) diff --git a/swift/Tests/Blockchains/TezosTests.swift b/swift/Tests/Blockchains/TezosTests.swift index b7374aa2e9d..d53d37f7483 100644 --- a/swift/Tests/Blockchains/TezosTests.swift +++ b/swift/Tests/Blockchains/TezosTests.swift @@ -17,7 +17,7 @@ class TezosTests: XCTestCase { } public func testAddressFromPublicKey() { - let privateKey = PrivateKey(data: Data(hexString: "b177a72743f54ed4bdf51f1b55527c31bcd68c6d2cb2436d76cadd0227c99ff0")!)! + let privateKey = PrivateKey(data: Data(hexString: "b177a72743f54ed4bdf51f1b55527c31bcd68c6d2cb2436d76cadd0227c99ff0")!, curve: CoinType.tezos.curve)! let publicKey = privateKey.getPublicKeyEd25519() let address = tezos.deriveAddressFromPublicKey(publicKey: publicKey) @@ -113,7 +113,7 @@ class TezosTests: XCTestCase { } public func testMessageSignerSignAndVerify() { - let privateKey = PrivateKey(data: Data(hexString: "91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a")!)! + let privateKey = PrivateKey(data: Data(hexString: "91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a")!, curve: CoinType.tezos.curve)! let msg = "05010000004254657a6f73205369676e6564204d6573736167653a207465737455726c20323032332d30322d30385431303a33363a31382e3435345a2048656c6c6f20576f726c64" let signature = TezosMessageSigner.signMessage(privateKey: privateKey, message: msg) XCTAssertEqual(signature, "edsigu3se2fcEJUCm1aqxjzbHdf7Wsugr4mLaA9YM2UVZ9Yy5meGv87VqHN3mmDeRwApTj1JKDaYjqmLZifSFdWCqBoghqaowwJ") @@ -135,7 +135,7 @@ class TezosTests: XCTestCase { public func testSigning() { let privateKeyData = Data(hexString: "c6377a4cc490dc913fc3f0d9cf67d293a32df4547c46cb7e9e33c3b7b97c64d8")! - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.tezos.curve)! let publicKey = privateKey.getPublicKeyEd25519() let branch = "BL8euoCWqNCny9AR3AKjnpi38haYMxjei1ZqNHuXMn19JSQnoWp" @@ -201,8 +201,8 @@ class TezosTests: XCTestCase { watermark.append(bytes) let hash = Hash.blake2b(data: watermark, size: 32) - let privateKey = PrivateKey(data: key)! - let signature = privateKey.sign(digest: hash, curve: .ed25519)! + let privateKey = PrivateKey(data: key, curve: .ed25519)! + let signature = privateKey.sign(digest: hash)! var signed = Data() signed.append(bytes) diff --git a/swift/Tests/Blockchains/TheOpenNetworkTests.swift b/swift/Tests/Blockchains/TheOpenNetworkTests.swift index 797ae8334e0..d8d2961cc8f 100644 --- a/swift/Tests/Blockchains/TheOpenNetworkTests.swift +++ b/swift/Tests/Blockchains/TheOpenNetworkTests.swift @@ -8,7 +8,7 @@ import XCTest class TheOpenNetworkTests: XCTestCase { func testAddressFromPrivateKey() { let data = Data(hexString: "63474e5fe9511f1526a50567ce142befc343e71a49b865ac3908f58667319cb8") - let privateKey = PrivateKey(data: data!)! + let privateKey = PrivateKey(data: data!, curve: CoinType.ton.curve)! let publicKey = privateKey.getPublicKeyEd25519() let address = AnyAddress(publicKey: publicKey, coin: .ton) XCTAssertEqual(address.description, "UQBm--PFwDv1yCeS-QTJ-L8oiUpqo9IT1BwgVptlSq3ts4DV") @@ -71,7 +71,7 @@ class TheOpenNetworkTests: XCTestCase { // from the following mnemonic: // document shield addict crime broom point story depend suit satisfy test chicken valid tail speak fortune sound drill seek cube cheap body music recipe let privateKeyData = Data(hexString: "112d4e2e700a468f1eae699329202f1ee671d6b665caa2d92dea038cf3868c18")! - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.ton.curve)! let message = "Hello world" let signature = TONMessageSigner.signMessage(privateKey: privateKey, message: message)! // The following signature has been computed by calling `window.ton.send("ton_personalSign", { data: "Hello world" });`. diff --git a/swift/Tests/Blockchains/ThetaFuelTests.swift b/swift/Tests/Blockchains/ThetaFuelTests.swift index e0c42392f32..ce0ac162714 100644 --- a/swift/Tests/Blockchains/ThetaFuelTests.swift +++ b/swift/Tests/Blockchains/ThetaFuelTests.swift @@ -7,7 +7,7 @@ import XCTest class ThetaFuelTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "4646464646464646464646464646464646464646464646464646464646464646")!)! + let key = PrivateKey(data: Data(hexString: "4646464646464646464646464646464646464646464646464646464646464646")!, curve: CoinType.thetaFuel.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: false) let address = AnyAddress(publicKey: pubkey, coin: .thetaFuel) let expected = AnyAddress(string: "0x9d8A62f656a8d1615C1294fd71e9CFb3E4855A4F", coin: .thetaFuel)! diff --git a/swift/Tests/Blockchains/TronTests.swift b/swift/Tests/Blockchains/TronTests.swift index 67ae3f91242..6f1d36d32a5 100644 --- a/swift/Tests/Blockchains/TronTests.swift +++ b/swift/Tests/Blockchains/TronTests.swift @@ -76,7 +76,7 @@ class TronTests: XCTestCase { } func testMessageAndVerifySigner() { - let privateKey = PrivateKey(data: Data(hexString: "75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")!)! + let privateKey = PrivateKey(data: Data(hexString: "75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")!, curve: CoinType.tron.curve)! let msg = "Hello World" let signature = TronMessageSigner.signMessage(privateKey: privateKey, message: msg) XCTAssertEqual(signature, "bc0753c070cc55693097df11bc11e1a7c4bd5e1a40b9dc94c75568e59bcc9d6b50a7873ef25b469e494490a54de37327b4bc7fc825c81a377b555e34fb7261ba1c") diff --git a/swift/Tests/Blockchains/WavesTests.swift b/swift/Tests/Blockchains/WavesTests.swift index 3f16f7bdfd0..9d6d93ac1db 100644 --- a/swift/Tests/Blockchains/WavesTests.swift +++ b/swift/Tests/Blockchains/WavesTests.swift @@ -9,7 +9,7 @@ class WavesTests: XCTestCase { func testSigner() throws { - let privateKey = PrivateKey(data: Data(hexString: "68b7a9adb4a655b205f43dac413803785921e22cd7c4d05857b203a62621075f")!)! + let privateKey = PrivateKey(data: Data(hexString: "68b7a9adb4a655b205f43dac413803785921e22cd7c4d05857b203a62621075f")!, curve: CoinType.waves.curve)! let transferMessage = WavesTransferMessage.with { $0.amount = 100_000_000 diff --git a/swift/Tests/Blockchains/ZcashTests.swift b/swift/Tests/Blockchains/ZcashTests.swift index 6d201b53ce1..7154fad82e7 100644 --- a/swift/Tests/Blockchains/ZcashTests.swift +++ b/swift/Tests/Blockchains/ZcashTests.swift @@ -80,7 +80,7 @@ class ZcashTests: XCTestCase { let txId = Data.reverse(hexString: "3a19dd44032dfed61bfca5ba5751aab8a107b30609cbd5d70dc5ef09885b6853") let sapplingBranchId = Data(hexString: "bb09b876")! - let privateKey = PrivateKey(data: privateKeyData)! + let privateKey = PrivateKey(data: privateKeyData, curve: CoinType.zcash.curve)! let utxo0 = BitcoinV2Input.with { $0.outPoint = UtxoOutPoint.with { diff --git a/swift/Tests/Blockchains/ZenTests.swift b/swift/Tests/Blockchains/ZenTests.swift index ab7adddffd9..9824b8ca8e7 100644 --- a/swift/Tests/Blockchains/ZenTests.swift +++ b/swift/Tests/Blockchains/ZenTests.swift @@ -7,7 +7,7 @@ import XCTest class ZenTests: XCTestCase { func testAddress() { - let key = PrivateKey(data: Data(hexString: "3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")!)! + let key = PrivateKey(data: Data(hexString: "3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")!, curve: CoinType.zen.curve)! let pubkey = key.getPublicKeySecp256k1(compressed: true) let address = AnyAddress(publicKey: pubkey, coin: .zen) let addressFromString = AnyAddress(string: "znk19H1wcARcCa7TM6zgmJUbWoWWtZ8k5cg", coin: .zen)! @@ -17,7 +17,7 @@ class ZenTests: XCTestCase { } func testSign() { - let key = PrivateKey(data: Data(hexString: "3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")!)! + let key = PrivateKey(data: Data(hexString: "3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")!, curve: CoinType.zen.curve)! let blockHash = Data(hexString: "81dc725fd33fada1062323802eefb54d3325d924d4297a692214560400000000")! let blockHeight = Int64(1147624) let utxos = [ diff --git a/swift/Tests/Blockchains/ZilliqaTests.swift b/swift/Tests/Blockchains/ZilliqaTests.swift index 060db939033..0113f3036b4 100644 --- a/swift/Tests/Blockchains/ZilliqaTests.swift +++ b/swift/Tests/Blockchains/ZilliqaTests.swift @@ -8,7 +8,7 @@ import WalletCore class ZilliqaTests: XCTestCase { let coin = CoinType.zilliqa - let privateKey = PrivateKey(data: Data(hexString: "0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748")!)! + let privateKey = PrivateKey(data: Data(hexString: "0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748")!, curve: CoinType.zilliqa.curve)! func testConfig() { XCTAssertEqual(coin.hrp, .zilliqa) diff --git a/swift/Tests/HDWalletTests.swift b/swift/Tests/HDWalletTests.swift index c36a17c62e3..9a3fe8541e2 100644 --- a/swift/Tests/HDWalletTests.swift +++ b/swift/Tests/HDWalletTests.swift @@ -75,7 +75,7 @@ class HDWalletTests: XCTestCase { func testMasterKey() { let wallet = HDWallet(mnemonic: "tiny escape drive pupil flavor endless love walk gadget match filter luxury", passphrase: "")! XCTAssertEqual(wallet.seed.hexString, "d430216f5b506dfd281d6ff6e92150d205868923df00774bc301e5ffdc2f4d1ad38a602017ddea6fc7d6315345d8b9cadbd8213ed2ffce5dfc550fa918665eb8") - let masterKey = wallet.getMasterKey(curve: Curve.secp256k1) + let masterKey = wallet.getMasterKey(curve: Curve.secp256k1)! XCTAssertEqual(masterKey.data.hexString, "e120fc1ef9d193a851926ebd937c3985dc2c4e642fb3d0832317884d5f18f3b3") } @@ -365,7 +365,7 @@ class HDWalletTests: XCTestCase { let wallet = HDWallet.test let key = wallet.getKeyForCoin(coin: eth) let hash = Data(hexString: "3F891FDA3704F0368DAB65FA81EBE616F4AA2A0854995DA4DC0B59D2CADBD64F")! - let result = key.sign(digest: hash, curve: .secp256k1)! + let result = key.sign(digest: hash)! let publicKey = key.getPublicKeySecp256k1(compressed: false) XCTAssertEqual(result.count, 65) diff --git a/swift/Tests/Keystore/AccountTests.swift b/swift/Tests/Keystore/AccountTests.swift index 772e741ea56..06e04567bfb 100755 --- a/swift/Tests/Keystore/AccountTests.swift +++ b/swift/Tests/Keystore/AccountTests.swift @@ -17,8 +17,8 @@ class AccountTests: XCTestCase { let wallet = Wallet(keyURL: URL(fileURLWithPath: "/"), key: key) let hash = Data(hexString: "3F891FDA3704F0368DAB65FA81EBE616F4AA2A0854995DA4DC0B59D2CADBD64F")! - let privateKey = PrivateKey(data: wallet.key.decryptPrivateKey(password: password)!)! - let result = privateKey.sign(digest: hash, curve: .secp256k1)! + let privateKey = PrivateKey(data: wallet.key.decryptPrivateKey(password: password)!, curve: .secp256k1)! + let result = privateKey.sign(digest: hash)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) XCTAssertEqual(result.count, 65) @@ -32,7 +32,7 @@ class AccountTests: XCTestCase { let hash = Data(hexString: "3F891FDA3704F0368DAB65FA81EBE616F4AA2A0854995DA4DC0B59D2CADBD64F")! let hdwallet = wallet.key.wallet(password: password)! let privateKey = hdwallet.getKeyForCoin(coin: .ethereum) - let result = privateKey.sign(digest: hash, curve: .secp256k1)! + let result = privateKey.sign(digest: hash)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) XCTAssertEqual(result.count, 65) diff --git a/swift/Tests/Keystore/KeyStoreTests.swift b/swift/Tests/Keystore/KeyStoreTests.swift index 99b2815b825..405dfeac7d3 100755 --- a/swift/Tests/Keystore/KeyStoreTests.swift +++ b/swift/Tests/Keystore/KeyStoreTests.swift @@ -181,7 +181,7 @@ class KeyStoreTests: XCTestCase { XCTAssertNotNil(keyStore.keyWallet) XCTAssertNotNil(storedData) - XCTAssertNotNil(PrivateKey(data: storedData!)) + XCTAssertNotNil(PrivateKey(data: storedData!, curve: CoinType.ethereum.curve)) } func testImportPrivateKeyAES256() throws { @@ -195,17 +195,17 @@ class KeyStoreTests: XCTestCase { XCTAssertNotNil(keyStore.keyWallet) XCTAssertNotNil(storedData) - XCTAssertNotNil(PrivateKey(data: storedData!)) + XCTAssertNotNil(PrivateKey(data: storedData!, curve: CoinType.ethereum.curve)) } func testImportPrivateKey() throws { let keyStore = try KeyStore(keyDirectory: keyDirectory) - let privateKey = PrivateKey(data: Data(hexString: "9cdb5cab19aec3bd0fcd614c5f185e7a1d97634d4225730eba22497dc89a716c")!)! + let privateKey = PrivateKey(data: Data(hexString: "9cdb5cab19aec3bd0fcd614c5f185e7a1d97634d4225730eba22497dc89a716c")!, curve: CoinType.ethereum.curve)! let wallet = try keyStore.import(privateKey: privateKey, name: "name", password: "password", coin: .ethereum) let storedData = wallet.key.decryptPrivateKey(password: Data("password".utf8)) XCTAssertNotNil(storedData) - XCTAssertNotNil(PrivateKey(data: storedData!)) + XCTAssertNotNil(PrivateKey(data: storedData!, curve: CoinType.ethereum.curve)) XCTAssertEqual(wallet.accounts.count, 1) diff --git a/swift/Tests/PrivateKeyTests.swift b/swift/Tests/PrivateKeyTests.swift index 1fd2ce348bb..4d6a5050821 100644 --- a/swift/Tests/PrivateKeyTests.swift +++ b/swift/Tests/PrivateKeyTests.swift @@ -7,7 +7,7 @@ import XCTest class PrivateKeyTests: XCTestCase { func testCreateNew() { - let privateKey = PrivateKey() + let privateKey = PrivateKey(curve: .secp256k1) XCTAssertEqual(privateKey.data.count, TWPrivateKeySize) XCTAssertTrue(PrivateKey.isValid(data: privateKey.data, curve: .secp256k1)) @@ -15,23 +15,23 @@ class PrivateKeyTests: XCTestCase { } func testCreateFromInvalid() { - let privateKey = PrivateKey(data: Data(hexString: "0xdeadbeef")!) + let privateKey = PrivateKey(data: Data(hexString: "0xdeadbeef")!, curve: .secp256k1) XCTAssertNil(privateKey) } func testStarkKeyCreation() { let data = Data(hexString: "06cf0a8bf113352eb863157a45c5e5567abb34f8d32cddafd2c22aa803f4892c")! XCTAssertTrue(PrivateKey.isValid(data: data, curve: .starkex)) - let privateKey = PrivateKey(data: data)! + let privateKey = PrivateKey(data: data, curve: .starkex)! let pubKey = privateKey.getPublicKeyByType(pubkeyType: .starkex) XCTAssertEqual(pubKey.data.hexString, "02d2bbdc1adaf887b0027cdde2113cfd81c60493aa6dc15d7887ddf1a82bc831") } func testStarkKeySigning() { let data = Data(hexString: "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79")! - let privateKey = PrivateKey(data: data)! + let privateKey = PrivateKey(data: data, curve: .starkex)! let digest = Data(hexString: "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76")! - let signature = privateKey.sign(digest: digest, curve: .starkex)! + let signature = privateKey.sign(digest: digest)! XCTAssertEqual(signature.hexString, "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") } @@ -43,22 +43,30 @@ class PrivateKeyTests: XCTestCase { } func testPublicKey() { - let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!)! + let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .secp256k1)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) XCTAssertEqual(publicKey.data.hexString, "0499c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c166b489a4b7c491e7688e6ebea3a71fc3a1a48d60f98d5ce84c93b65e423fde91") } func testSignSchnorr() { - let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!)! - let publicKey = privateKey.getPublicKeySecp256k1(compressed: true) + let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .zilliqaschnorr)! + let publicKey = privateKey.getPublicKeyZilliqaSchnorr() let message = "hello schnorr".data(using: .utf8)! - let sig = privateKey.signZilliqaSchnorr(message: message)! - let verified = publicKey.verifyZilliqaSchnorr(signature: sig, message: message) + let sig = privateKey.sign(digest: message)! + let verified = publicKey.verify(signature: sig, message: message) XCTAssertEqual(sig.hexString, "d166b1ae7892c5ef541461dc12a50214d0681b63d8037cda29a3fe6af8bb973e4ea94624d85bc0010bdc1b38d05198328fae21254adc2bf5feaf2804d54dba55") XCTAssertTrue(verified) } + + func testSignWithoutCurve() { + let data = Data(hexString: "0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79")! + let privateKey = PrivateKey(data: data, curve: .starkex)! + let digest = Data(hexString: "06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76")! + let signature = privateKey.sign(digest: digest)! + XCTAssertEqual(signature.hexString, "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a") + } } diff --git a/swift/Tests/PublicKeyTests.swift b/swift/Tests/PublicKeyTests.swift index 026935dbb6d..ad0dfe51511 100644 --- a/swift/Tests/PublicKeyTests.swift +++ b/swift/Tests/PublicKeyTests.swift @@ -7,9 +7,9 @@ import XCTest class PublicKeyTests: XCTestCase { - let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!)! func testCompressed() { + let privateKey = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .secp256k1)! let publicKey = privateKey.getPublicKeySecp256k1(compressed: false) XCTAssertEqual(publicKey.compressed.data.hexString, "0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1") } @@ -17,16 +17,20 @@ class PublicKeyTests: XCTestCase { func testVerify() { let message = Hash.sha256(data: "hello".data(using: .utf8)!) - let sig1 = privateKey.sign(digest: message, curve: .ed25519)! - let result1 = privateKey.getPublicKeyEd25519() + + let privateKey1 = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .ed25519)! + let sig1 = privateKey1.sign(digest: message)! + let result1 = privateKey1.getPublicKeyEd25519() .verify(signature: sig1, message: message) - let sig2 = privateKey.sign(digest: message, curve: .ed25519Blake2bNano)! - let result2 = privateKey.getPublicKeyEd25519Blake2b() + let privateKey2 = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .ed25519Blake2bNano)! + let sig2 = privateKey2.sign(digest: message)! + let result2 = privateKey2.getPublicKeyEd25519Blake2b() .verify(signature: sig2, message: message) - let sig3 = privateKey.sign(digest: message, curve: .secp256k1)! - let result3 = privateKey.getPublicKeySecp256k1(compressed: true) + let privateKey3 = PrivateKey(data: Data(hexString: "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")!, curve: .secp256k1)! + let sig3 = privateKey3.sign(digest: message)! + let result3 = privateKey3.getPublicKeySecp256k1(compressed: true) .verify(signature: sig3, message: message) XCTAssertTrue(result1) diff --git a/swift/common-xcframework.yml b/swift/common-xcframework.yml index 962bbaf4239..e7d216caa18 100644 --- a/swift/common-xcframework.yml +++ b/swift/common-xcframework.yml @@ -8,8 +8,8 @@ options: macOS: 10.14 settings: base: - HEADER_SEARCH_PATHS: $(SRCROOT)/wallet-core ${SRCROOT}/trezor-crypto/crypto - SYSTEM_HEADER_SEARCH_PATHS: ${SRCROOT}/include ${SRCROOT}/../build/local/include ${SRCROOT}/trezor-crypto/include $(SRCROOT)/protobuf /usr/local/include /opt/homebrew/include + HEADER_SEARCH_PATHS: $(SRCROOT)/wallet-core + SYSTEM_HEADER_SEARCH_PATHS: ${SRCROOT}/include ${SRCROOT}/../build/local/include $(SRCROOT)/protobuf /usr/local/include /opt/homebrew/include CLANG_CXX_LANGUAGE_STANDARD: c++20 GCC_WARN_64_TO_32_BIT_CONVERSION: NO @@ -37,8 +37,6 @@ targets: - "Cosmos/Protobuf/*.proto" - "Hedera/Protobuf/*.proto" dependencies: - - target: trezor-crypto_${platform} - link: true - target: protobuf_${platform} link: true - sdk: libc++.tbd @@ -51,74 +49,6 @@ targets: CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: $(inherited) false OTHER_CFLAGS: $(inherited) -Wno-comma - trezor-crypto: - type: library.static - platform: [iOS, macOS] - deploymentTarget: - iOS: 12.0 - macOS: 10.14 - sources: - - trezor-crypto/crypto/bignum.c - - trezor-crypto/crypto/ecdsa.c - - trezor-crypto/crypto/curves.c - - trezor-crypto/crypto/secp256k1.c - - trezor-crypto/crypto/rand.c - - trezor-crypto/crypto/hmac.c - - trezor-crypto/crypto/bip32.c - - trezor-crypto/crypto/bip39.c - - trezor-crypto/crypto/pbkdf2.c - - trezor-crypto/crypto/base58.c - - trezor-crypto/crypto/base32.c - - trezor-crypto/crypto/address.c - - trezor-crypto/crypto/script.c - - trezor-crypto/crypto/ripemd160.c - - trezor-crypto/crypto/sha2.c - - trezor-crypto/crypto/sha3.c - - trezor-crypto/crypto/hasher.c - - trezor-crypto/crypto/aes/aescrypt.c - - trezor-crypto/crypto/aes/aeskey.c - - trezor-crypto/crypto/aes/aestab.c - - trezor-crypto/crypto/aes/aes_modes.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-32bit.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-helpers.c - - trezor-crypto/crypto/ed25519-donna/modm-donna-32bit.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-basepoint-table.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-32bit-tables.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-impl-base.c - - trezor-crypto/crypto/ed25519-donna/ed25519.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c - - trezor-crypto/crypto/ed25519-donna/ed25519-blake2b.c - - trezor-crypto/crypto/ed25519-donna/ed25519-sha3.c - - trezor-crypto/crypto/ed25519-donna/ed25519-keccak.c - - trezor-crypto/crypto/monero/base58.c - - trezor-crypto/crypto/monero/serialize.c - - trezor-crypto/crypto/monero/range_proof.c - - trezor-crypto/crypto/blake256.c - - trezor-crypto/crypto/blake2b.c - - trezor-crypto/crypto/blake2s.c - - trezor-crypto/crypto/chacha_drbg.c - - trezor-crypto/crypto/chacha20poly1305/chacha20poly1305.c - - trezor-crypto/crypto/chacha20poly1305/chacha_merged.c - - trezor-crypto/crypto/chacha20poly1305/poly1305-donna.c - - trezor-crypto/crypto/chacha20poly1305/rfc7539.c - - trezor-crypto/crypto/rc4.c - - trezor-crypto/crypto/nano.c - - trezor-crypto/crypto/nem.c - - trezor-crypto/crypto/cash_addr.c - - trezor-crypto/crypto/memzero.c - - trezor-crypto/crypto/scrypt.c - - trezor-crypto/crypto/nist256p1.c - - trezor-crypto/crypto/groestl.c - - trezor-crypto/crypto/hmac_drbg.c - - trezor-crypto/crypto/rfc6979.c - - trezor-crypto/crypto/zilliqa.c - - trezor-crypto/crypto/cardano.c - - trezor-crypto/crypto/shamir.c - - trezor-crypto/crypto/sodium/private/fe_25_5/fe.c - - trezor-crypto/crypto/sodium/private/ed25519_ref10.c - - trezor-crypto/crypto/sodium/private/ed25519_ref10_fe_25_5.c - - trezor-crypto/crypto/sodium/keypair.c - protobuf: type: library.static platform: [iOS, macOS] diff --git a/swift/project.yml b/swift/project.yml index 9d68acab6cd..33e88af61b4 100644 --- a/swift/project.yml +++ b/swift/project.yml @@ -4,8 +4,8 @@ options: createIntermediateGroups: true settings: base: - HEADER_SEARCH_PATHS: $(SRCROOT)/wallet-core ${SRCROOT}/trezor-crypto/crypto - SYSTEM_HEADER_SEARCH_PATHS: ${SRCROOT}/include ${SRCROOT}/../build/local/include ${SRCROOT}/trezor-crypto/include $(SRCROOT)/protobuf /usr/local/include /opt/homebrew/include + HEADER_SEARCH_PATHS: $(SRCROOT)/wallet-core + SYSTEM_HEADER_SEARCH_PATHS: ${SRCROOT}/include ${SRCROOT}/../build/local/include $(SRCROOT)/protobuf /usr/local/include /opt/homebrew/include CLANG_CXX_LANGUAGE_STANDARD: c++20 SWIFT_VERSION: 5.1 IPHONEOS_DEPLOYMENT_TARGET: 13.0 @@ -33,8 +33,6 @@ targets: - "Hedera/Protobuf/*.proto" - Sources dependencies: - - target: trezor-crypto - link: true - target: protobuf link: true - sdk: libc++.tbd @@ -72,74 +70,6 @@ targets: - target: WalletCore - sdk: libc++.tbd - trezor-crypto: - type: library.static - platform: iOS - sources: - - trezor-crypto/crypto/bignum.c - - trezor-crypto/crypto/ecdsa.c - - trezor-crypto/crypto/curves.c - - trezor-crypto/crypto/secp256k1.c - - trezor-crypto/crypto/rand.c - - trezor-crypto/crypto/hmac.c - - trezor-crypto/crypto/bip32.c - - trezor-crypto/crypto/bip39.c - - trezor-crypto/crypto/pbkdf2.c - - trezor-crypto/crypto/base58.c - - trezor-crypto/crypto/base32.c - - trezor-crypto/crypto/address.c - - trezor-crypto/crypto/script.c - - trezor-crypto/crypto/ripemd160.c - - trezor-crypto/crypto/sha2.c - - trezor-crypto/crypto/sha3.c - - trezor-crypto/crypto/hasher.c - - trezor-crypto/crypto/aes/aescrypt.c - - trezor-crypto/crypto/aes/aeskey.c - - trezor-crypto/crypto/aes/aestab.c - - trezor-crypto/crypto/aes/aes_modes.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-32bit.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-helpers.c - - trezor-crypto/crypto/ed25519-donna/modm-donna-32bit.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-basepoint-table.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-32bit-tables.c - - trezor-crypto/crypto/ed25519-donna/ed25519-donna-impl-base.c - - trezor-crypto/crypto/ed25519-donna/ed25519.c - - trezor-crypto/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c - - trezor-crypto/crypto/ed25519-donna/ed25519-blake2b.c - - trezor-crypto/crypto/ed25519-donna/ed25519-sha3.c - - trezor-crypto/crypto/ed25519-donna/ed25519-keccak.c - - trezor-crypto/crypto/monero/base58.c - - trezor-crypto/crypto/monero/serialize.c - - trezor-crypto/crypto/monero/range_proof.c - - trezor-crypto/crypto/blake256.c - - trezor-crypto/crypto/blake2b.c - - trezor-crypto/crypto/blake2s.c - - trezor-crypto/crypto/chacha_drbg.c - - trezor-crypto/crypto/chacha20poly1305/chacha20poly1305.c - - trezor-crypto/crypto/chacha20poly1305/chacha_merged.c - - trezor-crypto/crypto/chacha20poly1305/poly1305-donna.c - - trezor-crypto/crypto/chacha20poly1305/rfc7539.c - - trezor-crypto/crypto/rc4.c - - trezor-crypto/crypto/nano.c - - trezor-crypto/crypto/nem.c - - trezor-crypto/crypto/cash_addr.c - - trezor-crypto/crypto/memzero.c - - trezor-crypto/crypto/scrypt.c - - trezor-crypto/crypto/nist256p1.c - - trezor-crypto/crypto/groestl.c - - trezor-crypto/crypto/hmac_drbg.c - - trezor-crypto/crypto/rfc6979.c - - trezor-crypto/crypto/zilliqa.c - - trezor-crypto/crypto/cardano.c - - trezor-crypto/crypto/shamir.c - - trezor-crypto/crypto/sodium/private/fe_25_5/fe.c - - trezor-crypto/crypto/sodium/private/ed25519_ref10.c - - trezor-crypto/crypto/sodium/private/ed25519_ref10_fe_25_5.c - - trezor-crypto/crypto/sodium/keypair.c - settings: - GCC_WARN_64_TO_32_BIT_CONVERSION: NO - OTHER_CFLAGS: $(inherited) -Wno-comma - protobuf: type: library.static platform: iOS diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 87ec8f86384..9fa76638556 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,7 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/build/local/src/gtest/googletest-1.16.0 # Test executable file(GLOB_RECURSE test_sources *.cpp **/*.cpp **/*.cc) add_executable(tests ${test_sources}) -target_link_libraries(tests gtest_main TrezorCrypto TrustWalletCore walletconsolelib protobuf Boost::boost) +target_link_libraries(tests gtest_main TrustWalletCore walletconsolelib protobuf Boost::boost) target_include_directories(tests PRIVATE ${CMAKE_SOURCE_DIR}/src) target_include_directories(tests PRIVATE ${CMAKE_SOURCE_DIR}/tests/common) target_compile_options(tests PRIVATE "-Wall") diff --git a/tests/chains/Aion/TransactionCompilerTests.cpp b/tests/chains/Aion/TransactionCompilerTests.cpp index e10e739bec2..1b5afac8aac 100644 --- a/tests/chains/Aion/TransactionCompilerTests.cpp +++ b/tests/chains/Aion/TransactionCompilerTests.cpp @@ -23,7 +23,7 @@ namespace TW::Aion::tests { TEST(AionCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) auto privateKey = parse_hex("db33ffdf82c7ba903daf68d961d3c23c20471a8ce6b408e52d579fd8add80cc9"); - auto key = PrivateKey(privateKey); + auto key = PrivateKey(privateKey, TWCurveED25519); auto publicKey = key.getPublicKey(TWPublicKeyTypeED25519); Proto::SigningInput input; @@ -50,7 +50,7 @@ TEST(AionCompiler, CompileWithSignatures) { EXPECT_EQ(hex(preImageHash), "d4423fe7d233b85c1bf5b1120ec03842e572fb25f3755f7a20bc83addc8c4d85"); // Simulate signature, normally obtained from signature server - const auto signature = key.sign(preImageHash, TWCurveED25519); + const auto signature = key.sign(preImageHash); /// Step 3: Compile transaction info auto outputData = diff --git a/tests/chains/Algorand/AddressTests.cpp b/tests/chains/Algorand/AddressTests.cpp index 993b0e3247c..7d3371042ed 100644 --- a/tests/chains/Algorand/AddressTests.cpp +++ b/tests/chains/Algorand/AddressTests.cpp @@ -29,7 +29,7 @@ TEST(AlgorandAddress, Validation) { } TEST(AlgorandAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("526d96fffdbfe787b2f00586298538f9a019e97f6587964dc61aae9ad1d7fa23")); + auto privateKey = PrivateKey(parse_hex("526d96fffdbfe787b2f00586298538f9a019e97f6587964dc61aae9ad1d7fa23"), TWCurveED25519); auto address = Address(privateKey.getPublicKey(TWPublicKeyTypeED25519)); ASSERT_EQ(address.string(), "JBCQYJ2FREG667NAN7BFKH4RFIKPT7CYDQJNW3SNN5Z7F7ILFLKQ346TSU"); } @@ -39,7 +39,7 @@ TEST(AlgorandAddress, FromPublicKey) { auto address = Address(publicKey); ASSERT_EQ(address.string(), "YK2CHL5IWAEV4WXBAVTIXENSCMW3JWW36OFM7RSJBDJUO2QADEP5QYVO5I"); - auto privateKey2 = PrivateKey(parse_hex("0806c458b262edd333a191e92f561aff338211ee3e18ab315a074a2d82aa343f")); + auto privateKey2 = PrivateKey(parse_hex("0806c458b262edd333a191e92f561aff338211ee3e18ab315a074a2d82aa343f"), TWCurveSECP256k1); auto publicKey2 = privateKey2.getPublicKey(TWPublicKeyTypeSECP256k1Extended); EXPECT_ANY_THROW(new Address(publicKey2)); } diff --git a/tests/chains/Aptos/TWAnySignerTests.cpp b/tests/chains/Aptos/TWAnySignerTests.cpp index b0ad67d6d8c..c1b44907593 100644 --- a/tests/chains/Aptos/TWAnySignerTests.cpp +++ b/tests/chains/Aptos/TWAnySignerTests.cpp @@ -26,7 +26,7 @@ TEST(TWAnySignerAptos, TxSign) { input.set_gas_unit_price(100); input.set_expiration_timestamp_secs(3664390082); input.set_chain_id(33); - auto privateKey = PrivateKey(parse_hex("5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec")); + auto privateKey = PrivateKey(parse_hex("5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec"), TWCoinTypeCurve(TWCoinTypeAptos)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); Proto::SigningOutput output; ANY_SIGN(input, TWCoinTypeAptos); @@ -85,7 +85,7 @@ TEST(TWAnySignerAptos, TxSignWithABI) { "u64", "bool" ])"); - auto privateKey = PrivateKey(parse_hex("5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec")); + auto privateKey = PrivateKey(parse_hex("5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec"), TWCoinTypeCurve(TWCoinTypeAptos)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); Proto::SigningOutput output; ANY_SIGN(input, TWCoinTypeAptos); diff --git a/tests/chains/Binance/TWWalletConnectSigning.cpp b/tests/chains/Binance/TWWalletConnectSigning.cpp index 7ee7e7956f4..b9ee8a4094b 100644 --- a/tests/chains/Binance/TWWalletConnectSigning.cpp +++ b/tests/chains/Binance/TWWalletConnectSigning.cpp @@ -7,7 +7,7 @@ #include "proto/WalletConnect.pb.h" #include "Coin.h" #include -#include +#include #include "TestUtilities.h" #include diff --git a/tests/chains/BinanceSmartChain/SignerTests.cpp b/tests/chains/BinanceSmartChain/SignerTests.cpp index c9196d6b53b..53addde1c4e 100644 --- a/tests/chains/BinanceSmartChain/SignerTests.cpp +++ b/tests/chains/BinanceSmartChain/SignerTests.cpp @@ -60,7 +60,7 @@ TEST(BinanceSmartChain, SignTokenTransfer) { auto tokenContractAddress = "0xed24fc36d5ee211ea25a80239fb8c4cfd80f12ee"; auto dummyAmount = store(uint256_t(0)); // addr: 0xB9F5771C27664bF2282D98E09D7F50cEc7cB01a7 mnemonic: isolate dismiss ... cruel note - auto privateKey = PrivateKey(parse_hex("4f96ed80e9a7555a6f74b3d658afdd9c756b0a40d4ca30c42c2039eb449bb904")); + auto privateKey = PrivateKey(parse_hex("4f96ed80e9a7555a6f74b3d658afdd9c756b0a40d4ca30c42c2039eb449bb904"), TWCoinTypeCurve(TWCoinTypeSmartChain)); input.set_chain_id(chainId.data(), chainId.size()); input.set_nonce(nonce.data(), nonce.size()); diff --git a/tests/chains/BinanceSmartChain/TWAnyAddressTests.cpp b/tests/chains/BinanceSmartChain/TWAnyAddressTests.cpp index 139e6a8368b..13ca90a3794 100644 --- a/tests/chains/BinanceSmartChain/TWAnyAddressTests.cpp +++ b/tests/chains/BinanceSmartChain/TWAnyAddressTests.cpp @@ -13,7 +13,7 @@ using namespace TW; TEST(TWBinanceSmartChain, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("727f677b390c151caf9c206fd77f77918f56904b5504243db9b21e51182c4c06").get(), TWCoinTypeCurve(TWCoinTypeSmartChain))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false)); auto string = "0xf3d468DBb386aaD46E92FF222adDdf872C8CC064"; diff --git a/tests/chains/Bitcoin/MessageSignerTests.cpp b/tests/chains/Bitcoin/MessageSignerTests.cpp index d55cded3107..8b04383336f 100644 --- a/tests/chains/Bitcoin/MessageSignerTests.cpp +++ b/tests/chains/Bitcoin/MessageSignerTests.cpp @@ -21,7 +21,7 @@ namespace TW::Bitcoin::MessageSignerTests { -const auto gPrivateKey = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); +const auto gPrivateKey = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCoinTypeCurve(TWCoinTypeBitcoin)); TEST(BitcoinMessageSigner, VerifyMessage) { EXPECT_TRUE(MessageSigner::verifyMessage( @@ -152,7 +152,7 @@ TEST(TWBitcoinMessageSigner, VerifyMessage) { TEST(TWBitcoinMessageSigner, SignAndVerify) { const auto privKeyData = "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeBitcoin))); const auto address = STRING("19cAJn4Ms8jodBBGtroBNNpCZiHAWGAq7X"); const auto message = STRING("test signature"); diff --git a/tests/chains/Bitcoin/TWAnyAddressTests.cpp b/tests/chains/Bitcoin/TWAnyAddressTests.cpp index f482783a01b..62c271c25b8 100644 --- a/tests/chains/Bitcoin/TWAnyAddressTests.cpp +++ b/tests/chains/Bitcoin/TWAnyAddressTests.cpp @@ -15,7 +15,7 @@ namespace TW::Bitcoin::tests { void testBitcoinAddressFromPublicKeyDerivation(const char* privateKey, TWDerivation derivation, const char* expectedAddr) { const auto data = DATA(privateKey); - const auto privkey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(data.get())); + const auto privkey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(data.get(), TWCoinTypeCurve(TWCoinTypeBitcoin))); const auto pubkey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyByType(privkey.get(), TWPublicKeyTypeSECP256k1)); const auto addr = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKeyDerivation(pubkey.get(), TWCoinTypeBitcoin, derivation)); const auto addrDescription = WRAPS(TWAnyAddressDescription(addr.get())); diff --git a/tests/chains/Bitcoin/TWBitcoinPsbtTests.cpp b/tests/chains/Bitcoin/TWBitcoinPsbtTests.cpp index 83ef3a6c6ba..57bb5cf23be 100644 --- a/tests/chains/Bitcoin/TWBitcoinPsbtTests.cpp +++ b/tests/chains/Bitcoin/TWBitcoinPsbtTests.cpp @@ -12,7 +12,7 @@ namespace TW::Bitcoin::PsbtTests { -const auto gPrivateKey = PrivateKey(parse_hex("f00ffbe44c5c2838c13d2778854ac66b75e04eb6054f0241989e223223ad5e55")); +const auto gPrivateKey = PrivateKey(parse_hex("f00ffbe44c5c2838c13d2778854ac66b75e04eb6054f0241989e223223ad5e55"), TWCoinTypeCurve(TWCoinTypeBitcoin)); const auto gPsbt = parse_hex("70736274ff0100bc0200000001147010db5fbcf619067c1090fec65c131443fbc80fb4aaeebe940e44206098c60000000000ffffffff0360ea000000000000160014f22a703617035ef7f490743d50f26ae08c30d0a70000000000000000426a403d3a474149412e41544f4d3a636f736d6f7331737377797a666d743675396a373437773537753438746778646575393573757a666c6d7175753a303a743a35303e12000000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d000000000001011f6603010000000000160014b139199ec796f36fc42e637f42da8e3e6720aa9d00000000"); TEST(TWBitcoinPsbt, SignThorSwap) { diff --git a/tests/chains/Bitcoin/TWBitcoinSigningTests.cpp b/tests/chains/Bitcoin/TWBitcoinSigningTests.cpp index ed56956b738..f8accd9173b 100644 --- a/tests/chains/Bitcoin/TWBitcoinSigningTests.cpp +++ b/tests/chains/Bitcoin/TWBitcoinSigningTests.cpp @@ -378,7 +378,7 @@ TEST(BitcoinSigning, SignBRC20TransferCommitV2) { auto forFeeAmount = fullAmount - brcInscribeAmount - minerFee; auto txId = parse_hex("089098890d2653567b9e8df2d1fbe5c3c8bf1910ca7184e301db0ad3b495c88e"); - PrivateKey key(privateKey); + PrivateKey key(privateKey, TWCurveSECP256k1); auto pubKey = key.getPublicKey(TWPublicKeyTypeSECP256k1); TW::BitcoinV2::Proto::SigningInput signing; @@ -1372,7 +1372,7 @@ SigningInput buildInputP2SH_P2WPKH(bool omitScript = false, bool omitKeys = fals input.changeAddress = "1FQc5LdgGHMHEN9nwkjmz6tWkxhPpxBvBU"; input.coinType = TWCoinTypeBitcoin; - auto utxoKey0 = PrivateKey(parse_hex("eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf")); + auto utxoKey0 = PrivateKey(parse_hex("eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf"), TWCurveSECP256k1); auto pubKey0 = utxoKey0.getPublicKey(TWPublicKeyTypeSECP256k1); auto utxoPubkeyHash = Hash::ripemd(Hash::sha256(pubKey0.bytes)); assert(hex(utxoPubkeyHash) == "79091972186c449eb1ded22b78e40d009bdf0089"); diff --git a/tests/chains/Bitcoin/TransactionCompilerTests.cpp b/tests/chains/Bitcoin/TransactionCompilerTests.cpp index fd1aeb639c6..0c9c0b1af34 100644 --- a/tests/chains/Bitcoin/TransactionCompilerTests.cpp +++ b/tests/chains/Bitcoin/TransactionCompilerTests.cpp @@ -249,9 +249,9 @@ TEST(BitcoinCompiler, CompileWithSignatures) { // 2 private keys are needed (despite >2 UTXOs) auto key0 = parse_hex("4646464646464646464646464646464646464646464646464646464646464646"); auto key1 = parse_hex("7878787878787878787878787878787878787878787878787878787878787878"); - EXPECT_EQ(hex(PrivateKey(key0).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), + EXPECT_EQ(hex(PrivateKey(key0, TWCurveSECP256k1).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), hex(inPubKey0)); - EXPECT_EQ(hex(PrivateKey(key1).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), + EXPECT_EQ(hex(PrivateKey(key1, TWCurveSECP256k1).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), hex(inPubKey1)); *input.add_private_key() = std::string(key0.begin(), key0.end()); *input.add_private_key() = std::string(key1.begin(), key1.end()); @@ -299,7 +299,7 @@ TEST(BitcoinCompiler, CompileWithSignaturesV2) { Bitcoin::Proto::SigningInput inputLegacy; auto& input = *inputLegacy.mutable_signing_v2(); - const PrivateKey alicePrivateKey(parse_hex("56429688a1a6b00b90ccd22a0de0a376b6569d8684022ae92229a28478bfb657")); + const PrivateKey alicePrivateKey(parse_hex("56429688a1a6b00b90ccd22a0de0a376b6569d8684022ae92229a28478bfb657"), TWCurveSECP256k1); const auto alicePublicKey = alicePrivateKey.getPublicKey(TWPublicKeyTypeSECP256k1); const auto bobPublicKey = parse_hex("037ed9a436e11ec4947ac4b7823787e24ba73180f1edd2857bff19c9f4d62b65bf"); @@ -351,7 +351,7 @@ TEST(BitcoinCompiler, CompileWithSignaturesV2) { // Step 3: Simulate signature, normally obtained from signature server - const auto sig0 = alicePrivateKey.sign(data(sighash0.sighash()), TWCurveSECP256k1); + const auto sig0 = alicePrivateKey.sign(data(sighash0.sighash())); EXPECT_EQ(hex(sig0), "78eda020d4b86fcb3af78ef919912e6d79b81164dbbb0b0b96da6ac58a2de4b11a5fd8d48734d5a02371c4b5ee551a69dca3842edbf577d863cf8ae9fdbbd45900"); // Step 4: Compile transaction info diff --git a/tests/chains/BitcoinCash/TWBitcoinCashTests.cpp b/tests/chains/BitcoinCash/TWBitcoinCashTests.cpp index d29e118c648..c2afdd8be9d 100644 --- a/tests/chains/BitcoinCash/TWBitcoinCashTests.cpp +++ b/tests/chains/BitcoinCash/TWBitcoinCashTests.cpp @@ -60,7 +60,7 @@ TEST(BitcoinCash, InvalidAddress) { } TEST(BitcoinCash, LegacyToCashAddr) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("28071bf4e2b0340db41b807ed8a5514139e5d6427ff9d58dbd22b7ed187103a4").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("28071bf4e2b0340db41b807ed8a5514139e5d6427ff9d58dbd22b7ed187103a4").get(), TWCoinTypeCurve(TWCoinTypeBitcoinCash))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), 0)); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); diff --git a/tests/chains/Cardano/AddressTests.cpp b/tests/chains/Cardano/AddressTests.cpp index c42ea1b5402..0edcac40785 100644 --- a/tests/chains/Cardano/AddressTests.cpp +++ b/tests/chains/Cardano/AddressTests.cpp @@ -144,16 +144,6 @@ TEST(CardanoAddress, MnemonicToAddressV3) { // check entropy EXPECT_EQ("30a6f50aeb58ff7699b822d63e0ef27aeff17d9f", hex(wallet.getEntropy())); - { - PrivateKey masterPrivKey = wallet.getMasterKey(TWCurve::TWCurveED25519ExtendedCardano); - PrivateKey masterPrivKeyExt = wallet.getMasterKeyExtension(TWCurve::TWCurveED25519ExtendedCardano); - // the two together matches first half of keypair - ASSERT_EQ("a018cd746e128a0be0782b228c275473205445c33b9000a33dd5668b430b5744", hex(masterPrivKey.bytes)); - ASSERT_EQ("26877cfe435fddda02409b839b7386f3738f10a30b95a225f4b720ee71d2505b", hex(masterPrivKeyExt.bytes)); - - PublicKey masterPublicKey = masterPrivKey.getPublicKey(TWPublicKeyTypeED25519); - ASSERT_EQ("3aecb95953edd0b16db20366097ddedcb3512fe36193473c5fca2af774d44739", hex(masterPublicKey.bytes)); - } { string addr = wallet.deriveAddress(TWCoinType::TWCoinTypeCardano); EXPECT_EQ("addr1qxxe304qg9py8hyyqu8evfj4wln7dnms943wsugpdzzsxnkvvjljtzuwxvx0pnwelkcruy95ujkq3aw6rl0vvg32x35qc92xkq", addr); @@ -246,7 +236,7 @@ TEST(CardanoAddress, MnemonicToAddressV3) { // V2 Tested against AdaLite auto mnemonicPlay1 = "youth away raise north opinion slice dash bus soldier dizzy bitter increase saddle live champion"; auto wallet = HDWallet(mnemonicPlay1, ""); - PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, DerivationPathIndex(0, true).derivationIndex(), 0, 0)); + PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, 0, 0, 0)); PublicKey publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); string addr = AddressV2(publicKey).string(); EXPECT_EQ("Ae2tdPwUPEZJYT9g1JgQWtLveUHavyRxQGi6hVzoQjct7yyCLGgk3pCyx7h", addr); @@ -255,7 +245,7 @@ TEST(CardanoAddress, MnemonicToAddressV3) { // V2 Tested against AdaLite auto mnemonicPlay2 = "return custom two home gain guilt kangaroo supply market current curtain tomorrow heavy blue robot"; auto wallet = HDWallet(mnemonicPlay2, ""); - PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, DerivationPathIndex(0, true).derivationIndex(), 0, 0)); + PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, 0, 0, 0)); PublicKey publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); string addr = AddressV2(publicKey).string(); EXPECT_EQ("Ae2tdPwUPEZLtJx7LA2XZ3zzwonH9x9ieX3dMzaTBD3TfXuKczjMSjTecr1", addr); @@ -265,7 +255,7 @@ TEST(CardanoAddress, MnemonicToAddressV3) { // In AdaLite V1 addr0 is DdzFFzCqrht7HGoJ87gznLktJGywK1LbAJT2sbd4txmgS7FcYLMQFhawb18ojS9Hx55mrbsHPr7PTraKh14TSQbGBPJHbDZ9QVh6Z6Di auto mnemonicALDemo = "civil void tool perfect avocado sweet immense fluid arrow aerobic boil flash"; auto wallet = HDWallet(mnemonicALDemo, ""); - PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, DerivationPathIndex(0, true).derivationIndex(), 0, 0)); + PrivateKey privateKey = wallet.getKey(TWCoinTypeCardano, DerivationPath(TWPurposeBIP44, TWCoinTypeCardano, 0, 0, 0)); PublicKey publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); string addr = AddressV2(publicKey).string(); EXPECT_EQ("Ae2tdPwUPEZJbLcD8iLgN7hVGvq66WdR4zocntRekSP97Ds3MvCfmEDjJYu", addr); @@ -320,13 +310,11 @@ TEST(CardanoAddress, FromDataV3_Base) { TEST(CardanoAddress, FromPrivateKeyV3) { { // from cardano-crypto.js test - auto privateKey = PrivateKey( + EXPECT_ANY_THROW(PrivateKey( parse_hex("d809b1b4b4c74734037f76aace501730a3fe2fca30b5102df99ad3f7c0103e48"), parse_hex("d54cde47e9041b31f3e6873d700d83f7a937bea746dadfa2c5b0a6a92502356c"), parse_hex("69272d81c376382b8a87c21370a7ae9618df8da708d1a9490939ec54ebe43000"), - dummyKey, dummyKey, dummyKey); - auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519); - EXPECT_ANY_THROW(new AddressV3(publicKey)); + dummyKey, dummyKey, dummyKey, TWCurveED25519)); } } @@ -409,7 +397,7 @@ TEST(CardanoAddress, FromPrivateKeyV2) { parse_hex("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744"), parse_hex("309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71eff"), parse_hex("bf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4"), - dummyKey, dummyKey, dummyKey + dummyKey, dummyKey, dummyKey, TWCurveED25519ExtendedCardano ); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); ASSERT_EQ(hex(publicKey.bytes), @@ -426,7 +414,7 @@ TEST(CardanoAddress, FromPrivateKeyV2) { parse_hex("a089c9423100960440ccd5b7adbd202d1ab1993a7bb30fc88b287d94016df247"), parse_hex("da86a87f08fb15de1431a6c0ccd5ebf51c3bee81f7eaf714801bbbe4d903154a"), parse_hex("e513fa1290da1d22e83a41f17eed72d4489483b561fff36b9555ffdb91c430e2"), - dummyKey, dummyKey, dummyKey + dummyKey, dummyKey, dummyKey, TWCurveED25519ExtendedCardano ); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); ASSERT_EQ(hex(publicKey.bytes), @@ -443,7 +431,7 @@ TEST(CardanoAddress, FromPrivateKeyV2) { parse_hex("d809b1b4b4c74734037f76aace501730a3fe2fca30b5102df99ad3f7c0103e48"), parse_hex("d54cde47e9041b31f3e6873d700d83f7a937bea746dadfa2c5b0a6a92502356c"), parse_hex("69272d81c376382b8a87c21370a7ae9618df8da708d1a9490939ec54ebe43000"), - dummyKey, dummyKey, dummyKey + dummyKey, dummyKey, dummyKey, TWCurveED25519ExtendedCardano ); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); ASSERT_EQ(hex(publicKey.bytes), @@ -456,13 +444,11 @@ TEST(CardanoAddress, FromPrivateKeyV2) { } { // from cardano-crypto.js test - auto privateKey = PrivateKey( + EXPECT_ANY_THROW(PrivateKey( parse_hex("d809b1b4b4c74734037f76aace501730a3fe2fca30b5102df99ad3f7c0103e48"), parse_hex("d54cde47e9041b31f3e6873d700d83f7a937bea746dadfa2c5b0a6a92502356c"), parse_hex("69272d81c376382b8a87c21370a7ae9618df8da708d1a9490939ec54ebe43000"), - dummyKey, dummyKey, dummyKey); - auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519); - EXPECT_ANY_THROW(new AddressV2(publicKey)); + dummyKey, dummyKey, dummyKey, TWCurveED25519)); } } @@ -472,14 +458,14 @@ TEST(CardanoAddress, PrivateKeyExtended) { parse_hex("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744"), parse_hex("309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71eff"), parse_hex("bf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4"), - dummyKey, dummyKey, dummyKey + dummyKey, dummyKey, dummyKey, TWCurveED25519ExtendedCardano ); auto publicKeyExt = privateKeyExt.getPublicKey(TWPublicKeyTypeED25519Cardano); ASSERT_EQ(128ul, publicKeyExt.bytes.size()); // Non-extended: both are 32 bytes. auto privateKeyNonext = PrivateKey( - parse_hex("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744")); + parse_hex("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744"), TWCurveED25519); auto publicKeyNonext = privateKeyNonext.getPublicKey(TWPublicKeyTypeED25519); ASSERT_EQ(32ul, publicKeyNonext.bytes.size()); } diff --git a/tests/chains/Cardano/SigningTests.cpp b/tests/chains/Cardano/SigningTests.cpp index aa2e4fb5763..6856feec9bf 100644 --- a/tests/chains/Cardano/SigningTests.cpp +++ b/tests/chains/Cardano/SigningTests.cpp @@ -143,7 +143,7 @@ TEST(CardanoSigning, SendNft) { utxo3->set_address(fromAddress); utxo3->set_amount(2000000); - PrivateKey privKey(parse_hex(fromAddressPrivKey)); + PrivateKey privKey(parse_hex(fromAddressPrivKey), TWCurveED25519ExtendedCardano); input.add_private_key(privKey.bytes.data(), privKey.bytes.size()); // Set an output info. @@ -1012,7 +1012,9 @@ TEST(CardanoSigning, SignMessageWithKey) { "69272d81c376382b8a87c21370a7ae9618df8da708d1a9490939ec54ebe43000" "1111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111111111" - "1111111111111111111111111111111111111111111111111111111111111111")); + "1111111111111111111111111111111111111111111111111111111111111111"), + TWCurveED25519ExtendedCardano + ); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Cardano); EXPECT_EQ(hex(publicKey.bytes), @@ -1024,7 +1026,7 @@ TEST(CardanoSigning, SignMessageWithKey) { const auto sampleMessageStr = "Hello world"; const auto sampleMessage = data(sampleMessageStr); - const auto signature = privateKey.sign(sampleMessage, TWCurveED25519ExtendedCardano); + const auto signature = privateKey.sign(sampleMessage); const auto sampleRightSignature = "1096ddcfb2ad21a4c0d861ef3fabe18841e8de88105b0d8e36430d7992c588634ead4100c32b2800b31b65e014d54a8238bdda63118d829bf0bcf1b631e86f0e"; EXPECT_EQ(hex(signature), sampleRightSignature); diff --git a/tests/chains/Cardano/TWCardanoAddressTests.cpp b/tests/chains/Cardano/TWCardanoAddressTests.cpp index d18caf17f49..5ff83f710c3 100644 --- a/tests/chains/Cardano/TWCardanoAddressTests.cpp +++ b/tests/chains/Cardano/TWCardanoAddressTests.cpp @@ -19,7 +19,7 @@ TEST(TWCardano, AddressFromPublicKey) { auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA( "b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71effbf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4" "639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7bed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a" - ).get())); + ).get(), TWCoinTypeCurve(TWCoinTypeCardano))); ASSERT_NE(nullptr, privateKey.get()); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyEd25519Cardano(privateKey.get())); ASSERT_NE(nullptr, publicKey.get()); diff --git a/tests/chains/Cosmos/CosmosTestHelpers.h b/tests/chains/Cosmos/CosmosTestHelpers.h index 50e81c4459f..650d9884289 100644 --- a/tests/chains/Cosmos/CosmosTestHelpers.h +++ b/tests/chains/Cosmos/CosmosTestHelpers.h @@ -68,7 +68,7 @@ namespace TW::Cosmos::tests::internal { } static inline void testCreateFromPrivKey(const CosmosAddressParameters& addressParameters) { - auto privateKey = PrivateKey(parse_hex(addressParameters.privKey)); + auto privateKey = PrivateKey(parse_hex(addressParameters.privKey), TWCoinTypeCurve(addressParameters.coinType)); auto address = Address(addressParameters.coinType, privateKey.getPublicKey(addressParameters.publicKeyType)); ASSERT_EQ(address.string(), addressParameters.address); } diff --git a/tests/chains/Cosmos/NativeInjective/TransactionCompilerTests.cpp b/tests/chains/Cosmos/NativeInjective/TransactionCompilerTests.cpp index 2bf1a12785a..c71cc623d9a 100644 --- a/tests/chains/Cosmos/NativeInjective/TransactionCompilerTests.cpp +++ b/tests/chains/Cosmos/NativeInjective/TransactionCompilerTests.cpp @@ -19,7 +19,7 @@ TEST(NativeInjectiveCompiler, CompileWithSignatures) { TW::Cosmos::Proto::SigningInput input; PrivateKey privateKey = - PrivateKey(parse_hex("727513ec3c54eb6fae24f2ff756bbc4c89b82945c6538bbd173613ae3de719d3")); + PrivateKey(parse_hex("727513ec3c54eb6fae24f2ff756bbc4c89b82945c6538bbd173613ae3de719d3"), TWCoinTypeCurve(coin)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); /// Step 1: Prepare transaction input (protobuf) diff --git a/tests/chains/Cosmos/TransactionCompilerTests.cpp b/tests/chains/Cosmos/TransactionCompilerTests.cpp index e55e966a13f..f70e77a427a 100644 --- a/tests/chains/Cosmos/TransactionCompilerTests.cpp +++ b/tests/chains/Cosmos/TransactionCompilerTests.cpp @@ -25,7 +25,7 @@ TEST(CosmosCompiler, CompileWithSignatures) { TW::Cosmos::Proto::SigningInput input; PrivateKey privateKey = - PrivateKey(parse_hex("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af")); + PrivateKey(parse_hex("8bbec3772ddb4df68f3186440380c301af116d1422001c1877d6f5e4dba8c8af"), TWCoinTypeCurve(coin)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); /// Step 1: Prepare transaction input (protobuf) diff --git a/tests/chains/ECash/TWECashTests.cpp b/tests/chains/ECash/TWECashTests.cpp index bd9f5738b3b..1ca9d6ff98e 100644 --- a/tests/chains/ECash/TWECashTests.cpp +++ b/tests/chains/ECash/TWECashTests.cpp @@ -57,7 +57,7 @@ TEST(ECash, InvalidAddress) { } TEST(ECash, LegacyToECashAddr) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("28071bf4e2b0340db41b807ed8a5514139e5d6427ff9d58dbd22b7ed187103a4").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("28071bf4e2b0340db41b807ed8a5514139e5d6427ff9d58dbd22b7ed187103a4").get(), TWCoinTypeCurve(TWCoinTypeECash))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), 0)); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); diff --git a/tests/chains/EOS/AddressTests.cpp b/tests/chains/EOS/AddressTests.cpp index 28aed7426a4..7bb2594660a 100644 --- a/tests/chains/EOS/AddressTests.cpp +++ b/tests/chains/EOS/AddressTests.cpp @@ -53,7 +53,7 @@ TEST(EOSAddress, FromPrivateKey) { "PUB_K1_6enPVMggisfqVVRZ1tj47d9UeHK46CBssoCmAz6sLDMBdtZk78"}; for (int i = 0; i < 4; i++) { - const auto privateKey = PrivateKey(parse_hex(privArray[i])); + const auto privateKey = PrivateKey(parse_hex(privArray[i]), privTypes[i] == Type::ModernR1 ? TWCurveNIST256p1 : TWCurveSECP256k1); const auto publicKey = PublicKey(privateKey.getPublicKey(privTypes[i] == Type::ModernR1 ? TWPublicKeyTypeNIST256p1 : TWPublicKeyTypeSECP256k1)); const auto address = Address(publicKey, privTypes[i]); diff --git a/tests/chains/EOS/TransactionCompilerTests.cpp b/tests/chains/EOS/TransactionCompilerTests.cpp index bb4bb23f72b..be5b2233d36 100644 --- a/tests/chains/EOS/TransactionCompilerTests.cpp +++ b/tests/chains/EOS/TransactionCompilerTests.cpp @@ -67,7 +67,7 @@ TEST(EOSCompiler, CompileWithSignatures) { EXPECT_EQ(hex(preImageHash), "14fc3299ee3e1113096bf1869dfa14c04a7ffdedd8ebdabf530683e4cfcd726c"); // Simulate signature, normally obtained from signature server - const PublicKey publicKey = PrivateKey(key).getPublicKey(TWPublicKeyTypeNIST256p1); + const PublicKey publicKey = PrivateKey(key, TWCurveNIST256p1).getPublicKey(TWPublicKeyTypeNIST256p1); const auto signature = parse_hex("1f6c4efceb5a6dadab271fd7e2153d97d22690938475b23f017cf9ec29e20d25725e90e541e130daa83c38fc4c933725f05837422c3f4a51f8c1d07208c8fd5e0b"); // data("SIG_K1_K9RdLC7DEDWjTfR64GU8BtDHcAjzR1ntcT651JMcfHNTpdsvDrUwfyzF1FkvL9fxEi2UCtGJZ9zYoNbJoMF1fbU64cRiJ7"); /// Step 3: Compile transaction info diff --git a/tests/chains/EOS/TransactionTests.cpp b/tests/chains/EOS/TransactionTests.cpp index 684aac0228e..8cb6bb50017 100644 --- a/tests/chains/EOS/TransactionTests.cpp +++ b/tests/chains/EOS/TransactionTests.cpp @@ -24,9 +24,9 @@ static std::string k1Sigs[5]{ static std::string r1Sigs[5]{ "SIG_R1_KC4qBxibZpXLESzN37F46Jv8w7dQtyPDeRmeFs8Z4DmEFhr3FACLkjcbSLkVN7acBt4eb6zUa9N76UfJncr4htxCSe7huZ", - "SIG_R1_KaWNQefJReykjKUsS51caChJRgeywUoeuucFReyKY1SPNveSoFFVgxT3jEzW56ZLtpN7qGgekoSNsKs1BzzyZ9snhCALcG", - "SIG_R1_KarN7JJxHeKgRJLmscWzCsdDpfdktWrBGJLvVFN7RYZpSeNHBsqNV7dKqxkvKtbhsqHukLKw1EQNTjcUcxUD6hUTVvNWcP", - "SIG_R1_KvHdcwEDW8RQWEPTA3BoK9RVZqtAwKqVvYQN9Wz44XUrzjrNyRkpc7vguqc8q6FLMJBUUen59hyXM3BuLvvrp2x4S6m1o8", + "SIG_R1_K11q2EFGPGXwAXMxFSoDUeEpSvXAdxLcHe9mFkQtJTZNBmaGtgKGvTAPN9eFg91Ub7Jf7tCuPkakQbGWGwE6KjA2Eez1zR", + "SIG_R1_K1MpistvFFsrrWDrgzJb7KAjquVwazP8e2tSKLogBzgoGp65dDhzf4unVunQnzQMX92ZA9CdRV8TdDRmjW9o2pdaG62G4P", + "SIG_R1_KLo6EWpBTjyawSGXyQyQDay1b5kMdoNTJGwsycRcpybqpwjhTntLi6XZpZWbu3P6JF9XmEBqDPPXhwJNGnu9YJ7x8Deuwd", "SIG_R1_KZB6ivprUS1zwGxMxZQJ7UvWk4Tpvoo6WiFKUPJuUHj4Es39ejiFVoD7ZB6MfSJxAaRPvnAF39hnApwzFAM8Erxmj3Suvm"}; TEST(EOSTransaction, Serialization) { @@ -55,7 +55,7 @@ TEST(EOSTransaction, Serialization) { // make transaction invalid and see if signing succeeds tx.maxNetUsageWords = UINT32_MAX; - ASSERT_THROW(signer.sign(PrivateKey(Hash::sha256(std::string("A"))), Type::ModernK1, tx), std::invalid_argument); + ASSERT_THROW(signer.sign(PrivateKey(Hash::sha256(std::string("A")), TWCurveSECP256k1), Type::ModernK1, tx), std::invalid_argument); referenceBlockId = parse_hex("000067d6f6a7e7799a1f3d487439a679f8cf95f1c986f35c0d2fa320f51a7144"); referenceBlockTime = 1554209118; diff --git a/tests/chains/Ethereum/EthereumMessageSignerTests.cpp b/tests/chains/Ethereum/EthereumMessageSignerTests.cpp index 6165fe32e47..524db7230f8 100644 --- a/tests/chains/Ethereum/EthereumMessageSignerTests.cpp +++ b/tests/chains/Ethereum/EthereumMessageSignerTests.cpp @@ -22,7 +22,7 @@ std::string load_file(const std::string& path) { namespace TW::Ethereum { TEST(EthereumEip712, SignMessageAndVerifyLegacy) { - PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")); + PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"), TWCurveSECP256k1); auto msg = R"( { "types": { @@ -56,7 +56,7 @@ namespace TW::Ethereum { } TEST(EthereumEip712, SignMessageAndVerifyEip155) { - PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")); + PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"), TWCurveSECP256k1); auto msg = R"( { "types": { @@ -90,7 +90,7 @@ namespace TW::Ethereum { } TEST(EthereumEip712, SignMessageAndVerifyInvalidEip155) { - PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")); + PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"), TWCurveSECP256k1); auto msg = R"( { "types": { @@ -122,7 +122,7 @@ namespace TW::Ethereum { } TEST(EthereumEip191, SignMessageAndVerifyLegacy) { - PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")); + PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"), TWCurveSECP256k1); auto msg = "Foo"; auto signature = Ethereum::MessageSigner::signMessage(ethKey, msg, MessageType::Legacy); ASSERT_EQ(signature, "21a779d499957e7fd39392d49a079679009e60e492d9654a148829be43d2490736ec72bc4a5644047d979c3cf4ebe2c1c514044cf436b063cb89fc6676be71101b"); @@ -131,7 +131,7 @@ namespace TW::Ethereum { } TEST(EthereumEip191, SignMessageAndVerifyEip155) { - PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d")); + PrivateKey ethKey(parse_hex("03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"), TWCurveSECP256k1); auto msg = "Foo"; auto signature = Ethereum::MessageSigner::signMessage(ethKey, msg, MessageType::Eip155, 0); ASSERT_EQ(signature, "21a779d499957e7fd39392d49a079679009e60e492d9654a148829be43d2490736ec72bc4a5644047d979c3cf4ebe2c1c514044cf436b063cb89fc6676be711023"); @@ -140,7 +140,7 @@ namespace TW::Ethereum { } TEST(EthereumEip191, SignMessageAndVerifyImmutableX) { - PrivateKey ethKey(parse_hex("3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84")); + PrivateKey ethKey(parse_hex("3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84"), TWCurveSECP256k1); auto msg = "Only sign this request if you’ve initiated an action with Immutable X.\n\nFor internal use:\nbd717ba31dca6e0f3f136f7c4197babce5f09a9f25176044c0b3112b1b6017a3"; auto signature = Ethereum::MessageSigner::signMessage(ethKey, msg, MessageType::ImmutableX); ASSERT_EQ(signature, "32cd5a58f3419fc5db672e3d57f76199b853eda0856d491b38f557b629b0a0814ace689412bf354a1af81126d2749207dffae8ae8845160f33948a6b787e17ee01"); @@ -150,7 +150,7 @@ namespace TW::Ethereum { TEST(TWEthereumMessageSigner, SignAndVerifyImmutableX) { const auto privKeyData = "3b0a61f46fdae924007146eacb6db6642de7a5603ad843ec58e10331d89d4b84"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); const auto message = STRING("Only sign this request if you’ve initiated an action with Immutable X.\n\nFor internal use:\nbd717ba31dca6e0f3f136f7c4197babce5f09a9f25176044c0b3112b1b6017a3"); const auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeEthereum)); @@ -161,7 +161,7 @@ namespace TW::Ethereum { TEST(TWEthereumMessageSigner, SignAndVerifyLegacy) { const auto privKeyData = "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); const auto message = STRING("Foo"); const auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeEthereum)); @@ -172,7 +172,7 @@ namespace TW::Ethereum { TEST(TWEthereumMessageSigner, SignAndVerifyEip155) { const auto privKeyData = "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); const auto message = STRING("Foo"); const auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeEthereum)); @@ -183,7 +183,7 @@ namespace TW::Ethereum { TEST(TWEthereumEip712, SignMessageAndVerifyLegacy) { const auto privKeyData = "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); auto msg = STRING(R"( { "types": { @@ -218,7 +218,7 @@ namespace TW::Ethereum { TEST(TWEthereumEip712, SignMessageAndVerifyEip155) { const auto privKeyData = "03a9ca895dca1623c7dfd69693f7b4111f5d819d2e145536e0b03c136025a25d"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); auto msg = STRING(R"( { "types": { @@ -259,7 +259,7 @@ namespace TW::Ethereum { auto typeData = load_file(path); const auto privKeyData = "9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeEthereum))); auto msg = STRING(typeData.c_str()); auto expected = "cb3a4684a991014a387a04a85b59227ebb79567c2025addcb296b4ca856e9f810d3b526f2a0d0fad6ad1b126b3b9516f8b3be020a7cca9c03ce3cf47f4199b6d1b"; const auto signature = WRAPS(TWEthereumMessageSignerSignTypedMessage(privateKey.get(), msg.get())); @@ -269,7 +269,7 @@ namespace TW::Ethereum { // Test `TWEthereumMessageSignerSignTypedMessageEip155` where `domain.chainId` is a base10 decimal string. // Generated by using https://metamask.github.io/test-dapp/ TEST(EthereumEip712, SignMessageAndVerifyEip155ChainIdString) { - PrivateKey ethKey(parse_hex("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0")); + PrivateKey ethKey(parse_hex("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0"), TWCurveSECP256k1); // 5600 auto chainId = 0x15e0; auto msg = R"( diff --git a/tests/chains/Ethereum/TWAnySignerTests.cpp b/tests/chains/Ethereum/TWAnySignerTests.cpp index f1ffacc0a1e..5e0b9fb8c1a 100644 --- a/tests/chains/Ethereum/TWAnySignerTests.cpp +++ b/tests/chains/Ethereum/TWAnySignerTests.cpp @@ -491,7 +491,7 @@ TEST(TWAnySignerEthereum, StakeRocketPool) { auto maxInclusionFeePerGas = store(uint256_t(1000000000)); auto toAddress = "0x2cac916b2a963bf162f076c0a8a4a8200bcfbfb4"; auto key = parse_hex("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498"); - const auto pk = PrivateKey(key); + const auto pk = PrivateKey(key, TWCurveSECP256k1); // 0.01 ETH auto valueData = store(uint256_t(10000000000000000)); @@ -540,7 +540,7 @@ TEST(TWAnySignerEthereum, UnstakeRocketPool) { auto maxInclusionFeePerGas = store(uint256_t(1000000000)); auto toAddress = "0xae78736Cd615f374D3085123A210448E74Fc6393"; auto key = parse_hex("9f56448d33de406db1561aae15fce64bdf0e9706ff15c45d4409e8fcbfd1a498"); - const auto pk = PrivateKey(key); + const auto pk = PrivateKey(key, TWCurveSECP256k1); auto valueData = store(uint256_t(0)); diff --git a/tests/chains/Everscale/AddressTests.cpp b/tests/chains/Everscale/AddressTests.cpp index f984140bd74..16bb5a983b8 100644 --- a/tests/chains/Everscale/AddressTests.cpp +++ b/tests/chains/Everscale/AddressTests.cpp @@ -36,7 +36,7 @@ TEST(EverscaleAddress, FromString) { } TEST(EverscaleAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("5b59e0372d19b6355c73fa8cc708fa3301ae2ec21bb6277e8b79d386ccb7846f")); + auto privateKey = PrivateKey(parse_hex("5b59e0372d19b6355c73fa8cc708fa3301ae2ec21bb6277e8b79d386ccb7846f"), TWCurveED25519); auto address = Address(privateKey.getPublicKey(TWPublicKeyTypeED25519), WorkchainType::Basechain); ASSERT_EQ(address.string(), "0:269fee242eb410786abe1777a14785c8bbeb1e34100c7570e17698b36ad66fb0"); } diff --git a/tests/chains/Evmos/TransactionCompilerTests.cpp b/tests/chains/Evmos/TransactionCompilerTests.cpp index 47a700bdf94..bd2dcd051ab 100644 --- a/tests/chains/Evmos/TransactionCompilerTests.cpp +++ b/tests/chains/Evmos/TransactionCompilerTests.cpp @@ -19,7 +19,7 @@ TEST(EvmosCompiler, CompileWithSignatures) { TW::Cosmos::Proto::SigningInput input; PrivateKey privateKey = - PrivateKey(parse_hex("727513ec3c54eb6fae24f2ff756bbc4c89b82945c6538bbd173613ae3de719d3")); + PrivateKey(parse_hex("727513ec3c54eb6fae24f2ff756bbc4c89b82945c6538bbd173613ae3de719d3"), TWCoinTypeCurve(coin)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); /// Step 1: Prepare transaction input (protobuf) diff --git a/tests/chains/FIO/AddressTests.cpp b/tests/chains/FIO/AddressTests.cpp index ffc99746168..c052f97bd2c 100644 --- a/tests/chains/FIO/AddressTests.cpp +++ b/tests/chains/FIO/AddressTests.cpp @@ -47,7 +47,7 @@ TEST(FIOAddress, FromStringInvalid) { } TEST(FIOAddress, FromPublicKey) { - auto key = PrivateKey(parse_hex("ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854")); + auto key = PrivateKey(parse_hex("ea8eb60b7e5868e218f248e032769020b4fea5dcfd02f2992861eaf4fb534854"), TWCurveSECP256k1); auto publicKey = key.getPublicKey(TWPublicKeyTypeSECP256k1); EXPECT_EQ(hex(publicKey.bytes), "0271195c66ec2799e436757a70cd8431d4b17733a097b18a5f7f1b6b085978ff0f"); auto address = Address(publicKey); diff --git a/tests/chains/FIO/EncryptionTests.cpp b/tests/chains/FIO/EncryptionTests.cpp index db8341d9eb4..81974e2b4a7 100644 --- a/tests/chains/FIO/EncryptionTests.cpp +++ b/tests/chains/FIO/EncryptionTests.cpp @@ -111,21 +111,21 @@ TEST(FIOEncryption, getSharedSecret) { // tests extracted from https://github.com/fioprotocol/fiojs/blob/master/src/tests/encryption-fio.test.ts // See also https://github.com/fioprotocol/fiojs/blob/master/docs/message_encryption.md { - const PrivateKey privateKey(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90")); + const PrivateKey privateKey(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90"), TWCurveSECP256k1); const PublicKey publicKey(parse_hex("024edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10"), TWPublicKeyTypeSECP256k1); Data secret = Encryption::getSharedSecret(privateKey, publicKey); EXPECT_EQ(secret.size(), 64ul); EXPECT_EQ(hex(secret), "a71b4ec5a9577926a1d2aa1d9d99327fd3b68f6a1ea597200a0d890bd3331df300a2d49fec0b2b3e6969ce9263c5d6cf47c191c1ef149373ecc9f0d98116b598"); } { - const PrivateKey privateKey(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9")); + const PrivateKey privateKey(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9"), TWCurveSECP256k1); const PublicKey publicKey(parse_hex("039997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803be"), TWPublicKeyTypeSECP256k1); Data secret = Encryption::getSharedSecret(privateKey, publicKey); EXPECT_EQ(secret.size(), 64ul); EXPECT_EQ(hex(secret), "a71b4ec5a9577926a1d2aa1d9d99327fd3b68f6a1ea597200a0d890bd3331df300a2d49fec0b2b3e6969ce9263c5d6cf47c191c1ef149373ecc9f0d98116b598"); } { - const PrivateKey privateKey(parse_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")); + const PrivateKey privateKey(parse_hex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), TWCurveSECP256k1); const PublicKey publicKey(parse_hex("03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd"), TWPublicKeyTypeSECP256k1); Data secret = Encryption::getSharedSecret(privateKey, publicKey); EXPECT_EQ(secret.size(), 64ul); @@ -136,7 +136,7 @@ TEST(FIOEncryption, getSharedSecret) { TEST(FIOEncryption, encryptAndEncode) { // tests extracted from https://github.com/fioprotocol/fiojs/blob/master/src/tests/encryption-fio.test.ts { - const PrivateKey privateKey(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90")); + const PrivateKey privateKey(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90"), TWCurveSECP256k1); const PublicKey publicKey(parse_hex("024edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10"), TWPublicKeyTypeSECP256k1); const Data message = parse_hex("0b70757273652e616c69636501310a66696f2e7265716f6274000000"); const Data iv = parse_hex("f300888ca4f512cebdc0020ff0f7224c"); @@ -146,7 +146,7 @@ TEST(FIOEncryption, encryptAndEncode) { EXPECT_EQ(encoded, "8wCIjKT1Es69wAIP8PciTA2ymExK2a+xJinwGoxqdjKLveF0BWVdxOPLMNrScplvsd6o5mLmQL4ZPiXUEUepBMVxtmSnOBq0HvBiRIrB4gU="); } { - const PrivateKey privateKey(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9")); + const PrivateKey privateKey(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9"), TWCurveSECP256k1); const PublicKey publicKey(parse_hex("039997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803be"), TWPublicKeyTypeSECP256k1); const Data message = parse_hex("0b70757273652e616c69636501310a66696f2e7265716f6274000000"); const Data iv = parse_hex("f300888ca4f512cebdc0020ff0f7224c"); @@ -158,11 +158,11 @@ TEST(FIOEncryption, encryptAndEncode) { } TEST(FIOEncryption, encryptEncodeDecodeDecrypt) { - const PrivateKey privateKeyAlice(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90")); + const PrivateKey privateKeyAlice(parse_hex("2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90"), TWCurveSECP256k1); const PublicKey publicKeyAlice = privateKeyAlice.getPublicKey(TWPublicKeyTypeSECP256k1); const Address addressAlice(publicKeyAlice); EXPECT_EQ(addressAlice.string(), "FIO7zsqi7QUAjTAdyynd6DVe8uv4K8gCTRHnAoMN9w9CA1xLCTDVv"); - const PrivateKey privateKeyBob(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9")); + const PrivateKey privateKeyBob(parse_hex("81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9"), TWCurveSECP256k1); const PublicKey publicKeyBob = privateKeyBob.getPublicKey(TWPublicKeyTypeSECP256k1); const Address addressBob(publicKeyBob); EXPECT_EQ(addressBob.string(), "FIO5VE6Dgy9FUmd1mFotXwF88HkQN1KysCWLPqpVnDMjRvGRi1YrM"); diff --git a/tests/chains/FIO/SignerTests.cpp b/tests/chains/FIO/SignerTests.cpp index a3104e15afc..194a0e3a7e6 100644 --- a/tests/chains/FIO/SignerTests.cpp +++ b/tests/chains/FIO/SignerTests.cpp @@ -9,6 +9,7 @@ #include "Base58.h" #include "Hash.h" #include "HexCoding.h" +#include "TestUtilities.h" #include @@ -24,7 +25,7 @@ TEST(FIOSigner, SignEncode) { TEST(FIOSigner, SignInternals) { // 5KEDWtAUJcFX6Vz38WXsAQAv2geNqT7UaZC8gYu9kTuryr3qkri FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf - PrivateKey pk = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")); + PrivateKey pk = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035"), TWCoinTypeCurve(TWCoinTypeFIO)); { Data pk2 = parse_hex("80"); append(pk2, pk.bytes); @@ -77,7 +78,7 @@ TEST(FIOSigner, Actor) { TEST(FIOSigner, compile) { const Data chainId = parse_hex("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77"); // 5KEDWtAUJcFX6Vz38WXsAQAv2geNqT7UaZC8gYu9kTuryr3qkri FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf - const PrivateKey privKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")); + const PrivateKey privKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035"), TWCoinTypeCurve(TWCoinTypeFIO)); const PublicKey pubKey6M = privKeyBA.getPublicKey(TWPublicKeyTypeSECP256k1); const Address addr6M(pubKey6M); Proto::SigningInput input; diff --git a/tests/chains/FIO/TWFIOTests.cpp b/tests/chains/FIO/TWFIOTests.cpp index 1c4f35285b3..311e6015e68 100644 --- a/tests/chains/FIO/TWFIOTests.cpp +++ b/tests/chains/FIO/TWFIOTests.cpp @@ -19,7 +19,7 @@ namespace TW::FIO::TWFIOTests { using namespace std; TEST(TWFIO, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035").get(), TWCoinTypeCurve(TWCoinTypeFIO))); ASSERT_NE(nullptr, privateKey.get()); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false)); ASSERT_NE(nullptr, publicKey.get()); @@ -39,7 +39,7 @@ TEST(TWFIO, Address) { const Data gChainId = parse_hex("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77"); const Data gChainIdMainnet = parse_hex("21dcae42c0182200e93f954a074011f9048a7624c6fe81d3c9541a614a88bd1c"); // 5KEDWtAUJcFX6Vz38WXsAQAv2geNqT7UaZC8gYu9kTuryr3qkri FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf -const PrivateKey privKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")); +const PrivateKey privKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035"), TWCoinTypeCurve(TWCoinTypeFIO)); const PublicKey pubKey6M = privKeyBA.getPublicKey(TWPublicKeyTypeSECP256k1); const Address addr6M(pubKey6M); diff --git a/tests/chains/FIO/TransactionBuilderTests.cpp b/tests/chains/FIO/TransactionBuilderTests.cpp index 16f16f92b06..556eca7bfd1 100644 --- a/tests/chains/FIO/TransactionBuilderTests.cpp +++ b/tests/chains/FIO/TransactionBuilderTests.cpp @@ -10,6 +10,7 @@ #include "BinaryCoding.h" #include "HexCoding.h" +#include "TestUtilities.h" #include #include @@ -19,7 +20,7 @@ using namespace std; const Data chainId = parse_hex("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77"); // 5KEDWtAUJcFX6Vz38WXsAQAv2geNqT7UaZC8gYu9kTuryr3qkri FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf -const PrivateKey gPrivKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")); +const PrivateKey gPrivKeyBA = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035"), TWCoinTypeCurve(TWCoinTypeFIO)); const PublicKey gPubKey6MA = gPrivKeyBA.getPublicKey(TWPublicKeyTypeSECP256k1); const Address gAddr6M(gPubKey6MA); diff --git a/tests/chains/FIO/TransactionCompilerTests.cpp b/tests/chains/FIO/TransactionCompilerTests.cpp index f3eaecbc159..635cee64a51 100644 --- a/tests/chains/FIO/TransactionCompilerTests.cpp +++ b/tests/chains/FIO/TransactionCompilerTests.cpp @@ -32,7 +32,7 @@ using namespace std; TEST(FIOCompiler, CompileWithSignatures) { Data chainId = parse_hex("4e46572250454b796d7296eec9e8896327ea82dd40f2cd74cf1b1d8ba90bcd77"); // 5KEDWtAUJcFX6Vz38WXsAQAv2geNqT7UaZC8gYu9kTuryr3qkri FIO6m1fMdTpRkRBnedvYshXCxLFiC5suRU8KDfx8xxtXp2hntxpnf - PrivateKey privateKey = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035")); + PrivateKey privateKey = PrivateKey(parse_hex("ba0828d5734b65e3bcc2c51c93dfc26dd71bd666cc0273adee77d73d9a322035"), TWCoinTypeCurve(TWCoinTypeFIO)); PublicKey pubKeyA = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); Address addrA(pubKeyA); const auto coin = TWCoinTypeFIO; diff --git a/tests/chains/Filecoin/SignerTests.cpp b/tests/chains/Filecoin/SignerTests.cpp index 8eccd8f6f76..7d0852c9e8b 100644 --- a/tests/chains/Filecoin/SignerTests.cpp +++ b/tests/chains/Filecoin/SignerTests.cpp @@ -6,6 +6,7 @@ #include "Filecoin/Signer.h" #include "HexCoding.h" #include "PrivateKey.h" +#include "TestUtilities.h" #include @@ -13,7 +14,7 @@ namespace TW::Filecoin { TEST(FilecoinSigner, DerivePublicKey) { const PrivateKey privateKey( - parse_hex("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe")); + parse_hex("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe"), TWCoinTypeCurve(TWCoinTypeFilecoin)); const PublicKey publicKey((privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended))); const Address address = Address::secp256k1Address(publicKey); ASSERT_EQ(address.string(), "f1z4a36sc7mfbv4z3qwutblp2flycdui3baffytbq"); @@ -21,7 +22,7 @@ TEST(FilecoinSigner, DerivePublicKey) { TEST(FilecoinSigner, Sign) { const PrivateKey privateKey( - parse_hex("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe")); + parse_hex("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe"), TWCoinTypeCurve(TWCoinTypeFilecoin)); const PublicKey publicKey((privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended))); const Address fromAddress = Address::secp256k1Address(publicKey); const Address toAddress("f1rletqqhinhagw6nxjcr4kbfws25thgt7owzuruy"); diff --git a/tests/chains/Filecoin/TransactionCompilerTests.cpp b/tests/chains/Filecoin/TransactionCompilerTests.cpp index f04883c127d..13277eb9393 100644 --- a/tests/chains/Filecoin/TransactionCompilerTests.cpp +++ b/tests/chains/Filecoin/TransactionCompilerTests.cpp @@ -26,7 +26,7 @@ TEST(FilecoinCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) Filecoin::Proto::SigningInput input; auto privateKey = parse_hex("1d969865e189957b9824bd34f26d5cbf357fda1a6d844cbf0c9ab1ed93fa7dbe"); - auto key = PrivateKey(privateKey); + auto key = PrivateKey(privateKey, TWCurveSECP256k1); auto publicKey = key.getPublicKey(TWPublicKeyTypeSECP256k1Extended); auto toAddress = "f3um6uo3qt5of54xjbx3hsxbw5mbsc6auxzrvfxekn5bv3duewqyn2tg5rhrlx73qahzzpkhuj7a34iq7oifsq"; @@ -60,7 +60,7 @@ TEST(FilecoinCompiler, CompileWithSignatures) { EXPECT_EQ(hex(preImageHash), "8368c0f622b2c529c7fa147d75aa02aaa7fc13fc4847d4dc57e7a5c59048aafe"); // Simulate signature, normally obtained from signature server - const auto signature = key.sign(preImageHash, TWCurveSECP256k1); + const auto signature = key.sign(preImageHash); /// Step 3: Compile transaction info auto outputData = diff --git a/tests/chains/Filecoin/TransactionTests.cpp b/tests/chains/Filecoin/TransactionTests.cpp index 82650f13499..73db00acad1 100644 --- a/tests/chains/Filecoin/TransactionTests.cpp +++ b/tests/chains/Filecoin/TransactionTests.cpp @@ -7,6 +7,8 @@ #include "HexCoding.h" #include "PrivateKey.h" +#include + #include namespace TW::Filecoin { @@ -23,7 +25,7 @@ TEST(FilecoinTransaction, EncodeBigInt) { TEST(FilecoinTransaction, Serialize) { const PrivateKey privateKey( - parse_hex("2f0f1d2c8de955c7c3fb4d9cae02539fadcb13fa998ccd9a1e871bed95f1941e")); + parse_hex("2f0f1d2c8de955c7c3fb4d9cae02539fadcb13fa998ccd9a1e871bed95f1941e"), TWCoinTypeCurve(TWCoinTypeFilecoin)); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); const Address fromAddress = Address::secp256k1Address(publicKey); const Address toAddress("f1hvadvq4rd2pyayrigjx2nbqz2nvemqouslw4wxi"); diff --git a/tests/chains/Firo/TWFiroAddressTests.cpp b/tests/chains/Firo/TWFiroAddressTests.cpp index 9054b6100c5..3bb59cc65b8 100644 --- a/tests/chains/Firo/TWFiroAddressTests.cpp +++ b/tests/chains/Firo/TWFiroAddressTests.cpp @@ -18,7 +18,7 @@ #include TEST(TWZCoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeFiro))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeFiro))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); diff --git a/tests/chains/Greenfield/TransactionCompilerTests.cpp b/tests/chains/Greenfield/TransactionCompilerTests.cpp index 9766bbcaa0c..ddfbe747e4f 100644 --- a/tests/chains/Greenfield/TransactionCompilerTests.cpp +++ b/tests/chains/Greenfield/TransactionCompilerTests.cpp @@ -23,7 +23,7 @@ TEST(GreenfieldCompiler, PreHashCompile) { // Successfully broadcasted https://greenfieldscan.com/tx/0x9f895cf2dd64fb1f428cefcf2a6585a813c3540fc9fe1ef42db1da2cb1df55ab auto privateKeyData = parse_hex("9066aa168c379a403becb235c15e7129c133c244e56a757ab07bc369288bcab0"); - PrivateKey privateKey(privateKeyData); + PrivateKey privateKey(privateKeyData, TWCurveSECP256k1); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); Proto::SigningInput input; @@ -60,7 +60,7 @@ TEST(GreenfieldCompiler, PreHashCompile) { // Step 2: Sign "remotely" - auto signature = privateKey.sign(data(preOutput.data_hash()), TWCurveSECP256k1); + auto signature = privateKey.sign(data(preOutput.data_hash())); EXPECT_EQ(hex(signature), "cb3a4684a991014a387a04a85b59227ebb79567c2025addcb296b4ca856e9f810d3b526f2a0d0fad6ad1b126b3b9516f8b3be020a7cca9c03ce3cf47f4199b6d00"); diff --git a/tests/chains/Groestlcoin/AddressTests.cpp b/tests/chains/Groestlcoin/AddressTests.cpp index 8fcce675012..1087102d79d 100644 --- a/tests/chains/Groestlcoin/AddressTests.cpp +++ b/tests/chains/Groestlcoin/AddressTests.cpp @@ -18,7 +18,7 @@ TEST(GroestlcoinAddress, FromPublicKey) { const auto address = Address(publicKey, 36); ASSERT_EQ(address.string(), "Fj62rBJi8LvbmWu2jzkaUX1NFXLEqDLoZM"); - const auto privateKey = PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")); + const auto privateKey = PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a"), TWCoinTypeCurve(TWCoinTypeGroestlcoin)); const auto publicKey2 = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeED25519)); EXPECT_ANY_THROW(new Address(publicKey2, 36)); } diff --git a/tests/chains/Groestlcoin/TWGroestlcoinSigningTests.cpp b/tests/chains/Groestlcoin/TWGroestlcoinSigningTests.cpp index 128edf79144..eef9548fc4a 100644 --- a/tests/chains/Groestlcoin/TWGroestlcoinSigningTests.cpp +++ b/tests/chains/Groestlcoin/TWGroestlcoinSigningTests.cpp @@ -133,7 +133,7 @@ TEST(GroestlcoinSigning, SignP2SH_P2WPKH) { input.set_change_address("grs1qw4teyraux2s77nhjdwh9ar8rl9dt7zww8r6lne"); // TX input - auto utxoKey0 = PrivateKey(parse_hex("302fc195a8fc96c5a581471e67e4c1ac2efda252f76ad5c77a53764c70d58f91")); + auto utxoKey0 = PrivateKey(parse_hex("302fc195a8fc96c5a581471e67e4c1ac2efda252f76ad5c77a53764c70d58f91"), TWCoinTypeCurve(TWCoinTypeGroestlcoin)); auto pubKey0 = utxoKey0.getPublicKey(TWPublicKeyTypeSECP256k1); auto utxoPubkeyHash = Hash::ripemd(Hash::sha256(pubKey0.bytes)); EXPECT_EQ(hex(utxoPubkeyHash), "2fc7d70acef142d1f7b5ef2f20b1a9b759797674"); diff --git a/tests/chains/Groestlcoin/TWGroestlcoinTests.cpp b/tests/chains/Groestlcoin/TWGroestlcoinTests.cpp index bb186cfd48f..18332219c78 100644 --- a/tests/chains/Groestlcoin/TWGroestlcoinTests.cpp +++ b/tests/chains/Groestlcoin/TWGroestlcoinTests.cpp @@ -15,7 +15,7 @@ #include TEST(Groestlcoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("3c3385ddc6fd95ba7282051aeb440bc75820b8c10db5c83c052d7586e3e98e84").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("3c3385ddc6fd95ba7282051aeb440bc75820b8c10db5c83c052d7586e3e98e84").get(), TWCoinTypeCurve(TWCoinTypeGroestlcoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWGroestlcoinAddress, TWGroestlcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeGroestlcoin))); auto addressString = WRAPS(TWGroestlcoinAddressDescription(address.get())); diff --git a/tests/chains/Groestlcoin/TransactionCompilerTests.cpp b/tests/chains/Groestlcoin/TransactionCompilerTests.cpp index dfe513977cf..fbc8c99062f 100644 --- a/tests/chains/Groestlcoin/TransactionCompilerTests.cpp +++ b/tests/chains/Groestlcoin/TransactionCompilerTests.cpp @@ -77,7 +77,7 @@ TEST(GroestlcoinCompiler, CompileWithSignatures) { "0fb3da786ad1028574f0b40ff1446515eb85cacccff3f3d0459e191b660597b3"); // compile - auto publicKey = PrivateKey(utxoKey0).getPublicKey(TWPublicKeyTypeSECP256k1); + auto publicKey = PrivateKey(utxoKey0, TWCoinTypeCurve(coin)).getPublicKey(TWPublicKeyTypeSECP256k1); auto signature = parse_hex("304402202163ab98b028aa13563f0de00b785d6df81df5eac0b7c91d23f5be7ea674aa3702202bf6cd7055c6f8f697ce045b1a4f9b997cf6e5761a661d27696ac34064479d19"); { const Data outputData = diff --git a/tests/chains/Harmony/AddressTests.cpp b/tests/chains/Harmony/AddressTests.cpp index 3d7786b76be..6366bfbc882 100644 --- a/tests/chains/Harmony/AddressTests.cpp +++ b/tests/chains/Harmony/AddressTests.cpp @@ -5,6 +5,7 @@ #include "Harmony/Address.h" #include "HexCoding.h" #include "PrivateKey.h" +#include "TestUtilities.h" #include @@ -38,7 +39,7 @@ TEST(HarmonyAddress, InvalidHarmonyAddress) { TEST(HarmonyAddress, FromPublicKey) { const auto privateKey = - PrivateKey(parse_hex("e2f88b4974ae763ca1c2db49218802c2e441293a09eaa9ab681779e05d1b7b94")); + PrivateKey(parse_hex("e2f88b4974ae763ca1c2db49218802c2e441293a09eaa9ab681779e05d1b7b94"), TWCoinTypeCurve(TWCoinTypeHarmony)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended)); const auto address = Address(publicKey); ASSERT_EQ(address.string(), "one1a50tun737ulcvwy0yvve0pvu5skq0kjargvhwe"); diff --git a/tests/chains/Harmony/SignerTests.cpp b/tests/chains/Harmony/SignerTests.cpp index dc917bf26b5..97205319f02 100644 --- a/tests/chains/Harmony/SignerTests.cpp +++ b/tests/chains/Harmony/SignerTests.cpp @@ -4,6 +4,7 @@ #include +#include "TestUtilities.h" #include "Ethereum/RLP.h" #include "Harmony/Address.h" #include "Harmony/Signer.h" @@ -54,7 +55,7 @@ TEST(HarmonySigner, RLPEncodingAndHashAssumeLocalNet) { TEST(HarmonySigner, SignAssumeLocalNet) { auto key = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); auto signer = SignerExposed(LOCAL_NET); uint256_t v("0x28"); @@ -77,7 +78,7 @@ TEST(HarmonySigner, SignProtoBufAssumeLocalNet) { trasactionMsg->set_to_address(TEST_RECEIVER.string()); const auto privateKey = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); auto payload = parse_hex(""); trasactionMsg->set_payload(payload.data(), payload.size()); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); @@ -119,7 +120,7 @@ TEST(HarmonySigner, SignOverProtoBufAssumeMainNet) { auto trasactionMsg = input.mutable_transaction_message(); trasactionMsg->set_to_address(TEST_RECEIVER.string()); const auto privateKey = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); auto payload = parse_hex(""); trasactionMsg->set_payload(payload.data(), payload.size()); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); @@ -166,7 +167,7 @@ TEST(HarmonySigner, BuildSigningOutput) { auto trasactionMsg = input.mutable_transaction_message(); trasactionMsg->set_to_address(TEST_RECEIVER.string()); const auto privateKey = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); auto payload = parse_hex(""); trasactionMsg->set_payload(payload.data(), payload.size()); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); @@ -216,7 +217,7 @@ TEST(HarmonySigner, BuildUnsignedTxBytes) { auto trasactionMsg = input.mutable_transaction_message(); trasactionMsg->set_to_address(TEST_RECEIVER.string()); const auto privateKey = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); auto payload = parse_hex(""); trasactionMsg->set_payload(payload.data(), payload.size()); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); @@ -254,7 +255,7 @@ TEST(HarmonySigner, BuildUnsignedStakingTxBytes) { auto input = Proto::SigningInput(); auto stakingMsg = input.mutable_staking_message(); const auto privateKey = - PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto value = store(MAIN_NET); diff --git a/tests/chains/Harmony/StakingTests.cpp b/tests/chains/Harmony/StakingTests.cpp index bbcce90bb7d..e54112a936e 100644 --- a/tests/chains/Harmony/StakingTests.cpp +++ b/tests/chains/Harmony/StakingTests.cpp @@ -20,7 +20,7 @@ static bool testAccountDecodeResult = Address::decode("one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9", TEST_ACCOUNT); static auto PRIVATE_KEY = - PrivateKey(parse_hex("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48")); + PrivateKey(parse_hex("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48"), TWCoinTypeCurve(TWCoinTypeHarmony)); TEST(HarmonyStaking, SignCreateValidator) { auto input = Proto::SigningInput(); diff --git a/tests/chains/Harmony/TWHarmonyStakingTests.cpp b/tests/chains/Harmony/TWHarmonyStakingTests.cpp index 5c0283c81f0..3db381203e3 100644 --- a/tests/chains/Harmony/TWHarmonyStakingTests.cpp +++ b/tests/chains/Harmony/TWHarmonyStakingTests.cpp @@ -20,7 +20,7 @@ namespace TW::Harmony::tests { static auto TEST_ACCOUNT = "one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9"; static auto PRIVATE_KEY = - PrivateKey(parse_hex("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48")); + PrivateKey(parse_hex("4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48"), TWCoinTypeCurve(TWCoinTypeHarmony)); TEST(TWHarmonyStakingSigner, CreateValidator) { auto input = Proto::SigningInput(); diff --git a/tests/chains/Harmony/TransactionCompilerTests.cpp b/tests/chains/Harmony/TransactionCompilerTests.cpp index 5cc34ad9765..86b6caf3db6 100644 --- a/tests/chains/Harmony/TransactionCompilerTests.cpp +++ b/tests/chains/Harmony/TransactionCompilerTests.cpp @@ -71,7 +71,7 @@ TEST(HarmonyCompiler, CompileWithSignatures) { ASSERT_EQ(hex(preImage), expectedPreImage); ASSERT_EQ(hex(preImageHash), expectedPreImageHash); - const auto privateKey = PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e")); + const auto privateKey = PrivateKey(parse_hex("b578822c5c718e510f67a9e291e9c6efdaf753f406020f55223b940e1ddb282e"), TWCoinTypeCurve(TWCoinTypeHarmony)); Data signature = parse_hex("43824f50bf4b16ebe1020114de16e3579bdb5f3dcaa26117de87a73b5414b72550506609fd60e3cb565b1f9bae0952d37f3a6c6be262380f7f18cbda5216f34300"); const PublicKey publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); diff --git a/tests/chains/Hedera/SignerTests.cpp b/tests/chains/Hedera/SignerTests.cpp index b1b4220226a..c66178986e6 100644 --- a/tests/chains/Hedera/SignerTests.cpp +++ b/tests/chains/Hedera/SignerTests.cpp @@ -10,6 +10,7 @@ #include "HexCoding.h" #include "PrivateKey.h" #include "PublicKey.h" +#include "TestUtilities.h" #include @@ -18,7 +19,7 @@ namespace TW::Hedera::tests { TEST(HederaSigner, Sign) { // Successfully broadcasted: https://hashscan.io/testnet/transaction/0.0.48694347-1667222879-749068449?t=1667222891.440398729&p=1 Proto::SigningInput input; - auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8")); + auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8"), TWCoinTypeCurve(TWCoinTypeHedera)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto* body = input.mutable_body(); @@ -43,7 +44,7 @@ TEST(HederaSigner, Sign) { TEST(HederaSigner, SignWithMemo) { // Successfully broadcasted: https://hashscan.io/testnet/transaction/0.0.48694347-1667227300-854561449?t=1667227312.554926003 Proto::SigningInput input; - auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8")); + auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8"), TWCoinTypeCurve(TWCoinTypeHedera)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto* body = input.mutable_body(); @@ -68,7 +69,7 @@ TEST(HederaSigner, SignWithMemo) { TEST(HederaSigner, SignWithMemoMainnet) { // Successfully broadcasted: https://hashscan.io/mainnet/transaction/0.0.1377988-1667566445-926176449?t=1667566457.533804616 Proto::SigningInput input; - auto privateKey = PrivateKey(parse_hex("650c5120cbdc6244e3d10001eb27eea4dd3f80c331b3b6969fa434797d4edd50")); + auto privateKey = PrivateKey(parse_hex("650c5120cbdc6244e3d10001eb27eea4dd3f80c331b3b6969fa434797d4edd50"), TWCoinTypeCurve(TWCoinTypeHedera)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto* body = input.mutable_body(); diff --git a/tests/chains/Hedera/TWAnySignerTests.cpp b/tests/chains/Hedera/TWAnySignerTests.cpp index 0e2d900604f..02e880b2f12 100644 --- a/tests/chains/Hedera/TWAnySignerTests.cpp +++ b/tests/chains/Hedera/TWAnySignerTests.cpp @@ -14,7 +14,7 @@ namespace TW::Hedera::tests { TEST(TWAnySignerHedera, Sign) { // Successfully broadcasted: https://hashscan.io/testnet/transaction/0.0.48694347-1667222879-749068449?t=1667222891.440398729&p=1 Proto::SigningInput input; - auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8")); + auto privateKey = PrivateKey(parse_hex("e87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8"), TWCoinTypeCurve(TWCoinTypeHedera)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto* body = input.mutable_body(); diff --git a/tests/chains/ICON/AddressTests.cpp b/tests/chains/ICON/AddressTests.cpp index 2d8229fac8f..4ace2694acb 100644 --- a/tests/chains/ICON/AddressTests.cpp +++ b/tests/chains/ICON/AddressTests.cpp @@ -5,6 +5,7 @@ #include "HexCoding.h" #include "Icon/Address.h" #include "PrivateKey.h" +#include "TestUtilities.h" #include @@ -32,7 +33,7 @@ TEST(IconAddress, String) { } TEST(IconAddress, FromPrivateKey) { - const auto privateKey = PrivateKey(parse_hex("94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f")); + const auto privateKey = PrivateKey(parse_hex("94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f"), TWCoinTypeCurve(TWCoinTypeICON)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended)); const auto address = Address(publicKey, TypeAddress); diff --git a/tests/chains/ICON/TransactionCompilerTests.cpp b/tests/chains/ICON/TransactionCompilerTests.cpp index a47dc54d2be..ae01ed8efa6 100644 --- a/tests/chains/ICON/TransactionCompilerTests.cpp +++ b/tests/chains/ICON/TransactionCompilerTests.cpp @@ -49,9 +49,9 @@ TEST(IconCompiler, CompileWithSignatures) { EXPECT_EQ(hex(preImageHash),"f0c68a4f588233d722fff7b5a738ffa6b56ad4cb62ad6bc9fb3e5facb0c25059"); auto key = parse_hex("2d42994b2f7735bbc93a3e64381864d06747e574aa94655c516f9ad0a74eed79"); - const auto privateKey = PrivateKey(key); + const auto privateKey = PrivateKey(key, TWCurveSECP256k1); const auto publicKey = privateKey.getPublicKey(TWCoinTypePublicKeyType(coin)); - const auto signature = privateKey.sign(parse_hex(hex(preImageHash)), TWCurveSECP256k1); + const auto signature = privateKey.sign(parse_hex(hex(preImageHash))); const Data outputData = TransactionCompiler::compileWithSignatures(coin, protoInputData, {signature}, {publicKey.bytes}); Icon::Proto::SigningOutput output; diff --git a/tests/chains/IOST/TransactionCompilerTests.cpp b/tests/chains/IOST/TransactionCompilerTests.cpp index 9db3d3e0d84..0da9e6da5b6 100644 --- a/tests/chains/IOST/TransactionCompilerTests.cpp +++ b/tests/chains/IOST/TransactionCompilerTests.cpp @@ -26,7 +26,7 @@ TEST(IostCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) const auto privKeyBytes = Base58::decode( "4TQwN7wWXg26ByuU5WkUPErd5v6PD6HsDuULyGNJgpS979wXF7jRU8NKviJs5boHrRKbLMomKycbek4NyDy6cLb8"); - const auto pkFrom = PrivateKey(Data(privKeyBytes.begin(), privKeyBytes.begin() + 32)); + const auto pkFrom = PrivateKey(Data(privKeyBytes.begin(), privKeyBytes.begin() + 32), TWCoinTypeCurve(coin)); const auto publicKey = pkFrom.getPublicKey(TWPublicKeyTypeED25519); TW::IOST::Proto::SigningInput input; input.set_transfer_memo(""); diff --git a/tests/chains/ImmutableX/StarkKeyTests.cpp b/tests/chains/ImmutableX/StarkKeyTests.cpp index 6f9efca154e..bdc6bd366dd 100644 --- a/tests/chains/ImmutableX/StarkKeyTests.cpp +++ b/tests/chains/ImmutableX/StarkKeyTests.cpp @@ -54,7 +54,7 @@ TEST(ImmutableX, GetPrivateKeyFromSignature) { TEST(ImmutableX, GetPublicKeyFromPrivateKey) { auto privKeyData = parse_hex("058ab7989d625b1a690400dcbe6e070627adedceff7bd196e58d4791026a8afe", true); - PrivateKey privKey(privKeyData); + PrivateKey privKey(privKeyData, TWCurveStarkex); auto pubKey = privKey.getPublicKey(TWPublicKeyTypeStarkex); auto pubKeyHex = hexEncoded(pubKey.bytes); ASSERT_EQ(pubKeyHex, "0x02a4c7332c55d6c1c510d24272d1db82878f2302f05b53bcc38695ed5f78fffd"); @@ -62,9 +62,9 @@ TEST(ImmutableX, GetPublicKeyFromPrivateKey) { TEST(ImmutableX, SimpleSign) { auto privKeyBytes = parse_hex("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79"); - PrivateKey privKey(privKeyBytes); + PrivateKey privKey(privKeyBytes, TWCurveStarkex); auto digest = parse_hex("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76"); - auto signature = hex(privKey.sign(digest, TWCurve::TWCurveStarkex)); + auto signature = hex(privKey.sign(digest)); auto expectedSignature = "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a"; ASSERT_EQ(signature.size(), 128ULL); ASSERT_EQ(signature.substr(0, 64), "061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f"); diff --git a/tests/chains/IoTeX/AddressTests.cpp b/tests/chains/IoTeX/AddressTests.cpp index fd94363fdff..92960150ec7 100644 --- a/tests/chains/IoTeX/AddressTests.cpp +++ b/tests/chains/IoTeX/AddressTests.cpp @@ -4,6 +4,7 @@ #include +#include "TestUtilities.h" #include "HexCoding.h" #include "PrivateKey.h" #include "PublicKey.h" @@ -35,7 +36,7 @@ TEST(IoTeXAddress, FromString) { } TEST(IoTeXAddress, FromPrivateKey) { - const auto privateKey = PrivateKey(parse_hex("0806c458b262edd333a191e92f561aff338211ee3e18ab315a074a2d82aa343f")); + const auto privateKey = PrivateKey(parse_hex("0806c458b262edd333a191e92f561aff338211ee3e18ab315a074a2d82aa343f"), TWCoinTypeCurve(TWCoinTypeIoTeX)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended)); const auto address = Address(publicKey); ASSERT_EQ(address.string(), "io187wzp08vnhjjpkydnr97qlh8kh0dpkkytfam8j"); diff --git a/tests/chains/IoTeX/SignerTests.cpp b/tests/chains/IoTeX/SignerTests.cpp index bb743500c66..7e4951cbab7 100644 --- a/tests/chains/IoTeX/SignerTests.cpp +++ b/tests/chains/IoTeX/SignerTests.cpp @@ -4,12 +4,14 @@ #include -#include "HexCoding.h" #include "Hash.h" +#include "HexCoding.h" #include "IoTeX/Address.h" #include "IoTeX/Signer.h" #include "proto/IoTeX.pb.h" +#include + namespace TW::IoTeX { TEST(IoTeXSigner, Sign) { @@ -84,7 +86,7 @@ TEST(IoTeXSigner, Compile) { ASSERT_EQ(hex(sig), checkSig); //build compile - auto k = PrivateKey(key); + auto k = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeIoTeX)); PublicKey pk = k.getPublicKey(TWPublicKeyTypeSECP256k1Extended); //merge hash data and signature auto output = signer.compile(input, sig, pk); diff --git a/tests/chains/IoTeX/TransactionCompilerTests.cpp b/tests/chains/IoTeX/TransactionCompilerTests.cpp index 4c25d7e5431..d7b12a6017a 100644 --- a/tests/chains/IoTeX/TransactionCompilerTests.cpp +++ b/tests/chains/IoTeX/TransactionCompilerTests.cpp @@ -43,10 +43,10 @@ TEST(TransactionCompiler, IoTeXCompileWithSignatures) { "0d1d3799c4700a0b1be21a41de4be56ce74dce8e526590f5b5f947385b00947c4c2ead014429aa706a2470055c" "56c7e57d1b119b487765d59b21bcdeafac25108f6929a14f9edf4b2309534501"; - const auto prkey0 = PrivateKey(privateKey0); + const auto prkey0 = PrivateKey(privateKey0, TWCoinTypeCurve(TWCoinTypeIoTeX)); const PublicKey pbkey0 = prkey0.getPublicKey(TWPublicKeyTypeSECP256k1Extended); - const auto prkey1 = PrivateKey(privateKey1); + const auto prkey1 = PrivateKey(privateKey1, TWCoinTypeCurve(TWCoinTypeIoTeX)); const PublicKey pbkey1 = prkey1.getPublicKey(TWPublicKeyTypeSECP256k1Extended); /// Step 1: Prepare transaction input (protobuf) @@ -101,7 +101,7 @@ TEST(TransactionCompiler, IoTeXCompileWithSignatures) { // keys were not used anywhere up to this point. TW::IoTeX::Proto::SigningInput signingInput; ASSERT_TRUE(signingInput.ParseFromArray(inputStrData.data(), (int)inputStrData.size())); - EXPECT_EQ(hex(PrivateKey(privateKey0).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), + EXPECT_EQ(hex(PrivateKey(privateKey0, TWCoinTypeCurve(TWCoinTypeIoTeX)).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), hex(pubKey0)); signingInput.set_privatekey(prkey0.bytes.data(), prkey0.bytes.size()); TW::IoTeX::Proto::SigningOutput output; @@ -113,7 +113,7 @@ TEST(TransactionCompiler, IoTeXCompileWithSignatures) { { // more signatures TW::IoTeX::Proto::SigningInput signingInput; ASSERT_TRUE(signingInput.ParseFromArray(inputStrData.data(), (int)inputStrData.size())); - EXPECT_EQ(hex(PrivateKey(privateKey1).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), + EXPECT_EQ(hex(PrivateKey(privateKey1, TWCoinTypeCurve(TWCoinTypeIoTeX)).getPublicKey(TWPublicKeyTypeSECP256k1).bytes), hex(pubKey1)); signingInput.set_privatekey(prkey1.bytes.data(), prkey1.bytes.size()); TW::IoTeX::Proto::SigningOutput output; diff --git a/tests/chains/Kusama/TWAnyAddressTests.cpp b/tests/chains/Kusama/TWAnyAddressTests.cpp index 426c15989de..c7491934fa5 100644 --- a/tests/chains/Kusama/TWAnyAddressTests.cpp +++ b/tests/chains/Kusama/TWAnyAddressTests.cpp @@ -35,7 +35,7 @@ TEST(KusamaAddress, Validation) { TEST(KusamaAddress, FromPrivateKey) { // from subkey: tiny escape drive pupil flavor endless love walk gadget match filter luxury - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0xa21981f3bb990c40837df44df639541ff57c5e600f9eb4ac00ed8d1f718364e5").get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0xa21981f3bb990c40837df44df639541ff57c5e600f9eb4ac00ed8d1f718364e5").get(), TWCoinTypeCurve(TWCoinTypeKusama))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeKusama)); const auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeKusama)); const auto addressStr = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Litecoin/TWLitecoinTests.cpp b/tests/chains/Litecoin/TWLitecoinTests.cpp index f85584a571a..a299be82d05 100644 --- a/tests/chains/Litecoin/TWLitecoinTests.cpp +++ b/tests/chains/Litecoin/TWLitecoinTests.cpp @@ -16,7 +16,7 @@ namespace TW::Litecoin::tests { TEST(Litecoin, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeLitecoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeLitecoin))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -24,7 +24,7 @@ TEST(Litecoin, LegacyAddress) { } TEST(Litecoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeLitecoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeLitecoin)); auto string = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Monacoin/TWMonacoinAddressTests.cpp b/tests/chains/Monacoin/TWMonacoinAddressTests.cpp index a4ef2fa7fca..96adfcbf806 100644 --- a/tests/chains/Monacoin/TWMonacoinAddressTests.cpp +++ b/tests/chains/Monacoin/TWMonacoinAddressTests.cpp @@ -15,7 +15,7 @@ #include TEST(Monacoin, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeMonacoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeMonacoin))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -23,7 +23,7 @@ TEST(Monacoin, LegacyAddress) { } TEST(Monacoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeMonacoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWSegwitAddress, TWSegwitAddressCreateWithPublicKey(TWHRPMonacoin, publicKey.get())); auto string = WRAPS(TWSegwitAddressDescription(address.get())); diff --git a/tests/chains/MultiversX/AddressTests.cpp b/tests/chains/MultiversX/AddressTests.cpp index 2135f4678bd..e0d36af87b6 100644 --- a/tests/chains/MultiversX/AddressTests.cpp +++ b/tests/chains/MultiversX/AddressTests.cpp @@ -47,11 +47,11 @@ TEST(MultiversXAddress, FromData) { } TEST(MultiversXAddress, FromPrivateKey) { - auto aliceKey = PrivateKey(parse_hex(ALICE_SEED_HEX)); + auto aliceKey = PrivateKey(parse_hex(ALICE_SEED_HEX), TWCurveED25519); auto alice = Address(aliceKey.getPublicKey(TWPublicKeyTypeED25519)); ASSERT_EQ(ALICE_BECH32, alice.string()); - auto bobKey = PrivateKey(parse_hex(BOB_SEED_HEX)); + auto bobKey = PrivateKey(parse_hex(BOB_SEED_HEX), TWCurveED25519); auto bob = Address(bobKey.getPublicKey(TWPublicKeyTypeED25519)); ASSERT_EQ(BOB_BECH32, bob.string()); } diff --git a/tests/chains/MultiversX/SignerTests.cpp b/tests/chains/MultiversX/SignerTests.cpp index 96401c1e104..3554757be70 100644 --- a/tests/chains/MultiversX/SignerTests.cpp +++ b/tests/chains/MultiversX/SignerTests.cpp @@ -709,7 +709,7 @@ TEST(ElrondSigner, buildSigningOutput) { auto privateKey = PrivateKey(parse_hex(ALICE_SEED_HEX), TWCurveED25519); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto unsignedTxBytes = Signer::buildUnsignedTxBytes(input); - auto signature = privateKey.sign(unsignedTxBytes, TWCurveED25519); + auto signature = privateKey.sign(unsignedTxBytes); auto output = Signer::buildSigningOutput(input, signature); std::string expectedSignatureHex = "e8647dae8b16e034d518a1a860c6a6c38d16192d0f1362833e62424f424e5da660770dff45f4b951d9cc58bfb9d14559c977d443449bfc4b8783ff9c84065700"; diff --git a/tests/chains/NEAR/AddressTests.cpp b/tests/chains/NEAR/AddressTests.cpp index 7ae6b77a671..1ced8e7702d 100644 --- a/tests/chains/NEAR/AddressTests.cpp +++ b/tests/chains/NEAR/AddressTests.cpp @@ -2,9 +2,11 @@ // // Copyright © 2017 Trust Wallet. -#include "NEAR/Address.h" #include "Base58.h" +#include "NEAR/Address.h" #include "PrivateKey.h" + +#include #include #include @@ -38,7 +40,7 @@ TEST(NEARAddress, FromString) { TEST(NEARAddress, FromPrivateKey) { auto fullKey = Base58::decode("3hoMW1HvnRLSFCLZnvPzWeoGwtdHzke34B2cTHM8rhcbG3TbuLKtShTv3DvyejnXKXKBiV7YPkLeqUHN1ghnqpFv"); - auto key = PrivateKey(Data(fullKey.begin(), fullKey.begin() + 32)); + auto key = PrivateKey(Data(fullKey.begin(), fullKey.begin() + 32), TWCoinTypeCurve(TWCoinTypeNEAR)); auto publicKey = key.getPublicKey(TWPublicKeyTypeED25519); auto address = Address(publicKey); diff --git a/tests/chains/NEO/AddressTests.cpp b/tests/chains/NEO/AddressTests.cpp index af24375ebfe..17dc11b03df 100644 --- a/tests/chains/NEO/AddressTests.cpp +++ b/tests/chains/NEO/AddressTests.cpp @@ -15,7 +15,7 @@ using namespace TW; namespace TW::NEO::tests { TEST(NEOAddress, FromPublicKey) { - const auto publicKey = PublicKey(parse_hex("0222b2277d039d67f4197a638dd5a1d99c290b17aa8c4a16ccee5165fe612de66a"), TWPublicKeyTypeSECP256k1); + const auto publicKey = PublicKey(parse_hex("0222b2277d039d67f4197a638dd5a1d99c290b17aa8c4a16ccee5165fe612de66a"), TWPublicKeyTypeNIST256p1); const auto address = Address(publicKey); EXPECT_EQ(string("AKmrAHRD9ZDUnu4m3vWWonpsojo4vgSuqp"), address.string()); } @@ -63,7 +63,7 @@ TEST(NEOAddress, Invalid) { } TEST(NEOAddress, FromPrivateKey) { - auto key = PrivateKey(parse_hex("0x2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB")); + auto key = PrivateKey(parse_hex("0x2A9EAB0FEC93CD94FA0A209AC5604602C1F0105FB02EAB398E17B4517C2FFBAB"), TWCurveNIST256p1); auto publicKey = key.getPublicKey(TWPublicKeyTypeNIST256p1); auto address = Address(publicKey); ASSERT_EQ(address.string(), "AQCSMB3oSDA1dHPn6GXN6KB4NHmdo1fX41"); diff --git a/tests/chains/NEO/SignerTests.cpp b/tests/chains/NEO/SignerTests.cpp index d9a3b56a17e..69fbb7088ff 100644 --- a/tests/chains/NEO/SignerTests.cpp +++ b/tests/chains/NEO/SignerTests.cpp @@ -4,7 +4,6 @@ #include "HexCoding.h" #include "PublicKey.h" -#include "PublicKeyLegacy.h" #include "NEO/Address.h" #include "NEO/Signer.h" @@ -17,7 +16,7 @@ using namespace std; TEST(NEOSigner, FromPublicPrivateKey) { auto hexPrvKey = "4646464646464646464646464646464646464646464646464646464646464646"; auto hexPubKey = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; - auto signer = Signer(PrivateKey(parse_hex(hexPrvKey))); + auto signer = Signer(PrivateKey(parse_hex(hexPrvKey), TWCurveNIST256p1)); auto prvKey = signer.getPrivateKey(); auto pubKey = signer.getPublicKey(); @@ -42,7 +41,7 @@ TEST(NEOSigner, SigningData) { TEST(NEOAccount, validity) { auto hexPrvKey = "4646464646464646464646464646464646464646464646464646464646464646"; auto hexPubKey = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; - auto signer = Signer(PrivateKey(parse_hex(hexPrvKey))); + auto signer = Signer(PrivateKey(parse_hex(hexPrvKey), TWCurveNIST256p1)); auto prvKey = signer.getPrivateKey(); auto pubKey = signer.getPublicKey(); EXPECT_EQ(hexPrvKey, hex(prvKey.bytes)); @@ -81,9 +80,7 @@ TEST(NEOSigner, SigningTransaction) { signer.sign(transaction); auto signedTx = transaction.serialize(); - EXPECT_EQ(hex(signedTx), "800000019c85b39cd5677e2bfd6bf8a711e8da93a2f1d172b2a52c6ca87757a4bccc24de0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500fcbbc414000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac0141405046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb27e1fc01c1858576228f1fef8c0945a8ad69688e52a4ed19f5b85f5eff7e961d7232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ(hex(signedTx), "800000019c85b39cd5677e2bfd6bf8a711e8da93a2f1d172b2a52c6ca87757a4bccc24de0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500fcbbc414000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac0141405046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89ed70e01073f6ba574e65071c87cc8cce59833d4d30479c37a232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); + EXPECT_EQ(hex(signedTx), "800000019c85b39cd5677e2bfd6bf8a711e8da93a2f1d172b2a52c6ca87757a4bccc24de0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500fcbbc414000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac0141405046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89ed70e01073f6ba574e65071c87cc8cce59833d4d30479c37a232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); } } // namespace TW::NEO::tests diff --git a/tests/chains/NEO/TWAnySignerTests.cpp b/tests/chains/NEO/TWAnySignerTests.cpp index e600d17ad3f..b080f432408 100644 --- a/tests/chains/NEO/TWAnySignerTests.cpp +++ b/tests/chains/NEO/TWAnySignerTests.cpp @@ -3,7 +3,6 @@ // Copyright © 2017 Trust Wallet. #include "PrivateKey.h" -#include "PublicKeyLegacy.h" #include "TestUtilities.h" #include #include "HexCoding.h" @@ -166,9 +165,7 @@ TEST(TWAnySignerNEO, Sign) { ANY_SIGN(input, TWCoinTypeNEO); // https://testnet-explorer.o3.network/transactions/0x7b138c753c24f474d0f70af30a9d79756e0ee9c1f38c12ed07fbdf6fc5132eaf - ASSERT_EQ(hex(output.encoded()), "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf122956bc88746dc666759a2d67f120fe3ce1659f916d22a91e0b02421d3bddbd1232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); - // TODO uncomment when nist256p1 Rust implementation is enabled. - // ASSERT_EQ(hex(output.encoded()), "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); + ASSERT_EQ(hex(output.encoded()), "8000001efb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00039b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50083064905000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ace72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c605013cf0617000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac014140dc261ac093a87640441bf0c3ad4a55ec727932b9175f600618bb5275f31aacf1dd6a943678b9239a98a65d2980edf01beed0a0b4904573f31309a6a128a54980232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); } TEST(TWAnySignerNEO, Plan) { @@ -186,10 +183,8 @@ TEST(TWAnySignerNEO, SignMultiOutput) { Proto::SigningInput input = createInputWithMultiOutput(); Proto::SigningOutput output; ANY_SIGN(input, TWCoinTypeNEO); - - ASSERT_EQ(hex(output.encoded()), "80000023fb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00e05bdf39f3b8c377a9801cb3eaa38eefe8abdd176642d5f2aab3b8217588a7e50000ebf6778b3fc3523ebc0acdbdeb29202135737ac0ac47cd814da0d63cdde955140000eeadb902cc55ac4954c1f9551ae6695c2364e0dfd0013857b5115208601271da0000ef7b431058f36524a668a7497c88ad45cc8b2c5b20891ad53d1071d3fe6c48040000f49e21b21a0c87edad0d96673223f47ad3560490613510650edb42a45570f2a50000049b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c2eb0b00000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5e069f3d21c000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac01414057b786872d667a637ff44412e3ccf50933a9c30609016ecbcaec8b9d80f2b0e26eb0cf111674ff0802a42357671867b11c334807c40146419825eed8c45a6eed232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); - // TODO uncomment when nist256p1 Rust implementation is enabled. - // ASSERT_EQ(hex(output.encoded()), "80000023fb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00e05bdf39f3b8c377a9801cb3eaa38eefe8abdd176642d5f2aab3b8217588a7e50000ebf6778b3fc3523ebc0acdbdeb29202135737ac0ac47cd814da0d63cdde955140000eeadb902cc55ac4954c1f9551ae6695c2364e0dfd0013857b5115208601271da0000ef7b431058f36524a668a7497c88ad45cc8b2c5b20891ad53d1071d3fe6c48040000f49e21b21a0c87edad0d96673223f47ad3560490613510650edb42a45570f2a50000049b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c2eb0b00000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5e069f3d21c000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac01414057b786872d667a637ff44412e3ccf50933a9c30609016ecbcaec8b9d80f2b0e2914f30ede98b00f8fd5bdca898e7984ea0b3b2a5e31658435b93dbea3808b664232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); + + ASSERT_EQ(hex(output.encoded()), "80000023fb50cb3be3e08917b308a1dbdb2408109394560ec67518af43035d8c260815c601000bd791a26120eef181d8162bd6cb7495dee1299aa67bb796dcd4a03769f9b24e00000bea299e6a243c9379c3e8884c9176b1456b3017611772b2fadc55d10901ee3f000026c413526bbd45cca355683db9f39d6864a7e298f481f2cdeefe8b578ccea96e00002b2647616d4f4143700f8e862aa8427efd7fa9998fe040e23ed877d2cbd35af700003159b899275e2f0e0b1314acddc7e1ec5948598fca40a9733e2b448fe9344705000036509c8a487005aa8e16663613d2d767461ee2f8dc4f678cc22f9148d4420c8b0000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040100385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040200385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040300385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040400385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040500385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040600385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040700385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040800385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f04090040ec871088beb680f5b149767dbb0b8ac7ec1a1c5836e177606b6200e6bc83cf00004e393bd89d886ae116ed9e6b49be427b21f7247d896923265e68dfa82b57d79b00005b99bf2caacf20bfc9cd51b3d3472499383c803c2d781d00f1e2dd970325eeb4000062ac42685ef8b856291bb0264fcb767b00706a15243326775f61a159a29c01e100006f011d435ef43c066689d1222f4eada1d4590ebaaa190960ac26a5acf29d37bd00007dea63ea47a6c9e8318f3b19a0df5ccb3a348f54a176736afa7b9b3b843f4c160000925e50254e8056bfd540f3d45f171dbab504f5b191070ee7af1e16764ac7ce4a00009677a6869128961a1a3b17e609e915d2d9a29ceaab5689dccb841ca729665c8900009692e4e512eb2e04b10042bcc28910140b2229ede40291b0e1a0c3c44381825400009dc6c119d0f4bacb1b1e9faffcba33581729c1915a2f1147ce7a6fc8abe4455300009f6b635afee02b5db0c93a5b1bfcace34a18c78d76c73b7bf90d21d4d0193ec80000b11bbb613e36b2bcc6c3a76c888c6c139957a1b7091dab26ce88b65c3fb056340000385bfb24fe7f6f5dd28e9836e8220c8ac766efcc4e04082bd9d982ccd6738f040a00e05bdf39f3b8c377a9801cb3eaa38eefe8abdd176642d5f2aab3b8217588a7e50000ebf6778b3fc3523ebc0acdbdeb29202135737ac0ac47cd814da0d63cdde955140000eeadb902cc55ac4954c1f9551ae6695c2364e0dfd0013857b5115208601271da0000ef7b431058f36524a668a7497c88ad45cc8b2c5b20891ad53d1071d3fe6c48040000f49e21b21a0c87edad0d96673223f47ad3560490613510650edb42a45570f2a50000049b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500ba1dd205000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c2eb0b00000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac9b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5e069f3d21c000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac01414057b786872d667a637ff44412e3ccf50933a9c30609016ecbcaec8b9d80f2b0e2914f30ede98b00f8fd5bdca898e7984ea0b3b2a5e31658435b93dbea3808b664232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"); } TEST(TWAnySignerNEO, PlanMultiOutput) { diff --git a/tests/chains/NEO/TransactionCompilerTests.cpp b/tests/chains/NEO/TransactionCompilerTests.cpp index 121919c7eda..3a00568449b 100644 --- a/tests/chains/NEO/TransactionCompilerTests.cpp +++ b/tests/chains/NEO/TransactionCompilerTests.cpp @@ -34,7 +34,7 @@ TEST(NEOCompiler, CompileWithSignatures) { TW::NEO::Proto::SigningInput input; auto privateKey = - PrivateKey(parse_hex("F18B2F726000E86B4950EBEA7BFF151F69635951BC4A31C44F28EE6AF7AEC128")); + PrivateKey(parse_hex("F18B2F726000E86B4950EBEA7BFF151F69635951BC4A31C44F28EE6AF7AEC128"), TWCoinTypeCurve(coin)); auto publicKey = privateKey.getPublicKey(publicKeyType(coin)); input.set_gas_asset_id(GAS_ASSET_ID); input.set_gas_change_address("AdtSLMBqACP4jv8tRWwyweXGpyGG46eMXV"); @@ -71,32 +71,19 @@ TEST(NEOCompiler, CompileWithSignatures) { // Simulate signature, normally obtained from signature server const auto publicKeyData = publicKey.bytes; const auto signature = - parse_hex("5046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb27e1fc01c18585762" - "28f1fef8c0945a8ad69688e52a4ed19f5b85f5eff7e961d7"); - // TODO uncomment when nist256p1 Rust implementation is enabled. - // const auto signature = - // parse_hex("5046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89e" - // "d70e01073f6ba574e65071c87cc8cce59833d4d30479c37a"); + parse_hex("5046619c8e20e1fdeec92ce95f3019f6e7cc057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89e" + "d70e01073f6ba574e65071c87cc8cce59833d4d30479c37a"); // Verify signature (pubkey & hash & signature) EXPECT_TRUE(publicKey.verify(signature, TW::data(preImageHash))); - /// Step 3: Compile transaction info auto expectedTx = "800000019c85b39cd5677e2bfd6bf8a711e8da93a2f1d172b2a52c6ca87757a4bccc24de0100029b7cffdaa674" "beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000ea610aa6db39bd8c8556c9" "569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500fcbbc4" "14000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac0141405046619c8e20e1fdeec92ce95f3019f6e7cc" - "057294eb16b2d5e55c105bf32eb27e1fc01c1858576228f1fef8c0945a8ad69688e52a4ed19f5b85f5eff7e961" - "d7232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"; - // TODO uncomment when nist256p1 Rust implementation is enabled. - // auto expectedTx = - // "800000019c85b39cd5677e2bfd6bf8a711e8da93a2f1d172b2a52c6ca87757a4bccc24de0100029b7cffdaa674" - // "beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e1f50500000000ea610aa6db39bd8c8556c9" - // "569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500fcbbc4" - // "14000000f2908c7efc0c9e43ffa7e79170ba37e501e1b4ac0141405046619c8e20e1fdeec92ce95f3019f6e7cc" - // "057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89ed70e01073f6ba574e65071c87cc8cce59833d4d30479c3" - // "7a232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"; + "057294eb16b2d5e55c105bf32eb281e03fe2e7a7a89ed70e01073f6ba574e65071c87cc8cce59833d4d30479c3" + "7a232102a41c2aea8568864b106553729d32b1317ec463aa23e7a3521455d95992e17a7aac"; auto outputData = TransactionCompiler::compileWithSignatures(coin, inputStrData, {signature}, {publicKeyData}); diff --git a/tests/chains/NULS/AddressTests.cpp b/tests/chains/NULS/AddressTests.cpp index 542d939d183..6e4d13f8f69 100644 --- a/tests/chains/NULS/AddressTests.cpp +++ b/tests/chains/NULS/AddressTests.cpp @@ -5,6 +5,8 @@ #include "NULS/Address.h" #include "HexCoding.h" #include "PrivateKey.h" +#include "TestUtilities.h" + #include namespace TW::NULS::tests { @@ -41,7 +43,7 @@ TEST(NULSAddress, FromString) { TEST(NULSAddress, FromPrivateKey) { const auto privateKey = - PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")); + PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a"), TWCoinTypeCurve(TWCoinTypeNULS)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); const auto address = Address(publicKey, true); ASSERT_EQ(address.string(), "NULSd6HghWa4CN5qdxqMwYVikQxRZyj57Jn4L"); @@ -58,7 +60,7 @@ TEST(NULSAddress, FromCompressedPublicKey) { } TEST(NULSAddress, FromPrivateKey33) { - const auto privateKey = PrivateKey(parse_hex("d77580833f0b3c35b7114c23d6b66790d726c308baf237ec8c369152f2c08d27")); + const auto privateKey = PrivateKey(parse_hex("d77580833f0b3c35b7114c23d6b66790d726c308baf237ec8c369152f2c08d27"), TWCoinTypeCurve(TWCoinTypeNULS)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); const auto address = Address(publicKey, true); diff --git a/tests/chains/NULS/TWAnySignerTests.cpp b/tests/chains/NULS/TWAnySignerTests.cpp index d82048ada7a..fa2031bfded 100644 --- a/tests/chains/NULS/TWAnySignerTests.cpp +++ b/tests/chains/NULS/TWAnySignerTests.cpp @@ -91,7 +91,7 @@ TEST(TWAnySigner, SignWithFeePayer) { parse_hex("0x48c91cd24a27a1cdc791022ff39316444229db1c466b3b1841b40c919dee3002"); auto feePayerPrivateKey = parse_hex("0x9401fd554cb700777e57b05338f9ff47597add8b23ce9f1c8e041e9b4e2116b6"); - auto pk = PrivateKey(privateKey); + auto pk = PrivateKey(privateKey, TWCoinTypeCurve(TWCoinTypeNULS)); auto amount = store(uint256_t(100000)); auto balance = store(uint256_t(1000000)); auto feePayerBalance = store(uint256_t(1000000)); diff --git a/tests/chains/Nano/TransactionCompilerTests.cpp b/tests/chains/Nano/TransactionCompilerTests.cpp index 88ec1cda1ca..422a846c9dc 100644 --- a/tests/chains/Nano/TransactionCompilerTests.cpp +++ b/tests/chains/Nano/TransactionCompilerTests.cpp @@ -28,7 +28,7 @@ namespace TW::Nano::tests { TEST(NanoCompiler, CompileWithSignatures) { /// Step 1 : Prepare transaction input(protobuf) auto coin = TWCoinTypeNano; - const auto privateKey = PrivateKey(parse_hex(kPrivateKey)); + const auto privateKey = PrivateKey(parse_hex(kPrivateKey), TWCurveED25519Blake2bNano); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519Blake2b); const auto linkBlock = parse_hex("491fca2c69a84607d374aaf1f6acd3ce70744c5be0721b5ed394653e85233507"); diff --git a/tests/chains/Nebl/AddressTests.cpp b/tests/chains/Nebl/AddressTests.cpp index 932f9dfd9b4..3a64c458302 100644 --- a/tests/chains/Nebl/AddressTests.cpp +++ b/tests/chains/Nebl/AddressTests.cpp @@ -25,7 +25,7 @@ TEST(NeblAddress, Invalid) { } TEST(NeblAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("4222aae79af41eade7b07ce6fd44d926ea8e3f95e51a06e85f8bdec89680cbd9")); + auto privateKey = PrivateKey(parse_hex("4222aae79af41eade7b07ce6fd44d926ea8e3f95e51a06e85f8bdec89680cbd9"), TWCoinTypeCurve(TWCoinTypeNebl)); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); auto address = Address(publicKey, TWCoinTypeP2pkhPrefix(TWCoinTypeNebl)); ASSERT_EQ(address.string(), "NboLGGKWtK5eXzaah5GVpXju9jCcoMi4cc"); diff --git a/tests/chains/Nebulas/AddressTests.cpp b/tests/chains/Nebulas/AddressTests.cpp index 8efe6395086..8a0b1f81ef2 100644 --- a/tests/chains/Nebulas/AddressTests.cpp +++ b/tests/chains/Nebulas/AddressTests.cpp @@ -5,6 +5,8 @@ #include "Nebulas/Address.h" #include "HexCoding.h" #include "PrivateKey.h" +#include "TestUtilities.h" + #include namespace TW::Nebulas::tests { @@ -40,7 +42,7 @@ TEST(NebulasAddress, Data) { } TEST(NebulasAddress, FromPrivateKey) { - const auto privateKey = PrivateKey(parse_hex("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b")); + const auto privateKey = PrivateKey(parse_hex("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b"), TWCoinTypeCurve(TWCoinTypeNebulas)); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); const auto address = Address(publicKey); ASSERT_EQ(address.string(), "n1V5bB2tbaM3FUiL4eRwpBLgEredS5C2wLY"); diff --git a/tests/chains/Nebulas/TWNebulasAddressTests.cpp b/tests/chains/Nebulas/TWNebulasAddressTests.cpp index e41a4e54e09..b7b2f8e92db 100644 --- a/tests/chains/Nebulas/TWNebulasAddressTests.cpp +++ b/tests/chains/Nebulas/TWNebulasAddressTests.cpp @@ -12,7 +12,7 @@ TEST(Nebulas, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("d2fd0ec9f6268fc8d1f563e3e976436936708bdf0dc60c66f35890f5967a8d2b").get(), TWCoinTypeCurve(TWCoinTypeNebulas))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeNebulas)); auto addressString = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Nervos/AddressTests.cpp b/tests/chains/Nervos/AddressTests.cpp index 4ff4d1246d5..bf757ca9543 100644 --- a/tests/chains/Nervos/AddressTests.cpp +++ b/tests/chains/Nervos/AddressTests.cpp @@ -30,7 +30,7 @@ TEST(NervosAddress, Invalid) { TEST(NervosAddress, FromPrivateKey) { auto privateKey = - PrivateKey(parse_hex("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb")); + PrivateKey(parse_hex("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb"), TWCoinTypeCurve(TWCoinTypeNervos)); auto address = Address(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); ASSERT_EQ(address.string(), "ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqwyk5x9er" "g8furras980hksatlslfaktks7epf25"); @@ -60,7 +60,7 @@ TEST(NervosAddress, FromString) { TEST(TWNervosAddress, AddressFromPublicKey) { auto privateKey = - PrivateKey(parse_hex("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb")); + PrivateKey(parse_hex("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb"), TWCoinTypeCurve(TWCoinTypeNervos)); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); ASSERT_EQ(publicKey.bytes.size(), 33ul); auto address = Address(publicKey); diff --git a/tests/chains/Nervos/SignerTests.cpp b/tests/chains/Nervos/SignerTests.cpp index af862b5f84a..0a0f99b7a4b 100644 --- a/tests/chains/Nervos/SignerTests.cpp +++ b/tests/chains/Nervos/SignerTests.cpp @@ -23,7 +23,7 @@ std::vector getPrivateKeys(Proto::SigningInput& input) { std::vector privateKeys; privateKeys.reserve(input.private_key_size()); for (auto&& privateKey : input.private_key()) { - privateKeys.emplace_back(privateKey); + privateKeys.emplace_back(privateKey, TWCoinTypeCurve(TWCoinTypeNervos)); } return privateKeys; } diff --git a/tests/chains/Nervos/TWAnyAddressTests.cpp b/tests/chains/Nervos/TWAnyAddressTests.cpp index be1c5f92e01..3116a8c57bd 100644 --- a/tests/chains/Nervos/TWAnyAddressTests.cpp +++ b/tests/chains/Nervos/TWAnyAddressTests.cpp @@ -19,7 +19,7 @@ TEST(TWAnyAddressNervos, AddressFromPublicKey) { auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData( - DATA("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb").get())); + DATA("8a2a726c44e46d1efaa0f9c2a8efed932f0e96d6050b914fde762ee285e61feb").get(), TWCoinTypeCurve(TWCoinTypeNervos))); ASSERT_NE(nullptr, privateKey.get()); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); ASSERT_NE(nullptr, publicKey.get()); diff --git a/tests/chains/Nimiq/SignerTests.cpp b/tests/chains/Nimiq/SignerTests.cpp index d8a56bdb9cd..cdcd691351d 100644 --- a/tests/chains/Nimiq/SignerTests.cpp +++ b/tests/chains/Nimiq/SignerTests.cpp @@ -7,20 +7,21 @@ #include "Nimiq/Address.h" #include "Nimiq/Signer.h" #include "Nimiq/Transaction.h" +#include "TestUtilities.h" #include namespace TW::Nimiq { TEST(NimiqSigner, DerivePublicKey) { - const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756")); + const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756"), TWCoinTypeCurve(TWCoinTypeNimiq)); const PublicKey publicKey((privateKey.getPublicKey(TWPublicKeyTypeED25519))); const auto address = Address(publicKey); ASSERT_EQ(address.string(), "NQ27 GBAY EVHP HK5X 6JHV JGFJ 5M3H BF4Y G7GD"); } TEST(NimiqSigner, Sign) { - const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756")); + const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756"), TWCoinTypeCurve(TWCoinTypeNimiq)); const auto pubkey = privateKey.getPublicKey(TWPublicKeyTypeED25519); std::array pubkeyBytes; std::copy(pubkey.bytes.begin(), pubkey.bytes.end(), pubkeyBytes.data()); diff --git a/tests/chains/Nimiq/TransactionTests.cpp b/tests/chains/Nimiq/TransactionTests.cpp index cd6eaeb2b22..8a58a97dc29 100644 --- a/tests/chains/Nimiq/TransactionTests.cpp +++ b/tests/chains/Nimiq/TransactionTests.cpp @@ -6,13 +6,14 @@ #include "PrivateKey.h" #include "Nimiq/Address.h" #include "Nimiq/Transaction.h" +#include "TestUtilities.h" #include namespace TW::Nimiq { TEST(NimiqTransaction, PreImage) { - const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756")); + const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756"), TWCoinTypeCurve(TWCoinTypeNimiq)); const auto pubkey = privateKey.getPublicKey(TWPublicKeyTypeED25519); std::array pubkeyBytes; std::copy(pubkey.bytes.begin(), pubkey.bytes.end(), pubkeyBytes.data()); @@ -30,7 +31,7 @@ TEST(NimiqTransaction, PreImage) { } TEST(NimiqTransaction, Serialize) { - const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756")); + const PrivateKey privateKey(parse_hex("e3cc33575834add098f8487123cd4bca543ee859b3e8cfe624e7e6a97202b756"), TWCoinTypeCurve(TWCoinTypeNimiq)); const auto pubkey = privateKey.getPublicKey(TWPublicKeyTypeED25519); std::array pubkeyBytes; std::copy(pubkey.bytes.begin(), pubkey.bytes.end(), pubkeyBytes.data()); diff --git a/tests/chains/Oasis/AddressTests.cpp b/tests/chains/Oasis/AddressTests.cpp index a85dd59c24f..9396d9eb3ed 100644 --- a/tests/chains/Oasis/AddressTests.cpp +++ b/tests/chains/Oasis/AddressTests.cpp @@ -6,6 +6,8 @@ #include "Oasis/Address.h" #include "PrivateKey.h" #include "PublicKey.h" +#include "TestUtilities.h" + #include #include @@ -43,7 +45,7 @@ TEST(OasisAddress, FromWrongData) { } TEST(OasisAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")); + auto privateKey = PrivateKey(parse_hex("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0"), TWCoinTypeCurve(TWCoinTypeOasis)); auto address = Address(privateKey.getPublicKey(TWPublicKeyTypeED25519)); ASSERT_EQ(address.string(), "oasis1qzawzy5kaa2xgphenf3r0f5enpr3mx5dps559yxm"); } diff --git a/tests/chains/Oasis/TransactionCompilerTests.cpp b/tests/chains/Oasis/TransactionCompilerTests.cpp index 18edd6b58e9..2190f36df97 100644 --- a/tests/chains/Oasis/TransactionCompilerTests.cpp +++ b/tests/chains/Oasis/TransactionCompilerTests.cpp @@ -22,7 +22,7 @@ namespace TW::Oasis::tests { TEST(OasisCompiler, CompileWithSignatures) { const auto coin = TWCoinTypeOasis; /// Step 1: Prepare transaction input (protobuf) - auto privateKey = PrivateKey(parse_hex("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0")); + auto privateKey = PrivateKey(parse_hex("4f8b5676990b00e23d9904a92deb8d8f428ff289c8939926358f1d20537c21a0"), TWCoinTypeCurve(TWCoinTypeOasis)); auto publicKey = privateKey.getPublicKey(publicKeyType(coin)); auto input = TW::Oasis::Proto::SigningInput(); diff --git a/tests/chains/Ontology/AccountTests.cpp b/tests/chains/Ontology/AccountTests.cpp index 1917eea454f..3693920515e 100644 --- a/tests/chains/Ontology/AccountTests.cpp +++ b/tests/chains/Ontology/AccountTests.cpp @@ -5,6 +5,7 @@ #include "Hash.h" #include "HexCoding.h" #include "PrivateKey.h" +#include "TestUtilities.h" #include "Ontology/Signer.h" @@ -16,7 +17,7 @@ namespace TW::Ontology::tests { TEST(OntologyAccount, validity) { auto hexPrvKey = "4646464646464646464646464646464646464646464646464646464646464646"; auto hexPubKey = "031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486"; - auto signer = Signer(PrivateKey(parse_hex(hexPrvKey))); + auto signer = Signer(PrivateKey(parse_hex(hexPrvKey), TWCoinTypeCurve(TWCoinTypeOntology))); auto prvKey = signer.getPrivateKey(); auto pubKey = signer.getPublicKey(); EXPECT_EQ(hexPrvKey, hex(prvKey.bytes)); diff --git a/tests/chains/Ontology/AddressTests.cpp b/tests/chains/Ontology/AddressTests.cpp index 559c5ebe5b0..b544cc726a0 100644 --- a/tests/chains/Ontology/AddressTests.cpp +++ b/tests/chains/Ontology/AddressTests.cpp @@ -4,7 +4,7 @@ #include "HexCoding.h" #include "PublicKey.h" - +#include "TestUtilities.h" #include "Ontology/Address.h" #include "Ontology/Signer.h" @@ -34,9 +34,9 @@ TEST(OntologyAddress, fromString) { } TEST(OntologyAddress, fromMultiPubKeys) { - auto signer1 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"))); - auto signer2 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"))); - auto signer3 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464658"))); + auto signer1 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology))); + auto signer2 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology))); + auto signer3 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464658"), TWCoinTypeCurve(TWCoinTypeOntology))); std::vector pubKeys{signer1.getPublicKey().bytes, signer2.getPublicKey().bytes, signer3.getPublicKey().bytes}; uint8_t m = 2; auto multiAddress = Address(m, pubKeys); diff --git a/tests/chains/Ontology/Oep4Tests.cpp b/tests/chains/Ontology/Oep4Tests.cpp index 6c43b61be89..7ebf934c1af 100644 --- a/tests/chains/Ontology/Oep4Tests.cpp +++ b/tests/chains/Ontology/Oep4Tests.cpp @@ -6,6 +6,7 @@ #include "Ontology/Oep4.h" #include "Ontology/Signer.h" +#include "TestUtilities.h" #include #include @@ -71,8 +72,8 @@ TEST(OntologyOep4, addressHack) { auto ownerbin = parse_hex("4646464646464646464646464646464646464646464646464646464646464646"); auto payerbin = parse_hex("4646464646464646464646464646464646464646464646464646464646464652"); - PrivateKey owner(ownerbin); - PrivateKey payer(payerbin); + PrivateKey owner(ownerbin, TWCoinTypeCurve(TWCoinTypeOntology)); + PrivateKey payer(payerbin, TWCoinTypeCurve(TWCoinTypeOntology)); auto pubKey = owner.getPublicKey(TWPublicKeyTypeNIST256p1); Address addr(pubKey); @@ -85,10 +86,10 @@ TEST(OntologyOep4, addressHack) { } TEST(OntologyOep4, transfer) { - PrivateKey fromPrivate(parse_hex("4646464646464646464646464646464646464646464646464646464646464652")); + PrivateKey fromPrivate(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer from(fromPrivate); - PrivateKey payerPrivate(parse_hex("4646464646464646464646464646464646464646464646464646464646464646")); + PrivateKey payerPrivate(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer payer(payerPrivate); auto toAddress = Address("AVY6LfvxauVQAVHDV9hC3ZCv7cQqzfDotH"); @@ -107,17 +108,15 @@ TEST(OntologyOep4, transfer) { auto rawTx = hex(rawTxBytes); // Transaction Hex tab // https://explorer.ont.io/testnet/tx/710266b8d497e794ecd47e01e269e4aeb6f4ff2b01eaeafc4cd371e062b13757 - EXPECT_EQ("00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa22871cfb819923fe01e9cb1e9ed16baa2b05c2feb76bcbe2ec125f72701c5e965232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9da4bb5dacd23dafba868cb31bacb38b4a6ff2607682a426c1dc09b05a1e158d6cd2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac", rawTx); - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ(rawTx, "00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa2d78e3046e66dc020e1634e1612e9455d0c8acac2305ae0563293d39bfa9d3bec232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9dab44a2531dc2504589734ce4534c74b58bdc0f3457cd53267331ec5211b0a4e842321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac"); + EXPECT_EQ(rawTx, "00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa2d78e3046e66dc020e1634e1612e9455d0c8acac2305ae0563293d39bfa9d3bec232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9dab44a2531dc2504589734ce4534c74b58bdc0f3457cd53267331ec5211b0a4e842321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac"); } TEST(OntologyOep4, transferMainnet) { auto from = Signer( - PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"))); + PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology))); auto payer = Signer( - PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"))); + PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology))); auto toAddress = Address("AUJJhwRNi4RsNfvuexLETxXEb6szu9D5Ad"); diff --git a/tests/chains/Ontology/OngTests.cpp b/tests/chains/Ontology/OngTests.cpp index 1aa603bebf9..e06bf3f6a02 100644 --- a/tests/chains/Ontology/OngTests.cpp +++ b/tests/chains/Ontology/OngTests.cpp @@ -6,6 +6,8 @@ #include "Ontology/Ong.h" +#include + #include #include @@ -33,10 +35,10 @@ TEST(OntologyOng, balanceOf) { } TEST(OntologyOng, transfer) { - PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646")); + PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer1(privateKey1); - PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652")); + PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer2(privateKey2); Address toAddress("Af1n2cZHhMZumNqKgw9sfCNoTWu9de4NDn"); @@ -51,31 +53,19 @@ TEST(OntologyOng, transfer) { "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" "00000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140ac3edf2d00540f9c" - "2f3b24878936b409c995c425ab5edf247c5b0d812a50df293ff63e173bac71a6cd0772ff78415c46ac64" - "f625cbc06fe90ccdecf9a94319c42321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" + "2f3b24878936b409c995c425ab5edf247c5b0d812a50df29c009c1e7c4538e5a32f88d0087bea3b91082" + "0487db572e9be6ebddc953200b8d2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" "47125f927b7486ac41406fea9f12b125d7f65a94774e765a796428b3c6c4c46b0470624b9a1cef4ff420" - "488828f308c263b35287363e51add8cd49136eb57a397c6ade95df80d9a16282232103d9fd62df332403" + "b777d70bf73d9c4dad78c9c1ae52273273d38bf82cde221a1523eb4222c1c2cf232103d9fd62df332403" "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", rawTxHex); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ("00d100000000f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df6" - // "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" - // "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" - // "00000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140ac3edf2d00540f9c" - // "2f3b24878936b409c995c425ab5edf247c5b0d812a50df29c009c1e7c4538e5a32f88d0087bea3b91082" - // "0487db572e9be6ebddc953200b8d2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" - // "47125f927b7486ac41406fea9f12b125d7f65a94774e765a796428b3c6c4c46b0470624b9a1cef4ff420" - // "b777d70bf73d9c4dad78c9c1ae52273273d38bf82cde221a1523eb4222c1c2cf232103d9fd62df332403" - // "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // rawTxHex); } TEST(OntologyOng, withdraw) { - PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646")); + PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer1(privateKey1); - PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652")); + PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer2(privateKey2); uint32_t nonce = 0; @@ -90,25 +80,12 @@ TEST(OntologyOng, withdraw) { "6b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc81400000000000000000000000000000000000000" "016a7cc814fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc8516a7cc86c0c7472616e7366657246726f" "6d1400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f" - "6b6500024140b8b859055c744a89ef4d4f6ae7a58e0a99fef2eb0f6cf09d740b56cf4c7c14ab64e00c28de9b1f" - "28921cbd62e6bcd6d452ab9871f8f5d2288812ff322ee2f4af2321031bec1250aa8f78275f99a6663688f31085" + "6b6500024140b8b859055c744a89ef4d4f6ae7a58e0a99fef2eb0f6cf09d740b56cf4c7c14ab9b1ff3d62164e0" + "d86de3429d1943292b6a3b623bae21cc5c6ba6cb90cd8030a22321031bec1250aa8f78275f99a6663688f31085" "848d0ed92f1203e447125f927b7486ac41406413b060329e133cd13709c361ccd90b3944477cf3937f1459313f" "0ea6435f6f2b1335192a5d1b346fd431e8af912bfa4e1a23ad7d0ab7fc5b808655af5c9043232103d9fd62df33" "2403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", rawTxHex); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ( - // "00d100000000f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df68b00c6" - // "6b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc81400000000000000000000000000000000000000" - // "016a7cc814fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc8516a7cc86c0c7472616e7366657246726f" - // "6d1400000000000000000000000000000000000000020068164f6e746f6c6f67792e4e61746976652e496e766f" - // "6b6500024140b8b859055c744a89ef4d4f6ae7a58e0a99fef2eb0f6cf09d740b56cf4c7c14ab9b1ff3d62164e0" - // "d86de3429d1943292b6a3b623bae21cc5c6ba6cb90cd8030a22321031bec1250aa8f78275f99a6663688f31085" - // "848d0ed92f1203e447125f927b7486ac41406413b060329e133cd13709c361ccd90b3944477cf3937f1459313f" - // "0ea6435f6f2b1335192a5d1b346fd431e8af912bfa4e1a23ad7d0ab7fc5b808655af5c9043232103d9fd62df33" - // "2403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // rawTxHex); } } // namespace TW::Ontology::tests diff --git a/tests/chains/Ontology/OntTests.cpp b/tests/chains/Ontology/OntTests.cpp index 4d499ddbdcc..f5ea71f4220 100644 --- a/tests/chains/Ontology/OntTests.cpp +++ b/tests/chains/Ontology/OntTests.cpp @@ -5,8 +5,10 @@ #include "HexCoding.h" #include "Ontology/Ont.h" -#include +#include + #include +#include namespace TW::Ontology::tests { @@ -32,10 +34,10 @@ TEST(OntologyOnt, queryBalance) { } TEST(OntologyOnt, transfer) { - PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646")); + PrivateKey privateKey1(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer1(privateKey1); - PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652")); + PrivateKey privateKey2(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology)); Signer signer2(privateKey2); auto toAddress = Address("Af1n2cZHhMZumNqKgw9sfCNoTWu9de4NDn"); @@ -49,24 +51,12 @@ TEST(OntologyOnt, transfer) { "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" "00000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b65000241407531e7d5bb9ae138" - "862585a65c26d624f1a7a61011298809d9ed9cf60d10a4504067dee9d549a836b480c4e48904e28f9b42" - "dd5fa14376cbb1ef27d931eaea552321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" + "862585a65c26d624f1a7a61011298809d9ed9cf60d10a450bf9821152ab657ca4b7f3b1b76fb1d7021a4" + "1d4e05d427b941caa2e9ca783afc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" "47125f927b7486ac4140bcc6df81d7f2f3143f152c446643ac5bf7910ef90046be8c89818264a11d360d" - "0576d7b092fabafd0913a67ccf8b2f8e3d2bd708f768c2bb67e2d2f759805608232103d9fd62df332403" + "fa89284e6d054503f6ec59833074d0717fbb23a4afaedbc98bd6f7cba2e2cf49232103d9fd62df332403" "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", rawTxHex); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ("00d100000000f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df6" - // "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" - // "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" - // "00000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b65000241407531e7d5bb9ae138" - // "862585a65c26d624f1a7a61011298809d9ed9cf60d10a450bf9821152ab657ca4b7f3b1b76fb1d7021a4" - // "1d4e05d427b941caa2e9ca783afc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" - // "47125f927b7486ac4140bcc6df81d7f2f3143f152c446643ac5bf7910ef90046be8c89818264a11d360d" - // "fa89284e6d054503f6ec59833074d0717fbb23a4afaedbc98bd6f7cba2e2cf49232103d9fd62df332403" - // "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // rawTxHex); } // Successfully broadcasted: https://explorer.ont.io/tx/785af64758886099b995e2aed914c56b15ab63c6e0c5acf42b66f3bbc3e95f98 diff --git a/tests/chains/Ontology/TWAnySignerTests.cpp b/tests/chains/Ontology/TWAnySignerTests.cpp index 3d9754490aa..4d33fee8ab9 100644 --- a/tests/chains/Ontology/TWAnySignerTests.cpp +++ b/tests/chains/Ontology/TWAnySignerTests.cpp @@ -79,24 +79,12 @@ TEST(TWAnySingerOntology, OntTransfer) { "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" "00000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6e" - "bb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb7cff28ddaf7f1048822c0ca21a0c4926323a" - "2497875b963f3b8cbd3717aa6e7c2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" + "bb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aac" + "d6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" "47125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860" "305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403" "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", hex(output.encoded())); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ("00d102d45c8bf401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df6" - // "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" - // "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" - // "00000000010068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140301766d925382a6e" - // "bb2ebeb18d3741954c9370dcf6d9c45b34ce7b18bc42dcdb8300d7215080efb87dd3f35de5f3b6d98aac" - // "d6161fbc0845b82d0d8be4b8b6d52321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" - // "47125f927b7486ac414038466b25ac49a22ba8c301328ef049a61711b257987e85e25d63e0444a14e860" - // "305a4cd3bb6ea2fe80fd293abb3c592e679c42c546cbf3baa051a07b28b374a6232103d9fd62df332403" - // "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // hex(output.encoded())); } TEST(TWAnySingerOntology, OngDecimals) { @@ -161,24 +149,12 @@ TEST(TWAnySingerOntology, OngTransfer) { "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" "00000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efa" - "d62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f73b8ab199a4d757b4c7b9ed46c4ff8cfa8ae" - "faa90b7fb6485e358034448cba752321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" + "d62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b007301438" + "00049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" "47125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74" - "3b078bd4e21bb4404c0182a32ee05260e22454dffb34dacccf458dfbee6d32db232103d9fd62df332403" + "c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403" "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", hex(output.encoded())); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ("00d19d3182a8f401000000000000204e00000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df6" - // "7100c66b14fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a6a7cc814feec06b79ed299ea06fcb94aba" - // "c41aaf3ead76586a7cc8516a7cc86c51c1087472616e7366657214000000000000000000000000000000" - // "00000000020068164f6e746f6c6f67792e4e61746976652e496e766f6b6500024140e27e935b87855efa" - // "d62bb76b21c7b591f445f867eff86f888ca6ee1870ecd80f8c4754e565b28a85b384612b93b007301438" - // "00049b97e83c95844a8eb7d66adc2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e4" - // "47125f927b7486ac4140450047b2efb384129a16ec4c707790e9379b978cc7085170071d8d7c5c037d74" - // "c4f8742a1de44bc0b3fe7d5cd11fad9edac2a5cdabe2c3b824743cc70df5f276232103d9fd62df332403" - // "d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac", - // hex(output.encoded())); } TEST(TWAnySingerOntology, OngWithdraw) { @@ -259,10 +235,7 @@ TEST(TWAnySingerOntology, Oep4Transfer) { auto rawTx = data(output.encoded()); auto rawTxHex = hex(rawTx); - EXPECT_EQ("00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa22871cfb819923fe01e9cb1e9ed16baa2b05c2feb76bcbe2ec125f72701c5e965232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9da4bb5dacd23dafba868cb31bacb38b4a6ff2607682a426c1dc09b05a1e158d6cd2321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac", hex(output.encoded())); - - // TODO uncomment when nist256p1 Rust implementation is enabled. - // EXPECT_EQ("00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa2d78e3046e66dc020e1634e1612e9455d0c8acac2305ae0563293d39bfa9d3bec232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9dab44a2531dc2504589734ce4534c74b58bdc0f3457cd53267331ec5211b0a4e842321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac", rawTxHex); + EXPECT_EQ("00d134120000c40900000000000050c3000000000000fbacc8214765d457c8e3f2b5a1d3c4981a2e9d2a4d02e9001496f688657b95be51c11a87b51adfda4ab69e9cbb1457e9d1a61f9aafa798b6c7fbeae35639681d7df653c1087472616e736665726733def739225d0f93dd2aed457d7b1fd074ec31ff00024140bd2923854d7b84b97a107bb3cddf18c8e3dddd2f36b41a1f5f5b23366484daa2d78e3046e66dc020e1634e1612e9455d0c8acac2305ae0563293d39bfa9d3bec232103d9fd62df332403d9114f3fa3da0d5aec9dfa42948c2f50738d52470469a1a1eeac41406d638653597774ce45812ea2653250806b657b32b7c6ad3e027ddeba91e9a9dab44a2531dc2504589734ce4534c74b58bdc0f3457cd53267331ec5211b0a4e842321031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac", rawTxHex); } TEST(TWAnySingerOntology, Oep4TokenBalanceOf) { diff --git a/tests/chains/Ontology/TransactionTests.cpp b/tests/chains/Ontology/TransactionTests.cpp index 43def521309..13d84d6da9e 100644 --- a/tests/chains/Ontology/TransactionTests.cpp +++ b/tests/chains/Ontology/TransactionTests.cpp @@ -8,6 +8,7 @@ #include "Ontology/ParamsBuilder.h" #include "Ontology/Signer.h" #include "Ontology/Transaction.h" +#include "TestUtilities.h" #include @@ -37,7 +38,7 @@ TEST(OntologyTransaction, validity) { "f66a7cc8516a7cc86c51c1087472616e736665721400000000000000000000000000000000000000010068164f" "6e746f6c6f67792e4e61746976652e496e766f6b650000"; EXPECT_EQ(hexTx, hex(tx.serialize())); - auto signer1 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"))); + auto signer1 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeOntology))); signer1.sign(tx); hexTx = "00d1e3388d5c5802000000000000e09304000000000057e9d1a61f9aafa798b6c7fbeae35639681d7df67100c6" @@ -48,7 +49,7 @@ TEST(OntologyTransaction, validity) { "21031bec1250aa8f78275f99a6663688f31085848d0ed92f1203e447125f927b7486ac"; EXPECT_EQ(520ul, hex(tx.serialize()).length()); EXPECT_EQ(hexTx.substr(0, 20), hex(tx.serialize()).substr(0, 20)); - auto signer2 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"))); + auto signer2 = Signer(PrivateKey(parse_hex("4646464646464646464646464646464646464646464646464646464646464652"), TWCoinTypeCurve(TWCoinTypeOntology))); signer2.addSign(tx); auto result = tx.serialize(); auto verifyPosition1 = diff --git a/tests/chains/Pactus/AddressTests.cpp b/tests/chains/Pactus/AddressTests.cpp index c3bcb0a260d..2710e27c21c 100644 --- a/tests/chains/Pactus/AddressTests.cpp +++ b/tests/chains/Pactus/AddressTests.cpp @@ -22,7 +22,7 @@ TEST(PactusAddress, AddressData) { } TEST(PactusAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("2134ae97465505dfd5a1fd05a8a0f146209c601eb3f1b0363b4cfe4b47ba1ab4")); + auto privateKey = PrivateKey(parse_hex("2134ae97465505dfd5a1fd05a8a0f146209c601eb3f1b0363b4cfe4b47ba1ab4"), TWCoinTypeCurve(TWCoinTypePactus)); auto pubkey = privateKey.getPublicKey(TWPublicKeyTypeED25519); Entry entry; auto address = entry.deriveAddress(TWCoinTypePactus, pubkey, TWDerivationDefault, std::monostate{}); diff --git a/tests/chains/Pactus/CompilerTests.cpp b/tests/chains/Pactus/CompilerTests.cpp index 0d4a902e2d9..c2ca6f52103 100644 --- a/tests/chains/Pactus/CompilerTests.cpp +++ b/tests/chains/Pactus/CompilerTests.cpp @@ -31,9 +31,9 @@ TEST(PactusCompiler, CompileAndSign) { EXPECT_EQ(hex(actualDataToSign), testCase.dataToSign); // Sign the pre-hash data. - auto privateKey = PrivateKey(parse_hex(PRIVATE_KEY_HEX)); + auto privateKey = PrivateKey(parse_hex(PRIVATE_KEY_HEX), TWCurveED25519); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519).bytes; - auto signature = privateKey.sign(actualDataToSign, TWCurveED25519); + auto signature = privateKey.sign(actualDataToSign); EXPECT_EQ(hex(signature), testCase.signature); // Compile the transaction. diff --git a/tests/chains/Pactus/SignerTests.cpp b/tests/chains/Pactus/SignerTests.cpp index cbb469310c0..f0d965b4f21 100644 --- a/tests/chains/Pactus/SignerTests.cpp +++ b/tests/chains/Pactus/SignerTests.cpp @@ -19,7 +19,7 @@ TEST(PactusSigner, Sign) { for (const auto& testCase : TEST_CASES) { auto input = testCase.createSigningInput(); - auto privateKey = PrivateKey(parse_hex(PRIVATE_KEY_HEX)); + auto privateKey = PrivateKey(parse_hex(PRIVATE_KEY_HEX), TWCoinTypeCurve(TWCoinTypePactus)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); TW::Pactus::Proto::SigningOutput output; diff --git a/tests/chains/Polkadot/TWAnyAddressTests.cpp b/tests/chains/Polkadot/TWAnyAddressTests.cpp index 2a18ba00c41..d8eb016e016 100644 --- a/tests/chains/Polkadot/TWAnyAddressTests.cpp +++ b/tests/chains/Polkadot/TWAnyAddressTests.cpp @@ -43,7 +43,7 @@ TEST(PolkadotAddress, Validation) { TEST(PolkadotAddress, FromPrivateKey) { // subkey phrase `chief menu kingdom stereo hope hazard into island bag trick egg route` - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0x612d82bc053d1b4729057688ecb1ebf62745d817ddd9b595bc822f5f2ba0e41a").get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0x612d82bc053d1b4729057688ecb1ebf62745d817ddd9b595bc822f5f2ba0e41a").get(), TWCoinTypeCurve(TWCoinTypePolkadot))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypePolkadot)); const auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypePolkadot)); const auto addressStr = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Polkadot/TWAnySignerTests.cpp b/tests/chains/Polkadot/TWAnySignerTests.cpp index 7c6328d4d98..de697f185db 100644 --- a/tests/chains/Polkadot/TWAnySignerTests.cpp +++ b/tests/chains/Polkadot/TWAnySignerTests.cpp @@ -26,9 +26,9 @@ uint32_t kusamaPrefix = ss58Prefix(TWCoinTypeKusama); uint32_t astarPrefix = 5; uint32_t parallelPrefix = 172; -auto privateKey = PrivateKey(parse_hex("0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a76909115")); +auto privateKey = PrivateKey(parse_hex("0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a76909115"), TWCoinTypeCurve(TWCoinTypePolkadot)); auto privateKeyThrow2Data = DATA("70a794d4f1019c3ce002f33062f45029c4f930a56b3d20ec477f7668c6bbc37f"); -auto privateKeyThrow2 = TWPrivateKeyCreateWithData(privateKeyThrow2Data.get()); +auto privateKeyThrow2 = TWPrivateKeyCreateWithData(privateKeyThrow2Data.get(), TWCoinTypeCurve(TWCoinTypePolkadot)); auto addressThrow2 = "14Ztd3KJDaB9xyJtRkREtSZDdhLSbm7UUKt8Z7AwSv7q85G2"; auto genesisHash = parse_hex("91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"); diff --git a/tests/chains/Polymesh/TWAnyAddressTests.cpp b/tests/chains/Polymesh/TWAnyAddressTests.cpp index 1602ff3e1a0..eac9a1942cf 100644 --- a/tests/chains/Polymesh/TWAnyAddressTests.cpp +++ b/tests/chains/Polymesh/TWAnyAddressTests.cpp @@ -54,7 +54,7 @@ TEST(PolymeshAddress, Validation) { TEST(PolymeshAddress, FromPrivateKey) { // subkey phrase `chief menu kingdom stereo hope hazard into island bag trick egg route` - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0x612d82bc053d1b4729057688ecb1ebf62745d817ddd9b595bc822f5f2ba0e41a").get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("0x612d82bc053d1b4729057688ecb1ebf62745d817ddd9b595bc822f5f2ba0e41a").get(), TWCoinTypeCurve(TWCoinTypePolymesh))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypePolymesh)); const auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypePolymesh)); const auto addressStr = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Qtum/TWQtumAddressTests.cpp b/tests/chains/Qtum/TWQtumAddressTests.cpp index cf95e3bc12a..20a48ef2813 100644 --- a/tests/chains/Qtum/TWQtumAddressTests.cpp +++ b/tests/chains/Qtum/TWQtumAddressTests.cpp @@ -15,7 +15,7 @@ #include TEST(Qtum, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeQtum))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeQtum))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -23,7 +23,7 @@ TEST(Qtum, LegacyAddress) { } TEST(Qtum, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeQtum))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWSegwitAddress, TWSegwitAddressCreateWithPublicKey(TWHRPQtum, publicKey.get())); auto string = WRAPS(TWSegwitAddressDescription(address.get())); diff --git a/tests/chains/Solana/AddressTests.cpp b/tests/chains/Solana/AddressTests.cpp index 6e040826979..65960797cc0 100644 --- a/tests/chains/Solana/AddressTests.cpp +++ b/tests/chains/Solana/AddressTests.cpp @@ -6,6 +6,7 @@ #include "HexCoding.h" #include "PrivateKey.h" #include "Solana/Address.h" +#include "TestUtilities.h" #include @@ -22,7 +23,7 @@ TEST(SolanaAddress, FromPublicKey) { ASSERT_EQ(addressString, address.string()); } { - const auto privateKey = PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a")); + const auto privateKey = PrivateKey(parse_hex("a1269039e4ffdf43687852d7247a295f0b5bc55e6dda031cffaa3295ca0a9d7a"), TWCoinTypeCurve(TWCoinTypeSolana)); const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); EXPECT_ANY_THROW(new Address(publicKey)); } @@ -59,10 +60,10 @@ TEST(SolanaAddress, isValidOnCurve) { EXPECT_TRUE(PublicKey(Base58::decode("68io7dTfyeWua1wD1YcCMka4y5iiChceaFRCBjqCM5PK"), TWPublicKeyTypeED25519).isValidED25519()); EXPECT_TRUE(PublicKey(Base58::decode("Dra34QLFCjxnk8tUNcBwxs6pgb5spF4oseQYF2xn7ABZ"), TWPublicKeyTypeED25519).isValidED25519()); // negative case - EXPECT_FALSE(PublicKey(Base58::decode("6X4X1Ae24mkoWeCEpktevySVG9jzeCufut5vtUW3wFrD"), TWPublicKeyTypeED25519).isValidED25519()); - EXPECT_FALSE(PublicKey(Base58::decode("EDNd1ycsydWYwVmrYZvqYazFqwk1QjBgAUKFjBoz1jKP"), TWPublicKeyTypeED25519).isValidED25519()); - EXPECT_FALSE(PublicKey(Base58::decode("ANVCrmRw7Ww7rTFfMbrjApSPXEEcZpBa6YEiBdf98pAf"), TWPublicKeyTypeED25519).isValidED25519()); - EXPECT_FALSE(PublicKey(Base58::decode("AbygL37RheNZv327cMvZPqKYLLkZ6wqWYexRxgNiZyeP"), TWPublicKeyTypeED25519).isValidED25519()); + EXPECT_FALSE(PublicKey::isValid(Base58::decode("6X4X1Ae24mkoWeCEpktevySVG9jzeCufut5vtUW3wFrD"), TWPublicKeyTypeED25519)); + EXPECT_FALSE(PublicKey::isValid(Base58::decode("EDNd1ycsydWYwVmrYZvqYazFqwk1QjBgAUKFjBoz1jKP"), TWPublicKeyTypeED25519)); + EXPECT_FALSE(PublicKey::isValid(Base58::decode("ANVCrmRw7Ww7rTFfMbrjApSPXEEcZpBa6YEiBdf98pAf"), TWPublicKeyTypeED25519)); + EXPECT_FALSE(PublicKey::isValid(Base58::decode("AbygL37RheNZv327cMvZPqKYLLkZ6wqWYexRxgNiZyeP"), TWPublicKeyTypeED25519)); } } // namespace TW::Solana::tests diff --git a/tests/chains/Solana/SolanaMessageSigner.cpp b/tests/chains/Solana/SolanaMessageSigner.cpp index a335ed7109e..eb567d005ec 100644 --- a/tests/chains/Solana/SolanaMessageSigner.cpp +++ b/tests/chains/Solana/SolanaMessageSigner.cpp @@ -2,7 +2,7 @@ // // Copyright © 2017 Trust Wallet. -#include +#include #include #include "Data.h" diff --git a/tests/chains/Solana/TWSolanaTransaction.cpp b/tests/chains/Solana/TWSolanaTransaction.cpp index f562dcfb8b4..7e545a08e72 100644 --- a/tests/chains/Solana/TWSolanaTransaction.cpp +++ b/tests/chains/Solana/TWSolanaTransaction.cpp @@ -2,7 +2,7 @@ // // Copyright © 2017 Trust Wallet. -#include "TrustWalletCore/TWSolanaTransaction.h" +#include "TrustWalletCore/Generated/TWSolanaTransaction.h" #include "TrustWalletCore/TWTransactionDecoder.h" #include "TrustWalletCore/TWAnySigner.h" #include "proto/Solana.pb.h" diff --git a/tests/chains/Solana/TWWalletConnectSolana.cpp b/tests/chains/Solana/TWWalletConnectSolana.cpp index f8c23d0c80e..1be2ca2329e 100644 --- a/tests/chains/Solana/TWWalletConnectSolana.cpp +++ b/tests/chains/Solana/TWWalletConnectSolana.cpp @@ -7,7 +7,7 @@ #include "proto/WalletConnect.pb.h" #include "Coin.h" #include -#include +#include #include "TestUtilities.h" #include diff --git a/tests/chains/StarkEx/MessageSignerTests.cpp b/tests/chains/StarkEx/MessageSignerTests.cpp index d8140ecead3..a9bf919ed43 100644 --- a/tests/chains/StarkEx/MessageSignerTests.cpp +++ b/tests/chains/StarkEx/MessageSignerTests.cpp @@ -12,7 +12,7 @@ namespace TW::StarkEx::tests { TEST(StarkExMessageSigner, SignAndVerify) { - PrivateKey starkPrivKey(parse_hex("04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de", true)); + PrivateKey starkPrivKey(parse_hex("04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de", true), TWCurveStarkex); auto starkPubKey = starkPrivKey.getPublicKey(TWPublicKeyTypeStarkex); auto starkMsg = "463a2240432264a3aa71a5713f2a4e4c1b9e12bbb56083cd56af6d878217cf"; auto starkSignature = StarkEx::MessageSigner::signMessage(starkPrivKey, starkMsg); @@ -22,7 +22,7 @@ TEST(StarkExMessageSigner, SignAndVerify) { TEST(TWStarkExMessageSigner, SignAndVerify) { const auto privKeyData = "04be51a04e718c202e4dca60c2b72958252024cfc1070c090dd0f170298249de"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCurveStarkex)); const auto message = STRING("463a2240432264a3aa71a5713f2a4e4c1b9e12bbb56083cd56af6d878217cf"); const auto pubKey = TWPrivateKeyGetPublicKeyByType(privateKey.get(), TWPublicKeyTypeStarkex); diff --git a/tests/chains/Stellar/AddressTests.cpp b/tests/chains/Stellar/AddressTests.cpp index b4c84772273..8aeeff383bf 100644 --- a/tests/chains/Stellar/AddressTests.cpp +++ b/tests/chains/Stellar/AddressTests.cpp @@ -6,6 +6,7 @@ #include "HexCoding.h" #include "PrivateKey.h" #include "Stellar/Address.h" +#include "TestUtilities.h" #include @@ -20,7 +21,7 @@ TEST(StellarAddress, FromPublicKey) { auto str = hex(address.bytes); ASSERT_EQ(string("GAB6EDWGWSRZUYUYCWXAFQFBHE5ZEJPDXCIMVZC3LH2C7IU35FTI2NOQ"), address.string()); - const auto privateKey = PrivateKey(parse_hex("94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f")); + const auto privateKey = PrivateKey(parse_hex("94d1a980d5e528067d44bf8a60d646f556e40ca71e17cd4ead2d56f89e4bd20f"), TWCoinTypeCurve(TWCoinTypeStellar)); const auto publicKey2 = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended)); EXPECT_ANY_THROW(new Address(publicKey2)); } diff --git a/tests/chains/Stellar/TWAnySignerTests.cpp b/tests/chains/Stellar/TWAnySignerTests.cpp index fe8728b1de4..fbecc9bcfc2 100644 --- a/tests/chains/Stellar/TWAnySignerTests.cpp +++ b/tests/chains/Stellar/TWAnySignerTests.cpp @@ -37,7 +37,7 @@ TEST(TWAnySingerStellar, Sign_Payment) { TEST(TWAnySingerStellar, Sign_Payment_66b5) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); @@ -60,7 +60,7 @@ TEST(TWAnySingerStellar, Sign_Payment_66b5) { TEST(TWAnySingerStellar, Sign_Payment_Asset_ea50) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); @@ -85,7 +85,7 @@ TEST(TWAnySingerStellar, Sign_Payment_Asset_ea50) { TEST(TWAnySingerStellar, Sign_Change_Trust_ad9c) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); @@ -109,7 +109,7 @@ TEST(TWAnySingerStellar, Sign_Change_Trust_ad9c) { TEST(TWAnySingerStellar, Sign_Change_Trust_2) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); @@ -132,7 +132,7 @@ TEST(TWAnySingerStellar, Sign_Change_Trust_2) { TEST(TWAnySingerStellar, Sign_Create_Claimable_Balance_1f1f84) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); @@ -158,7 +158,7 @@ TEST(TWAnySingerStellar, Sign_Create_Claimable_Balance_1f1f84) { TEST(TWAnySingerStellar, Sign_Claim_Claimable_Balance_c1fb3c) { auto key = parse_hex("3c0635f8638605aed6e461cf3fa2d508dd895df1a1655ff92c79bfbeaf88d4b9"); - PrivateKey privKey = PrivateKey(key); + PrivateKey privKey = PrivateKey(key, TWCoinTypeCurve(TWCoinTypeStellar)); PublicKey pubKey = privKey.getPublicKey(TWPublicKeyTypeED25519); Address addr = Address(pubKey); EXPECT_EQ(addr.string(), "GDFEKJIFKUZP26SESUHZONAUJZMBSODVN2XBYN4KAGNHB7LX2OIXLPUL"); diff --git a/tests/chains/Stellar/TransactionCompilerTests.cpp b/tests/chains/Stellar/TransactionCompilerTests.cpp index 578877ba49c..9647d465b53 100644 --- a/tests/chains/Stellar/TransactionCompilerTests.cpp +++ b/tests/chains/Stellar/TransactionCompilerTests.cpp @@ -25,7 +25,7 @@ TEST(StellarCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) TW::Stellar::Proto::SigningInput input; auto privateKey = - PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto publicKey = privateKey.getPublicKey(::publicKeyType(coin)); input.set_passphrase(TWStellarPassphrase_Stellar); diff --git a/tests/chains/Stellar/TransactionTests.cpp b/tests/chains/Stellar/TransactionTests.cpp index 1803cb1605f..e950671eb26 100644 --- a/tests/chains/Stellar/TransactionTests.cpp +++ b/tests/chains/Stellar/TransactionTests.cpp @@ -37,7 +37,7 @@ TEST(StellarTransaction, sign) { } TEST(StellarTransaction, signWithMemoText) { - auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto input = TW::Stellar::Proto::SigningInput(); input.set_passphrase(TWStellarPassphrase_Stellar); input.set_account("GAE2SZV4VLGBAPRYRFV2VY7YYLYGYIP5I7OU7BSP6DJT7GAZ35OKFDYI"); @@ -57,7 +57,7 @@ TEST(StellarTransaction, signWithMemoText) { } TEST(StellarTransaction, signWithMemoHash) { - auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto input = TW::Stellar::Proto::SigningInput(); input.set_passphrase(TWStellarPassphrase_Stellar); input.set_account("GAE2SZV4VLGBAPRYRFV2VY7YYLYGYIP5I7OU7BSP6DJT7GAZ35OKFDYI"); @@ -78,7 +78,7 @@ TEST(StellarTransaction, signWithMemoHash) { } TEST(StellarTransaction, signWithMemoReturn) { - auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto input = TW::Stellar::Proto::SigningInput(); input.set_passphrase(TWStellarPassphrase_Stellar); input.set_account("GAE2SZV4VLGBAPRYRFV2VY7YYLYGYIP5I7OU7BSP6DJT7GAZ35OKFDYI"); @@ -99,7 +99,7 @@ TEST(StellarTransaction, signWithMemoReturn) { } TEST(StellarTransaction, signWithMemoID) { - auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto input = TW::Stellar::Proto::SigningInput(); input.set_passphrase(TWStellarPassphrase_Stellar); input.set_account("GAE2SZV4VLGBAPRYRFV2VY7YYLYGYIP5I7OU7BSP6DJT7GAZ35OKFDYI"); @@ -119,7 +119,7 @@ TEST(StellarTransaction, signWithMemoID) { } TEST(StellarTransaction, signAcreateAccount) { - auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722")); + auto privateKey = PrivateKey(parse_hex("59a313f46ef1c23a9e4f71cea10fc0c56a2a6bb8a4b9ea3d5348823e5a478722"), TWCoinTypeCurve(TWCoinTypeStellar)); auto input = TW::Stellar::Proto::SigningInput(); input.set_passphrase(TWStellarPassphrase_Stellar); input.set_account("GAE2SZV4VLGBAPRYRFV2VY7YYLYGYIP5I7OU7BSP6DJT7GAZ35OKFDYI"); diff --git a/tests/chains/Stratis/TWStratisTests.cpp b/tests/chains/Stratis/TWStratisTests.cpp index 6d8dbf1f95b..d5a26660eea 100644 --- a/tests/chains/Stratis/TWStratisTests.cpp +++ b/tests/chains/Stratis/TWStratisTests.cpp @@ -14,7 +14,7 @@ #include TEST(Stratis, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeStratis))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeStratis))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -22,7 +22,7 @@ TEST(Stratis, LegacyAddress) { } TEST(Stratis, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeStratis))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeStratis)); auto string = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Sui/CompilerTests.cpp b/tests/chains/Sui/CompilerTests.cpp index b496546ff43..df31fe10a41 100644 --- a/tests/chains/Sui/CompilerTests.cpp +++ b/tests/chains/Sui/CompilerTests.cpp @@ -32,9 +32,9 @@ TEST(SuiCompiler, PreHashAndCompile) { EXPECT_EQ(data(preSigningOutput.data()), expectedData); EXPECT_EQ(data(preSigningOutput.data_hash()), expectedHash); - auto privateKey = PrivateKey(parse_hex("3823dce5288ab55dd1c00d97e91933c613417fdb282a0b8b01a7f5f5a533b266")); + auto privateKey = PrivateKey(parse_hex("3823dce5288ab55dd1c00d97e91933c613417fdb282a0b8b01a7f5f5a533b266"), TWCurveED25519); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519).bytes; - auto signature = privateKey.sign(expectedHash, TWCurveED25519); + auto signature = privateKey.sign(expectedHash); auto outputData = TransactionCompiler::compileWithSignatures(TWCoinTypeSui, inputStrData, {signature}, {publicKey}); Proto::SigningOutput output; diff --git a/tests/chains/Sui/MessageSignerTests.cpp b/tests/chains/Sui/MessageSignerTests.cpp index 414cb6ee95d..1483d1ee476 100644 --- a/tests/chains/Sui/MessageSignerTests.cpp +++ b/tests/chains/Sui/MessageSignerTests.cpp @@ -2,7 +2,7 @@ // // Copyright © 2017 Trust Wallet. -#include +#include #include #include "Data.h" diff --git a/tests/chains/Sui/SignerTests.cpp b/tests/chains/Sui/SignerTests.cpp index ce801ca9113..f2f66305022 100644 --- a/tests/chains/Sui/SignerTests.cpp +++ b/tests/chains/Sui/SignerTests.cpp @@ -17,7 +17,7 @@ TEST(SuiSigner, Transfer) { Proto::SigningInput input; auto txMsg = "AAACAAgQJwAAAAAAAAAgJZ/4B0q0Jcu0ifI24Y4I8D8aeFa998eih3vWT3OLUBUCAgABAQAAAQEDAAAAAAEBANV1rX8Y6UhGKlz2mPVk7zlKdSpx/sYkk6+KBVwBLA1QAQbywsjB2JZN8QGdZhbpcFcZvrq9kx2idVy5SM635olk7AIAAAAAAAAgYEVuxmf1zRBGdoDr+VDtMpIFF12s2Ua7I2ru1XyGF8/Vda1/GOlIRipc9pj1ZO85SnUqcf7GJJOvigVcASwNUAEAAAAAAAAA0AcAAAAAAAAA"; input.mutable_sign_direct_message()->set_unsigned_tx_msg(txMsg); - auto privateKey = PrivateKey(parse_hex("3823dce5288ab55dd1c00d97e91933c613417fdb282a0b8b01a7f5f5a533b266")); + auto privateKey = PrivateKey(parse_hex("3823dce5288ab55dd1c00d97e91933c613417fdb282a0b8b01a7f5f5a533b266"), TWCoinTypeCurve(TWCoinTypeSui)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); Proto::SigningOutput output; diff --git a/tests/chains/Syscoin/TWSyscoinTests.cpp b/tests/chains/Syscoin/TWSyscoinTests.cpp index 77cc8390314..cabdcc847de 100644 --- a/tests/chains/Syscoin/TWSyscoinTests.cpp +++ b/tests/chains/Syscoin/TWSyscoinTests.cpp @@ -14,7 +14,7 @@ #include TEST(Syscoin, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeSyscoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeSyscoin))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -22,7 +22,7 @@ TEST(Syscoin, LegacyAddress) { } TEST(Syscoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeSyscoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeSyscoin)); auto string = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Tezos/ForgingTests.cpp b/tests/chains/Tezos/ForgingTests.cpp index 95ffe14dd78..259ea77d070 100644 --- a/tests/chains/Tezos/ForgingTests.cpp +++ b/tests/chains/Tezos/ForgingTests.cpp @@ -100,7 +100,7 @@ TEST(Forging, forge_tz3) { TEST(Forging, ForgeED25519PublicKey) { auto expected = "00311f002e899cdd9a52d96cb8be18ea2bbab867c505da2b44ce10906f511cff95"; - auto privateKey = PrivateKey(parse_hex("c6377a4cc490dc913fc3f0d9cf67d293a32df4547c46cb7e9e33c3b7b97c64d8")); + auto privateKey = PrivateKey(parse_hex("c6377a4cc490dc913fc3f0d9cf67d293a32df4547c46cb7e9e33c3b7b97c64d8"), TWCoinTypeCurve(TWCoinTypeTezos)); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeED25519); auto output = forgePublicKey(publicKey); @@ -134,7 +134,7 @@ TEST(Forging, ForgeMichelsonFA12) { TEST(Forging, ForgeSECP256k1PublicKey) { auto expected = "0102b4ac9056d20c52ac11b0d7e83715dd3eac851cfc9cb64b8546d9ea0d4bb3bdfe"; - auto privateKey = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")); + auto privateKey = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a"), TWCoinTypeCurve(TWCoinTypeTezos)); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); auto output = forgePublicKey(publicKey); diff --git a/tests/chains/Tezos/MessageSignerTests.cpp b/tests/chains/Tezos/MessageSignerTests.cpp index 3f38133d55a..3e085896d47 100644 --- a/tests/chains/Tezos/MessageSignerTests.cpp +++ b/tests/chains/Tezos/MessageSignerTests.cpp @@ -24,7 +24,7 @@ TEST(TezosMessageSigner, formatMessage) { TEST(TezosMessageSigner, SignMessage) { auto payload = Tezos::MessageSigner::inputToPayload("Tezos Signed Message: testUrl 2023-02-08T10:36:18.454Z Hello World"); - PrivateKey privKey(parse_hex("91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a")); + PrivateKey privKey(parse_hex("91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a"), TWCoinTypeCurve(TWCoinTypeTezos)); auto result = Tezos::MessageSigner::signMessage(privKey, payload); auto expected = "edsigu3se2fcEJUCm1aqxjzbHdf7Wsugr4mLaA9YM2UVZ9Yy5meGv87VqHN3mmDeRwApTj1JKDaYjqmLZifSFdWCqBoghqaowwJ"; ASSERT_EQ(result, expected); @@ -48,7 +48,7 @@ TEST(TWTezosMessageSigner, inputToPayload) { TEST(TWTezosMessageSigner, SignAndVerify) { const auto privKeyData = "91b4fb8d7348db2e7de2693f58ce1cceb966fa960739adac1d9dba2cbaa0940a"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeTezos))); const auto message = STRING("05010000004254657a6f73205369676e6564204d6573736167653a207465737455726c20323032332d30322d30385431303a33363a31382e3435345a2048656c6c6f20576f726c64"); const auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeTezos)); diff --git a/tests/chains/Tezos/TransactionCompilerTests.cpp b/tests/chains/Tezos/TransactionCompilerTests.cpp index 56f3ec7a008..fe1fae2c44b 100644 --- a/tests/chains/Tezos/TransactionCompilerTests.cpp +++ b/tests/chains/Tezos/TransactionCompilerTests.cpp @@ -24,7 +24,7 @@ TEST(TezosCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) auto privateKey = - PrivateKey(parse_hex("2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6f")); + PrivateKey(parse_hex("2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6f"), TWCoinTypeCurve(coin)); auto publicKey = privateKey.getPublicKey(::publicKeyType(coin)); auto revealKey = parse_hex("311f002e899cdd9a52d96cb8be18ea2bbab867c505da2b44ce10906f511cff95"); diff --git a/tests/chains/TheOpenNetwork/TWTONAddressConverterTests.cpp b/tests/chains/TheOpenNetwork/TWTONAddressConverterTests.cpp index ec93a9dc78d..f5f7b0a4447 100644 --- a/tests/chains/TheOpenNetwork/TWTONAddressConverterTests.cpp +++ b/tests/chains/TheOpenNetwork/TWTONAddressConverterTests.cpp @@ -4,7 +4,7 @@ #include "TestUtilities.h" -#include +#include namespace TW::TheOpenNetwork::tests { diff --git a/tests/chains/TheOpenNetwork/TWTONMessageSignerTests.cpp b/tests/chains/TheOpenNetwork/TWTONMessageSignerTests.cpp index fd9367dffd7..8d0d79f266a 100644 --- a/tests/chains/TheOpenNetwork/TWTONMessageSignerTests.cpp +++ b/tests/chains/TheOpenNetwork/TWTONMessageSignerTests.cpp @@ -5,13 +5,13 @@ #include "TestUtilities.h" #include "HexCoding.h" -#include "TrustWalletCore/TWTONMessageSigner.h" +#include "TrustWalletCore/Generated/TWTONMessageSigner.h" namespace TW::TheOpenNetwork::tests { TEST(TWTONMessageSigner, SignMessage) { const auto privateKeyBytes = DATA("112d4e2e700a468f1eae699329202f1ee671d6b665caa2d92dea038cf3868c18"); - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(privateKeyBytes.get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(privateKeyBytes.get(), TWCoinTypeCurve(TWCoinTypeTON))); const auto message = STRING("Hello world"); const auto signature = WRAPS(TWTONMessageSignerSignMessage(privateKey.get(), message.get())); diff --git a/tests/chains/TheOpenNetwork/TWTONWalletTests.cpp b/tests/chains/TheOpenNetwork/TWTONWalletTests.cpp index b346ee5568b..e97d8502d62 100644 --- a/tests/chains/TheOpenNetwork/TWTONWalletTests.cpp +++ b/tests/chains/TheOpenNetwork/TWTONWalletTests.cpp @@ -5,7 +5,7 @@ #include "TestUtilities.h" #include "HexCoding.h" -#include "TrustWalletCore/TWTONWallet.h" +#include "TrustWalletCore/Generated/TWTONWallet.h" namespace TW::TheOpenNetwork::tests { diff --git a/tests/chains/Theta/TransactionCompilerTests.cpp b/tests/chains/Theta/TransactionCompilerTests.cpp index fd35e22f406..3b44fe54e45 100644 --- a/tests/chains/Theta/TransactionCompilerTests.cpp +++ b/tests/chains/Theta/TransactionCompilerTests.cpp @@ -24,7 +24,7 @@ TEST(ThetaCompiler, CompileWithSignatures) { const auto coin = TWCoinTypeTheta; /// Step 1: Prepare transaction input (protobuf) const auto pkFrom = - PrivateKey(parse_hex("0x93a90ea508331dfdf27fb79757d4250b4e84954927ba0073cd67454ac432c737")); + PrivateKey(parse_hex("0x93a90ea508331dfdf27fb79757d4250b4e84954927ba0073cd67454ac432c737"), TWCoinTypeCurve(coin)); const auto publicKey = pkFrom.getPublicKey(TWPublicKeyTypeSECP256k1Extended); TW::Theta::Proto::SigningInput input; input.set_chain_id("privatenet"); diff --git a/tests/chains/Tron/AddressTests.cpp b/tests/chains/Tron/AddressTests.cpp index 7489812ddca..4b3cdf165bd 100644 --- a/tests/chains/Tron/AddressTests.cpp +++ b/tests/chains/Tron/AddressTests.cpp @@ -5,23 +5,24 @@ #include "HexCoding.h" #include "PrivateKey.h" #include "Tron/Address.h" +#include "TestUtilities.h" #include namespace TW::Tron { TEST(TronAddress, FromPublicKey) { - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); const auto address = Address(publicKey); ASSERT_EQ(address.string(), "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"); - const auto privateKey2 = PrivateKey(parse_hex("BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835")); + const auto privateKey2 = PrivateKey(parse_hex("BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835"), TWCoinTypeCurve(TWCoinTypeTron)); const auto publicKey2 = privateKey2.getPublicKey(TWPublicKeyTypeSECP256k1Extended); const auto address2 = Address(publicKey2); ASSERT_EQ(address2.string(), "THRF3GuPnvvPzKoaT8pJex5XHmo8NNbCb3"); - const auto privateKey3 = PrivateKey(parse_hex("BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835")); + const auto privateKey3 = PrivateKey(parse_hex("BE88DF1D0BF30A923CB39C3BB953178BAAF3726E8D3CE81E7C8462E046E0D835"), TWCoinTypeCurve(TWCoinTypeTron)); const auto publicKey3 = privateKey3.getPublicKey(TWPublicKeyTypeED25519); EXPECT_ANY_THROW(new Address(publicKey3)); } diff --git a/tests/chains/Tron/SerializationTests.cpp b/tests/chains/Tron/SerializationTests.cpp index ef321093f73..7b7ece7d625 100644 --- a/tests/chains/Tron/SerializationTests.cpp +++ b/tests/chains/Tron/SerializationTests.cpp @@ -7,6 +7,7 @@ #include "PrivateKey.h" #include "HexCoding.h" #include "uint256.h" +#include "TestUtilities.h" #include @@ -35,7 +36,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -67,7 +68,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -101,7 +102,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -135,7 +136,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -166,7 +167,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -197,7 +198,7 @@ namespace TW::Tron { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); diff --git a/tests/chains/Tron/SignerTests.cpp b/tests/chains/Tron/SignerTests.cpp index b62ac222b73..84d5c0bdd0b 100644 --- a/tests/chains/Tron/SignerTests.cpp +++ b/tests/chains/Tron/SignerTests.cpp @@ -9,6 +9,7 @@ #include "uint256.h" #include "proto/Tron.pb.h" #include "Tron/Signer.h" +#include "TestUtilities.h" #include @@ -16,7 +17,7 @@ namespace TW::Tron { TEST(TronSigner, SignDirectTransferAsset) { auto input = Proto::SigningInput(); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); input.set_txid("546a3d07164c624809cf4e564a083a7a7974bb3c4eff6bb3e278b0ca21083fcb"); const auto output = Signer::sign(input); @@ -48,7 +49,7 @@ TEST(TronSigner, SignTransferAsset) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -80,7 +81,7 @@ TEST(TronSigner, SignTransfer) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -114,7 +115,7 @@ TEST(TronSigner, SignTransferWithMemo) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(30); - const auto privateKey = PrivateKey(parse_hex("7c2108a30f6f69f8dce72a7df897eabadfe9810eee6976b43bdf8c0b0d35337d")); + const auto privateKey = PrivateKey(parse_hex("7c2108a30f6f69f8dce72a7df897eabadfe9810eee6976b43bdf8c0b0d35337d"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -147,7 +148,7 @@ TEST(TronSigner, SignFreezeBalanceV2) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(26); - const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -178,7 +179,7 @@ TEST(TronSigner, WithdrawExpireUnfreezeContract) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(27); - const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -211,7 +212,7 @@ TEST(TronSigner, SignUnFreezeBalanceV2) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(26); - const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -245,7 +246,7 @@ TEST(TronSigner, DelegateResourceContract) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(26); - const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -279,7 +280,7 @@ TEST(TronSigner, UnDelegateResourceContract) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(26); - const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + const auto privateKey = PrivateKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -313,7 +314,7 @@ TEST(TronSigner, SignFreezeBalance) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -345,7 +346,7 @@ TEST(TronSigner, SignUnFreezeBalance) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -375,7 +376,7 @@ TEST(TronSigner, SignUnFreezeAsset) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -405,7 +406,7 @@ TEST(TronSigner, SignWithdrawBalance) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -438,7 +439,7 @@ TEST(TronSigner, SignVoteAsset) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -473,7 +474,7 @@ TEST(TronSigner, SignVoteWitness) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -508,7 +509,7 @@ TEST(TronSigner, SignTriggerSmartContract) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); @@ -540,7 +541,7 @@ TEST(TronSigner, SignTransferTrc20Contract) { blockHeader.set_witness_address(witnessAddress.data(), witnessAddress.size()); blockHeader.set_version(3); - const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + const auto privateKey = PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); const auto output = Signer::sign(input); diff --git a/tests/chains/Tron/TransactionCompilerTests.cpp b/tests/chains/Tron/TransactionCompilerTests.cpp index 0962f4bda07..839f190cba8 100644 --- a/tests/chains/Tron/TransactionCompilerTests.cpp +++ b/tests/chains/Tron/TransactionCompilerTests.cpp @@ -21,7 +21,7 @@ using namespace TW; TEST(TronCompiler, CompileWithSignatures) { const auto privateKey = - PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54")); + PrivateKey(parse_hex("2d8f68944bdbfbc0769542fba8fc2d2a3de67393334471624364c7006da2aa54"), TWCoinTypeCurve(TWCoinTypeTron)); const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); const auto coin = TWCoinTypeTron; /// Step 1: Prepare transaction input (protobuf) diff --git a/tests/chains/Tron/TronMessageSignerTests.cpp b/tests/chains/Tron/TronMessageSignerTests.cpp index 548e44f394d..1ca2d3b039e 100644 --- a/tests/chains/Tron/TronMessageSignerTests.cpp +++ b/tests/chains/Tron/TronMessageSignerTests.cpp @@ -12,7 +12,7 @@ namespace TW::Tron { TEST(TronMessageSigner, SignMessageAndVerify) { - PrivateKey tronKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a")); + PrivateKey tronKey(parse_hex("75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"), TWCoinTypeCurve(TWCoinTypeTron)); auto msg = "Hello World"; auto signature = Tron::MessageSigner::signMessage(tronKey, msg); auto pubKey = tronKey.getPublicKey(TWPublicKeyTypeSECP256k1Extended); @@ -29,7 +29,7 @@ namespace TW::Tron { TEST(TWTronMessageSigner, SignAndVerifyLegacy) { const auto privKeyData = "75065f100e38d3f3b4c5c4235834ba8216de62272a4f03532c44b31a5734360a"; - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(privKeyData).get(), TWCoinTypeCurve(TWCoinTypeTron))); const auto message = STRING("Hello World"); const auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeTron)); diff --git a/tests/chains/VeChain/TransactionCompilerTests.cpp b/tests/chains/VeChain/TransactionCompilerTests.cpp index 6a9f9ab9c90..e5e54512ef5 100644 --- a/tests/chains/VeChain/TransactionCompilerTests.cpp +++ b/tests/chains/VeChain/TransactionCompilerTests.cpp @@ -25,7 +25,7 @@ TEST(VechainCompiler, CompileWithSignatures) { /// Step 1: Prepare transaction input (protobuf) TW::VeChain::Proto::SigningInput input; PrivateKey privateKey = - PrivateKey(parse_hex("0x4646464646464646464646464646464646464646464646464646464646464646")); + PrivateKey(parse_hex("0x4646464646464646464646464646464646464646464646464646464646464646"), TWCoinTypeCurve(TWCoinTypeVeChain)); input.set_private_key(privateKey.bytes.data(), privateKey.bytes.size()); auto publicKey = privateKey.getPublicKey(publicKeyType(coin)); diff --git a/tests/chains/Verge/AddressTests.cpp b/tests/chains/Verge/AddressTests.cpp index 5185d3bd005..25e96d2a243 100644 --- a/tests/chains/Verge/AddressTests.cpp +++ b/tests/chains/Verge/AddressTests.cpp @@ -26,7 +26,7 @@ TEST(VergeAddress, Invalid) { } TEST(VergeAddress, FromPrivateKey) { - auto privateKey = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto privateKey = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); auto address = Address(publicKey, TWCoinTypeP2pkhPrefix(TWCoinTypeVerge)); ASSERT_EQ(address.string(), "DRyNFvJaybnF22UfMS6NR1Qav3mqxPj86E"); diff --git a/tests/chains/Verge/SignerTests.cpp b/tests/chains/Verge/SignerTests.cpp index 14ff7bb0720..5cfa19dc02a 100644 --- a/tests/chains/Verge/SignerTests.cpp +++ b/tests/chains/Verge/SignerTests.cpp @@ -44,7 +44,7 @@ TEST(VergeSigner, Sign) { utxo0->mutable_out_point()->set_sequence(4294967294); utxo0->set_amount(2500000000); - auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); auto script0 = Bitcoin::Script::lockScriptForAddress("DRyNFvJaybnF22UfMS6NR1Qav3mqxPj86E", TWCoinTypeVerge); ASSERT_EQ(hex(script0.bytes), "76a914e4839a523f120882d11eb3dda13a18e11fdcbd4a88ac"); utxo0->set_script(script0.bytes.data(), script0.bytes.size()); @@ -106,7 +106,7 @@ TEST(VergeSigner, SignAnyoneCanPay) { ASSERT_EQ(hex(script1.bytes), "76a914e4839a523f120882d11eb3dda13a18e11fdcbd4a88ac"); utxo1->set_script(script1.bytes.data(), script1.bytes.size()); - auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); input.add_private_key(utxoKey0.bytes.data(), utxoKey0.bytes.size()); auto plan = TransactionBuilder::plan(input); @@ -156,7 +156,7 @@ TEST(VergeSigner, SignSegwit) { EXPECT_EQ(hex(script0.bytes), "0014e4839a523f120882d11eb3dda13a18e11fdcbd4a"); utxo0->set_script(script0.bytes.data(), script0.bytes.size()); - auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); input.add_private_key(utxoKey0.bytes.data(), utxoKey0.bytes.size()); auto plan = TransactionBuilder::plan(input); diff --git a/tests/chains/Verge/TWAnySignerTests.cpp b/tests/chains/Verge/TWAnySignerTests.cpp index 7d65a5a792d..7423968307d 100644 --- a/tests/chains/Verge/TWAnySignerTests.cpp +++ b/tests/chains/Verge/TWAnySignerTests.cpp @@ -44,7 +44,7 @@ TEST(TWAnySignerVerge, Sign) { utxo0->mutable_out_point()->set_sequence(4294967294); utxo0->set_amount(2500000000); - auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); auto script0 = Bitcoin::Script::lockScriptForAddress("DRyNFvJaybnF22UfMS6NR1Qav3mqxPj86E", TWCoinTypeVerge); ASSERT_EQ(hex(script0.bytes), "76a914e4839a523f120882d11eb3dda13a18e11fdcbd4a88ac"); utxo0->set_script(script0.bytes.data(), script0.bytes.size()); diff --git a/tests/chains/Verge/TransactionBuilderTests.cpp b/tests/chains/Verge/TransactionBuilderTests.cpp index dd0b84e1c94..dee08abbca6 100644 --- a/tests/chains/Verge/TransactionBuilderTests.cpp +++ b/tests/chains/Verge/TransactionBuilderTests.cpp @@ -39,7 +39,7 @@ TEST(VergeTransactionBuilder, BuildWithTime) { utxo0->mutable_out_point()->set_sequence(4294967294); utxo0->set_amount(2500000000); - auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a")); + auto utxoKey0 = PrivateKey(parse_hex("693dfe6f3ed717573eb10c24ebe5eb592fa3c239245cd499c487eb7b8ea7ed3a"), TWCoinTypeCurve(TWCoinTypeVerge)); auto script0 = Bitcoin::Script::lockScriptForAddress("DRyNFvJaybnF22UfMS6NR1Qav3mqxPj86E", TWCoinTypeVerge); ASSERT_EQ(hex(script0.bytes), "76a914e4839a523f120882d11eb3dda13a18e11fdcbd4a88ac"); utxo0->set_script(script0.bytes.data(), script0.bytes.size()); diff --git a/tests/chains/Viacoin/TWViacoinAddressTests.cpp b/tests/chains/Viacoin/TWViacoinAddressTests.cpp index 996afe1fe8b..3f902297c88 100644 --- a/tests/chains/Viacoin/TWViacoinAddressTests.cpp +++ b/tests/chains/Viacoin/TWViacoinAddressTests.cpp @@ -15,7 +15,7 @@ #include TEST(Viacoin, LegacyAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("a22ddec5c567b4488bb00f69b6146c50da2ee883e2c096db098726394d585730").get(), TWCoinTypeCurve(TWCoinTypeViacoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWBitcoinAddress, TWBitcoinAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeP2pkhPrefix(TWCoinTypeViacoin))); auto addressString = WRAPS(TWBitcoinAddressDescription(address.get())); @@ -23,7 +23,7 @@ TEST(Viacoin, LegacyAddress) { } TEST(Viacoin, Address) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("55f9cbb0376c422946fa28397c1219933ac60b312ede41bfacaf701ecd546625").get(), TWCoinTypeCurve(TWCoinTypeViacoin))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWSegwitAddress, TWSegwitAddressCreateWithPublicKey(TWHRPViacoin, publicKey.get())); auto string = WRAPS(TWSegwitAddressDescription(address.get())); diff --git a/tests/chains/Waves/AddressTests.cpp b/tests/chains/Waves/AddressTests.cpp index 22de9778b55..781b94a3838 100644 --- a/tests/chains/Waves/AddressTests.cpp +++ b/tests/chains/Waves/AddressTests.cpp @@ -24,7 +24,7 @@ TEST(WavesAddress, SecureHash) { TEST(WavesAddress, FromPrivateKey) { const auto privateKey = - PrivateKey(parse_hex("9864a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a")); + PrivateKey(parse_hex("9864a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a"), TWCoinTypeCurve(TWCoinTypeWaves)); const auto publicKeyEd25519 = privateKey.getPublicKey(TWPublicKeyTypeED25519); ASSERT_EQ(hex(Data(publicKeyEd25519.bytes.begin(), publicKeyEd25519.bytes.end())), "ff84c4bfc095df25b01e48807715856d95af93d88c5b57f30cb0ce567ca4ced6"); diff --git a/tests/chains/Waves/SignerTests.cpp b/tests/chains/Waves/SignerTests.cpp index c4e6f61e263..bf67021ae62 100644 --- a/tests/chains/Waves/SignerTests.cpp +++ b/tests/chains/Waves/SignerTests.cpp @@ -6,8 +6,9 @@ #include "PublicKey.h" #include "Waves/Signer.h" #include "Waves/Transaction.h" +#include "Utils.h" -#include +#include #include using namespace TW; @@ -55,7 +56,9 @@ TEST(WavesSigner, curve25519_pk_to_ed25519) { parse_hex("559a50cb45a9a8e8d4f83295c354725990164d10bb505275d1a3086c08fb935d"); auto r = Data(); r.resize(32); - curve25519_pk_to_ed25519(r.data(), publicKeyCurve25519.data()); + auto curvePubkey = wrapTWData(TWDataCreateWithBytes(publicKeyCurve25519.data(), publicKeyCurve25519.size())); + auto ed25519Pubkey = wrapTWData(TWCurve25519PubkeyToEd25519(curvePubkey.get())); + r = dataFromTWData(ed25519Pubkey); EXPECT_EQ(hex(r), "ff84c4bfc095df25b01e48807715856d95af93d88c5b57f30cb0ce567ca4ce56"); } diff --git a/tests/chains/XRP/TransactionCompilerTests.cpp b/tests/chains/XRP/TransactionCompilerTests.cpp index 0849aa99e20..099dcd27fda 100644 --- a/tests/chains/XRP/TransactionCompilerTests.cpp +++ b/tests/chains/XRP/TransactionCompilerTests.cpp @@ -46,7 +46,7 @@ TEST(RippleCompiler, CompileRippleWithSignatures) { auto preImageHash = preSigningOutput.data_hash(); EXPECT_EQ(hex(preImageHash), "86ef78df7a4aad29e6b3730f7965c1bd5ccd2439426cb738d7c494a64cfaf4af"); // Simulate signature, normally obtained from signature server - const auto signature = privateKey.sign(TW::data(preImageHash), TWCurveSECP256k1); + const auto signature = privateKey.sign(TW::data(preImageHash)); // Verify signature (pubkey & hash & signature) EXPECT_TRUE(publicKey.verify(signature, TW::data(preImageHash))); diff --git a/tests/chains/Zcash/TWZcashAddressTests.cpp b/tests/chains/Zcash/TWZcashAddressTests.cpp index 4b1cfd3dee6..6301eef9894 100644 --- a/tests/chains/Zcash/TWZcashAddressTests.cpp +++ b/tests/chains/Zcash/TWZcashAddressTests.cpp @@ -17,7 +17,7 @@ #include TEST(TWZcash, TransparentAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("987919d988ef94e678bce254c932e7a7a76744b2c008467448406d4246513132").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("987919d988ef94e678bce254c932e7a7a76744b2c008467448406d4246513132").get(), TWCoinTypeCurve(TWCoinTypeZcash))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeZcash)); auto addressString = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Zelcash/TWZelcashAddressTests.cpp b/tests/chains/Zelcash/TWZelcashAddressTests.cpp index f247625c93d..deb07d608c6 100644 --- a/tests/chains/Zelcash/TWZelcashAddressTests.cpp +++ b/tests/chains/Zelcash/TWZelcashAddressTests.cpp @@ -14,7 +14,7 @@ #include TEST(TWZelcash, TransparentAddress) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("987919d988ef94e678bce254c932e7a7a76744b2c008467448406d4246513132").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("987919d988ef94e678bce254c932e7a7a76744b2c008467448406d4246513132").get(), TWCoinTypeCurve(TWCoinTypeZelcash))); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); auto address = WRAP(TWAnyAddress, TWAnyAddressCreateWithPublicKey(publicKey.get(), TWCoinTypeZelcash)); auto addressString = WRAPS(TWAnyAddressDescription(address.get())); diff --git a/tests/chains/Zen/TWAnySignerTests.cpp b/tests/chains/Zen/TWAnySignerTests.cpp index 55a83993273..5fe8e1bad12 100644 --- a/tests/chains/Zen/TWAnySignerTests.cpp +++ b/tests/chains/Zen/TWAnySignerTests.cpp @@ -46,7 +46,7 @@ TEST(TWAnySignerZen, Sign) { utxo0->mutable_out_point()->set_sequence(UINT32_MAX); utxo0->set_amount(17600); - auto utxoKey0 = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")); + auto utxoKey0 = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a"), TWCoinTypeCurve(TWCoinTypeZen)); auto utxoAddr0 = TW::deriveAddress(TWCoinTypeZen, utxoKey0); ASSERT_EQ(utxoAddr0, "znk19H1wcARcCa7TM6zgmJUbWoWWtZ8k5cg"); auto script0 = Bitcoin::Script::lockScriptForAddress(utxoAddr0, TWCoinTypeZen, blockHash, blockHeight); diff --git a/tests/chains/Zen/TransactionBuilderTests.cpp b/tests/chains/Zen/TransactionBuilderTests.cpp index 8ba691be1b6..96d50a75a3c 100644 --- a/tests/chains/Zen/TransactionBuilderTests.cpp +++ b/tests/chains/Zen/TransactionBuilderTests.cpp @@ -52,7 +52,7 @@ TEST(ZenTransactionBuilder, Build) { utxo0->mutable_out_point()->set_sequence(UINT32_MAX); utxo0->set_amount(17600); - auto utxoKey0 = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a")); + auto utxoKey0 = PrivateKey(parse_hex("3a8e0a528f62f4ca2c77744c8a571def2845079b50105a9f7ef6b1b823def67a"), TWCoinTypeCurve(TWCoinTypeZen)); auto utxoAddr0 = TW::deriveAddress(TWCoinTypeZen, utxoKey0); ASSERT_EQ(utxoAddr0, "znk19H1wcARcCa7TM6zgmJUbWoWWtZ8k5cg"); auto script0 = Bitcoin::Script::lockScriptForAddress(utxoAddr0, TWCoinTypeZen, blockHash, blockHeight); diff --git a/tests/chains/Zilliqa/AddressTests.cpp b/tests/chains/Zilliqa/AddressTests.cpp index 26861fb8ca7..cd64513a77a 100644 --- a/tests/chains/Zilliqa/AddressTests.cpp +++ b/tests/chains/Zilliqa/AddressTests.cpp @@ -15,8 +15,8 @@ namespace TW::Zilliqa::tests { TEST(ZilliqaAddress, FromPrivateKey) { const auto privateKey = - PrivateKey(parse_hex("3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6"), TWCurveSECP256k1); - const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeSECP256k1)); + PrivateKey(parse_hex("3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6"), TWCurveZILLIQASchnorr); + const auto publicKey = PublicKey(privateKey.getPublicKey(TWPublicKeyTypeZILLIQASchnorr)); const auto address = Address(publicKey); auto expectedAddress = "zil1j8xae6lggm8y63m3y2r7aefu797ze7mhzulnqg"; diff --git a/tests/chains/Zilliqa/SignatureTests.cpp b/tests/chains/Zilliqa/SignatureTests.cpp index bea022cd485..8fbcba85e47 100644 --- a/tests/chains/Zilliqa/SignatureTests.cpp +++ b/tests/chains/Zilliqa/SignatureTests.cpp @@ -14,14 +14,14 @@ using namespace TW; TEST(ZilliqaSignature, Signing) { auto keyData = WRAPD(TWDataCreateWithHexString(STRING("0xafeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get())); - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(keyData.get())); - auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(keyData.get(), TWCoinTypeCurve(TWCoinTypeZilliqa))); + auto pubKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyZilliqaSchnorr(privateKey.get())); auto message = "hello schnorr"; auto messageData = WRAPD(TWDataCreateWithBytes((uint8_t *)message, strnlen(message, 13))); - auto signatureData = WRAPD(TWPrivateKeySignZilliqaSchnorr(privateKey.get(), messageData.get())); + auto signatureData = WRAPD(TWPrivateKeySign(privateKey.get(), messageData.get())); auto signature = data(TWDataBytes(signatureData.get()), TWDataSize(signatureData.get())); - ASSERT_TRUE(TWPublicKeyVerifyZilliqaSchnorr(pubKey.get(), signatureData.get(), messageData.get())); + ASSERT_TRUE(TWPublicKeyVerify(pubKey.get(), signatureData.get(), messageData.get())); EXPECT_EQ(hex(signature), "d166b1ae7892c5ef541461dc12a50214d0681b63d8037cda29a3fe6af8bb973e4ea94624d85bc0010bdc1b38d05198328fae21254adc2bf5feaf2804d54dba55"); } diff --git a/tests/chains/Zilliqa/SignerTests.cpp b/tests/chains/Zilliqa/SignerTests.cpp index dec0e6f67fe..132f6dcc5ed 100644 --- a/tests/chains/Zilliqa/SignerTests.cpp +++ b/tests/chains/Zilliqa/SignerTests.cpp @@ -14,8 +14,8 @@ namespace TW::Zilliqa::tests { TEST(ZilliqaSigner, PreImage) { - auto privateKey = PrivateKey(parse_hex("0E891B9DFF485000C7D1DC22ECF3A583CC50328684321D61947A86E57CF6C638"), TWCurveSECP256k1); - auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); + auto privateKey = PrivateKey(parse_hex("0E891B9DFF485000C7D1DC22ECF3A583CC50328684321D61947A86E57CF6C638"), TWCurveZILLIQASchnorr); + auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeZILLIQASchnorr); ASSERT_EQ(hex(pubKey.bytes), "034ae47910d58b9bde819c3cffa8de4441955508db00aa2540db8e6bf6e99abc1b"); auto amount = uint256_t(15000000000000); @@ -42,12 +42,12 @@ TEST(ZilliqaSigner, PreImage) { ASSERT_EQ(hex(preImage), "0881800410041a149ca91eb535fb92fda5094110fdaeb752edb9b03922230a21034ae47910d58b9bde819c3cffa8de4441955508db00aa2540db8e6bf6e99abc1b2a120a10000000000000000000000da475abf00032120a100000000000000000000000003b9aca003801"); - ASSERT_TRUE(pubKey.verifyZilliqa(Data(signature.begin(), signature.end()), preImage)); + ASSERT_TRUE(pubKey.verify(Data(signature.begin(), signature.end()), preImage)); } TEST(ZilliqaSigner, Signing) { - auto privateKey = PrivateKey(parse_hex("0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748"), TWCurveSECP256k1); - auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); + auto privateKey = PrivateKey(parse_hex("0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748"), TWCurveZILLIQASchnorr); + auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeZILLIQASchnorr); // 1 ZIL auto amount = uint256_t(1000000000000); @@ -76,8 +76,8 @@ TEST(ZilliqaSigner, Signing) { TEST(ZilliqaSigner, SigningData) { // https://viewblock.io/zilliqa/tx/0x6228b3d7e69fc3481b84fd00e892cec359a41654f58948ff7b1b932396b00ad9 - auto privateKey = PrivateKey(parse_hex("0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748"), TWCurveSECP256k1); - auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); + auto privateKey = PrivateKey(parse_hex("0x68ffa8ec149ce50da647166036555f73d57f662eb420e154621e5f24f6cf9748"), TWCurveZILLIQASchnorr); + auto pubKey = privateKey.getPublicKey(TWPublicKeyTypeZILLIQASchnorr); // 10 ZIL auto amount = uint256_t(10000000000000); diff --git a/tests/common/CoinAddressDerivationTests.cpp b/tests/common/CoinAddressDerivationTests.cpp index fd35b42420c..705706ddc97 100644 --- a/tests/common/CoinAddressDerivationTests.cpp +++ b/tests/common/CoinAddressDerivationTests.cpp @@ -14,8 +14,7 @@ namespace TW { TEST(Coin, DeriveAddress) { auto dummyKeyData = parse_hex("0x4646464646464646464646464646464646464646464646464646464646464646"); - const auto privateKey = PrivateKey(dummyKeyData); - const auto privateKeyExt = PrivateKey(dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData); + const auto privateKey = PrivateKey(dummyKeyData, TWCurveSECP256k1); const auto coins = TW::getCoinTypes(); for (auto& c : coins) { @@ -25,11 +24,12 @@ TEST(Coin, DeriveAddress) { address = TW::deriveAddress(c, privateKey); break; - case TWCoinTypeCardano: - case TWCoinTypeNEO: + case TWCoinTypeCardano: { + const auto privateKeyExt = PrivateKey(dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData, dummyKeyData, TWCurveED25519ExtendedCardano); address = TW::deriveAddress(c, privateKeyExt); break; } + } switch (c) { // Ethereum and ... diff --git a/tests/common/EncryptTests.cpp b/tests/common/EncryptTests.cpp index 52c030913a2..8e8d58c7614 100644 --- a/tests/common/EncryptTests.cpp +++ b/tests/common/EncryptTests.cpp @@ -20,27 +20,6 @@ inline void assertHexEqual(const Data& data, const char* expected) { EXPECT_EQ(hex(data), expected); } -TEST(Encrypt, paddingSize) { - EXPECT_EQ(paddingSize(0, 16, TWAESPaddingModeZero), 0ul); - EXPECT_EQ(paddingSize(1, 16, TWAESPaddingModeZero), 15ul); - EXPECT_EQ(paddingSize(8, 16, TWAESPaddingModeZero), 8ul); - EXPECT_EQ(paddingSize(15, 16, TWAESPaddingModeZero), 1ul); - EXPECT_EQ(paddingSize(16, 16, TWAESPaddingModeZero), 0ul); - EXPECT_EQ(paddingSize(17, 16, TWAESPaddingModeZero), 15ul); - EXPECT_EQ(paddingSize(24, 16, TWAESPaddingModeZero), 8ul); - EXPECT_EQ(paddingSize(31, 16, TWAESPaddingModeZero), 1ul); - EXPECT_EQ(paddingSize(32, 16, TWAESPaddingModeZero), 0ul); - EXPECT_EQ(paddingSize(0, 16, TWAESPaddingModePKCS7), 16ul); - EXPECT_EQ(paddingSize(1, 16, TWAESPaddingModePKCS7), 15ul); - EXPECT_EQ(paddingSize(8, 16, TWAESPaddingModePKCS7), 8ul); - EXPECT_EQ(paddingSize(15, 16, TWAESPaddingModePKCS7), 1ul); - EXPECT_EQ(paddingSize(16, 16, TWAESPaddingModePKCS7), 16ul); - EXPECT_EQ(paddingSize(17, 16, TWAESPaddingModePKCS7), 15ul); - EXPECT_EQ(paddingSize(24, 16, TWAESPaddingModePKCS7), 8ul); - EXPECT_EQ(paddingSize(31, 16, TWAESPaddingModePKCS7), 1ul); - EXPECT_EQ(paddingSize(32, 16, TWAESPaddingModePKCS7), 16ul); -} - TEST(Encrypt, AESCBCEncrypt) { auto iv = parse_hex("000102030405060708090A0B0C0D0E0F"); auto data = parse_hex("6bc1bee22e409f96e93d7e117393172a"); @@ -149,7 +128,7 @@ TEST(Encrypt, AESCBCEncryptInvalidKeySize) { Data iv = Data(16); try { Data result = AESCBCEncrypt(Data(19), Data(100), iv); - } catch (std::invalid_argument&) { + } catch (...) { // expected exception, OK return; } @@ -160,7 +139,7 @@ TEST(Encrypt, AESCBCDecryptInvalidKeySize) { Data iv = Data(16); try { Data result = AESCBCDecrypt(Data(19), Data(100), iv); - } catch (std::invalid_argument&) { + } catch (...) { // expected exception, OK return; } @@ -171,7 +150,7 @@ TEST(Encrypt, AESCBCDecryptInvalidDataSize) { Data iv = Data(16); try { Data result = AESCBCDecrypt(Data(16), Data(100), iv); - } catch (std::invalid_argument&) { + } catch (...) { // expected exception, OK return; } @@ -182,7 +161,7 @@ TEST(Encrypt, AESCTREncryptInvalidKeySize) { Data iv = Data(16); try { Data result = AESCTREncrypt(Data(19), Data(100), iv); - } catch (std::invalid_argument&) { + } catch (...) { // expected exception, OK return; } @@ -193,7 +172,7 @@ TEST(Encrypt, AESCTRDecryptInvalidKeySize) { Data iv = Data(16); try { Data result = AESCTRDecrypt(Data(19), Data(100), iv); - } catch (std::invalid_argument&) { + } catch (...) { // expected exception, OK return; } diff --git a/tests/common/HDWallet/HDWalletInternalTests.cpp b/tests/common/HDWallet/HDWalletInternalTests.cpp deleted file mode 100644 index 6b0554a65d3..00000000000 --- a/tests/common/HDWallet/HDWalletInternalTests.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include "HDWallet.h" -#include "Data.h" -#include "HexCoding.h" -#include "PrivateKey.h" -#include "PublicKey.h" -#include -#include -#include "TestUtilities.h" - -#include -#include -#include - -namespace TW::HDWalletInternalTests { - -const auto mnemonic1 = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal"; - -std::string nodeToHexString(const HDNode& node) { - std::string s; - s += std::to_string(node.depth); - s += "-" + std::to_string(node.child_num); - s += "--" + hex(data(node.chain_code, 32)); - s += "--" + hex(data(node.private_key, 32)); - s += "--" + hex(data(node.private_key_extension, 32)); - s += "--" + hex(data(node.public_key, 33)); - return s; -} - -Data publicKeyFromPrivateKey(const Data& privateKey) { - return PrivateKey(privateKey, TWCurveSECP256k1).getPublicKey(TWPublicKeyTypeSECP256k1).bytes; -} - -TEST(HDWalletInternal, SquareDerivationRoutes) { - /* - Test 'square' derivation routes, result should be the same. - Performing private derivation, then taking the public key yields the same as - taking the public key first, and performing public derivation. - This makes XPUB schemes possible. - - priv_node --priv_deriv.--> priv_child_node - - | | - get_pub get_pub - | | - v v - - pub_node ---pub_deriv.---> pub_key - - */ - - HDWallet wallet = HDWallet(mnemonic1, ""); - const auto derivationPath = DerivationPath("m/84'/0'/0'/1"); - const auto dpLastIndex = 2; - const auto ExpectedFinalPublicKey = "02e0b4765e9012bfbbfe8c714f99beb681acc0a92bdb5acbf2f362c0aff986ad49"; - - // getMasterNode - auto masterNode = HDNode(); - hdnode_from_seed(wallet.getSeed().data(), HDWallet<>::mSeedSize, SECP256K1_NAME, &masterNode); - - auto node0 = masterNode; - // getNode - for (auto& index : derivationPath.indices) { - hdnode_private_ckd(&node0, index.derivationIndex()); - } - EXPECT_EQ(nodeToHexString(node0), "4-1--8423e869d887b6b0e7ca5f3bbed6e69234fb5d51aa02e9e8069fbffb2dc3c095--55f85b343359ec33aa3519a40673773d1f52677a044c7185529ce8f5fdb70625--0000000000000000000000000000000000000000000000000000000000000000--000000000000000000000000000000000000000000000000000000000000000000"); - - { - // Route 1 step 1: private node derivation - auto node11 = node0; - EXPECT_EQ(hdnode_private_ckd(&node11, dpLastIndex), 1); - EXPECT_EQ(nodeToHexString(node11), "5-2--53aaec7a112524bc3c8c91b278ccb0cf7e322077dac6a832563eb33149bb0051--512503395481ea0c26fe341bc342c29f4a706be003d12179ec6b65aa8a8c352d--0000000000000000000000000000000000000000000000000000000000000000--000000000000000000000000000000000000000000000000000000000000000000"); - - // Route 1 step 2: public key from private - const auto publicKey = publicKeyFromPrivateKey(data(node11.private_key, 32)); - EXPECT_EQ(hex(publicKey), ExpectedFinalPublicKey); - } - - { - // Route 2 step 1: public node from private (extended public key) - auto node21 = node0; - const auto pub21 = publicKeyFromPrivateKey(data(node21.private_key, 32)); - ::memcpy(node21.public_key, pub21.data(), 33); - EXPECT_EQ(nodeToHexString(node21), "4-1--8423e869d887b6b0e7ca5f3bbed6e69234fb5d51aa02e9e8069fbffb2dc3c095--55f85b343359ec33aa3519a40673773d1f52677a044c7185529ce8f5fdb70625--0000000000000000000000000000000000000000000000000000000000000000--026a940b5b683237037ecb230c402c5e351f38d41f00215e4d36006e9ff6b5cfba"); - - // Route 2 step 2: public node derivation - auto node22 = node21; - EXPECT_EQ(hdnode_public_ckd(&node22, dpLastIndex), 1); - EXPECT_EQ(nodeToHexString(node22), "5-2--53aaec7a112524bc3c8c91b278ccb0cf7e322077dac6a832563eb33149bb0051--0000000000000000000000000000000000000000000000000000000000000000--0000000000000000000000000000000000000000000000000000000000000000--02e0b4765e9012bfbbfe8c714f99beb681acc0a92bdb5acbf2f362c0aff986ad49"); - const auto publicKey = PublicKey(data(node22.public_key, 33), TWPublicKeyTypeSECP256k1); - EXPECT_EQ(hex(publicKey.bytes), ExpectedFinalPublicKey); - } -} - -TEST(HDWalletInternal, PrivateAndPublicCkdDerivation) { - /* - - PrivateKey1 ----> PrivateKey2 - - | | - v v - - PublicKey1 ----> PublicKey2 - - */ - - const auto PrivateKey1 = "55f85b343359ec33aa3519a40673773d1f52677a044c7185529ce8f5fdb70625"; - const auto PrivateKey2 = "512503395481ea0c26fe341bc342c29f4a706be003d12179ec6b65aa8a8c352d"; - const auto PublicKey1 = "026a940b5b683237037ecb230c402c5e351f38d41f00215e4d36006e9ff6b5cfba"; - const auto PublicKey2 = "02e0b4765e9012bfbbfe8c714f99beb681acc0a92bdb5acbf2f362c0aff986ad49"; - const auto ChainCode0 = "8423e869d887b6b0e7ca5f3bbed6e69234fb5d51aa02e9e8069fbffb2dc3c095"; - const auto dpIndex = 2; - const auto curve = get_curve_by_name(SECP256K1_NAME); - - { // PrivateKey1 -> PublicKey1 - EXPECT_EQ(hex(publicKeyFromPrivateKey(parse_hex(PrivateKey1))), PublicKey1); - } - { // PrivateKey2 -> PublicKey2 - EXPECT_EQ(hex(publicKeyFromPrivateKey(parse_hex(PrivateKey2))), PublicKey2); - } - { // PrivateKey1 -> PrivateKey2 - auto node = HDNode(); - node.depth = 4; - node.child_num = 1; - node.curve = curve; - ::memcpy(node.chain_code, parse_hex(ChainCode0).data(), 32); - ::memcpy(node.private_key, parse_hex(PrivateKey1).data(), 32); - EXPECT_EQ(nodeToHexString(node), "4-1--8423e869d887b6b0e7ca5f3bbed6e69234fb5d51aa02e9e8069fbffb2dc3c095--55f85b343359ec33aa3519a40673773d1f52677a044c7185529ce8f5fdb70625--0000000000000000000000000000000000000000000000000000000000000000--000000000000000000000000000000000000000000000000000000000000000000"); - - EXPECT_EQ(hdnode_private_ckd(&node, dpIndex), 1); - - EXPECT_EQ(nodeToHexString(node), "5-2--53aaec7a112524bc3c8c91b278ccb0cf7e322077dac6a832563eb33149bb0051--512503395481ea0c26fe341bc342c29f4a706be003d12179ec6b65aa8a8c352d--0000000000000000000000000000000000000000000000000000000000000000--000000000000000000000000000000000000000000000000000000000000000000"); - EXPECT_EQ(hex(data(node.private_key, 32)), PrivateKey2); - } - { // PublicKey1 -> PublicKey2 - auto node = HDNode(); - node.depth = 4; - node.child_num = 1; - node.curve = curve; - ::memcpy(node.chain_code, parse_hex(ChainCode0).data(), 32); - ::memcpy(node.public_key, parse_hex(PublicKey1).data(), 33); - EXPECT_EQ(nodeToHexString(node), "4-1--8423e869d887b6b0e7ca5f3bbed6e69234fb5d51aa02e9e8069fbffb2dc3c095--0000000000000000000000000000000000000000000000000000000000000000--0000000000000000000000000000000000000000000000000000000000000000--026a940b5b683237037ecb230c402c5e351f38d41f00215e4d36006e9ff6b5cfba"); - - EXPECT_EQ(hdnode_public_ckd(&node, dpIndex), 1); - - EXPECT_EQ(nodeToHexString(node), "5-2--53aaec7a112524bc3c8c91b278ccb0cf7e322077dac6a832563eb33149bb0051--0000000000000000000000000000000000000000000000000000000000000000--0000000000000000000000000000000000000000000000000000000000000000--02e0b4765e9012bfbbfe8c714f99beb681acc0a92bdb5acbf2f362c0aff986ad49"); - EXPECT_EQ(hex(data(node.public_key, 33)), PublicKey2); - } -} - -} // namespace diff --git a/tests/common/Keystore/StoredKeyTests.cpp b/tests/common/Keystore/StoredKeyTests.cpp index 02c9bed047b..f3e3cbfb1e5 100644 --- a/tests/common/Keystore/StoredKeyTests.cpp +++ b/tests/common/Keystore/StoredKeyTests.cpp @@ -49,6 +49,54 @@ TEST(StoredKey, CreateWithMnemonic) { EXPECT_EQ(json["crypto"]["kdfparams"]["salt"].get().size(), 64ul); } +TEST(StoredKey, CreateWithMnemonicAes192Ctr) { + auto key = StoredKey::createWithMnemonic("name", gPassword, gMnemonic, TWStoredKeyEncryptionLevelDefault, TWStoredKeyEncryptionAes192Ctr); + EXPECT_EQ(key.type, StoredKeyType::mnemonicPhrase); + const Data& mnemo2Data = key.payload.decrypt(gPassword); + EXPECT_EQ(string(mnemo2Data.begin(), mnemo2Data.end()), string(gMnemonic)); + EXPECT_EQ(key.accounts.size(), 0ul); + EXPECT_EQ(key.wallet(gPassword).getMnemonic(), string(gMnemonic)); + + const auto json = key.json(); + EXPECT_EQ(json["name"], "name"); + EXPECT_EQ(json["type"], "mnemonic"); + EXPECT_EQ(json["version"], 3); + // Salt is 32 bytes, encoded as hex. + EXPECT_EQ(json["crypto"]["kdfparams"]["salt"].get().size(), 64ul); +} + +TEST(StoredKey, CreateWithMnemonicAes256Ctr) { + auto key = StoredKey::createWithMnemonic("name", gPassword, gMnemonic, TWStoredKeyEncryptionLevelDefault, TWStoredKeyEncryptionAes256Ctr); + EXPECT_EQ(key.type, StoredKeyType::mnemonicPhrase); + const Data& mnemo2Data = key.payload.decrypt(gPassword); + EXPECT_EQ(string(mnemo2Data.begin(), mnemo2Data.end()), string(gMnemonic)); + EXPECT_EQ(key.accounts.size(), 0ul); + EXPECT_EQ(key.wallet(gPassword).getMnemonic(), string(gMnemonic)); + + const auto json = key.json(); + EXPECT_EQ(json["name"], "name"); + EXPECT_EQ(json["type"], "mnemonic"); + EXPECT_EQ(json["version"], 3); + // Salt is 32 bytes, encoded as hex. + EXPECT_EQ(json["crypto"]["kdfparams"]["salt"].get().size(), 64ul); +} + +TEST(StoredKey, CreateWithMnemonicCbc) { + auto key = StoredKey::createWithMnemonic("name", gPassword, gMnemonic, TWStoredKeyEncryptionLevelDefault, TWStoredKeyEncryptionAes128Cbc); + EXPECT_EQ(key.type, StoredKeyType::mnemonicPhrase); + const Data& mnemo2Data = key.payload.decrypt(gPassword); + EXPECT_EQ(string(mnemo2Data.begin(), mnemo2Data.end()), string(gMnemonic)); + EXPECT_EQ(key.accounts.size(), 0ul); + EXPECT_EQ(key.wallet(gPassword).getMnemonic(), string(gMnemonic)); + + const auto json = key.json(); + EXPECT_EQ(json["name"], "name"); + EXPECT_EQ(json["type"], "mnemonic"); + EXPECT_EQ(json["version"], 3); + // Salt is 32 bytes, encoded as hex. + EXPECT_EQ(json["crypto"]["kdfparams"]["salt"].get().size(), 64ul); +} + TEST(StoredKey, CreateWithMnemonicInvalid) { try { auto key = StoredKey::createWithMnemonic("name", gPassword, "_THIS_IS_NOT_A_VALID_MNEMONIC_", TWStoredKeyEncryptionLevelDefault); @@ -461,6 +509,22 @@ TEST(StoredKey, CreateAccountsAes256) { EXPECT_EQ(key.account(coinTypeBc, &wallet)->extendedPublicKey, "zpub6qbsWdbcKW9sC6shTKK4VEhfWvDCoWpfLnnVfYKHLHt31wKYUwH3aFDz4WLjZvjHZ5W4qVEyk37cRwzTbfrrT1Gnu8SgXawASnkdQ994atn"); } +TEST(StoredKey, CreateAccountsAesCbc128) { + string mnemonicPhrase = "team engine square letter hero song dizzy scrub tornado fabric divert saddle"; + auto key = StoredKey::createWithMnemonic("name", gPassword, mnemonicPhrase, TWStoredKeyEncryptionLevelDefault, TWStoredKeyEncryptionAes128Cbc); + auto header = key.payload; + const auto wallet = key.wallet(gPassword); + + EXPECT_EQ(header.params.cipher(), "aes-128-cbc"); + EXPECT_EQ(key.account(TWCoinTypeEthereum, &wallet)->address, "0x494f60cb6Ac2c8F5E1393aD9FdBdF4Ad589507F7"); + EXPECT_EQ(key.account(TWCoinTypeEthereum, &wallet)->publicKey, "04cc32a479080d83fdcf69966713f0aad1bc1dc3ecf873b034894e84259841bc1c9b122717803e68905220ff54952d3f5ea2ab2698ca31f843addf94ae73fae9fd"); + EXPECT_EQ(key.account(TWCoinTypeEthereum, &wallet)->extendedPublicKey, ""); + + EXPECT_EQ(key.account(coinTypeBc, &wallet)->address, "bc1qturc268v0f2srjh4r2zu4t6zk4gdutqd5a6zny"); + EXPECT_EQ(key.account(coinTypeBc, &wallet)->publicKey, "02df6fc590ab3101bbe0bb5765cbaeab9b5dcfe09ac9315d707047cbd13bc7e006"); + EXPECT_EQ(key.account(coinTypeBc, &wallet)->extendedPublicKey, "zpub6qbsWdbcKW9sC6shTKK4VEhfWvDCoWpfLnnVfYKHLHt31wKYUwH3aFDz4WLjZvjHZ5W4qVEyk37cRwzTbfrrT1Gnu8SgXawASnkdQ994atn"); +} + TEST(StoredKey, DecodingEthereumAddress) { const auto key = StoredKey::load(testDataPath("key.json")); diff --git a/tests/common/PrivateKeyTests.cpp b/tests/common/PrivateKeyTests.cpp index fccfebcff6f..145d8dc6f65 100644 --- a/tests/common/PrivateKeyTests.cpp +++ b/tests/common/PrivateKeyTests.cpp @@ -5,9 +5,8 @@ #include "Hash.h" #include "HexCoding.h" #include "PrivateKey.h" -#include +#include "rand.h" #include "PublicKey.h" -#include "PublicKeyLegacy.h" #include @@ -15,7 +14,6 @@ using namespace TW; using namespace std; namespace TW::tests { - TEST(PrivateKey, CreateValid) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); EXPECT_TRUE(PrivateKey::isValid(privKeyData, TWCurveSECP256k1)); @@ -25,7 +23,7 @@ TEST(PrivateKey, CreateValid) { string TestInvalid(const Data& privKeyData) { try { - auto privateKey = PrivateKey(privKeyData); + auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); return hex(privateKey.bytes); } catch (invalid_argument& ex) { // expected exception @@ -58,7 +56,7 @@ TEST(PrivateKey, InvalidSECP256k1) { string TestInvalidExtended(const Data& data, const Data& ext, const Data& chainCode, const Data& data2, const Data& ext2, const Data& chainCode2) { try { - auto privateKey = PrivateKey(data, ext, chainCode, data2, ext2, chainCode2); + auto privateKey = PrivateKey(data, ext, chainCode, data2, ext2, chainCode2, TWCurveSECP256k1); return hex(privateKey.bytes); } catch (invalid_argument& ex) { // expected exception @@ -149,7 +147,7 @@ TEST(PrivateKey, PublicKey) { TEST(PrivateKey, Cleanup) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - auto privateKey = new PrivateKey(privKeyData); + auto privateKey = new PrivateKey(privKeyData, TWCurveSECP256k1); auto ptr = privateKey->bytes.data(); ASSERT_EQ(hex(privKeyData), hex(data(ptr, 32))); @@ -175,7 +173,7 @@ TEST(PrivateKey, GetType) { TEST(PrivateKey, PrivateKeyExtended) { // Non-extended: both keys are 32 bytes. auto privateKeyNonext = PrivateKey(parse_hex( - "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveED25519); EXPECT_EQ("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5", hex(privateKeyNonext.bytes)); auto publicKeyNonext = privateKeyNonext.getPublicKey(TWPublicKeyTypeED25519); EXPECT_EQ(32ul, publicKeyNonext.bytes.size()); @@ -188,7 +186,7 @@ TEST(PrivateKey, PrivateKeyExtended) { "d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7b" "ed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a"; // Extended keys: private key is 2x3x32 bytes, public key is 2x64 bytes - auto privateKeyExt = PrivateKey(parse_hex(fullkey)); + auto privateKeyExt = PrivateKey(parse_hex(fullkey), TWCurveED25519ExtendedCardano); EXPECT_EQ(fullkey, hex(privateKeyExt.bytes)); EXPECT_EQ("b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744", hex(privateKeyExt.key())); EXPECT_EQ("309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71eff", hex(privateKeyExt.extension())); @@ -207,16 +205,16 @@ TEST(PrivateKey, PrivateKeyExtended) { parse_hex("bf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4"), parse_hex("639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05"), parse_hex("d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7b"), - parse_hex("ed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a")); + parse_hex("ed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a"), + TWCurveED25519ExtendedCardano + ); EXPECT_EQ(fullkey, hex(privateKeyExt.bytes)); } TEST(PrivateKey, PrivateKeyExtendedError) { - // TWPublicKeyTypeED25519Cardano pubkey with non-extended private: error - auto privateKeyNonext = PrivateKey(parse_hex( - "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); try { - auto publicKeyError = privateKeyNonext.getPublicKey(TWPublicKeyTypeED25519Cardano); + auto privateKeyNonext = PrivateKey(parse_hex( + "afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveED25519ExtendedCardano); } catch (invalid_argument& ex) { // expected exception return; @@ -226,10 +224,10 @@ TEST(PrivateKey, PrivateKeyExtendedError) { TEST(PrivateKey, SignSECP256k1) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - auto privateKey = PrivateKey(privKeyData); + auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); Data messageData = TW::data("hello"); Data hash = Hash::keccak256(messageData); - Data actual = privateKey.sign(hash, TWCurveSECP256k1); + Data actual = privateKey.sign(hash); EXPECT_EQ( "8720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba624d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de901", @@ -239,10 +237,12 @@ TEST(PrivateKey, SignSECP256k1) { TEST(PrivateKey, SignExtended) { const auto privateKeyExt = PrivateKey(parse_hex( "b0884d248cb301edd1b34cf626ba6d880bb3ae8fd91b4696446999dc4f0b5744309941d56938e943980d11643c535e046653ca6f498c014b88f2ad9fd6e71effbf36a8fa9f5e11eb7a852c41e185e3969d518e66e6893c81d3fc7227009952d4" - "639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7bed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a")); + "639aadd8b6499ae39b78018b79255fbd8f585cbda9cbb9e907a72af86afb7a05d41a57c2dec9a6a19d6bf3b1fa784f334f3a0048d25ccb7b78a7b44066f9ba7bed7f28be986cbe06819165f2ee41b403678a098961013cf4a2f3e9ea61fb6c1a"), + TWCurveED25519ExtendedCardano + ); Data messageData = TW::data("hello"); Data hash = Hash::keccak256(messageData); - Data actual = privateKeyExt.sign(hash, TWCurveED25519ExtendedCardano); + Data actual = privateKeyExt.sign(hash); EXPECT_EQ( "375df53b6a4931dcf41e062b1c64288ed4ff3307f862d5c1b1c71964ce3b14c99422d0fdfeb2807e9900a26d491d5e8a874c24f98eec141ed694d7a433a90f08", @@ -250,55 +250,36 @@ TEST(PrivateKey, SignExtended) { } TEST(PrivateKey, SignSchnorr) { - const auto privateKey = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); + const auto privateKey = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveZILLIQASchnorr); const Data messageData = TW::data("hello schnorr"); const Data digest = Hash::sha256(messageData); - const auto signature = privateKey.signZilliqa(digest); + const auto signature = privateKey.sign(digest); EXPECT_EQ(hex(signature), "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853"); } TEST(PrivateKey, SignNIST256p1) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - auto privateKey = PrivateKey(privKeyData); + auto privateKey = PrivateKey(privKeyData, TWCurveNIST256p1); Data messageData = TW::data("hello"); Data hash = Hash::keccak256(messageData); - Data actual = privateKey.sign(hash, TWCurveNIST256p1); + Data actual = privateKey.sign(hash); EXPECT_EQ( "8859e63a0c0cc2fc7f788d7e78406157b288faa6f76f76d37c4cd1534e8d83c468f9fd6ca7dde378df594625dcde98559389569e039282275e3d87c26e36447401", hex(actual)); } -TEST(PrivateKey, SignNIST256p1VerifyLegacy) { - for (auto i = 0; i < 1000; ++i) { - Data secret(32); - random_buffer(secret.data(), 32); - - Data msg(32); - random_buffer(msg.data(), 32); - - PrivateKey privateKey(secret); - auto signature = privateKey.sign(msg, TWCurveNIST256p1); - - auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeNIST256p1); - EXPECT_TRUE(TrezorCrypto::verifyNist256p1Signature(publicKey.bytes, signature, msg)) - << "Error verifying nist256p1 signature" << std::endl - << "Private key: " << hex(secret) << std::endl - << "Message: " << hex(msg); - } -} - -int isCanonical([[maybe_unused]] uint8_t by, [[maybe_unused]] uint8_t sig[64]) { +int isCanonical([[maybe_unused]] uint8_t by, [[maybe_unused]] const uint8_t sig[64]) { return 1; } TEST(PrivateKey, SignCanonicalSECP256k1) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - auto privateKey = PrivateKey(privKeyData); + auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); Data messageData = TW::data("hello"); Data hash = Hash::keccak256(messageData); - Data actual = privateKey.sign(hash, TWCurveSECP256k1, isCanonical); + Data actual = privateKey.sign(hash, isCanonical); EXPECT_EQ( "208720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba624d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de9", @@ -307,69 +288,23 @@ TEST(PrivateKey, SignCanonicalSECP256k1) { TEST(PrivateKey, SignShortDigest) { Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - auto privateKey = PrivateKey(privKeyData); Data shortDigest = TW::data("12345"); { - Data actual = privateKey.sign(shortDigest, TWCurveSECP256k1); + auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); + Data actual = privateKey.sign(shortDigest); EXPECT_EQ(actual.size(), 0ul); } { - Data actual = privateKey.sign(shortDigest, TWCurveNIST256p1); + auto privateKey = PrivateKey(privKeyData, TWCurveNIST256p1); + Data actual = privateKey.sign(shortDigest); EXPECT_EQ(actual.size(), 0ul); } { - Data actual = privateKey.sign(shortDigest, TWCurveSECP256k1, isCanonical); + auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); + Data actual = privateKey.sign(shortDigest, isCanonical); EXPECT_EQ(actual.size(), 0ul); } } -TEST(PrivateKey, SignWithDifferentCurveWorks) { - Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - // Using the deprecated constructor without specifying a curve - auto privateKey = PrivateKey(privKeyData); - Data messageData = TW::data("hello"); - Data hash = Hash::keccak256(messageData); - - // Should be able to sign with any curve when using the normal constructor - try { - auto signatureSECP256k1 = privateKey.sign(hash, TWCurveSECP256k1); - EXPECT_FALSE(signatureSECP256k1.empty()); - EXPECT_EQ(signatureSECP256k1.size(), 65ul); - - auto signatureNIST256p1 = privateKey.sign(hash, TWCurveNIST256p1); - EXPECT_FALSE(signatureNIST256p1.empty()); - EXPECT_EQ(signatureNIST256p1.size(), 65ul); - - // Verify the signatures are different for different curves - EXPECT_NE(hex(signatureSECP256k1), hex(signatureNIST256p1)); - } catch (const std::exception& e) { - FAIL() << "Unexpected exception was thrown: " << e.what(); - } -} - -TEST(PrivateKey, SignWithDifferentCurveThrows) { - Data privKeyData = parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"); - // Using the constructor that specifies a curve - auto privateKey = PrivateKey(privKeyData, TWCurveSECP256k1); - Data messageData = TW::data("hello"); - Data hash = Hash::keccak256(messageData); - - // Should throw an exception if signing with a different curve - try { - auto _ = privateKey.sign(hash, TWCurveNIST256p1); - FAIL() << "Expected exception was not thrown"; - } catch (const std::invalid_argument& e) { - EXPECT_STREQ("Specified curve is different from the curve of the private key", e.what()); - } - - // Check that signing with the same curve works fine - try { - auto signature = privateKey.sign(hash, TWCurveSECP256k1); - EXPECT_EQ(signature.size(), 65ul); - EXPECT_TRUE(!signature.empty()); - } catch (const std::exception& e) { - FAIL() << "Unexpected exception was thrown: " << e.what(); - } -} } // namespace TW::tests diff --git a/tests/common/PublicKeyLegacy.h b/tests/common/PublicKeyLegacy.h deleted file mode 100644 index 33007667c76..00000000000 --- a/tests/common/PublicKeyLegacy.h +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#pragma once - -#include -#include -#include "Data.h" - -namespace TW::TrezorCrypto { - -/// Verifies a signature for the provided message by using `trezor-crypto` library (legacy implementation). -inline bool verifyNist256p1Signature(const Data& publicKey, const Data& signature, const Data& message) { - return ecdsa_verify_digest(&nist256p1, publicKey.data(), signature.data(), message.data()) == 0; -} - -} // namespace TW::TrezorCrypto diff --git a/tests/common/PublicKeyTests.cpp b/tests/common/PublicKeyTests.cpp index d69e1bc7952..c1278e59dbb 100644 --- a/tests/common/PublicKeyTests.cpp +++ b/tests/common/PublicKeyTests.cpp @@ -238,28 +238,28 @@ TEST(PublicKeyTests, VerifyEd25519Extended) { } TEST(PublicKeyTests, VerifySchnorr) { - const auto key = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveSECP256k1); + const auto key = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveZILLIQASchnorr); const auto privateKey = PrivateKey(key); const Data messageData = TW::data("hello schnorr"); const Data digest = Hash::sha256(messageData); - const auto signature = privateKey.signZilliqa(digest); - const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSECP256k1); - EXPECT_TRUE(publicKey.verifyZilliqa(signature, digest)); + const auto signature = privateKey.sign(digest); + const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeZILLIQASchnorr); + EXPECT_TRUE(publicKey.verify(signature, digest)); EXPECT_EQ(hex(signature), "b8118ccb99563fe014279c957b0a9d563c1666e00367e9896fe541765246964f64a53052513da4e6dc20fdaf69ef0d95b4ca51c87ad3478986cf053c2dd0b853"); } TEST(PublicKeyTests, VerifySchnorrWrongType) { - const auto key = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveSECP256k1); + const auto key = PrivateKey(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveZILLIQASchnorr); const auto privateKey = PrivateKey(key); const Data messageData = TW::data("hello schnorr"); const Data digest = Hash::sha256(messageData); - const auto signature = privateKey.signZilliqa(digest); - const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeNIST256p1); - EXPECT_FALSE(publicKey.verifyZilliqa(signature, digest)); + const auto signature = privateKey.sign(digest); + const auto publicKey = privateKey.getPublicKey(TWPublicKeyTypeSchnorr); + EXPECT_FALSE(publicKey.verify(signature, digest)); } TEST(PublicKeyTests, RecoverRaw) { @@ -305,13 +305,13 @@ TEST(PublicKeyTests, RecoverRawNegative) { const auto message = parse_hex("de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb11432"); const auto signature = parse_hex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"); // recid >= 4 - EXPECT_EXCEPTION(PublicKey::recoverRaw(signature, 4ul, message), "Invalid recId"); + EXPECT_EXCEPTION(PublicKey::recoverRaw(signature, 4ul, message), "Recover failed"); // signature too short EXPECT_EXCEPTION(PublicKey::recoverRaw(parse_hex("00000000000000000000000000000000000000000000000000000000000000020123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd"), 1ul, message), - "signature too short"); + "Recover failed"); // Digest too short EXPECT_EXCEPTION(PublicKey::recoverRaw(signature, 1ul, parse_hex("de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb114")), - "digest too short"); + "Recover failed"); } TEST(PublicKeyTests, Recover) { @@ -355,10 +355,8 @@ TEST(PublicKeyTests, isValidED25519) { EXPECT_TRUE(PublicKey::isValid(parse_hex("01beff0e5d6f6e6e6d573d3044f3e2bfb353400375dc281da3337468d4aa527908"), TWPublicKeyTypeED25519)); EXPECT_TRUE(PublicKey(parse_hex("01beff0e5d6f6e6e6d573d3044f3e2bfb353400375dc281da3337468d4aa527908"), TWPublicKeyTypeED25519).isValidED25519()); // Following 32 bytes are not valid public keys (not on the curve) - EXPECT_TRUE(PublicKey::isValid(parse_hex("8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"), TWPublicKeyTypeED25519)); - EXPECT_FALSE(PublicKey(parse_hex("8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"), TWPublicKeyTypeED25519).isValidED25519()); - EXPECT_TRUE(PublicKey::isValid(parse_hex("51fdd5feae59d7dcbf5ebea99c05593ebee302577a5486ceac706ed568aa1e0e"), TWPublicKeyTypeED25519)); - EXPECT_FALSE(PublicKey(parse_hex("51fdd5feae59d7dcbf5ebea99c05593ebee302577a5486ceac706ed568aa1e0e"), TWPublicKeyTypeED25519).isValidED25519()); + EXPECT_FALSE(PublicKey::isValid(parse_hex("8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"), TWPublicKeyTypeED25519)); + EXPECT_FALSE(PublicKey::isValid(parse_hex("51fdd5feae59d7dcbf5ebea99c05593ebee302577a5486ceac706ed568aa1e0e"), TWPublicKeyTypeED25519)); // invalid input size/format EXPECT_FALSE(PublicKey::isValid(parse_hex("1234"), TWPublicKeyTypeED25519)); EXPECT_FALSE(PublicKey::isValid(parse_hex("beff0e5d6f6e6e6d573d3044f3e2bfb353400375dc281da3337468d4aa5279"), TWPublicKeyTypeED25519)); diff --git a/tests/interface/TWAESTests.cpp b/tests/interface/TWAESTests.cpp index 52675f2aaab..f492703c2a3 100644 --- a/tests/interface/TWAESTests.cpp +++ b/tests/interface/TWAESTests.cpp @@ -4,7 +4,8 @@ #include "TestUtilities.h" -#include +#include +#include #include diff --git a/tests/interface/TWCoinTypeTests.cpp b/tests/interface/TWCoinTypeTests.cpp index b7547ae34a9..a3faf369ff4 100644 --- a/tests/interface/TWCoinTypeTests.cpp +++ b/tests/interface/TWCoinTypeTests.cpp @@ -93,7 +93,7 @@ TEST(TWCoinType, TWPublicKeyType) { ASSERT_EQ(TWPublicKeyTypeSECP256k1Extended, TWCoinTypePublicKeyType(TWCoinTypeIoTeX)); ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeViacoin)); ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeQtum)); - ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeZilliqa)); + ASSERT_EQ(TWPublicKeyTypeZILLIQASchnorr, TWCoinTypePublicKeyType(TWCoinTypeZilliqa)); ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeTerra)); ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeMonacoin)); ASSERT_EQ(TWPublicKeyTypeSECP256k1, TWCoinTypePublicKeyType(TWCoinTypeKava)); diff --git a/tests/interface/TWCryptoBoxTests.cpp b/tests/interface/TWCryptoBoxTests.cpp index cb9a3335c54..301381e171f 100644 --- a/tests/interface/TWCryptoBoxTests.cpp +++ b/tests/interface/TWCryptoBoxTests.cpp @@ -4,8 +4,8 @@ #include "TestUtilities.h" #include "TrustWalletCore/TWCryptoBox.h" -#include "TrustWalletCore/TWCryptoBoxPublicKey.h" -#include "TrustWalletCore/TWCryptoBoxSecretKey.h" +#include "TrustWalletCore/Generated/TWCryptoBoxPublicKey.h" +#include "TrustWalletCore/Generated/TWCryptoBoxSecretKey.h" #include diff --git a/tests/interface/TWHDWalletTests.cpp b/tests/interface/TWHDWalletTests.cpp index cff8a206c30..970ca669c7a 100644 --- a/tests/interface/TWHDWalletTests.cpp +++ b/tests/interface/TWHDWalletTests.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -258,7 +258,7 @@ TEST(HDWallet, DeriveDoge) { TEST(HDWallet, DeriveZilliqa) { auto wallet = WRAP(TWHDWallet, TWHDWalletCreateWithMnemonic(gWords.get(), gPassphrase.get())); auto key = WRAP(TWPrivateKey, TWHDWalletGetKeyForCoin(wallet.get(), TWCoinTypeZilliqa)); - auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(key.get(), true)); + auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyZilliqaSchnorr(key.get())); auto publicKeyData = WRAPD(TWPublicKeyData(publicKey.get())); assertHexEqual(publicKeyData, "0262746d4988c63b9972c63272461e9fa080d4dfa2a1fda3dd01285620c0a60c22"); @@ -442,12 +442,12 @@ TEST(HDWallet, PublicKeyFromExtended_Ethereum) { } TEST(HDWallet, PublicKeyFromExtended_NIST256p1) { - const auto xpub = STRING("xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj"); + const auto xpub = STRING("xpub6C14EL78ogJs6aQEpzMdPa6oUdo7dUFdScW7ckC6MXxUAN7zDiEP6pGQphtcjS2cv4Nusp4i9CVJPmtuGmp1RKN3pCvUPWkDFcoMHCHERTA"); const auto xpubAddr = WRAP(TWPublicKey, TWHDWalletGetPublicKeyFromExtended(xpub.get(), TWCoinTypeNEO, STRING("m/44'/888'/0'/0/0").get())); // Neo ASSERT_NE(xpubAddr.get(), nullptr); auto data = WRAPD(TWPublicKeyData(xpubAddr.get())); ASSERT_NE(data.get(), nullptr); - assertHexEqual(data, "03774c910fcf07fa96886ea794f0d5caed9afe30b44b83f7e213bb92930e7df4bd"); + assertHexEqual(data, "023c73be53bc3bbbacf6af57850efd294f07f1d8e324f8bb88df9274a188eac4b0"); } TEST(HDWallet, PublicKeyFromExtended_Negative) { diff --git a/tests/interface/TWMnemonicTests.cpp b/tests/interface/TWMnemonicTests.cpp index 2fd55e74b85..9a9b1cb7640 100644 --- a/tests/interface/TWMnemonicTests.cpp +++ b/tests/interface/TWMnemonicTests.cpp @@ -4,7 +4,7 @@ #include "TestUtilities.h" -#include +#include TEST(TWMnemonic, IsValid) { EXPECT_TRUE(TWMnemonicIsValid(STRING("credit expect life fade cover suit response wash pear what skull force").get())); diff --git a/tests/interface/TWPBKDF2Tests.cpp b/tests/interface/TWPBKDF2Tests.cpp index dbd22ca6fa4..70d53daabf3 100644 --- a/tests/interface/TWPBKDF2Tests.cpp +++ b/tests/interface/TWPBKDF2Tests.cpp @@ -4,12 +4,12 @@ #include "TestUtilities.h" -#include +#include #include TEST(TWPBKDF2, Sha256_sha512) { - auto password = DATA("50617373776f7264"); // Password + auto password = DATA("50617373776f7264"); // Password auto salt = DATA("4e61436c"); // NaCl auto sha256Result = WRAPD(TWPBKDF2HmacSha256(password.get(), salt.get(), 80000, 128)); diff --git a/tests/interface/TWPrivateKeyTests.cpp b/tests/interface/TWPrivateKeyTests.cpp index 3c4882247ec..63102e99543 100644 --- a/tests/interface/TWPrivateKeyTests.cpp +++ b/tests/interface/TWPrivateKeyTests.cpp @@ -17,7 +17,7 @@ const auto key1Hex = "22667b69166481c9f334756f49c8dddfd72c6bcdd68a7386886e97a82f741130"; TEST(TWPrivateKeyTests, Create) { - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(key1Hex).get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(key1Hex).get(), TWCurveSECP256k1)); ASSERT_TRUE(privateKey.get() != nullptr); const auto data = WRAPD(TWPrivateKeyData(privateKey.get())); @@ -25,17 +25,17 @@ TEST(TWPrivateKeyTests, Create) { } TEST(TWPrivateKeyTests, CreateNewRandom) { - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreate()); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreate(TWCurveSECP256k1)); ASSERT_TRUE(privateKey.get() != nullptr); } TEST(TWPrivateKeyTests, CreateInvalid) { - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("deadbeef").get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("deadbeef").get(), TWCurveSECP256k1)); ASSERT_EQ(privateKey.get(), nullptr); } TEST(TWPrivateKeyTests, CreateCopy) { - const auto privateKey1 = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(key1Hex).get())); + const auto privateKey1 = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA(key1Hex).get(), TWCurveSECP256k1)); ASSERT_TRUE(privateKey1.get() != nullptr); const auto privateKey2 = WRAP(TWPrivateKey, TWPrivateKeyCreateCopy(privateKey1.get())); ASSERT_TRUE(privateKey2.get() != nullptr); @@ -44,7 +44,7 @@ TEST(TWPrivateKeyTests, CreateCopy) { TEST(TWPrivateKeyTests, AllZeros) { auto bytes = TW::Data(32); auto data = WRAPD(TWDataCreateWithBytes(bytes.data(), bytes.size())); - auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(data.get())); + auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(data.get(), TWCurveSECP256k1)); ASSERT_EQ(privateKey.get(), nullptr); } @@ -68,20 +68,23 @@ TEST(TWPrivateKeyTests, IsValid) { } TEST(TWPrivateKeyTests, PublicKey) { - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get())); { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCurveSECP256k1)); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false)); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "0499c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c166b489a4b7c491e7688e6ebea3a71fc3a1a48d60f98d5ce84c93b65e423fde91"); } { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCurveNIST256p1)); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyNist256p1(privateKey.get())); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "026d786ab8fda678cf50f71d13641049a393b325063b8c0d4e5070de48a2caf9ab"); } { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCurveCurve25519)); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyCurve25519(privateKey.get())); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "686cfce9108566dd43fc6aa75e31f9a9f319c9e9c04d6ad0a52505b86bc17c3a"); } { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCoinTypeCurve(TWCoinTypeEthereum))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeEthereum)); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "0499c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c166b489a4b7c491e7688e6ebea3a71fc3a1a48d60f98d5ce84c93b65e423fde91"); @@ -91,30 +94,32 @@ TEST(TWPrivateKeyTests, PublicKey) { ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), TW::hex(publicKeyByType.get()->impl.bytes)); } { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCoinTypeCurve(TWCoinTypeNEO))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeNEO)); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "026d786ab8fda678cf50f71d13641049a393b325063b8c0d4e5070de48a2caf9ab"); } { + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCoinTypeCurve(TWCoinTypeWaves))); const auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKey(privateKey.get(), TWCoinTypeWaves)); ASSERT_EQ(TW::hex(publicKey.get()->impl.bytes), "686cfce9108566dd43fc6aa75e31f9a9f319c9e9c04d6ad0a52505b86bc17c3a"); } } TEST(TWPrivateKeyTests, Sign) { - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCurveSECP256k1)); const auto message = "hello"; const auto data = WRAPD(TWDataCreateWithBytes((uint8_t *)message, strlen(message))); const auto hash = WRAPD(TWHashKeccak256(data.get())); - const auto actual = WRAPD(TWPrivateKeySign(privateKey.get(), hash.get(), TWCurveSECP256k1)); + const auto actual = WRAPD(TWPrivateKeySign(privateKey.get(), hash.get())); ASSERT_EQ(TW::hex(*((TW::Data*)actual.get())), "8720a46b5b3963790d94bcc61ad57ca02fd153584315bfa161ed3455e336ba624d68df010ed934b8792c5b6a57ba86c3da31d039f9612b44d1bf054132254de901"); } TEST(TWPrivateKeyTests, SignAsDER) { - const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get())); + const auto privateKey = WRAP(TWPrivateKey, TWPrivateKeyCreateWithData(DATA("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5").get(), TWCurveSECP256k1)); const auto message = "hello"; const auto data = WRAPD(TWDataCreateWithBytes((uint8_t *)message, strlen(message))); diff --git a/tests/interface/TWPublicKeyTests.cpp b/tests/interface/TWPublicKeyTests.cpp index 90b060da2ad..99e4c8c4462 100644 --- a/tests/interface/TWPublicKeyTests.cpp +++ b/tests/interface/TWPublicKeyTests.cpp @@ -25,7 +25,7 @@ TEST(TWPublicKeyTests, Create) { } TEST(TWPublicKeyTests, CreateFromPrivateSecp256k1) { - const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); + const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveSECP256k1); const auto privateKey = WRAP(TWPrivateKey, new TWPrivateKey{ key }); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); @@ -33,7 +33,7 @@ TEST(TWPublicKeyTests, CreateFromPrivateSecp256k1) { auto publicKeyData = WRAPD(TWPublicKeyData(publicKey.get())); EXPECT_EQ(hex(*((Data*)(publicKeyData.get()))), "0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1"); EXPECT_EQ(*((std::string*)(WRAPS(TWPublicKeyDescription(publicKey.get())).get())), "0399c6f51ad6f98c9c583f8e92bb7758ab2ca9a04110c0a1126ec43e5453d196c1"); - EXPECT_TRUE(TWPublicKeyIsValid(publicKey.get(), TWPublicKeyTypeSECP256k1)); + EXPECT_TRUE(TWPublicKeyIsValid(publicKeyData.get(), TWPublicKeyTypeSECP256k1)); EXPECT_TRUE(TWPublicKeyIsCompressed(publicKey.get())); } @@ -43,26 +43,29 @@ TEST(TWPublicKeyTests, CreateInvalid) { } TEST(TWPublicKeyTests, CompressedExtended) { - const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); + const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveCurve25519); const auto privateKey = WRAP(TWPrivateKey, new TWPrivateKey{ key }); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), true)); + auto publicKeyData = WRAPD(TWPublicKeyData(publicKey.get())); EXPECT_EQ(TWPublicKeyKeyType(publicKey.get()), TWPublicKeyTypeSECP256k1); EXPECT_EQ(publicKey.get()->impl.bytes.size(), 33ul); EXPECT_EQ(TWPublicKeyIsCompressed(publicKey.get()), true); - EXPECT_TRUE(TWPublicKeyIsValid(publicKey.get(), TWPublicKeyTypeSECP256k1)); + EXPECT_TRUE(TWPublicKeyIsValid(publicKeyData.get(), TWPublicKeyTypeSECP256k1)); auto extended = WRAP(TWPublicKey, TWPublicKeyUncompressed(publicKey.get())); + auto extendedData = WRAPD(TWPublicKeyData(extended.get())); EXPECT_EQ(TWPublicKeyKeyType(extended.get()), TWPublicKeyTypeSECP256k1Extended); EXPECT_EQ(extended.get()->impl.bytes.size(), 65ul); EXPECT_EQ(TWPublicKeyIsCompressed(extended.get()), false); - EXPECT_TRUE(TWPublicKeyIsValid(extended.get(), TWPublicKeyTypeSECP256k1Extended)); + EXPECT_TRUE(TWPublicKeyIsValid(extendedData.get(), TWPublicKeyTypeSECP256k1Extended)); auto compressed = WRAP(TWPublicKey, TWPublicKeyCompressed(extended.get())); + auto compressedData = WRAPD(TWPublicKeyData(publicKey.get())); //EXPECT_TRUE(compressed == publicKey.get()); EXPECT_EQ(TWPublicKeyKeyType(compressed.get()), TWPublicKeyTypeSECP256k1); EXPECT_EQ(compressed.get()->impl.bytes.size(), 33ul); EXPECT_EQ(TWPublicKeyIsCompressed(compressed.get()), true); - EXPECT_TRUE(TWPublicKeyIsValid(compressed.get(), TWPublicKeyTypeSECP256k1)); + EXPECT_TRUE(TWPublicKeyIsValid(compressedData.get(), TWPublicKeyTypeSECP256k1)); } TEST(TWPublicKeyTests, Verify) { @@ -73,7 +76,7 @@ TEST(TWPublicKeyTests, Verify) { auto messageData = WRAPD(TWDataCreateWithBytes((const uint8_t*)message, strlen(message))); auto digest = WRAPD(TWHashKeccak256(messageData.get())); - auto signature = WRAPD(TWPrivateKeySign(privateKey.get(), digest.get(), TWCurveSECP256k1)); + auto signature = WRAPD(TWPrivateKeySign(privateKey.get(), digest.get())); auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeySecp256k1(privateKey.get(), false)); ASSERT_TRUE(TWPublicKeyVerify(publicKey.get(), signature.get(), digest.get())); @@ -97,18 +100,19 @@ TEST(TWPublicKeyTests, VerifyAsDER) { } TEST(TWPublicKeyTests, VerifyEd25519) { - const PrivateKey key(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5")); - const auto privateKey = WRAP(TWPrivateKey, new TWPrivateKey{ key }); - const char* message = "Hello"; auto messageData = WRAPD(TWDataCreateWithBytes((const uint8_t*)message, strlen(message))); auto digest = WRAPD(TWHashSHA256(messageData.get())); - auto signature = WRAPD(TWPrivateKeySign(privateKey.get(), digest.get(), TWCurveED25519)); - auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyEd25519(privateKey.get())); + const PrivateKey key1(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveED25519); + const auto privateKey1 = WRAP(TWPrivateKey, new TWPrivateKey{ key1 }); + auto signature = WRAPD(TWPrivateKeySign(privateKey1.get(), digest.get())); + auto publicKey = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyEd25519(privateKey1.get())); - auto signature2 = WRAPD(TWPrivateKeySign(privateKey.get(), digest.get(), TWCurveED25519Blake2bNano)); - auto publicKey2 = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyEd25519Blake2b(privateKey.get())); + const PrivateKey key2(parse_hex("afeefca74d9a325cf1d6b6911d61a65c32afa8e02bd5e78e2e4ac2910bab45f5"), TWCurveED25519Blake2bNano); + const auto privateKey2 = WRAP(TWPrivateKey, new TWPrivateKey{ key2 }); + auto signature2 = WRAPD(TWPrivateKeySign(privateKey2.get(), digest.get())); + auto publicKey2 = WRAP(TWPublicKey, TWPrivateKeyGetPublicKeyEd25519Blake2b(privateKey2.get())); ASSERT_TRUE(TWPublicKeyVerify(publicKey.get(), signature.get(), digest.get())); ASSERT_TRUE(TWPublicKeyVerify(publicKey2.get(), signature2.get(), digest.get())); diff --git a/tools/build-and-test b/tools/build-and-test index bd4ba92c6cf..e97fab530ef 100755 --- a/tools/build-and-test +++ b/tools/build-and-test @@ -11,17 +11,14 @@ tools/generate-files native echo "#### Building... ####" cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -make -Cbuild -j12 tests TrezorCryptoTests +make -Cbuild -j12 tests if [ -x "$(command -v clang-tidy)" ]; then echo "#### Linting... ####" tools/lint fi -echo "#### Running trezor-crypto tests... ####" export CK_TIMEOUT_MULTIPLIER=4 -build/trezor-crypto/crypto/tests/TrezorCryptoTests - echo "#### Running unit tests... ####" FILTER="*" if [ -n "$1" ]; then diff --git a/tools/coverage b/tools/coverage index 88b246fecd7..00dd403e4fb 100755 --- a/tools/coverage +++ b/tools/coverage @@ -8,11 +8,10 @@ # - run cmake, to enable coverage measurement # cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug # - build tester -# make -Cbuild -j12 tests TrezorCryptoTests +# make -Cbuild -j12 tests # - Remove any old coverage files # find . -name "*.gcda" -exec rm \{\} \; # - run unit tests -# ./build/trezor-crypto/crypto/tests/TrezorCryptoTests # ./build/tests/tests tests --gtest_output=xml # - generate coverage info (slow). Optionally generate report in HTML format: # ./tools/coverage html diff --git a/tools/ios-release b/tools/ios-release index 2fce33e89ad..17d764fd17f 100755 --- a/tools/ios-release +++ b/tools/ios-release @@ -59,6 +59,12 @@ Pod::Spec.new do |s| http: '${download_url}' } s.default_subspec = 'Core' + + s.prepare_command = <<-CMD + find include -name "*.h" -print0 | xargs -0 sed -i '' 's/\\\(<\\\)TrustWalletCore\\\/Generated\\\/\\\(.*\\\)\\\(>\\\)/\\\"\\\2\\\"/' + find include -name "*.h" -print0 | xargs -0 sed -i '' 's/\\\(<\\\)TrustWalletCore\\\/\\\(.*\\\)\\\(>\\\)/\\\"\\\2\\\"/' + CMD + s.subspec 'Types' do |ss| ss.source_files = 'Sources/Types/*.swift', diff --git a/tools/rust-test b/tools/rust-test index 05cb5f47638..895c64c9e26 100755 --- a/tools/rust-test +++ b/tools/rust-test @@ -18,7 +18,10 @@ if [[ "$1" == "wasm" ]]; then source ../emsdk/emsdk_env.sh export CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER=node - cargo test --target wasm32-unknown-emscripten --profile wasm-test --workspace --exclude wallet_core_bin + # Increase the `TOTAL_MEMORY` value if required. + CONFIG='build.rustflags=["-C","link-arg=-s","-C","link-arg=TOTAL_MEMORY=33554432"]' + + cargo --config "$CONFIG" test --target wasm32-unknown-emscripten --profile wasm-test --workspace --exclude wallet_core_bin elif [[ "$1" == "doc" ]]; then cargo test --doc else diff --git a/tools/tests b/tools/tests index 58a23f853d2..8ee3832b6b0 100755 --- a/tools/tests +++ b/tools/tests @@ -5,10 +5,9 @@ set -e cmake -H. -Bbuild -make -Cbuild -j12 tests TrezorCryptoTests +make -Cbuild -j12 tests export CK_TIMEOUT_MULTIPLIER=4 -build/trezor-crypto/crypto/tests/TrezorCryptoTests build/tests/tests tests diff --git a/trezor-crypto/.gitignore b/trezor-crypto/.gitignore deleted file mode 100644 index c98ec5d108b..00000000000 --- a/trezor-crypto/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -.cache/ -.vscode/ -_attic/ -*.o -*.d -*.exe -*~ -tests/aestst -tests/test_openssl -tests/test_speed -tests/test_check -tests/libtrezor-crypto.so -*.os -*.pyc diff --git a/trezor-crypto/CMakeLists.txt b/trezor-crypto/CMakeLists.txt deleted file mode 100644 index a3ef46a38f2..00000000000 --- a/trezor-crypto/CMakeLists.txt +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# -# Copyright © 2017 Trust Wallet. - -set(TW_WARNING_FLAGS - -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 - -Wno-missing-braces -) - -set(CMAKE_C_STANDARD 11) - -add_library(TrezorCrypto - crypto/bignum.c crypto/ecdsa.c crypto/curves.c crypto/secp256k1.c crypto/rand.c crypto/hmac.c crypto/bip32.c crypto/bip39.c crypto/slip39.c crypto/pbkdf2.c crypto/base58.c crypto/base32.c - crypto/address.c - crypto/script.c - crypto/ripemd160.c - crypto/sha2.c - crypto/sha3.c - crypto/hasher.c - crypto/aes/aescrypt.c crypto/aes/aeskey.c crypto/aes/aestab.c crypto/aes/aes_modes.c - crypto/ed25519-donna/curve25519-donna-32bit.c crypto/ed25519-donna/curve25519-donna-helpers.c crypto/ed25519-donna/modm-donna-32bit.c - crypto/ed25519-donna/ed25519-donna-basepoint-table.c crypto/ed25519-donna/ed25519-donna-32bit-tables.c crypto/ed25519-donna/ed25519-donna-impl-base.c - crypto/ed25519-donna/ed25519.c crypto/ed25519-donna/curve25519-donna-scalarmult-base.c crypto/ed25519-donna/ed25519-sha3.c crypto/ed25519-donna/ed25519-keccak.c crypto/ed25519-donna/ed25519-blake2b.c - crypto/sodium/private/fe_25_5/fe.c crypto/sodium/private/ed25519_ref10.c crypto/sodium/private/ed25519_ref10_fe_25_5.c crypto/sodium/keypair.c - crypto/monero/base58.c - crypto/monero/serialize.c - #crypto/monero/xmr.c - crypto/monero/range_proof.c - crypto/blake256.c - crypto/blake2b.c crypto/blake2s.c - crypto/chacha_drbg.c - crypto/chacha20poly1305/chacha20poly1305.c crypto/chacha20poly1305/chacha_merged.c crypto/chacha20poly1305/poly1305-donna.c crypto/chacha20poly1305/rfc7539.c - crypto/rc4.c - crypto/nano.c - crypto/nem.c - crypto/cash_addr.c - crypto/memzero.c - crypto/scrypt.c - crypto/nist256p1.c - crypto/groestl.c - crypto/hmac_drbg.c - crypto/rfc6979.c - crypto/shamir.c - crypto/zilliqa.c - crypto/cardano.c -) - -if (EMSCRIPTEN) - message(STATUS "Skip building trezor-crypto/tests") - set(TW_WARNING_FLAGS ${TW_WARNING_FLAGS} -Wno-bitwise-instead-of-logical) -else () - if(NOT ANDROID AND NOT IOS_PLATFORM AND NOT TW_COMPILE_JAVA) - add_subdirectory(crypto/tests) - endif() -endif() - -target_compile_options(TrezorCrypto PRIVATE ${TW_WARNING_FLAGS} -Werror PUBLIC -Wno-deprecated-volatile) - -target_include_directories(TrezorCrypto - PUBLIC - $ - $ - PRIVATE - src -) - -install( - TARGETS TrezorCrypto - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) - -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/trezor-crypto/crypto/AUTHORS b/trezor-crypto/crypto/AUTHORS deleted file mode 100644 index 51c9bdab086..00000000000 --- a/trezor-crypto/crypto/AUTHORS +++ /dev/null @@ -1,2 +0,0 @@ -Tomas Dzetkulic -Pavol Rusnak diff --git a/trezor-crypto/crypto/CONTRIBUTORS b/trezor-crypto/crypto/CONTRIBUTORS deleted file mode 100644 index 300b9788d21..00000000000 --- a/trezor-crypto/crypto/CONTRIBUTORS +++ /dev/null @@ -1,16 +0,0 @@ -Tomas Dzetkulic -Pavol Rusnak -Jochen Hoenicke -Dustin Laurence -Ondrej Mikle -Roman Zeyde -Alex Beregszaszi -netanelkl -Jan Pochyla -Ondrej Mikle -Josh Billings -Adam Mackler -Oleg Andreev -mog -John Dvorak -Christian Reitter diff --git a/trezor-crypto/crypto/LICENSE b/trezor-crypto/crypto/LICENSE deleted file mode 100644 index 1ea1df7037e..00000000000 --- a/trezor-crypto/crypto/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -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. diff --git a/trezor-crypto/crypto/README.md b/trezor-crypto/crypto/README.md deleted file mode 100644 index 856dbb44ac5..00000000000 --- a/trezor-crypto/crypto/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# trezor-crypto - -[![Build Status](https://travis-ci.org/trezor/trezor-crypto.svg?branch=master)](https://travis-ci.org/trezor/trezor-crypto) [![gitter](https://badges.gitter.im/trezor/community.svg)](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 -- public key conversion between Curve25519 to Ed25519 and vice versa - -Distributed 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 diff --git a/trezor-crypto/crypto/address.c b/trezor-crypto/crypto/address.c deleted file mode 100644 index 77f307b0ae8..00000000000 --- a/trezor-crypto/crypto/address.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * 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 -#include - -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 - -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 = {0}; - uint8_t hash[32] = {0}; - keccak_256_Init(&ctx); - if (rskip60) { - char prefix[16] = {0}; - int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false, - 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 diff --git a/trezor-crypto/crypto/aes/aes_modes.c b/trezor-crypto/crypto/aes/aes_modes.c deleted file mode 100644 index 15877912619..00000000000 --- a/trezor-crypto/crypto/aes/aes_modes.c +++ /dev/null @@ -1,957 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 -#include -#include - -#include - -#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 = 0, 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = NULL, *op = NULL; - - 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 = 0, blen = 0, 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] = {0}; -#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 diff --git a/trezor-crypto/crypto/aes/aescrypt.c b/trezor-crypto/crypto/aes/aescrypt.c deleted file mode 100644 index 8a168d04efe..00000000000 --- a/trezor-crypto/crypto/aes/aescrypt.c +++ /dev/null @@ -1,307 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 -#include - -#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 = NULL; -#if defined( dec_fmvars ) - dec_fmvars; /* declare variables for fwd_mcol() if needed */ -#endif - - if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) - return EXIT_FAILURE; - - 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 encryption (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 = NULL; - - if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) - return EXIT_FAILURE; - - 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 diff --git a/trezor-crypto/crypto/aes/aeskey.c b/trezor-crypto/crypto/aes/aeskey.c deleted file mode 100644 index 74bc9eb6eab..00000000000 --- a/trezor-crypto/crypto/aes/aeskey.c +++ /dev/null @@ -1,561 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 -#include -#include - -#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 diff --git a/trezor-crypto/crypto/aes/aestab.c b/trezor-crypto/crypto/aes/aestab.c deleted file mode 100644 index 8d63a800e94..00000000000 --- a/trezor-crypto/crypto/aes/aestab.c +++ /dev/null @@ -1,418 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 -#include - -#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 - -#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); -} - -int init = 0; - -AES_RETURN aes_init(void) -{ uint32_t i, w; - -#if defined(FF_TABLES) - - uint8_t pow[512] = {0}, log[256] = {0}; - - 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 - diff --git a/trezor-crypto/crypto/base32.c b/trezor-crypto/crypto/base32.c deleted file mode 100644 index aca56c4f461..00000000000 --- a/trezor-crypto/crypto/base32.c +++ /dev/null @@ -1,241 +0,0 @@ -/** - * 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 - -#include - -const char *BASE32_ALPHABET_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789"; - -static inline void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out); -static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, - const char *alphabet); -static inline void base32_8to5_raw(const uint8_t *in, uint8_t length, - uint8_t *out); - -static inline int base32_encode_character(uint8_t decoded, - const char *alphabet); -static inline int base32_decode_character(char encoded, const char *alphabet); - -char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, - const char *alphabet) { - size_t length = base32_encoded_length(inlen); - if (outlen <= length) { - return NULL; - } - - 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 = 0, j = 0; - for (i = 0, j = 0; i < limit; i += 5, j += 8) { - base32_5to8(&in[i], 5, &out[j]); - } - - if (remainder) base32_5to8(&in[i], remainder, &out[j]); -} - -bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, - const char *alphabet) { - uint8_t remainder = inlen % 8; - size_t limit = inlen - remainder; - - size_t i = 0, j = 0; - for (i = 0, j = 0; i < limit; i += 8, j += 5) { - if (!base32_8to5(&in[i], 8, &out[j], alphabet)) { - return false; - } - } - - 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]; - memset(decoded, 0, sizeof(decoded)); - - 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; - } -} diff --git a/trezor-crypto/crypto/base58.c b/trezor-crypto/crypto/base58.c deleted file mode 100644 index 1a007a2cbc0..00000000000 --- a/trezor-crypto/crypto/base58.c +++ /dev/null @@ -1,274 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include - -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, -}; - -typedef uint64_t b58_maxint_t; -typedef uint32_t b58_almostmaxint_t; -#define b58_almostmaxint_bits (sizeof(b58_almostmaxint_t) * 8) -const b58_almostmaxint_t b58_almostmaxint_mask = - ((((b58_maxint_t)1) << b58_almostmaxint_bits) - 1); - -// Decodes a null-terminated Base58 string `b58` to binary and writes the result -// at the end of the buffer `bin` of size `*binszp`. On success `*binszp` is set -// to the number of valid bytes at the end of the buffer. -bool b58tobin(void *bin, size_t *binszp, const char *b58) { - size_t binsz = *binszp; - - if (binsz == 0) { - return false; - } - - const unsigned char *b58u = (const unsigned char *)b58; - unsigned char *binu = bin; - size_t outisz = - (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t); - b58_almostmaxint_t outi[outisz]; - b58_maxint_t t = 0; - b58_almostmaxint_t c = 0; - size_t i = 0, j = 0; - uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t); - b58_almostmaxint_t zeromask = - bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0; - unsigned zerocount = 0; - - size_t b58sz = strlen(b58); - - memzero(outi, sizeof(outi)); - - // Leading zeros, just count - for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount; - - for (; i < b58sz; ++i) { - if (b58u[i] & 0x80) - // High-bit set on invalid digit - return false; - if (b58digits_map[b58u[i]] == -1) - // Invalid base58 digit - return false; - c = (unsigned)b58digits_map[b58u[i]]; - for (j = outisz; j--;) { - t = ((b58_maxint_t)outi[j]) * 58 + c; - c = t >> b58_almostmaxint_bits; - outi[j] = t & b58_almostmaxint_mask; - } - if (c) - // Output number too big (carry to the next int32) - return false; - if (outi[0] & zeromask) - // Output number too big (last int32 filled too far) - return false; - } - - j = 0; - if (bytesleft) { - for (i = bytesleft; i > 0; --i) { - *(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff; - } - ++j; - } - - for (; j < outisz; ++j) { - for (i = sizeof(*outi); i > 0; --i) { - *(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff; - } - } - - // locate the most significant byte - binu = bin; - for (i = 0; i < binsz; ++i) { - if (binu[i]) break; - } - - // prepend the correct number of null-bytes - if (zerocount > i) { - /* result too large */ - return false; - } - *binszp = binsz - i + zerocount; - - return true; -} - -int b58check(const void *bin, size_t binsz, HasherType hasher_type, - const char *base58str) { - unsigned char buf[32] = {0}; - const uint8_t *binc = bin; - unsigned i = 0; - if (binsz < 4) return -4; - hasher_Raw(hasher_type, bin, binsz - 4, buf); - if (memcmp(&binc[binsz - 4], buf, 4)) return -1; - - // Check number of zeros is correct AFTER verifying checksum (to avoid - // possibility of accessing base58str beyond the end) - for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) { - } // Just finding the end of zeros, nothing to do in loop - if (binc[i] == '\0' || base58str[i] == '1') return -3; - - return binc[0]; -} - -bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) { - const uint8_t *bin = data; - int carry = 0; - size_t i = 0, j = 0, high = 0, zcount = 0; - size_t size = 0; - - while (zcount < binsz && !bin[zcount]) ++zcount; - - size = (binsz - zcount) * 138 / 100 + 1; - uint8_t buf[size]; - memzero(buf, size); - - for (i = zcount, high = size - 1; i < binsz; ++i, high = j) { - for (carry = bin[i], j = size - 1; (j > high) || carry; --j) { - carry += 256 * buf[j]; - buf[j] = carry % 58; - carry /= 58; - if (!j) { - // Otherwise j wraps to maxint which is > high - break; - } - } - } - - for (j = 0; j < 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 < 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]; - memset(buf, 0, sizeof(buf)); - uint8_t *hash = buf + datalen; - memcpy(buf, data, datalen); - hasher_Raw(hasher_type, data, datalen, hash); - size_t res = strsize; - bool success = b58enc(str, &res, buf, datalen + 4); - memzero(buf, sizeof(buf)); - return success ? res : 0; -} - -int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, - int datalen) { - if (datalen > 128) { - return 0; - } - uint8_t d[datalen + 4]; - memset(d, 0, sizeof(d)); - size_t res = datalen + 4; - if (b58tobin(d, &res, str) != true) { - return 0; - } - uint8_t *nd = d + datalen + 4 - res; - if (b58check(nd, res, hasher_type, str) < 0) { - return 0; - } - memcpy(data, nd, res - 4); - return res - 4; -} - -#if USE_GRAPHENE -int b58gphcheck(const void *bin, size_t binsz, const char *base58str) { - unsigned char buf[32] = {0}; - const uint8_t *binc = bin; - unsigned i = 0; - 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]; - memset(buf, 0, sizeof(buf)); - 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]; - memset(d, 0, sizeof(d)); - size_t res = datalen + 4; - if (b58tobin(d, &res, str) != true) { - return 0; - } - uint8_t *nd = d + datalen + 4 - res; - if (b58gphcheck(nd, res, str) < 0) { - return 0; - } - memcpy(data, nd, res - 4); - return res - 4; -} -#endif diff --git a/trezor-crypto/crypto/bignum.c b/trezor-crypto/crypto/bignum.c deleted file mode 100644 index 5791448d100..00000000000 --- a/trezor-crypto/crypto/bignum.c +++ /dev/null @@ -1,1827 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * Copyright (c) 2015 Jochen Hoenicke - * 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. - */ - -#include - -#include -#include -#include -#include - -#include -#include - -/* - This library implements 256-bit numbers arithmetic. - - An unsigned 256-bit number is represented by a bignum256 structure, that is an - array of nine 32-bit values called limbs. Limbs are digits of the number in - the base 2**29 representation in the little endian order. This means that - bignum256 x; - represents the value - sum([x[i] * 2**(29*i) for i in range(9)). - - A limb of a bignum256 is *normalized* iff it's less than 2**29. - A bignum256 is *normalized* iff every its limb is normalized. - A number is *fully reduced modulo p* iff it is less than p. - A number is *partly reduced modulo p* iff it is less than 2*p. - The number p is usually a prime number such that 2^256 - 2^224 <= p <= 2^256. - - All functions except bn_fast_mod expect that all their bignum256 inputs are - normalized. (The function bn_fast_mod allows the input number to have the - most significant limb unnormalized). All bignum256 outputs of all functions - are guaranteed to be normalized. - - A number can be partly reduced with bn_fast_mod, a partly reduced number can - be fully reduced with bn_mod. - - A function has *constant control flow with regard to its argument* iff the - order in which instructions of the function are executed doesn't depend on the - value of the argument. - A function has *constant memory access flow with regard to its argument* iff - the memory addresses that are acessed and the order in which they are accessed - don't depend on the value of the argument. - A function *has contant control (memory access) flow* iff it has constant - control (memory access) flow with regard to all its arguments. - - The following function has contant control flow with regard to its arugment - n, however is doesn't have constant memory access flow with regard to it: - void (int n, int *a) } - a[0] = 0; - a[n] = 0; // memory address reveals the value of n - } - - Unless stated otherwise all functions are supposed to have both constant - control flow and constant memory access flow. - */ - -#define BN_MAX_DECIMAL_DIGITS \ - 79 // floor(log(2**(LIMBS * BITS_PER_LIMB), 10)) + 1 - -// out_number = (bignum256) in_number -// Assumes in_number is a raw bigendian 256-bit number -// Guarantees out_number is normalized -void bn_read_be(const uint8_t *in_number, bignum256 *out_number) { - uint32_t temp = 0; - - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t limb = read_be(in_number + (BN_LIMBS - 2 - i) * 4); - - temp |= limb << (BN_EXTRA_BITS * i); - out_number->val[i] = temp & BN_LIMB_MASK; - - temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); - } - - out_number->val[BN_LIMBS - 1] = temp; -} - -// out_number = (256BE) in_number -// Assumes in_number < 2**256 -// Guarantess out_number is a raw bigendian 256-bit number -void bn_write_be(const bignum256 *in_number, uint8_t *out_number) { - uint32_t temp = in_number->val[BN_LIMBS - 1]; - for (int i = BN_LIMBS - 2; i >= 0; i--) { - uint32_t limb = in_number->val[i]; - - temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | - (limb >> (BN_EXTRA_BITS * i)); - write_be(out_number + (BN_LIMBS - 2 - i) * 4, temp); - - temp = limb; - } -} - -// out_number = (bignum256) in_number -// Assumes in_number is a raw little endian 256-bit number -// Guarantees out_number is normalized -void bn_read_le(const uint8_t *in_number, bignum256 *out_number) { - uint32_t temp = 0; - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t limb = read_le(in_number + i * 4); - - temp |= limb << (BN_EXTRA_BITS * i); - out_number->val[i] = temp & BN_LIMB_MASK; - temp = limb >> (32 - BN_EXTRA_BITS * (i + 1)); - } - - out_number->val[BN_LIMBS - 1] = temp; -} - -// out_number = (256LE) in_number -// Assumes in_number < 2**256 -// Guarantess out_number is a raw little endian 256-bit number -void bn_write_le(const bignum256 *in_number, uint8_t *out_number) { - uint32_t temp = in_number->val[BN_LIMBS - 1]; - - for (int i = BN_LIMBS - 2; i >= 0; i--) { - uint32_t limb = in_number->val[i]; - temp = (temp << (BN_BITS_PER_LIMB - BN_EXTRA_BITS * i)) | - (limb >> (BN_EXTRA_BITS * i)); - write_le(out_number + i * 4, temp); - temp = limb; - } -} - -// out_number = (bignum256) in_number -// Guarantees out_number is normalized -void bn_read_uint32(uint32_t in_number, bignum256 *out_number) { - out_number->val[0] = in_number & BN_LIMB_MASK; - out_number->val[1] = in_number >> BN_BITS_PER_LIMB; - for (uint32_t i = 2; i < BN_LIMBS; i++) out_number->val[i] = 0; -} - -// out_number = (bignum256) in_number -// Guarantees out_number is normalized -void bn_read_uint64(uint64_t in_number, bignum256 *out_number) { - out_number->val[0] = in_number & BN_LIMB_MASK; - out_number->val[1] = (in_number >>= BN_BITS_PER_LIMB) & BN_LIMB_MASK; - out_number->val[2] = in_number >> BN_BITS_PER_LIMB; - for (uint32_t i = 3; i < BN_LIMBS; i++) out_number->val[i] = 0; -} - -// Returns the bitsize of x -// Assumes x is normalized -// The function doesn't have neither constant control flow nor constant memory -// access flow -int bn_bitcount(const bignum256 *x) { - for (int i = BN_LIMBS - 1; i >= 0; i--) { - uint32_t limb = x->val[i]; - if (limb != 0) { - // __builtin_clz returns the number of leading zero bits starting at the - // most significant bit position - return i * BN_BITS_PER_LIMB + (32 - __builtin_clz(limb)); - } - } - return 0; -} - -// Returns the number of decimal digits of x; if x is 0, returns 1 -// Assumes x is normalized -// The function doesn't have neither constant control flow nor constant memory -// access flow -unsigned int bn_digitcount(const bignum256 *x) { - bignum256 val = {0}; - bn_copy(x, &val); - - unsigned int digits = 1; - for (unsigned int i = 0; i < BN_MAX_DECIMAL_DIGITS; i += 3) { - uint32_t limb = 0; - - bn_divmod1000(&val, &limb); - - if (limb >= 100) { - digits = i + 3; - } else if (limb >= 10) { - digits = i + 2; - } else if (limb >= 1) { - digits = i + 1; - } - } - - memzero(&val, sizeof(val)); - - return digits; -} - -// x = 0 -// Guarantees x is normalized -void bn_zero(bignum256 *x) { - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = 0; - } -} - -// x = 1 -// Guarantees x is normalized -void bn_one(bignum256 *x) { - x->val[0] = 1; - for (int i = 1; i < BN_LIMBS; i++) { - x->val[i] = 0; - } -} - -// Returns x == 0 -// Assumes x is normalized -int bn_is_zero(const bignum256 *x) { - uint32_t result = 0; - for (int i = 0; i < BN_LIMBS; i++) { - result |= x->val[i]; - } - return !result; -} - -// Returns x == 1 -// Assumes x is normalized -int bn_is_one(const bignum256 *x) { - uint32_t result = x->val[0] ^ 1; - for (int i = 1; i < BN_LIMBS; i++) { - result |= x->val[i]; - } - return !result; -} - -// Returns x < y -// Assumes x, y are normalized -int bn_is_less(const bignum256 *x, const bignum256 *y) { - uint32_t res1 = 0; - uint32_t res2 = 0; - for (int i = BN_LIMBS - 1; i >= 0; i--) { - res1 = (res1 << 1) | (x->val[i] < y->val[i]); - res2 = (res2 << 1) | (x->val[i] > y->val[i]); - } - return res1 > res2; -} - -// Returns x == y -// Assumes x, y are normalized -int bn_is_equal(const bignum256 *x, const bignum256 *y) { - uint32_t result = 0; - for (int i = 0; i < BN_LIMBS; i++) { - result |= x->val[i] ^ y->val[i]; - } - return !result; -} - -// res = cond if truecase else falsecase -// Assumes cond is either 0 or 1 -// Works properly even if &res == &truecase or &res == &falsecase or -// &truecase == &falsecase or &res == &truecase == &falsecase -void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, - const bignum256 *falsecase) { - assert((int)(cond == 1) | (cond == 0)); - - uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 - uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF - - for (int i = 0; i < BN_LIMBS; i++) { - res->val[i] = (truecase->val[i] & tmask) | (falsecase->val[i] & fmask); - } -} - -// x = -x % prime if cond else x, -// Explicitly x = (3 * prime - x if x > prime else 2 * prime - x) if cond else -// else (x if x > prime else x + prime) -// Assumes x is normalized and partly reduced -// Assumes cond is either 1 or 0 -// Guarantees x is normalized -// Assumes prime is normalized and -// 0 < prime < 2**260 == 2**(BITS_PER_LIMB * LIMBS - 1) -void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime) { - assert((int)(cond == 1) | (cond == 0)); - - uint32_t tmask = -cond; // tmask = 0xFFFFFFFF if cond else 0x00000000 - uint32_t fmask = ~tmask; // fmask = 0x00000000 if cond else 0xFFFFFFFF - - bn_mod(x, prime); - // x < prime - - uint32_t acc1 = 1; - uint32_t acc2 = 0; - - for (int i = 0; i < BN_LIMBS; i++) { - acc1 += (BN_BASE - 1) + 2 * prime->val[i] - x->val[i]; - // acc1 neither overflows 32 bits nor underflows 0 - // Proof: - // acc1 + (BASE - 1) + 2 * prime[i] - x[i] - // >= (BASE - 1) - x >= (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) - // == 0 - // acc1 + (BASE - 1) + 2 * prime[i] - x[i] - // <= acc1 + (BASE - 1) + 2 * prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) - // == 7 + 3 * 2**29 < 2**32 - - acc2 += prime->val[i] + x->val[i]; - // acc2 doesn't overflow 32 bits - // Proof: - // acc2 + prime[i] + x[i] - // <= 2**(32 - BITS_PER_LIMB) - 1 + 2 * (2**BITS_PER_LIMB - 1) - // == 2**(32 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB + 1) - 2 - // == 2**30 + 5 < 2**32 - - // x = acc1 & LIMB_MASK if cond else acc2 & LIMB_MASK - x->val[i] = ((acc1 & tmask) | (acc2 & fmask)) & BN_LIMB_MASK; - - acc1 >>= BN_BITS_PER_LIMB; - // acc1 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc1 == 2**(BITS_PER_LIMB * (i + 1)) + 2 * prime[:i + 1] - x[:i + 1] - // >> BITS_PER_LIMB * (i + 1) - - acc2 >>= BN_BITS_PER_LIMB; - // acc2 <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - // acc2 == prime[:i + 1] + x[:i + 1] >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc1 == 1); // assert prime <= 2**260 - // assert(acc2 == 0); - - // clang-format off - // acc1 == 1 - // Proof: - // acc1 == 2**(BITS_PER_LIMB * LIMBS) + 2 * prime[:LIMBS] - x[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + 2 * prime - x >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) + 2 * prime >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) + 2 * (2**(BITS_PER_LIMB * LIMBS - 1) - 1) >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) + 2**(BITS_PER_LIMB * LIMBS) - 2 >> BITS_PER_LIMB * LIMBS - // == 1 - - // acc1 == 2**(BITS_PER_LIMB * LIMBS) + 2 * prime[:LIMBS] - x[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + 2 * prime - x >> BITS_PER_LIMB * LIMBS - // >= 2**(BITS_PER_LIMB * LIMBS) + 0 >> BITS_PER_LIMB * LIMBS - // == 1 - - // acc2 == 0 - // Proof: - // acc2 == prime[:LIMBS] + x[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == prime + x >> BITS_PER_LIMB * LIMBS - // <= 2 * prime - 1 >> BITS_PER_LIMB * LIMBS - // <= 2 * (2**(BITS_PER_LIMB * LIMBS - 1) - 1) - 1 >> 261 - // == 2**(BITS_PER_LIMB * LIMBS) - 3 >> BITS_PER_LIMB * LIMBS - // == 0 - // clang-format on -} - -// x <<= 1 -// Assumes x is normalized, x < 2**260 == 2**(LIMBS*BITS_PER_LIMB - 1) -// Guarantees x is normalized -void bn_lshift(bignum256 *x) { - for (int i = BN_LIMBS - 1; i > 0; i--) { - x->val[i] = ((x->val[i] << 1) & BN_LIMB_MASK) | - (x->val[i - 1] >> (BN_BITS_PER_LIMB - 1)); - } - x->val[0] = (x->val[0] << 1) & BN_LIMB_MASK; -} - -// x >>= 1, i.e. x = floor(x/2) -// Assumes x is normalized -// Guarantees x is normalized -// If x is partly reduced (fully reduced) modulo prime, -// guarantess x will be partly reduced (fully reduced) modulo prime -void bn_rshift(bignum256 *x) { - for (int i = 0; i < BN_LIMBS - 1; i++) { - x->val[i] = - (x->val[i] >> 1) | ((x->val[i + 1] & 1) << (BN_BITS_PER_LIMB - 1)); - } - x->val[BN_LIMBS - 1] >>= 1; -} - -// Sets i-th least significant bit (counting from zero) -// Assumes x is normalized and 0 <= i < 261 == LIMBS*BITS_PER_LIMB -// Guarantees x is normalized -// The function has constant control flow but not constant memory access flow -// with regard to i -void bn_setbit(bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - x->val[i / BN_BITS_PER_LIMB] |= (1u << (i % BN_BITS_PER_LIMB)); -} - -// clears i-th least significant bit (counting from zero) -// Assumes x is normalized and 0 <= i < 261 == LIMBS*BITS_PER_LIMB -// Guarantees x is normalized -// The function has constant control flow but not constant memory access flow -// with regard to i -void bn_clearbit(bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - x->val[i / BN_BITS_PER_LIMB] &= ~(1u << (i % BN_BITS_PER_LIMB)); -} - -// returns i-th least significant bit (counting from zero) -// Assumes x is normalized and 0 <= i < 261 == LIMBS*BITS_PER_LIMB -// The function has constant control flow but not constant memory access flow -// with regard to i -uint32_t bn_testbit(const bignum256 *x, uint16_t i) { - assert(i < BN_LIMBS * BN_BITS_PER_LIMB); - return (x->val[i / BN_BITS_PER_LIMB] >> (i % BN_BITS_PER_LIMB)) & 1; -} - -// res = x ^ y -// Assumes x, y are normalized -// Guarantees res is normalized -// Works properly even if &res == &x or &res == &y or &res == &x == &y -void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y) { - for (int i = 0; i < BN_LIMBS; i++) { - res->val[i] = x->val[i] ^ y->val[i]; - } -} - -// x = x / 2 % prime -// Explicitly x = x / 2 if is_even(x) else (x + prime) / 2 -// Assumes x is normalized, x + prime < 261 == LIMBS * BITS_PER_LIMB -// Guarantees x is normalized -// If x is partly reduced (fully reduced) modulo prime, -// guarantess x will be partly reduced (fully reduced) modulo prime -// Assumes prime is an odd number and normalized -void bn_mult_half(bignum256 *x, const bignum256 *prime) { - // x = x / 2 if is_even(x) else (x + prime) / 2 - - uint32_t x_is_odd_mask = - -(x->val[0] & 1); // x_is_odd_mask = 0xFFFFFFFF if is_odd(x) else 0 - - uint32_t acc = (x->val[0] + (prime->val[0] & x_is_odd_mask)) >> 1; - // acc < 2**BITS_PER_LIMB - // Proof: - // acc == x[0] + prime[0] & x_is_odd_mask >> 1 - // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) >> 1 - // == 2**(BITS_PER_LIMB + 1) - 2 >> 1 - // < 2**(BITS_PER_LIMB) - - for (int i = 0; i < BN_LIMBS - 1; i++) { - uint32_t temp = (x->val[i + 1] + (prime->val[i + 1] & x_is_odd_mask)); - // temp < 2**(BITS_PER_LIMB + 1) - // Proof: - // temp == x[i + 1] + val[i + 1] & x_is_odd_mask - // <= (2**(BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB) - 1) - // < 2**(BITS_PER_LIMB + 1) - - acc += (temp & 1) << (BN_BITS_PER_LIMB - 1); - // acc doesn't overflow 32 bits - // Proof: - // acc + (temp & 1 << BITS_PER_LIMB - 1) - // <= 2**(BITS_PER_LIMB + 1) + 2**(BITS_PER_LIMB - 1) - // <= 2**30 + 2**28 < 2**32 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - acc += temp >> 1; - // acc < 2**(BITS_PER_LIMB + 1) - // Proof: - // acc + (temp >> 1) - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**(BITS_PER_LIMB + 1) - 1 >> 1) - // == 7 + 2**(BITS_PER_LIMB) - 1 < 2**(BITS_PER_LIMB + 1) - - // acc == x[:i+2]+(prime[:i+2] & x_is_odd_mask) >> BITS_PER_LIMB * (i+1) - } - x->val[BN_LIMBS - 1] = acc; - - // assert(acc >> BITS_PER_LIMB == 0); - // acc >> BITS_PER_LIMB == 0 - // Proof: - // acc - // == x[:LIMBS] + (prime[:LIMBS] & x_is_odd_mask) >> BITS_PER_LIMB*LIMBS - // == x + (prime & x_is_odd_mask) >> BITS_PER_LIMB * LIMBS - // <= x + prime >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // == 0 -} - -// x = x * k % prime -// Assumes x is normalized, 0 <= k <= 8 = 2**(32 - BITS_PER_LIMB) -// Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 -// Guarantees x is normalized and partly reduced modulo prime -void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime) { - assert(k <= 8); - - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = k * x->val[i]; - // x[i] doesn't overflow 32 bits - // k * x[i] <= 2**(32 - BITS_PER_LIMB) * (2**BITS_PER_LIMB - 1) - // < 2**(32 - BITS_PER_LIMB) * 2**BITS_PER_LIMB == 2**32 - } - - bn_fast_mod(x, prime); -} - -// Reduces partly reduced x modulo prime -// Explicitly x = x if x < prime else x - prime -// Assumes x is partly reduced modulo prime -// Guarantees x is fully reduced modulo prime -// Assumes prime is nonzero and normalized -void bn_mod(bignum256 *x, const bignum256 *prime) { - uint32_t x_less_prime = bn_is_less(x, prime); - - bignum256 temp = {0}; - bn_subtract(x, prime, &temp); - bn_cmov(x, x_less_prime, x, &temp); - - memzero(&temp, sizeof(temp)); -} - -// Auxiliary function for bn_multiply -// res = k * x -// Assumes k and x are normalized -// Guarantees res is normalized 18 digit little endian number in base 2**29 -void bn_multiply_long(const bignum256 *k, const bignum256 *x, - uint32_t res[2 * BN_LIMBS]) { - // Uses long multiplication in base 2**29, see - // https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication - - uint64_t acc = 0; - - // compute lower half - for (int i = 0; i < BN_LIMBS; i++) { - for (int j = 0; j <= i; j++) { - acc += k->val[j] * (uint64_t)x->val[i - j]; - // acc doesn't overflow 64 bits - // Proof: - // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) - // <= (2**(64 - BITS_PER_LIMB) - 1) + - // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) - // <= 2**35 + 9 * 2**58 < 2**64 - } - - res[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**35 - 1 == 2**(64 - BITS_PER_LIMB) - 1 - } - - // compute upper half - for (int i = BN_LIMBS; i < 2 * BN_LIMBS - 1; i++) { - for (int j = i - BN_LIMBS + 1; j < BN_LIMBS; j++) { - acc += k->val[j] * (uint64_t)x->val[i - j]; - // acc doesn't overflow 64 bits - // Proof: - // acc <= acc + sum([k[j] * x[i-j] for j in range(i)]) - // <= (2**(64 - BITS_PER_LIMB) - 1) - // LIMBS * (2**BITS_PER_LIMB - 1) * (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + 9 * (2**29 - 1) * (2**29 - 1) - // <= 2**35 + 9 * 2**58 < 2**64 - } - - res[i] = acc & (BN_BASE - 1); - acc >>= BN_BITS_PER_LIMB; - // acc < 2**35 == 2**(64 - BITS_PER_LIMB) - } - - res[2 * BN_LIMBS - 1] = acc; -} - -// Auxiliary function for bn_multiply -// Assumes 0 <= d <= 8 == LIMBS - 1 -// Assumes res is normalized and res < 2**(256 + 29*d + 31) -// Guarantess res in normalized and res < 2 * prime * 2**(29*d) -// Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply_reduce_step(uint32_t res[2 * BN_LIMBS], const bignum256 *prime, - uint32_t d) { - // clang-format off - // Computes res = res - (res // 2**(256 + BITS_PER_LIMB * d)) * prime * 2**(BITS_PER_LIMB * d) - - // res - (res // 2**(256 + BITS_PER_LIMB * d)) * prime * 2**(BITS_PER_LIMB * d) < 2 * prime * 2**(BITS_PER_LIMB * d) - // Proof: - // res - res // (2**(256 + BITS_PER_LIMB * d)) * 2**(BITS_PER_LIMB * d) * prime - // == res - res // (2**(256 + BITS_PER_LIMB * d)) * 2**(BITS_PER_LIMB * d) * (2**256 - (2**256 - prime)) - // == res - res // (2**(256 + BITS_PER_LIMB * d)) * 2**(BITS_PER_LIMB * d) * 2**256 + res // (2**(256 + BITS_PER_LIMB * d)) * 2**(BITS_PER_LIMB * d) * (2**256 - prime) - // == (res % 2**(256 + BITS_PER_LIMB * d)) + res // (2**256 + BITS_PER_LIMB * d) * 2**(BITS_PER_LIMB * d) * (2**256 - prime) - // <= (2**(256 + 29*d + 31) % 2**(256 + 29*d)) + (2**(256 + 29*d + 31) - 1) / (2**256 + 29*d) * 2**(29*d) * (2**256 - prime) - // <= 2**(256 + 29*d) + 2**(256 + 29*d + 31) / (2**256 + 29*d) * 2**(29*d) * (2**256 - prime) - // == 2**(256 + 29*d) + 2**31 * 2**(29*d) * (2**256 - prime) - // == 2**(29*d) * (2**256 + 2**31 * (2*256 - prime)) - // <= 2**(29*d) * (2**256 + 2**31 * 2*224) - // <= 2**(29*d) * (2**256 + 2**255) - // <= 2**(29*d) * 2 * (2**256 - 2**224) - // <= 2 * prime * 2**(29*d) - // clang-format on - - uint32_t coef = - (res[d + BN_LIMBS - 1] >> (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB)) + - (res[d + BN_LIMBS] << ((BN_LIMBS * BN_BITS_PER_LIMB) - 256)); - - // coef == res // 2**(256 + BITS_PER_LIMB * d) - - // coef < 2**31 - // Proof: - // coef == res // 2**(256 + BITS_PER_LIMB * d) - // < 2**(256 + 29 * d + 31) // 2**(256 + 29 * d) - // == 2**31 - - const int shift = 31; - uint64_t acc = 1ull << shift; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += (((uint64_t)(BN_BASE - 1)) << shift) + res[d + i] - - prime->val[i] * (uint64_t)coef; - // acc neither overflow 64 bits nor underflow zero - // Proof: - // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef - // >= ((BASE - 1) << shift) - prime[i] * coef - // == 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * - // (2**31 - 1) - // == (2**shift - 2**31 + 1) * (2**BITS_PER_LIMB - 1) - // == (2**31 - 2**31 + 1) * (2**29 - 1) - // == 2**29 - 1 > 0 - // acc + ((BASE - 1) << shift) + res[d + i] - prime[i] * coef - // <= acc + ((BASE - 1) << shift) + res[d+i] - // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) - // + (2*BITS_PER_LIMB - 1) - // == (2**(64 - BITS_PER_LIMB) - 1) + (2**shift + 1) * - // (2**BITS_PER_LIMB - 1) - // == (2**35 - 1) + (2**31 + 1) * (2**29 - 1) - // <= 2**35 + 2**60 + 2**29 < 2**64 - - res[d + i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 - - // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + res[d : d + i + 1] - // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } - - // acc += (((uint64_t)(BASE - 1)) << shift) + res[d + LIMBS]; - // acc >>= BITS_PER_LIMB; - // assert(acc <= 1ul << shift); - - // clang-format off - // acc == 1 << shift - // Proof: - // acc - // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + res[d : d + LIMBS + 1] - coef * prime[:LIMBS] >> BITS_PER_LIMB * (LIMBS + 1) - // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + res[d : d + LIMBS + 1] - coef * prime >> BITS_PER_LIMB * (LIMBS + 1) - - // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + (res[d : d + LIMBS + 1] - coef * prime) >> BITS_PER_LIMB * (LIMBS + 1) - // <= (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + (res[:d] + BASE**d * res[d : d + LIMBS + 1] - BASE**d * coef * prime)//BASE**d >> BITS_PER_LIMB * (LIMBS + 1) - // <= (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + (res - BASE**d * coef * prime) // BASE**d >> BITS_PER_LIMB * (LIMBS + 1) - // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + (2 * prime * BASE**d) // BASE**d >> BITS_PER_LIMB * (LIMBS + 1) - // <= (1 << 321) + 2 * 2**256 >> 290 - // == 1 << 31 == 1 << shift - - // == (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + res[d : d + LIMBS + 1] - coef * prime[:LIMBS + 1] >> BITS_PER_LIMB * (LIMBS + 1) - // >= (1 << BITS_PER_LIMB * (LIMBS + 1) + shift) + 0 >> BITS_PER_LIMB * (LIMBS + 1) - // == 1 << shift - // clang-format on - - res[d + BN_LIMBS] = 0; -} - -// Auxiliary function for bn_multiply -// Partly reduces res and stores both in x and res -// Assumes res in normalized and res < 2**519 -// Guarantees x is normalized and partly reduced modulo prime -// Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply_reduce(bignum256 *x, uint32_t res[2 * BN_LIMBS], - const bignum256 *prime) { - for (int i = BN_LIMBS - 1; i >= 0; i--) { - // res < 2**(256 + 29*i + 31) - // Proof: - // if i == LIMBS - 1: - // res < 2**519 - // == 2**(256 + 29 * 8 + 31) - // == 2**(256 + 29 * (LIMBS - 1) + 31) - // else: - // res < 2 * prime * 2**(29 * (i + 1)) - // <= 2**256 * 2**(29*i + 29) < 2**(256 + 29*i + 31) - bn_multiply_reduce_step(res, prime, i); - } - - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] = res[i]; - } -} - -// x = k * x % prime -// Assumes k, x are normalized, k * x < 2**519 -// Guarantees x is normalized and partly reduced modulo prime -// Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime) { - uint32_t res[2 * BN_LIMBS] = {0}; - - bn_multiply_long(k, x, res); - bn_multiply_reduce(x, res, prime); - - memzero(res, sizeof(res)); -} - -// Partly reduces x modulo prime -// Assumes limbs of x except the last (the most significant) one are normalized -// Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 -// Guarantees x is normalized and partly reduced modulo prime -void bn_fast_mod(bignum256 *x, const bignum256 *prime) { - // Computes x = x - (x // 2**256) * prime - - // x < 2**((LIMBS - 1) * BITS_PER_LIMB + 32) == 2**264 - - // x - (x // 2**256) * prime < 2 * prime - // Proof: - // x - (x // 2**256) * prime - // == x - (x // 2**256) * (2**256 - (2**256 - prime)) - // == x - ((x // 2**256) * 2**256) + (x // 2**256) * (2**256 - prime) - // == (x % prime) + (x // 2**256) * (2**256 - prime) - // <= prime - 1 + (2**264 // 2**256) * (2**256 - prime) - // <= 2**256 + 2**8 * 2**224 == 2**256 + 2**232 - // < 2 * (2**256 - 2**224) - // <= 2 * prime - - // x - (x // 2**256 - 1) * prime < 2 * prime - // Proof: - // x - (x // 2**256) * prime + prime - // == x - (x // 2**256) * (2**256 - (2**256 - prime)) + prime - // == x - ((x//2**256) * 2**256) + (x//2**256) * (2**256 - prime) + prime - // == (x % prime) + (x // 2**256) * (2**256 - prime) + prime - // <= 2 * prime - 1 + (2**264 // 2**256) * (2**256 - prime) - // <= 2 * prime + 2**8 * 2**224 == 2**256 + 2**232 + 2**256 - 2**224 - // < 2 * (2**256 - 2**224) - // <= 2 * prime - - uint32_t coef = - x->val[BN_LIMBS - 1] >> (256 - ((BN_LIMBS - 1) * BN_BITS_PER_LIMB)); - - // clang-format off - // coef == x // 2**256 - // 0 <= coef < 2**((LIMBS - 1) * BITS_PER_LIMB + 32 - 256) == 256 - // Proof: - //* Let x[[a : b] be the number consisting of a-th to (b-1)-th bit of the number x. - // x[LIMBS - 1] >> (256 - ((LIMBS - 1) * BITS_PER_LIMB)) - // == x[[(LIMBS - 1) * BITS_PER_LIMB : (LIMBS - 1) * BITS_PER_LIMB + 32]] >> (256 - ((LIMBS - 1) * BITS_PER_LIMB)) - // == x[[256 - ((LIMBS - 1) * BITS_PER_LIMB) + (LIMBS - 1) * BITS_PER_LIMB : (LIMBS - 1) * BITS_PER_LIMB + 32]] - // == x[[256 : (LIMBS - 1) * BITS_PER_LIMB + 32]] - // == x[[256 : 264]] == x // 2**256 - // clang-format on - - const int shift = 8; - uint64_t acc = 1ull << shift; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += (((uint64_t)(BN_BASE - 1)) << shift) + x->val[i] - - prime->val[i] * (uint64_t)coef; - // acc neither overflows 64 bits nor underflows 0 - // Proof: - // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef - // >= (BASE - 1 << shift) - prime[i] * coef - // >= 2**shift * (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) * 255 - // == (2**shift - 255) * (2**BITS_PER_LIMB - 1) - // == (2**8 - 255) * (2**29 - 1) == 2**29 - 1 >= 0 - // acc + (BASE - 1 << shift) + x[i] - prime[i] * coef - // <= acc + ((BASE - 1) << shift) + x[i] - // <= (2**(64 - BITS_PER_LIMB) - 1) + 2**shift * (2**BITS_PER_LIMB - 1) - // + (2**32 - 1) - // == (2**35 - 1) + 2**8 * (2**29 - 1) + 2**32 - // < 2**35 + 2**37 + 2**32 < 2**64 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 2**(64 - BITS_PER_LIMB) - 1 == 2**35 - 1 - - // acc == (1 << BITS_PER_LIMB * (i + 1) + shift) + x[:i + 1] - // - coef * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc == 1 << shift); - - // clang-format off - // acc == 1 << shift - // Proof: - // acc - // == (1 << BITS_PER_LIMB * LIMBS + shift) + x[:LIMBS] - coef * prime[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == (1 << BITS_PER_LIMB * LIMBS + shift) + (x - coef * prime) >> BITS_PER_LIMB * LIMBS - // <= (1 << BITS_PER_LIMB * LIMBS + shift) + (2 * prime) >> BITS_PER_LIMB * LIMBS - // <= (1 << BITS_PER_LIMB * LIMBS + shift) + 2 * 2**256 >> BITS_PER_LIMB * LIMBS - // <= 2**269 + 2**257 >> 2**261 - // <= 1 << 8 == 1 << shift - - // acc - // == (1 << BITS_PER_LIMB * LIMBS + shift) + x[:LIMBS] - coef * prime[:LIMBS] >> BITS_PER_LIMB * LIMBS - // >= (1 << BITS_PER_LIMB * LIMBS + shift) + 0 >> BITS_PER_LIMB * LIMBS - // == (1 << BITS_PER_LIMB * LIMBS + shift) + 0 >> BITS_PER_LIMB * LIMBS - // <= 1 << 8 == 1 << shift - // clang-format on -} - -// res = x**e % prime -// Assumes both x and e are normalized, x < 2**259 -// Guarantees res is normalized and partly reduced modulo prime -// Works properly even if &x == &res -// Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to e -void bn_power_mod(const bignum256 *x, const bignum256 *e, - const bignum256 *prime, bignum256 *res) { - // Uses iterative right-to-left exponentiation by squaring, see - // https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method - - bignum256 acc = {0}; - bn_copy(x, &acc); - - bn_one(res); - for (int i = 0; i < BN_LIMBS; i++) { - uint32_t limb = e->val[i]; - - for (int j = 0; j < BN_BITS_PER_LIMB; j++) { - // Break if the following bits of the last limb are zero - if (i == BN_LIMBS - 1 && limb == 0) break; - - if (limb & 1) - // acc * res < 2**519 - // Proof: - // acc * res <= max(2**259 - 1, 2 * prime) * (2 * prime) - // == max(2**259 - 1, 2**257) * 2**257 < 2**259 * 2**257 - // == 2**516 < 2**519 - bn_multiply(&acc, res, prime); - - limb >>= 1; - // acc * acc < 2**519 - // Proof: - // acc * acc <= max(2**259 - 1, 2 * prime)**2 - // <= (2**259)**2 == 2**518 < 2**519 - bn_multiply(&acc, &acc, prime); - } - // acc == x**(e[:i + 1]) % prime - } - - memzero(&acc, sizeof(acc)); -} - -// x = sqrt(x) % prime -// Explicitly x = x**((prime+1)/4) % prime -// The other root is -sqrt(x) -// Assumes x is normalized, x < 2**259 and quadratic residuum mod prime -// Assumes prime is a prime number, prime % 4 == 3, it is normalized and -// 2**256 - 2**224 <= prime <= 2**256 -// Guarantees x is normalized and fully reduced modulo prime -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to prime -void bn_sqrt(bignum256 *x, const bignum256 *prime) { - // Uses the Lagrange formula for the primes of the special form, see - // http://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus - // If prime % 4 == 3, then sqrt(x) % prime == x**((prime+1)//4) % prime - - assert(prime->val[BN_LIMBS - 1] % 4 == 3); - - // e = (prime + 1) // 4 - bignum256 e = {0}; - bn_copy(prime, &e); - bn_addi(&e, 1); - bn_rshift(&e); - bn_rshift(&e); - - bn_power_mod(x, &e, prime, x); - bn_mod(x, prime); - - memzero(&e, sizeof(e)); -} - -// a = 1/a % 2**n -// Assumes a is odd, 1 <= n <= 32 -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to n -uint32_t inverse_mod_power_two(uint32_t a, uint32_t n) { - // Uses "Explicit Quadratic Modular inverse modulo 2" from section 3.3 of "On - // Newton-Raphson iteration for multiplicative inverses modulo prime powers" - // by Jean-Guillaume Dumas, see - // https://arxiv.org/pdf/1209.6626.pdf - - // 1/a % 2**n - // = (2-a) * product([1 + (a-1)**(2**i) for i in range(1, floor(log2(n)))]) - - uint32_t acc = 2 - a; - uint32_t f = a - 1; - - // mask = (1 << n) - 1 - uint32_t mask = n == 32 ? 0xFFFFFFFF : (1u << n) - 1; - - for (uint32_t i = 1; i < n; i <<= 1) { - f = (f * f) & mask; - acc = (acc * (1 + f)) & mask; - } - - return acc; -} - -// x = (x / 2**BITS_PER_LIMB) % prime -// Assumes both x and prime are normalized -// Assumes prime is an odd number and normalized -// Guarantees x is normalized -// If x is partly reduced (fully reduced) modulo prime, -// guarantess x will be partly reduced (fully reduced) modulo prime -void bn_divide_base(bignum256 *x, const bignum256 *prime) { - // Uses an explicit formula for the modular inverse of power of two - // (x / 2**n) % prime == (x + ((-x / prime) % 2**n) * prime) // 2**n - // Proof: - // (x + ((-x / prime) % 2**n) * prime) % 2**n - // == (x - x / prime * prime) % 2**n - // == 0 - // (x + ((-1 / prime) % 2**n) * prime) % prime - // == x - // if x < prime: - // (x + ((-x / prime) % 2**n) * prime) // 2**n - // <= ((prime - 1) + (2**n - 1) * prime) / 2**n - // == (2**n * prime - 1) / 2**n == prime - 1 / 2**n < prime - // if x < 2 * prime: - // (x + ((-x / prime) % 2**n) * prime) // 2**n - // <= ((2 * prime - 1) + (2**n - 1) * prime) / 2**n - // == (2**n * prime + prime - 1) / 2**n - // == prime + (prime - 1) / 2**n < 2 * prime - - // m = (-x / prime) % 2**BITS_PER_LIMB - uint32_t m = (x->val[0] * (BN_BASE - inverse_mod_power_two( - prime->val[0], BN_BITS_PER_LIMB))) & - BN_LIMB_MASK; - // m < 2**BITS_PER_LIMB - - uint64_t acc = x->val[0] + (uint64_t)m * prime->val[0]; - acc >>= BN_BITS_PER_LIMB; - - for (int i = 1; i < BN_LIMBS; i++) { - acc = acc + x->val[i] + (uint64_t)m * prime->val[i]; - // acc does not overflow 64 bits - // acc == acc + x + m * prime - // <= 2**(64 - BITS_PER_LIMB) + 2**(BITS_PER_LIMB) - // 2**(BITS_PER_LIMB) * 2**(BITS_PER_LIMB) - // <= 2**(2 * BITS_PER_LIMB) + 2**(64 - BITS_PER_LIMB) + - // 2**(BITS_PER_LIMB) - // <= 2**58 + 2**35 + 2**29 < 2**64 - - x->val[i - 1] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc < 2**35 == 2**(64 - BITS_PER_LIMB) - - // acc == x[:i + 1] + m * prime[:i + 1] >> BITS_PER_LIMB * (i + 1) - } - - x->val[BN_LIMBS - 1] = acc; - - assert(acc >> BN_BITS_PER_LIMB == 0); - - // clang-format off - // acc >> BITS_PER_LIMB == 0 - // Proof: - // acc >> BITS_PER_LIMB - // == (x[:LIMB] + m * prime[:LIMB] >> BITS_PER_LIMB * LIMBS) >> BITS_PER_LIMB * (LIMBS + 1) - // == x + m * prime >> BITS_PER_LIMB * (LIMBS + 1) - // <= (2**(BITS_PER_LIMB * LIMBS) - 1) + (2**BITS_PER_LIMB - 1) * (2**(BITS_PER_LIMB * LIMBS) - 1) >> BITS_PER_LIMB * (LIMBS + 1) - // == 2**(BITS_PER_LIMB * LIMBS) - 1 + 2**(BITS_PER_LIMB * (LIMBS + 1)) - 2**(BITS_PER_LIMB * LIMBS) - 2**BITS_PER_LIMB + 1 >> BITS_PER_LIMB * (LIMBS + 1) - // == 2**(BITS_PER_LIMB * (LIMBS + 1)) - 2**BITS_PER_LIMB >> BITS_PER_LIMB * (LIMBS + 1) - // == 0 - // clang-format on -} - -// x = 1/x % prime if x != 0 else 0 -// Assumes x is normalized -// Assumes prime is a prime number -// Guarantees x is normalized and fully reduced modulo prime -// Assumes prime is normalized, 2**256 - 2**224 <= prime <= 2**256 -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to prime -void bn_inverse_slow(bignum256 *x, const bignum256 *prime) { - // Uses formula 1/x % prime == x**(prime - 2) % prime - // See https://en.wikipedia.org/wiki/Fermat%27s_little_theorem - - bn_fast_mod(x, prime); - - // e = prime - 2 - bignum256 e = {0}; - bn_read_uint32(2, &e); - bn_subtract(prime, &e, &e); - - bn_power_mod(x, &e, prime, x); - bn_mod(x, prime); - - memzero(&e, sizeof(e)); -} - -#if false -// x = 1/x % prime if x != 0 else 0 -// Assumes x is is_normalized -// Assumes GCD(x, prime) = 1 -// Guarantees x is normalized and fully reduced modulo prime -// Assumes prime is odd, normalized, 2**256 - 2**224 <= prime <= 2**256 -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to prime and x -void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { - // "The Almost Montgomery Inverse" from the section 3 of "Constant Time - // Modular Inversion" by Joppe W. Bos - // See http://www.joppebos.com/files/CTInversion.pdf - - /* - u = prime - v = x & prime - s = 1 - r = 0 - - k = 0 - while v != 1: - k += 1 - if is_even(u): - u = u // 2 - s = 2 * s - elif is_even(v): - v = v // 2 - r = 2 * r - elif v < u: - u = (u - v) // 2 - r = r + s - s = 2 * s - else: - v = (v - u) // 2 - s = r + s - r = 2 * r - - s = (s / 2**k) % prime - return s - */ - - if (bn_is_zero(x)) return; - - bn_fast_mod(x, prime); - bn_mod(x, prime); - - bignum256 u = {0}, v = {0}, r = {0}, s = {0}; - bn_copy(prime, &u); - bn_copy(x, &v); - bn_one(&s); - bn_zero(&r); - - int k = 0; - while (!bn_is_one(&v)) { - if ((u.val[0] & 1) == 0) { - bn_rshift(&u); - bn_lshift(&s); - } else if ((v.val[0] & 1) == 0) { - bn_rshift(&v); - bn_lshift(&r); - } else if (bn_is_less(&v, &u)) { - bn_subtract(&u, &v, &u); - bn_rshift(&u); - bn_add(&r, &s); - bn_lshift(&s); - } else { - bn_subtract(&v, &u, &v); - bn_rshift(&v); - bn_add(&s, &r); - bn_lshift(&r); - } - k += 1; - assert(!bn_is_zero(&v)); // assert GCD(x, prime) == 1 - } - - // s = s / 2**(k // BITS_PER_LIMB * BITS_PER_LIMB) - for (int i = 0; i < k / BITS_PER_LIMB; i++) { - bn_divide_base(&s, prime); - } - - // s = s / 2**(k % BITS_PER_LIMB) - for (int i = 0; i < k % BN_BITS_PER_LIMB; i++) { - bn_mult_half(&s, prime); - } - - bn_copy(&s, x); - - memzero(&u, sizeof(u)); - memzero(&v, sizeof(v)); - memzero(&r, sizeof(r)); - memzero(&s, sizeof(s)); -} -#endif - -// x = 1/x % prime if x != 0 else 0 -// Assumes x is is_normalized -// Assumes GCD(x, prime) = 1 -// Guarantees x is normalized and fully reduced modulo prime -// Assumes prime is odd, normalized, 2**256 - 2**224 <= prime <= 2**256 -// The function has constant control flow but not constant memory access flow -// with regard to prime and x -void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { - // Custom constant time version of "The Almost Montgomery Inverse" from the - // section 3 of "Constant Time Modular Inversion" by Joppe W. Bos - // See http://www.joppebos.com/files/CTInversion.pdf - - /* - u = prime - v = x % prime - s = 1 - r = 0 - - k = 0 - while v != 1: - k += 1 - if is_even(u): # b1 - u = u // 2 - s = 2 * s - elif is_even(v): # b2 - v = v // 2 - r = 2 * r - elif v < u: # b3 - u = (u - v) // 2 - r = r + s - s = 2 * s - else: # b4 - v = (v - u) // 2 - s = r + s - r = 2 * r - - s = (s / 2**k) % prime - return s - */ - - bn_fast_mod(x, prime); - bn_mod(x, prime); - - bignum256 u = {0}, v = {0}, r = {0}, s = {0}; - bn_copy(prime, &u); - bn_copy(x, &v); - bn_one(&s); - bn_zero(&r); - - bignum256 zero = {0}; - bn_zero(&zero); - - int k = 0; - - int finished = 0, u_even = 0, v_even = 0, v_less_u = 0, b1 = 0, b2 = 0, - b3 = 0, b4 = 0; - finished = 0; - - for (int i = 0; i < 2 * BN_LIMBS * BN_BITS_PER_LIMB; i++) { - finished = finished | -bn_is_one(&v); - u_even = -bn_is_even(&u); - v_even = -bn_is_even(&v); - v_less_u = -bn_is_less(&v, &u); - - b1 = ~finished & u_even; - b2 = ~finished & ~b1 & v_even; - b3 = ~finished & ~b1 & ~b2 & v_less_u; - b4 = ~finished & ~b1 & ~b2 & ~b3; - -// The ternary operator for pointers with constant control flow -// BN_INVERSE_FAST_TERNARY(c, t, f) = t if c else f -// Very nasty hack, sorry for that -#define BN_INVERSE_FAST_TERNARY(c, t, f) \ - ((void *)(((c) & (uintptr_t)(t)) | (~(c) & (uintptr_t)(f)))) - - bn_subtract(BN_INVERSE_FAST_TERNARY(b3, &u, &v), - BN_INVERSE_FAST_TERNARY( - b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &v, &u), &zero), - BN_INVERSE_FAST_TERNARY(b3, &u, &v)); - - bn_add(BN_INVERSE_FAST_TERNARY(b3, &r, &s), - BN_INVERSE_FAST_TERNARY(b3 | b4, BN_INVERSE_FAST_TERNARY(b3, &s, &r), - &zero)); - bn_rshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &u, &v)); - bn_lshift(BN_INVERSE_FAST_TERNARY(b1 | b3, &s, &r)); - - k = k - ~finished; - } - - // s = s / 2**(k // BITS_PER_LIMB * BITS_PER_LIMB) - for (int i = 0; i < 2 * BN_LIMBS; i++) { - // s = s / 2**BITS_PER_LIMB % prime if i < k // BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_divide_base(&r, prime); - bn_cmov(&s, i < k / BN_BITS_PER_LIMB, &r, &s); - } - - // s = s / 2**(k % BITS_PER_LIMB) - for (int i = 0; i < BN_BITS_PER_LIMB; i++) { - // s = s / 2 % prime if i < k % BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_mult_half(&r, prime); - bn_cmov(&s, i < k % BN_BITS_PER_LIMB, &r, &s); - } - - bn_cmov(x, bn_is_zero(x), x, &s); - - memzero(&u, sizeof(u)); - memzero(&v, sizeof(v)); - memzero(&r, sizeof(s)); - memzero(&s, sizeof(s)); -} - -#if false -// x = 1/x % prime if x != 0 else 0 -// Assumes x is is_normalized -// Assumes GCD(x, prime) = 1 -// Guarantees x is normalized and fully reduced modulo prime -// Assumes prime is odd, normalized, 2**256 - 2**224 <= prime <= 2**256 -void bn_inverse_fast(bignum256 *x, const bignum256 *prime) { - // Custom constant time version of "The Almost Montgomery Inverse" from the - // section 3 of "Constant Time Modular Inversion" by Joppe W. Bos - // See http://www.joppebos.com/files/CTInversion.pdf - - /* - u = prime - v = x % prime - s = 1 - r = 0 - - k = 0 - while v != 1: - k += 1 - if is_even(u): # b1 - u = u // 2 - s = 2 * s - elif is_even(v): # b2 - v = v // 2 - r = 2 * r - elif v < u: # b3 - u = (u - v) // 2 - r = r + s - s = 2 * s - else: # b4 - v = (v - u) // 2 - s = r + s - r = 2 * r - - s = (s / 2**k) % prime - return s - */ - - bn_fast_mod(x, prime); - bn_mod(x, prime); - - bignum256 u = {0}, v = {0}, r = {0}, s = {0}; - bn_copy(prime, &u); - bn_copy(x, &v); - bn_one(&s); - bn_zero(&r); - - bignum256 zero = {0}; - bn_zero(&zero); - - int k = 0; - - uint32_t finished = 0, u_even = 0, v_even = 0, v_less_u = 0, b1 = 0, b2 = 0, - b3 = 0, b4 = 0; - finished = 0; - - bignum256 u_half = {0}, v_half = {0}, u_minus_v_half = {0}, v_minus_u_half = {0}, r_plus_s = {0}, r_twice = {0}, s_twice = {0}; - for (int i = 0; i < 2 * BN_LIMBS * BN_BITS_PER_LIMB; i++) { - finished = finished | bn_is_one(&v); - u_even = bn_is_even(&u); - v_even = bn_is_even(&v); - v_less_u = bn_is_less(&v, &u); - - b1 = (finished ^ 1) & u_even; - b2 = (finished ^ 1) & (b1 ^ 1) & v_even; - b3 = (finished ^ 1) & (b1 ^ 1) & (b2 ^ 1) & v_less_u; - b4 = (finished ^ 1) & (b1 ^ 1) & (b2 ^ 1) & (b3 ^ 1); - - // u_half = u // 2 - bn_copy(&u, &u_half); - bn_rshift(&u_half); - - // v_half = v // 2 - bn_copy(&v, &v_half); - bn_rshift(&v_half); - - // u_minus_v_half = (u - v) // 2 - bn_subtract(&u, &v, &u_minus_v_half); - bn_rshift(&u_minus_v_half); - - // v_minus_u_half = (v - u) // 2 - bn_subtract(&v, &u, &v_minus_u_half); - bn_rshift(&v_minus_u_half); - - // r_plus_s = r + s - bn_copy(&r, &r_plus_s); - bn_add(&r_plus_s, &s); - - // r_twice = 2 * r - bn_copy(&r, &r_twice); - bn_lshift(&r_twice); - - // s_twice = 2 * s - bn_copy(&s, &s_twice); - bn_lshift(&s_twice); - - bn_cmov(&u, b1, &u_half, &u); - bn_cmov(&u, b3, &u_minus_v_half, &u); - - bn_cmov(&v, b2, &v_half, &v); - bn_cmov(&v, b4, &v_minus_u_half, &v); - - bn_cmov(&r, b2 | b4, &r_twice, &r); - bn_cmov(&r, b3, &r_plus_s, &r); - - bn_cmov(&s, b1 | b3, &s_twice, &s); - bn_cmov(&s, b4, &r_plus_s, &s); - - k = k + (finished ^ 1); - } - - // s = s / 2**(k // BITS_PER_LIMB * BITS_PER_LIMB) - for (int i = 0; i < 2 * BN_LIMBS; i++) { - // s = s / 2**BITS_PER_LIMB % prime if i < k // BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_divide_base(&r, prime); - bn_cmov(&s, i < k / BITS_PER_LIMB, &r, &s); - } - - // s = s / 2**(k % BITS_PER_LIMB) - for (int i = 0; i < BN_BITS_PER_LIMB; i++) { - // s = s / 2 % prime if i < k % BITS_PER_LIMB else s - bn_copy(&s, &r); - bn_mult_half(&r, prime); - bn_cmov(&s, i < k % BN_BITS_PER_LIMB, &r, &s); - } - - bn_cmov(x, bn_is_zero(x), x, &s); - - memzero(&u, sizeof(u)); - memzero(&v, sizeof(v)); - memzero(&r, sizeof(r)); - memzero(&s, sizeof(s)); - memzero(&u_half, sizeof(u_half)); - memzero(&v_half, sizeof(v_half)); - memzero(&u_minus_v_half, sizeof(u_minus_v_half)); - memzero(&v_minus_u_half, sizeof(v_minus_u_half)); - memzero(&r_twice, sizeof(r_twice)); - memzero(&s_twice, sizeof(s_twice)); - memzero(&r_plus_s, sizeof(r_plus_s)); -} -#endif - -// Normalizes x -// Assumes x < 2**261 == 2**(LIMBS * BITS_PER_LIMB) -// Guarantees x is normalized -void bn_normalize(bignum256 *x) { - uint32_t acc = 0; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // acc + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) - // == 7 + 2**29 - 1 < 2**32 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= (BN_BITS_PER_LIMB); - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - } -} - -// x = x + y -// Assumes x, y are normalized, x + y < 2**(LIMBS*BITS_PER_LIMB) == 2**261 -// Guarantees x is normalized -// Works properly even if &x == &y -void bn_add(bignum256 *x, const bignum256 *y) { - uint32_t acc = 0; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i] + y->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // acc + x[i] + y[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) - // == (2**(32 - BITS_PER_LIMB) - 1) + 2**(BITS_PER_LIMB + 1) - 2 - // == 7 + 2**30 - 2 < 2**32 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == x[:i + 1] + y[:i + 1] >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc == 0); // assert x + y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + y[:LIMBS] >> LIMBS * BITS_PER_LIMB - // == x + y >> LIMBS * BITS_PER_LIMB - // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> LIMBS * BITS_PER_LIMB == 0 -} - -// x = x + y % prime -// Assumes x, y are normalized -// Guarantees x is normalized and partly reduced modulo prime -// Assumes prime is normalized and 2^256 - 2^224 <= prime <= 2^256 -void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime) { - for (int i = 0; i < BN_LIMBS; i++) { - x->val[i] += y->val[i]; - // x[i] doesn't overflow 32 bits - // Proof: - // x[i] + y[i] - // <= 2 * (2**BITS_PER_LIMB - 1) - // == 2**30 - 2 < 2**32 - } - - bn_fast_mod(x, prime); -} - -// x = x + y -// Assumes x is normalized -// Assumes y <= 2**32 - 2**29 == 2**32 - 2**BITS_PER_LIMB and -// x + y < 2**261 == 2**(LIMBS * BITS_PER_LIMB) -// Guarantees x is normalized -void bn_addi(bignum256 *x, uint32_t y) { - // assert(y <= 3758096384); // assert y <= 2**32 - 2**29 - uint32_t acc = y; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // if i == 0: - // acc + x[i] == y + x[0] - // <= (2**32 - 2**BITS_PER_LIMB) + (2**BITS_PER_LIMB - 1) - // == 2**32 - 1 < 2**32 - // else: - // acc + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) - // == 7 + 2**29 - 1 < 2**32 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= (BN_BITS_PER_LIMB); - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == x[:i + 1] + y >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc == 0); // assert x + y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + y << LIMBS * BITS_PER_LIMB - // == x + y << LIMBS * BITS_PER_LIMB - // <= 2**(LIMBS + BITS_PER_LIMB) - 1 << LIMBS * BITS_PER_LIMB - // == 0 -} - -// x = x - y % prime -// Explicitly x = x + prime - y -// Assumes x, y are normalized -// Assumes y < prime[0], x + prime - y < 2**261 == 2**(LIMBS * BITS_PER_LIMB) -// Guarantees x is normalized -// If x is fully reduced modulo prime, -// guarantess x will be partly reduced modulo prime -// Assumes prime is nonzero and normalized -void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime) { - assert(y < prime->val[0]); - - // x = x + prime - y - - uint32_t acc = -y; - for (int i = 0; i < BN_LIMBS; i++) { - acc += x->val[i] + prime->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + x[i] + prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + 2 * (2**BITS_PER_LIMB - 1) - // <= 7 + 2**30 - 2 < 2**32 - // acc + x[i] + prime[i] - // >= -y + prime[0] >= 0 - - x->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == x[:i + 1] + prime[:i + 1] - y >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc == 0); // assert x + prime - y < 2**261 - // acc == 0 - // Proof: - // acc == x[:LIMBS] + prime[:LIMBS] - y >> BITS_PER_LIMB * LIMBS - // == x + prime - y >> BITS_PER_LIMB * LIMBS - // <= 2**(LIMBS * BITS_PER_LIMB) - 1 >> BITS_PER_LIMB * LIMBS == 0 -} - -// res = x - y % prime -// Explicitly res = x + (2 * prime - y) -// Assumes x, y are normalized, y is partly reduced -// Assumes x + 2 * prime - y < 2**261 == 2**(BITS_PER_LIMB * LIMBS) -// Guarantees res is normalized -// Assumes prime is nonzero and normalized -void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, - const bignum256 *prime) { - // res = x + (2 * prime - y) - - uint32_t acc = 1; - - for (int i = 0; i < BN_LIMBS; i++) { - acc += (BN_BASE - 1) + x->val[i] + 2 * prime->val[i] - y->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] - // >= (BASE - 1) - y[i] - // == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) == 0 - // acc + (BASE - 1) + x[i] + 2 * prime[i] - y[i] - // <= acc + (BASE - 1) + x[i] + 2 * prime[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) + 2 * (2**BITS_PER_LIMB - 1) - // <= (2**(32 - BITS_PER_LIMB) - 1) + 4 * (2**BITS_PER_LIMB - 1) - // == 7 + 4 * 2**29 - 4 == 2**31 + 3 < 2**32 - - res->val[i] = acc & (BN_BASE - 1); - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i+1] - y[:i+1] + 2*prime[:i+1] - // >> BITS_PER_LIMB * (i+1) - } - - // assert(acc == 1); // assert x + 2 * prime - y < 2**261 - - // clang-format off - // acc == 1 - // Proof: - // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] + 2 * prime[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x - y + 2 * prime >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x + (2 * prime - y) >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) + 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // <= 2 * 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // == 1 - - // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] + 2 * prime[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x - y + 2 * prime >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x + (2 * prime - y) >> BITS_PER_LIMB * LIMBS - // >= 2**(BITS_PER_LIMB * LIMBS) + 0 + 1 >> BITS_PER_LIMB * LIMBS - // == 1 - // clang-format on -} - -// res = x - y -// Assumes x, y are normalized and x >= y -// Guarantees res is normalized -// Works properly even if &x == &y or &x == &res or &y == &res or -// &x == &y == &res -void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res) { - uint32_t acc = 1; - for (int i = 0; i < BN_LIMBS; i++) { - acc += (BN_BASE - 1) + x->val[i] - y->val[i]; - // acc neither overflows 32 bits nor underflows 0 - // Proof: - // acc + (BASE - 1) + x[i] - y[i] - // >= (BASE - 1) - y == (2**BITS_PER_LIMB - 1) - (2**BITS_PER_LIMB - 1) - // == 0 - // acc + (BASE - 1) + x[i] - y[i] - // <= acc + (BASE - 1) + x[i] - // <= (2**(32 - BITS_PER_LIMB) - 1) + (2**BITS_PER_LIMB - 1) + - // (2**BITS_PER_LIMB - 1) - // == 7 + 2 * 2**29 < 2 **32 - - res->val[i] = acc & BN_LIMB_MASK; - acc >>= BN_BITS_PER_LIMB; - // acc <= 7 == 2**(32 - BITS_PER_LIMB) - 1 - - // acc == 2**(BITS_PER_LIMB * (i + 1)) + x[:i + 1] - y[:i + 1] - // >> BITS_PER_LIMB * (i + 1) - } - - // assert(acc == 1); // assert x >= y - - // clang-format off - // acc == 1 - // Proof: - // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x - y >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x >> BITS_PER_LIMB * LIMBS - // <= 2**(BITS_PER_LIMB * LIMBS) + 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // <= 2 * 2**(BITS_PER_LIMB * LIMBS) - 1 >> BITS_PER_LIMB * LIMBS - // == 1 - - // acc == 2**(BITS_PER_LIMB * LIMBS) + x[:LIMBS] - y[:LIMBS] >> BITS_PER_LIMB * LIMBS - // == 2**(BITS_PER_LIMB * LIMBS) + x - y >> BITS_PER_LIMB * LIMBS - // >= 2**(BITS_PER_LIMB * LIMBS) >> BITS_PER_LIMB * LIMBS - // == 1 -} - -// q = x // d, r = x % d -// Assumes x is normalized, 1 <= d <= 61304 -// Guarantees q is normalized -void bn_long_division(bignum256 *x, uint32_t d, bignum256 *q, uint32_t *r) { - assert(1 <= d && d < 61304); - - uint32_t acc = 0; - - *r = x->val[BN_LIMBS - 1] % d; - q->val[BN_LIMBS - 1] = x->val[BN_LIMBS - 1] / d; - - for (int i = BN_LIMBS - 2; i >= 0; i--) { - acc = *r * (BN_BASE % d) + x->val[i]; - // acc doesn't overflow 32 bits - // Proof: - // r * (BASE % d) + x[i] - // <= (d - 1) * (d - 1) + (2**BITS_PER_LIMB - 1) - // == d**2 - 2*d + 2**BITS_PER_LIMB - // == 61304**2 - 2 * 61304 + 2**29 - // == 3758057808 + 2**29 < 2**32 - - q->val[i] = *r * (BN_BASE / d) + (acc / d); - // q[i] doesn't overflow 32 bits - // Proof: - // r * (BASE // d) + (acc // d) - // <= (d - 1) * (2**BITS_PER_LIMB / d) + - // ((d**2 - 2*d + 2**BITS_PER_LIMB) / d) - // <= (d - 1) * (2**BITS_PER_LIMB / d) + (d - 2 + 2**BITS_PER_LIMB / d) - // == (d - 1 + 1) * (2**BITS_PER_LIMB / d) + d - 2 - // == 2**BITS_PER_LIMB + d - 2 <= 2**29 + 61304 < 2**32 - - // q[i] == (r * BASE + x[i]) // d - // Proof: - // q[i] == r * (BASE // d) + (acc // d) - // == r * (BASE // d) + (r * (BASE % d) + x[i]) // d - // == (r * d * (BASE // d) + r * (BASE % d) + x[i]) // d - // == (r * (d * (BASE // d) + (BASE % d)) + x[i]) // d - // == (r * BASE + x[i]) // d - - // q[i] < 2**BITS_PER_LIMB - // Proof: - // q[i] == (r * BASE + x[i]) // d - // <= ((d - 1) * 2**BITS_PER_LIMB + (2**BITS_PER_LIMB - 1)) / d - // == (d * 2**BITS_PER_LIMB - 1) / d == 2**BITS_PER_LIMB - 1 / d - // < 2**BITS_PER_LIMB - - *r = acc % d; - // r == (r * BASE + x[i]) % d - // Proof: - // r == acc % d == (r * (BASE % d) + x[i]) % d - // == (r * BASE + x[i]) % d - - // x[:i] == q[:i] * d + r - } -} - -// x = x // 58, r = x % 58 -// Assumes x is normalized -// Guarantees x is normalized -void bn_divmod58(bignum256 *x, uint32_t *r) { bn_long_division(x, 58, x, r); } - -// x = x // 1000, r = x % 1000 -// Assumes x is normalized -// Guarantees x is normalized -void bn_divmod1000(bignum256 *x, uint32_t *r) { - bn_long_division(x, 1000, x, r); -} - -// x = x // 10, r = x % 10 -// Assumes x is normalized -// Guarantees x is normalized -void bn_divmod10(bignum256 *x, uint32_t *r) { bn_long_division(x, 10, x, r); } - -// Formats amount -// Assumes amount is normalized -// Assumes prefix and suffix are null-terminated strings -// Assumes output is an array of length output_length -// The function doesn't have neither constant control flow nor constant memory -// access flow with regard to any its argument -size_t bn_format(const bignum256 *amount, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *output, size_t output_length) { - -/* - Python prototype of the function: - - def format(amount, prefix, suffix, decimals, exponent, trailing): - if exponent >= 0: - amount *= 10 ** exponent - else: - amount //= 10 ** (-exponent) - - d = pow(10, decimals) - - if decimals: - output = "%d.%0*d" % (amount // d, decimals, amount % d) - if not trailing: - output = output.rstrip("0").rstrip(".") - else: - output = "%d" % (amount // d) - - return prefix + output + suffix -*/ - -// Auxiliary macro for bn_format -// If enough space adds one character to output starting from the end -#define BN_FORMAT_ADD_OUTPUT_CHAR(c) \ - { \ - --position; \ - if (output <= position && position < output + output_length) { \ - *position = (c); \ - } else { \ - memset(output, '\0', output_length); \ - return 0; \ - } \ - } - - bignum256 temp = {0}; - bn_copy(amount, &temp); - uint32_t digit = 0; - - char *position = output + output_length; - - // Add string ending character - BN_FORMAT_ADD_OUTPUT_CHAR('\0'); - - // Add suffix - size_t suffix_length = suffix ? strlen(suffix) : 0; - for (int i = suffix_length - 1; i >= 0; --i) - BN_FORMAT_ADD_OUTPUT_CHAR(suffix[i]) - - // amount //= 10**exponent - for (; exponent < 0; ++exponent) { - // if temp == 0, there is no need to divide it by 10 anymore - if (bn_is_zero(&temp)) { - exponent = 0; - break; - } - bn_divmod10(&temp, &digit); - } - - // exponent >= 0 && decimals >= 0 - - bool fractional_part = false; // is fractional-part of amount present - - { // Add fractional-part digits of amount - // Add trailing zeroes - unsigned int trailing_zeros = decimals < (unsigned int) exponent ? decimals : (unsigned int) exponent; - // When casting a negative int to unsigned int, UINT_MAX is added to the int before - // Since exponent >= 0, the value remains unchanged - decimals -= trailing_zeros; - exponent -= trailing_zeros; - - if (trailing && trailing_zeros) { - fractional_part = true; - for (; trailing_zeros > 0; --trailing_zeros) - BN_FORMAT_ADD_OUTPUT_CHAR('0') - } - - // exponent == 0 || decimals == 0 - - // Add significant digits and leading zeroes - for (; decimals > 0; --decimals) { - bn_divmod10(&temp, &digit); - - if (fractional_part || digit || trailing) { - fractional_part = true; - BN_FORMAT_ADD_OUTPUT_CHAR('0' + digit) - } - else if (bn_is_zero(&temp)) { - // We break since the remaining digits are zeroes and fractional_part == trailing == false - decimals = 0; - break; - } - } - // decimals == 0 - } - - if (fractional_part) { - BN_FORMAT_ADD_OUTPUT_CHAR('.') - } - - { // Add integer-part digits of amount - // Add trailing zeroes - if (!bn_is_zero(&temp)) { - for (; exponent > 0; --exponent) { - BN_FORMAT_ADD_OUTPUT_CHAR('0') - } - } - // decimals == 0 && exponent == 0 - - // Add significant digits - do { - bn_divmod10(&temp, &digit); - BN_FORMAT_ADD_OUTPUT_CHAR('0' + digit) - } while (!bn_is_zero(&temp)); - } - - // Add prefix - size_t prefix_length = prefix ? strlen(prefix) : 0; - for (int i = prefix_length - 1; i >= 0; --i) - BN_FORMAT_ADD_OUTPUT_CHAR(prefix[i]) - - // Move formatted amount to the start of output - int length = output - position + output_length; - memmove(output, position, length); - return length - 1; -} - -#if USE_BN_PRINT -// Prints x in hexadecimal -// Assumes x is normalized and x < 2**256 -void bn_print(const bignum256 *x) { - printf("%06x", x->val[8]); - printf("%08x", ((x->val[7] << 3) | (x->val[6] >> 26))); - printf("%07x", ((x->val[6] << 2) | (x->val[5] >> 27)) & 0x0FFFFFFF); - printf("%07x", ((x->val[5] << 1) | (x->val[4] >> 28)) & 0x0FFFFFFF); - printf("%07x", x->val[4] & 0x0FFFFFFF); - printf("%08x", ((x->val[3] << 3) | (x->val[2] >> 26))); - printf("%07x", ((x->val[2] << 2) | (x->val[1] >> 27)) & 0x0FFFFFFF); - printf("%07x", ((x->val[1] << 1) | (x->val[0] >> 28)) & 0x0FFFFFFF); - printf("%07x", x->val[0] & 0x0FFFFFFF); -} - -// Prints comma separated list of limbs of x -void bn_print_raw(const bignum256 *x) { - for (int i = 0; i < BN_LIMBS - 1; i++) { - printf("0x%08x, ", x->val[i]); - } - printf("0x%08x", x->val[BN_LIMBS - 1]); -} -#endif - -#if USE_INVERSE_FAST -void bn_inverse(bignum256 *x, const bignum256 *prime) { - bn_inverse_fast(x, prime); -} -#else -void bn_inverse(bignum256 *x, const bignum256 *prime) { - bn_inverse_slow(x, prime); -} -#endif diff --git a/trezor-crypto/crypto/bip32.c b/trezor-crypto/crypto/bip32.c deleted file mode 100644 index 4d821a8cf69..00000000000 --- a/trezor-crypto/crypto/bip32.c +++ /dev/null @@ -1,834 +0,0 @@ -/** - * 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 -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if USE_KECCAK -#include -#endif -#if USE_NEM -#include "nem.h" -#endif -#if USE_CARDANO -#include -#endif -#include - -const curve_info ed25519_info = { - .bip32_name = ED25519_SEED_NAME, - .params = NULL, - .hasher_base58 = HASHER_SHA2D, - .hasher_sign = HASHER_SHA2D, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; - -// [wallet-core] -const curve_info ed25519_blake2b_nano_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_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 = {0}; - bn_read_be(private_key, &a); - if (bn_is_zero(&a)) { // == 0 - failed = true; - } else { - if (!bn_is_less(&a, &info->params->order)) { // >= order - failed = true; - } - } - memzero(&a, sizeof(a)); - } - - 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) { - 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; - } - CONFIDENTIAL HMAC_SHA512_CTX ctx; - hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name, - strlen(out->curve->bip32_name)); - hmac_sha512_Update(&ctx, seed, seed_len); - hmac_sha512_Final(&ctx, I); - - if (out->curve->params) { - bignum256 a = {0}; - while (true) { - bn_read_be(I, &a); - if (!bn_is_zero(&a) // != 0 - && bn_is_less(&a, &out->curve->params->order)) { // < order - break; - } - hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name, - strlen(out->curve->bip32_name)); - hmac_sha512_Update(&ctx, I, sizeof(I)); - hmac_sha512_Final(&ctx, I); - } - memzero(&a, sizeof(a)); - } - memcpy(out->private_key, I, 32); - memcpy(out->chain_code, I + 32, 32); - memzero(out->public_key, sizeof(out->public_key)); - memzero(I, sizeof(I)); - return 1; -} - -uint32_t hdnode_fingerprint(HDNode *node) { - uint8_t digest[32] = {0}; - uint32_t fingerprint = 0; - - hdnode_fill_public_key(node); - hasher_Raw(node->curve->hasher_pubkey, node->public_key, 33, digest); - fingerprint = ((uint32_t)digest[0] << 24) + (digest[1] << 16) + - (digest[2] << 8) + digest[3]; - memzero(digest, sizeof(digest)); - return fingerprint; -} - -int hdnode_private_ckd_bip32(HDNode *inout, uint32_t i) { - CONFIDENTIAL uint8_t data[1 + 32 + 4]; - CONFIDENTIAL uint8_t I[32 + 32]; - CONFIDENTIAL bignum256 a, b; - -#if USE_CARDANO - if (inout->curve == &ed25519_cardano_info) { - return 0; - } -#endif - - if (i & 0x80000000) { // private derivation - data[0] = 0; - memcpy(data + 1, inout->private_key, 32); - } else { // public derivation - if (!inout->curve->params) { - return 0; - } - if (hdnode_fill_public_key(inout) != 0) { - return 0; - } - memcpy(data, inout->public_key, 33); - } - write_be(data + 33, i); - - bn_read_be(inout->private_key, &a); - - 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; -} - -int hdnode_private_ckd(HDNode *inout, uint32_t i) { -#if USE_CARDANO - if (inout->curve == &ed25519_cardano_info) { - return hdnode_private_ckd_cardano(inout, i); - } else -#endif - { - return hdnode_private_ckd_bip32(inout, i); - } -} - -int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, - const uint8_t *parent_chain_code, uint32_t i, - curve_point *child, uint8_t *child_chain_code) { - uint8_t data[(1 + 32) + 4] = {0}; - uint8_t I[32 + 32] = {0}; - bignum256 c = {0}; - - 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 = {0}, child = {0}; - - if (!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &parent)) { - return 0; - } - if (!hdnode_public_ckd_cp(inout->curve->params, &parent, inout->chain_code, i, - &child, inout->chain_code)) { - return 0; - } - memzero(inout->private_key, 32); - inout->depth++; - inout->child_num = i; - inout->public_key[0] = 0x02 | (child.y.val[0] & 0x01); - bn_write_be(&child.x, inout->public_key + 1); - - // Wipe all stack data. - memzero(&parent, sizeof(parent)); - memzero(&child, sizeof(child)); - - return 1; -} - -void hdnode_public_ckd_address_optimized(const curve_point *pub, - const uint8_t *chain_code, uint32_t i, - uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize, int addrformat) { - uint8_t child_pubkey[33] = {0}; - curve_point b = {0}; - - hdnode_public_ckd_cp(&secp256k1, pub, chain_code, i, &b, NULL); - child_pubkey[0] = 0x02 | (b.y.val[0] & 0x01); - bn_write_be(&b.x, child_pubkey + 1); - - switch (addrformat) { - case 1: // Segwit-in-P2SH - ecdsa_get_address_segwit_p2sh(child_pubkey, version, hasher_pubkey, - hasher_base58, addr, addrsize); - break; - default: // normal address - ecdsa_get_address(child_pubkey, version, hasher_pubkey, hasher_base58, - addr, addrsize); - break; - } -} - -#if USE_BIP32_CACHE -bool private_ckd_cache_root_set = false; -CONFIDENTIAL HDNode private_ckd_cache_root; -int private_ckd_cache_index = 0; - -CONFIDENTIAL struct { - bool set; - size_t depth; - uint32_t i[BIP32_CACHE_MAXDEPTH]; - HDNode node; -} private_ckd_cache[BIP32_CACHE_SIZE]; - -void bip32_cache_clear(void) { - private_ckd_cache_root_set = false; - private_ckd_cache_index = 0; - memzero(&private_ckd_cache_root, sizeof(private_ckd_cache_root)); - memzero(private_ckd_cache, sizeof(private_ckd_cache)); -} - -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 = 0; - for (j = 0; j < BIP32_CACHE_SIZE; j++) { - if (private_ckd_cache[j].set && - private_ckd_cache[j].depth == i_count - 1 && - memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == - 0 && - private_ckd_cache[j].node.curve == inout->curve) { - memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode)); - found = true; - break; - } - } - } - - // else derive parent - if (!found) { - size_t k = 0; - for (k = 0; k < i_count - 1; k++) { - if (hdnode_private_ckd(inout, i[k]) == 0) return 0; - } - // and save it - memzero(&(private_ckd_cache[private_ckd_cache_index]), - sizeof(private_ckd_cache[private_ckd_cache_index])); - private_ckd_cache[private_ckd_cache_index].set = true; - private_ckd_cache[private_ckd_cache_index].depth = i_count - 1; - memcpy(private_ckd_cache[private_ckd_cache_index].i, i, - (i_count - 1) * sizeof(uint32_t)); - memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout, - sizeof(HDNode)); - private_ckd_cache_index = (private_ckd_cache_index + 1) % BIP32_CACHE_SIZE; - } - - if (fingerprint) { - *fingerprint = hdnode_fingerprint(inout); - } - if (hdnode_private_ckd(inout, i[i_count - 1]) == 0) return 0; - - return 1; -} -#endif - -int hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) { - if (hdnode_fill_public_key(node) != 0) { - return 1; - } - ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey, - addr_raw); - return 0; -} - -int hdnode_get_address(HDNode *node, uint32_t version, char *addr, - int addrsize) { - if (hdnode_fill_public_key(node) != 0) { - return 1; - } - ecdsa_get_address(node->public_key, version, node->curve->hasher_pubkey, - node->curve->hasher_base58, addr, addrsize); - return 0; -} - -int hdnode_fill_public_key(HDNode *node) { - if (node->public_key[0] != 0) return 0; - -#if USE_BIP32_25519_CURVES - if (node->curve->params) { - if (ecdsa_get_public_key33(node->curve->params, node->private_key, - node->public_key) != 0) { - return 1; - } - } else { - node->public_key[0] = 1; - if (node->curve == &ed25519_info) { - ed25519_publickey(node->private_key, node->public_key + 1); - } else if (node->curve == &ed25519_sha3_info) { - ed25519_publickey_sha3(node->private_key, node->public_key + 1); -#if 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->public_key + 1); -#endif - } - } -#else - - if (ecdsa_get_public_key33(node->curve->params, node->private_key, - node->public_key) != 0) { - return 1; - } -#endif - return 0; -} - -#if USE_ETHEREUM -int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) { - uint8_t buf[65] = {0}; - SHA3_CTX ctx = {0}; - - /* get uncompressed public key */ - if (ecdsa_get_public_key65(node->curve->params, node->private_key, buf) != - 0) { - return 0; - } - - /* compute sha3 of x and y coordinate without 04 prefix */ - sha3_256_Init(&ctx); - sha3_Update(&ctx, buf + 1, 64); - keccak_Final(&ctx, buf); - - /* 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; - } - - if (hdnode_fill_public_key(node) != 0) { - return 0; - } - - 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] = {0}; - uint8_t remainder = size % AES_BLOCK_SIZE; - - // Round down to last whole block - size -= remainder; - // Copy old last block - memcpy(last_block, &payload[size], remainder); - // Pad new last block with number of missing bytes - memset(&last_block[remainder], AES_BLOCK_SIZE - remainder, - AES_BLOCK_SIZE - remainder); - - // the IV gets mutated, so we make a copy not to touch the original - uint8_t iv[AES_BLOCK_SIZE] = {0}; - memcpy(iv, iv_immut, AES_BLOCK_SIZE); - - uint8_t shared_key[SHA3_256_DIGEST_LENGTH] = {0}; - if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { - return 0; - } - - aes_encrypt_ctx ctx = {0}; - - 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] = {0}; - - if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) { - return 0; - } - - aes_decrypt_ctx ctx = {0}; - - 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 { - if (node->curve == &ed25519_info) { - ed25519_sign(msg, msg_len, node->private_key, sig); - } else if (node->curve == &ed25519_sha3_info) { - ed25519_sign_sha3(msg, msg_len, node->private_key, sig); -#if USE_KECCAK - } else if (node->curve == &ed25519_keccak_info) { - ed25519_sign_keccak(msg, msg_len, node->private_key, sig); -#endif - } else { - return 1; // unknown or unsupported curve - } - 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, bool use_private, char *str, - int strsize) { - uint8_t node_data[78] = {0}; - write_be(node_data, version); - node_data[4] = node->depth; - write_be(node_data + 5, fingerprint); - write_be(node_data + 9, node->child_num); - memcpy(node_data + 13, node->chain_code, 32); - if (use_private) { - node_data[45] = 0; - memcpy(node_data + 46, node->private_key, 32); - } else { - memcpy(node_data + 45, node->public_key, 33); - } - int ret = base58_encode_check(node_data, sizeof(node_data), - node->curve->hasher_base58, str, strsize); - memzero(node_data, sizeof(node_data)); - return ret; -} - -int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, - uint32_t version, char *str, int strsize) { - return hdnode_serialize(node, fingerprint, version, false, str, strsize); -} - -int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, - uint32_t version, char *str, int strsize) { - return hdnode_serialize(node, fingerprint, version, true, str, strsize); -} - -// check for validity of curve point in case of public data not performed -static int hdnode_deserialize(const char *str, uint32_t version, - bool use_private, const char *curve, HDNode *node, - uint32_t *fingerprint) { - uint8_t node_data[78] = {0}; - memzero(node, sizeof(HDNode)); - node->curve = get_curve_by_name(curve); - if (base58_decode_check(str, node->curve->hasher_base58, node_data, - sizeof(node_data)) != sizeof(node_data)) { - return -1; - } - uint32_t ver = read_be(node_data); - if (ver != version) { - return -3; // invalid version - } - if (use_private) { - // invalid data - if (node_data[45]) { - return -2; - } - memcpy(node->private_key, node_data + 46, 32); - memzero(node->public_key, sizeof(node->public_key)); - } else { - memzero(node->private_key, sizeof(node->private_key)); - memcpy(node->public_key, node_data + 45, 33); - } - node->depth = node_data[4]; - if (fingerprint) { - *fingerprint = read_be(node_data + 5); - } - node->child_num = read_be(node_data + 9); - memcpy(node->chain_code, node_data + 13, 32); - return 0; -} - -int hdnode_deserialize_public(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint) { - return hdnode_deserialize(str, version, false, curve, node, fingerprint); -} - -int hdnode_deserialize_private(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint) { - return hdnode_deserialize(str, version, true, curve, node, fingerprint); -} - -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; - } - // [wallet-core] - if (strcmp(curve_name, ED25519_CARDANO_NAME) == 0) { - return &ed25519_cardano_info; - } - // [wallet-core] - if (strcmp(curve_name, ED25519_BLAKE2B_NANO_NAME) == 0) { - return &ed25519_blake2b_nano_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; -} diff --git a/trezor-crypto/crypto/bip39.c b/trezor-crypto/crypto/bip39.c deleted file mode 100644 index fc61539c938..00000000000 --- a/trezor-crypto/crypto/bip39.c +++ /dev/null @@ -1,305 +0,0 @@ -/** - * 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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if USE_BIP39_CACHE - -int bip39_cache_index = 0; - -CONFIDENTIAL struct { - bool set; - char mnemonic[256]; - char passphrase[64]; - uint8_t seed[512 / 8]; -} bip39_cache[BIP39_CACHE_SIZE]; - -void bip39_cache_clear(void) { - memzero(bip39_cache, sizeof(bip39_cache)); - bip39_cache_index = 0; -} - -#endif - -// [wallet-core] Added output buffer -const char *mnemonic_generate(int strength, char *buf, int buflen) { - if (strength % 32 || strength < 128 || strength > 256) { - return 0; - } - uint8_t data[32] = {0}; - random_buffer(data, 32); - const char *r = mnemonic_from_data(data, strength / 8, buf, buflen); - memzero(data, sizeof(data)); - return r; -} - -// [wallet-core] Global buffer no longer used -//CONFIDENTIAL char mnemo[24 * 10]; - -// [wallet-core] Added output buffer -const char *mnemonic_from_data(const uint8_t *data, int len, char *buf, int buflen) { - if (len % 4 || len < 16 || len > 32) { - return 0; - } - // [wallet-core] Check provided buffer validity, size - if (!buf || buflen < (BIP39_MAX_WORDS * (BIP39_MAX_WORD_LENGTH + 1))) { - return 0; - } - - uint8_t bits[32 + 1] = {0}; - - sha256_Raw(data, len, bits); - // checksum - bits[len] = bits[0]; - // data - memcpy(bits, data, len); - - int mlen = len * 3 / 4; - - int i = 0, j = 0, idx = 0; - char *p = buf; // [wallet-core] - 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 buf; // [wallet-core] -} - -// [wallet-core] No longer used -//void mnemonic_clear(void) { memzero(mnemo, sizeof(mnemo)); } - -int mnemonic_to_bits(const char *mnemonic, uint8_t *bits) { - if (!mnemonic) { - return 0; - } - - uint32_t i = 0, n = 0; - - while (mnemonic[i]) { - if (mnemonic[i] == ' ') { - n++; - } - i++; - } - n++; - - // check number of words - // [wallet-core] also accept 15- and 21-word - if (n != 12 && n != 15 && n != 18 && n != 21 && n != 24) { - return 0; - } - - char current_word[10] = {0}; - uint32_t j = 0, k = 0, ki = 0, bi = 0; - uint8_t result[32 + 1] = {0}; - - memzero(result, sizeof(result)); - i = 0; - while (mnemonic[i]) { - j = 0; - while (mnemonic[i] != ' ' && mnemonic[i] != 0) { - if (j >= sizeof(current_word) - 1) { - return 0; - } - current_word[j] = mnemonic[i]; - i++; - j++; - } - current_word[j] = 0; - if (mnemonic[i] != 0) { - i++; - } - 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))) { - result[bi / 8] |= 1 << (7 - (bi % 8)); - } - bi++; - } - break; - } - k++; - } - } - if (bi != n * 11) { - return 0; - } - memcpy(bits, result, sizeof(result)); - memzero(result, sizeof(result)); - - // returns amount of entropy + checksum BITS - return n * 11; -} - -int mnemonic_check(const char *mnemonic) { - uint8_t bits[32 + 1] = {0}; - int mnemonic_bits_len = mnemonic_to_bits(mnemonic, bits); - // [wallet-core] also accept 15- and 21-word - if (mnemonic_bits_len != (12 * 11) && mnemonic_bits_len != (18 * 11) && - mnemonic_bits_len != (24 * 11) && - mnemonic_bits_len != (15 * 11) && mnemonic_bits_len != (21 * 11)) { - return 0; - } - int words = mnemonic_bits_len / 11; - - uint8_t checksum = bits[words * 4 / 3]; - sha256_Raw(bits, words * 4 / 3, bits); - if (words == 12) { - return (bits[0] & 0xF0) == (checksum & 0xF0); // compare first 4 bits - } else if (words == 15) { - return (bits[0] & 0xF8) == (checksum & 0xF8); // compare first 5 bits - } else if (words == 18) { - return (bits[0] & 0xFC) == (checksum & 0xFC); // compare first 6 bits - } else if (words == 21) { - return (bits[0] & 0xFE) == (checksum & 0xFE); // compare first 7 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] = {0}; - memcpy(salt, "mnemonic", 8); - memcpy(salt + 8, passphrase, passphraselen); - 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 -} - -// binary search for finding the word in the wordlist -int mnemonic_find_word(const char *word) { - int lo = 0, hi = BIP39_WORD_COUNT - 1; - while (lo <= hi) { - int mid = lo + (hi - lo) / 2; - int cmp = strcmp(word, wordlist[mid]); - if (cmp == 0) { - return mid; - } - if (cmp > 0) { - lo = mid + 1; - } else { - hi = mid - 1; - } - } - return -1; -} - -const char *mnemonic_complete_word(const char *prefix, int len) { - // we need to perform linear search, - // because we want to return the first match - for (const char *const *w = wordlist; *w != 0; w++) { - if (strncmp(*w, prefix, len) == 0) { - return *w; - } - } - return NULL; -} - -const char *mnemonic_get_word(int index) { - if (index >= 0 && index < BIP39_WORD_COUNT) { - return wordlist[index]; - } else { - return NULL; - } -} - -uint32_t mnemonic_word_completion_mask(const char *prefix, int len) { - if (len <= 0) { - return 0x3ffffff; // all letters (bits 1-26 set) - } - uint32_t res = 0; - for (const char *const *w = wordlist; *w != 0; w++) { - const char *word = *w; - if (strncmp(word, prefix, len) == 0 && word[len] >= 'a' && - word[len] <= 'z') { - res |= 1 << (word[len] - 'a'); - } - } - return res; -} diff --git a/trezor-crypto/crypto/blake256.c b/trezor-crypto/crypto/blake256.c deleted file mode 100644 index a4e9b489c37..00000000000 --- a/trezor-crypto/crypto/blake256.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - BLAKE reference C implementation - - Copyright (c) 2012 Jean-Philippe Aumasson - - 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 . - */ -#include - -#include - -#define U8TO32_BIG(p) \ - (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ - ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) - -#define U32TO8_BIG(p, v) \ - (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ - (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); - -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 } -}; - -const uint32_t u256[16] = -{ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 -}; - -const uint8_t padding[129] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static void blake256_compress( BLAKE256_CTX *S, const uint8_t *block ) -{ - uint32_t v[16] = {0}, m[16] = {0}, i = 0; -#define ROT(x,n) (((x)<<(32-n))|( (x)>>(n))) -#define G(a,b,c,d,e) \ - v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e+1]]) + v[b]; \ - v[d] = ROT( v[d] ^ v[a],16); \ - v[c] += v[d]; \ - v[b] = ROT( v[b] ^ v[c],12); \ - v[a] += (m[sigma[i][e+1]] ^ u256[sigma[i][e]])+v[b]; \ - v[d] = ROT( v[d] ^ v[a], 8); \ - v[c] += v[d]; \ - v[b] = ROT( v[b] ^ v[c], 7); - - for( i = 0; i < 16; ++i ) m[i] = U8TO32_BIG( block + i * 4 ); - - for( i = 0; i < 8; ++i ) v[i] = S->h[i]; - - v[ 8] = S->s[0] ^ u256[0]; - v[ 9] = S->s[1] ^ u256[1]; - v[10] = S->s[2] ^ u256[2]; - v[11] = S->s[3] ^ u256[3]; - v[12] = u256[4]; - v[13] = u256[5]; - v[14] = u256[6]; - v[15] = u256[7]; - - /* don't xor t when the block is only padding */ - if ( !S->nullt ) - { - v[12] ^= S->t[0]; - v[13] ^= S->t[0]; - v[14] ^= S->t[1]; - v[15] ^= S->t[1]; - } - - for( i = 0; i < 14; ++i ) - { - /* column step */ - G( 0, 4, 8, 12, 0 ); - G( 1, 5, 9, 13, 2 ); - G( 2, 6, 10, 14, 4 ); - G( 3, 7, 11, 15, 6 ); - /* diagonal step */ - G( 0, 5, 10, 15, 8 ); - G( 1, 6, 11, 12, 10 ); - G( 2, 7, 8, 13, 12 ); - G( 3, 4, 9, 14, 14 ); - } - - for( i = 0; i < 16; ++i ) S->h[i % 8] ^= v[i]; - - for( i = 0; i < 8 ; ++i ) S->h[i] ^= S->s[i % 4]; -} - - -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 + inlen; -} - - -void blake256_Final( BLAKE256_CTX *S, uint8_t *out ) -{ - uint8_t msglen[8] = {0}, zo = 0x01, oo = 0x81; - uint32_t lo = S->t[0] + ( S->buflen << 3 ), hi = S->t[1]; - - /* support for hashing more than 2^32 bits */ - if ( lo < ( S->buflen << 3 ) ) hi++; - - U32TO8_BIG( msglen + 0, hi ); - U32TO8_BIG( msglen + 4, lo ); - - if ( S->buflen == 55 ) /* one padding byte */ - { - S->t[0] -= 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 = {0}; - blake256_Init( &S ); - blake256_Update( &S, in, inlen ); - blake256_Final( &S, out ); -} diff --git a/trezor-crypto/crypto/blake2b.c b/trezor-crypto/crypto/blake2b.c deleted file mode 100644 index 5b71c58de65..00000000000 --- a/trezor-crypto/crypto/blake2b.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . 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 - -#include -#include -#include - -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; - -const uint64_t blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -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 = 0; - memzero( S, sizeof( blake2b_state ) ); - - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; -} - -/* init xors IV with input parameter block */ -static int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - const uint8_t *p = ( const uint8_t * )( P ); - size_t i = 0; - - blake2b_init0( S ); - - /* 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 tc_blake2b_Init( blake2b_state *S, size_t outlen ) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - return blake2b_init_param( S, P ); -} - -int tc_blake2b_InitPersonal( blake2b_state *S, size_t outlen, const void *personal, size_t personal_len) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - if ( ( !personal ) || ( personal_len != BLAKE2B_PERSONALBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); - return blake2b_init_param( S, P ); -} - -int tc_blake2b_InitKey( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store32( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - memzero( P->reserved, sizeof( P->reserved ) ); - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - - if( blake2b_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2B_BLOCKBYTES] = {0}; - memzero( block, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - tc_blake2b_Update( S, block, BLAKE2B_BLOCKBYTES ); - memzero( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) -{ - uint64_t m[16] = {0}; - uint64_t v[16] = {0}; - size_t i = 0; - - for( i = 0; i < 16; ++i ) { - m[i] = load64( block + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = blake2b_IV[4] ^ S->t[0]; - v[13] = blake2b_IV[5] ^ S->t[1]; - v[14] = blake2b_IV[6] ^ S->f[0]; - v[15] = blake2b_IV[7] ^ S->f[1]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } -} - -#undef G -#undef ROUND - -int tc_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 tc_blake2b_Final( blake2b_state *S, void *out, size_t outlen ) -{ - uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; - size_t i = 0; - - if( out == NULL || outlen < S->outlen ) - return -1; - - if( 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 tc_blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen) -{ - BLAKE2B_CTX ctx; - if (0 != tc_blake2b_Init(&ctx, outlen)) return -1; - if (0 != tc_blake2b_Update(&ctx, msg, msg_len)) return -1; - if (0 != tc_blake2b_Final(&ctx, out, outlen)) return -1; - return 0; -} - -// [wallet-core] -int tc_blake2b_Personal(const uint8_t *msg, uint32_t msg_len, const void *personal, size_t personal_len, void *out, size_t outlen) -{ - BLAKE2B_CTX ctx; - if (0 != tc_blake2b_InitPersonal(&ctx, outlen, personal, personal_len)) return -1; - if (0 != tc_blake2b_Update(&ctx, msg, msg_len)) return -1; - if (0 != tc_blake2b_Final(&ctx, out, outlen)) return -1; - return 0; -} - -int tc_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 != tc_blake2b_InitKey(&ctx, outlen, key, keylen)) return -1; - if (0 != tc_blake2b_Update(&ctx, msg, msg_len)) return -1; - if (0 != tc_blake2b_Final(&ctx, out, outlen)) return -1; - return 0; -} diff --git a/trezor-crypto/crypto/blake2s.c b/trezor-crypto/crypto/blake2s.c deleted file mode 100644 index 2dfd8523345..00000000000 --- a/trezor-crypto/crypto/blake2s.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . 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 - -#include -#include -#include - -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; - -const uint32_t blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -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 = 0; - 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 = 0; - - 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] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - return blake2s_init_param( S, P ); -} - -int blake2s_InitPersonal( blake2s_state *S, size_t outlen, const void *personal, size_t personal_len) -{ - blake2s_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - if ( ( !personal ) || ( personal_len != BLAKE2S_PERSONALBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); - return blake2s_init_param( S, P ); -} - - -int blake2s_InitKey( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_param P[1] = {0}; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memzero(P->reserved, sizeof(P->reserved) ); */ - memzero( P->salt, sizeof( P->salt ) ); - memzero( P->personal, sizeof( P->personal ) ); - - if( blake2s_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2S_BLOCKBYTES] = {0}; - memzero( block, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2s_Update( S, block, BLAKE2S_BLOCKBYTES ); - memzero( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2s_sigma[r][2*i+0]]; \ - d = rotr32(d ^ a, 16); \ - c = c + d; \ - b = rotr32(b ^ c, 12); \ - a = a + b + m[blake2s_sigma[r][2*i+1]]; \ - d = rotr32(d ^ a, 8); \ - c = c + d; \ - b = rotr32(b ^ c, 7); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) -{ - uint32_t m[16] = {0}; - uint32_t v[16] = {0}; - size_t i = 0; - - for( i = 0; i < 16; ++i ) { - m[i] = load32( in + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2s_IV[0]; - v[ 9] = blake2s_IV[1]; - v[10] = blake2s_IV[2]; - v[11] = blake2s_IV[3]; - v[12] = S->t[0] ^ blake2s_IV[4]; - v[13] = S->t[1] ^ blake2s_IV[5]; - v[14] = S->f[0] ^ blake2s_IV[6]; - v[15] = S->f[1] ^ blake2s_IV[7]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } -} - -#undef G -#undef ROUND - -int blake2s_Update( blake2s_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - if( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = BLAKE2S_BLOCKBYTES - left; - if( inlen > fill ) - { - S->buflen = 0; - memcpy( S->buf + left, in, fill ); /* Fill buffer */ - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); /* Compress */ - in += fill; inlen -= fill; - while(inlen > BLAKE2S_BLOCKBYTES) { - blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); - blake2s_compress( S, in ); - in += BLAKE2S_BLOCKBYTES; - inlen -= BLAKE2S_BLOCKBYTES; - } - } - 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 = 0; - - 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; -} diff --git a/trezor-crypto/crypto/cardano.c b/trezor-crypto/crypto/cardano.c deleted file mode 100644 index 6b07f776c15..00000000000 --- a/trezor-crypto/crypto/cardano.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Copyright (c) 2013-2021 SatoshiLabs - * - * 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 -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if USE_CARDANO - -#define CARDANO_MAX_NODE_DEPTH 1048576 - -const curve_info ed25519_cardano_info = { - .bip32_name = ED25519_CARDANO_NAME, - .params = NULL, - .hasher_base58 = HASHER_SHA2D, - .hasher_sign = HASHER_SHA2D, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; - -static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst) { - uint8_t prev_acc = 0; - for (int i = 0; i < bytes; i++) { - dst[i] = (src[i] << 3) + (prev_acc & 0x7); - prev_acc = src[i] >> 5; - } - dst[bytes] = src[bytes - 1] >> 5; -} - -static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2, - uint8_t *dst) { - uint16_t r = 0; - for (int i = 0; i < 32; i++) { - r = r + (uint16_t)src1[i] + (uint16_t)src2[i]; - dst[i] = r & 0xff; - r >>= 8; - } -} - -static void cardano_ed25519_tweak_bits(uint8_t private_key[32]) { - private_key[0] &= 0xf8; - private_key[31] &= 0x1f; - private_key[31] |= 0x40; -} - -int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) { - if (inout->curve != &ed25519_cardano_info) { - return 0; - } - - if (inout->depth >= CARDANO_MAX_NODE_DEPTH) { - return 0; - } - - // checks for hardened/non-hardened derivation, keysize 32 means we are - // dealing with public key and thus non-h, keysize 64 is for private key - int keysize = 32; - if (index & 0x80000000) { - keysize = 64; - } - - CONFIDENTIAL uint8_t data[1 + 64 + 4]; - CONFIDENTIAL uint8_t z[32 + 32]; - CONFIDENTIAL uint8_t priv_key[64]; - CONFIDENTIAL uint8_t res_key[64]; - - write_le(data + keysize + 1, index); - - memcpy(priv_key, inout->private_key, 32); - memcpy(priv_key + 32, inout->private_key_extension, 32); - - if (keysize == 64) { // private derivation - data[0] = 0; - memcpy(data + 1, inout->private_key, 32); - memcpy(data + 1 + 32, inout->private_key_extension, 32); - } else { // public derivation - if (hdnode_fill_public_key(inout) != 0) { - return 0; - } - data[0] = 2; - memcpy(data + 1, inout->public_key + 1, 32); - } - - 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); - - 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_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], - HDNode *out) { - memzero(out, sizeof(HDNode)); - out->depth = 0; - out->child_num = 0; - out->curve = &ed25519_cardano_info; - memcpy(out->private_key, secret, 32); - memcpy(out->private_key_extension, secret + 32, 32); - memcpy(out->chain_code, secret + 64, 32); - - cardano_ed25519_tweak_bits(out->private_key); - - out->public_key[0] = 0; - if (hdnode_fill_public_key(out) != 0) { - return 0; - } - - return 1; -} - -// Derives the root Cardano secret from a master secret, aka seed, as defined in -// SLIP-0023. -int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]) { - CONFIDENTIAL uint8_t I[SHA512_DIGEST_LENGTH]; - CONFIDENTIAL HMAC_SHA512_CTX ctx; - - hmac_sha512_Init(&ctx, (const uint8_t *)ED25519_CARDANO_NAME, - strlen(ED25519_CARDANO_NAME)); - hmac_sha512_Update(&ctx, seed, seed_len); - hmac_sha512_Final(&ctx, I); - - sha512_Raw(I, 32, secret_out); - - memcpy(secret_out + SHA512_DIGEST_LENGTH, I + 32, 32); - cardano_ed25519_tweak_bits(secret_out); - - memzero(I, sizeof(I)); - memzero(&ctx, sizeof(ctx)); - return 1; -} - -// Derives the root Cardano secret from a BIP-32 master secret via the Ledger -// derivation: -// https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Ledger.md -int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]) { - CONFIDENTIAL uint8_t chain_code[SHA256_DIGEST_LENGTH]; - CONFIDENTIAL uint8_t root_key[SHA512_DIGEST_LENGTH]; - CONFIDENTIAL HMAC_SHA256_CTX ctx; - CONFIDENTIAL HMAC_SHA512_CTX sctx; - - const uint8_t *intermediate_result = seed; - int intermediate_result_len = seed_len; - do { - // STEP 1: derive a master secret like in BIP-32/SLIP-10 - hmac_sha512_Init(&sctx, (const uint8_t *)ED25519_SEED_NAME, - strlen(ED25519_SEED_NAME)); - hmac_sha512_Update(&sctx, intermediate_result, intermediate_result_len); - hmac_sha512_Final(&sctx, root_key); - - // STEP 2: check that the resulting key does not have a particular bit set, - // otherwise iterate like in SLIP-10 - intermediate_result = root_key; - intermediate_result_len = sizeof(root_key); - } while (root_key[31] & 0x20); - - // STEP 3: calculate the chain code as a HMAC-SHA256 of "\x01" + seed, - // key is "ed25519 seed" - hmac_sha256_Init(&ctx, (const unsigned char *)ED25519_SEED_NAME, - strlen(ED25519_SEED_NAME)); - hmac_sha256_Update(&ctx, (const unsigned char *)"\x01", 1); - hmac_sha256_Update(&ctx, seed, seed_len); - hmac_sha256_Final(&ctx, chain_code); - - // STEP 4: extract information into output - _Static_assert( - SHA512_DIGEST_LENGTH + SHA256_DIGEST_LENGTH == CARDANO_SECRET_LENGTH, - "Invalid configuration of Cardano secret size"); - memcpy(secret_out, root_key, SHA512_DIGEST_LENGTH); - memcpy(secret_out + SHA512_DIGEST_LENGTH, chain_code, SHA256_DIGEST_LENGTH); - - // STEP 5: tweak bits of the private key - cardano_ed25519_tweak_bits(secret_out); - - memzero(&ctx, sizeof(ctx)); - memzero(&sctx, sizeof(sctx)); - memzero(root_key, sizeof(root_key)); - memzero(chain_code, sizeof(chain_code)); - return 1; -} - -#define CARDANO_ICARUS_STEPS 32 -_Static_assert( - CARDANO_ICARUS_PBKDF2_ROUNDS % CARDANO_ICARUS_STEPS == 0, - "CARDANO_ICARUS_STEPS does not divide CARDANO_ICARUS_PBKDF2_ROUNDS"); -#define CARDANO_ICARUS_ROUNDS_PER_STEP \ - (CARDANO_ICARUS_PBKDF2_ROUNDS / CARDANO_ICARUS_STEPS) - -// Derives the root Cardano HDNode from a passphrase and the entropy encoded in -// a BIP-0039 mnemonic using the Icarus derivation scheme, aka V2 derivation -// scheme: -// https://github.com/cardano-foundation/CIPs/blob/09d7d8ee1bd64f7e6b20b5a6cae088039dce00cb/CIP-0003/Icarus.md -int secret_from_entropy_cardano_icarus( - const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH], - void (*progress_callback)(uint32_t, uint32_t)) { - CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx; - CONFIDENTIAL uint8_t digest[SHA512_DIGEST_LENGTH]; - uint32_t progress = 0; - - // PASS 1: first 64 bytes - pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 1); - if (progress_callback) { - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) { - pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); - if (progress_callback) { - progress += CARDANO_ICARUS_ROUNDS_PER_STEP; - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - } - pbkdf2_hmac_sha512_Final(&pctx, digest); - - memcpy(secret_out, digest, SHA512_DIGEST_LENGTH); - - // PASS 2: remaining 32 bytes - pbkdf2_hmac_sha512_Init(&pctx, pass, pass_len, entropy, entropy_len, 2); - if (progress_callback) { - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - for (int i = 0; i < CARDANO_ICARUS_STEPS; i++) { - pbkdf2_hmac_sha512_Update(&pctx, CARDANO_ICARUS_ROUNDS_PER_STEP); - if (progress_callback) { - progress += CARDANO_ICARUS_ROUNDS_PER_STEP; - progress_callback(progress, CARDANO_ICARUS_PBKDF2_ROUNDS * 2); - } - } - pbkdf2_hmac_sha512_Final(&pctx, digest); - - memcpy(secret_out + SHA512_DIGEST_LENGTH, digest, - CARDANO_SECRET_LENGTH - SHA512_DIGEST_LENGTH); - - cardano_ed25519_tweak_bits(secret_out); - - memzero(&pctx, sizeof(pctx)); - memzero(digest, sizeof(digest)); - return 1; -} - -#endif // USE_CARDANO diff --git a/trezor-crypto/crypto/chacha20poly1305/LICENSE b/trezor-crypto/crypto/chacha20poly1305/LICENSE deleted file mode 100644 index 95404966f07..00000000000 --- a/trezor-crypto/crypto/chacha20poly1305/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (C) 2016 Will Glozer - -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. diff --git a/trezor-crypto/crypto/chacha20poly1305/chacha20poly1305.c b/trezor-crypto/crypto/chacha20poly1305/chacha20poly1305.c deleted file mode 100644 index 514c452ffb7..00000000000 --- a/trezor-crypto/crypto/chacha20poly1305/chacha20poly1305.c +++ /dev/null @@ -1,60 +0,0 @@ -// Implementations of the XChaCha20 + Poly1305 and ChaCha20 + Poly1305 -// AEAD constructions with a goal of simplicity and correctness rather -// than performance. - -#include -#include - -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 = {0}; - - // 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); -} diff --git a/trezor-crypto/crypto/chacha20poly1305/chacha_merged.c b/trezor-crypto/crypto/chacha20poly1305/chacha_merged.c deleted file mode 100644 index 3819b865a59..00000000000 --- a/trezor-crypto/crypto/chacha20poly1305/chacha_merged.c +++ /dev/null @@ -1,253 +0,0 @@ -/* -chacha-merged.c version 20080118 -D. J. Bernstein -Public domain. -*/ - -#include -#include - -#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; -} - -// [wallet-core][non static] rename to avoid duplicate symbol in blake256.c -const char chacha_sigma[16] = "expand 32-byte k"; -const char tau[16] = "expand 16-byte k"; - -void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits) -{ - (void)ivbits; - const char *constants = (const char *)0; - - x->input[4] = U8TO32_LITTLE(k + 0); - x->input[5] = U8TO32_LITTLE(k + 4); - x->input[6] = U8TO32_LITTLE(k + 8); - x->input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = chacha_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_ctrsetup(ECRYPT_ctx *x,const u8 *ctr) -{ - x->input[12] = U8TO32_LITTLE(ctr + 0); - x->input[13] = U8TO32_LITTLE(ctr + 4); -} - -void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes) -{ - u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; - u32 j0 = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, j6 = 0, j7 = 0, j8 = 0, j9 = 0, j10 = 0, j11 = 0, j12 = 0, j13 = 0, j14 = 0, j15 = 0; - u8 *ctarget = 0; - u8 tmp[64] = {0}; - int i = 0; - - if (!bytes) return; - - j0 = x->input[0]; - j1 = x->input[1]; - j2 = x->input[2]; - j3 = x->input[3]; - j4 = x->input[4]; - j5 = x->input[5]; - j6 = x->input[6]; - j7 = x->input[7]; - j8 = x->input[8]; - j9 = x->input[9]; - j10 = x->input[10]; - j11 = x->input[11]; - j12 = x->input[12]; - j13 = x->input[13]; - j14 = x->input[14]; - j15 = x->input[15]; - - for (;;) { - if (bytes < 64) { - for (i = 0;i < (int)bytes;++i) tmp[i] = m[i]; - m = tmp; - ctarget = c; - c = tmp; - } - x0 = j0; - x1 = j1; - x2 = j2; - x3 = j3; - x4 = j4; - x5 = j5; - x6 = j6; - x7 = j7; - x8 = j8; - x9 = j9; - x10 = j10; - x11 = j11; - x12 = j12; - x13 = j13; - x14 = j14; - x15 = j15; - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - x0 = PLUS(x0,j0); - x1 = PLUS(x1,j1); - x2 = PLUS(x2,j2); - x3 = PLUS(x3,j3); - x4 = PLUS(x4,j4); - x5 = PLUS(x5,j5); - x6 = PLUS(x6,j6); - x7 = PLUS(x7,j7); - x8 = PLUS(x8,j8); - x9 = PLUS(x9,j9); - x10 = PLUS(x10,j10); - x11 = PLUS(x11,j11); - x12 = PLUS(x12,j12); - x13 = PLUS(x13,j13); - x14 = PLUS(x14,j14); - x15 = PLUS(x15,j15); - - x0 = XOR(x0,U8TO32_LITTLE(m + 0)); - x1 = XOR(x1,U8TO32_LITTLE(m + 4)); - x2 = XOR(x2,U8TO32_LITTLE(m + 8)); - x3 = XOR(x3,U8TO32_LITTLE(m + 12)); - x4 = XOR(x4,U8TO32_LITTLE(m + 16)); - x5 = XOR(x5,U8TO32_LITTLE(m + 20)); - x6 = XOR(x6,U8TO32_LITTLE(m + 24)); - x7 = XOR(x7,U8TO32_LITTLE(m + 28)); - x8 = XOR(x8,U8TO32_LITTLE(m + 32)); - x9 = XOR(x9,U8TO32_LITTLE(m + 36)); - x10 = XOR(x10,U8TO32_LITTLE(m + 40)); - x11 = XOR(x11,U8TO32_LITTLE(m + 44)); - x12 = XOR(x12,U8TO32_LITTLE(m + 48)); - x13 = XOR(x13,U8TO32_LITTLE(m + 52)); - x14 = XOR(x14,U8TO32_LITTLE(m + 56)); - x15 = XOR(x15,U8TO32_LITTLE(m + 60)); - - j12 = PLUSONE(j12); - if (!j12) { - j13 = PLUSONE(j13); - /* stopping at 2^70 bytes per nonce is user's responsibility */ - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x4); - U32TO8_LITTLE(c + 20,x5); - U32TO8_LITTLE(c + 24,x6); - U32TO8_LITTLE(c + 28,x7); - U32TO8_LITTLE(c + 32,x8); - U32TO8_LITTLE(c + 36,x9); - U32TO8_LITTLE(c + 40,x10); - U32TO8_LITTLE(c + 44,x11); - U32TO8_LITTLE(c + 48,x12); - U32TO8_LITTLE(c + 52,x13); - U32TO8_LITTLE(c + 56,x14); - U32TO8_LITTLE(c + 60,x15); - - if (bytes <= 64) { - if (bytes < 64) { - for (i = 0;i < (int)bytes;++i) ctarget[i] = c[i]; - } - x->input[12] = j12; - x->input[13] = j13; - return; - } - 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 = 0; - for (i = 0;i < bytes;++i) stream[i] = 0; - ECRYPT_encrypt_bytes(x,stream,stream,bytes); -} - -void hchacha20(ECRYPT_ctx *x,u8 *c) -{ - u32 x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0; - int i = 0; - - x0 = x->input[0]; - x1 = x->input[1]; - x2 = x->input[2]; - x3 = x->input[3]; - x4 = x->input[4]; - x5 = x->input[5]; - x6 = x->input[6]; - x7 = x->input[7]; - x8 = x->input[8]; - x9 = x->input[9]; - x10 = x->input[10]; - x11 = x->input[11]; - x12 = x->input[12]; - x13 = x->input[13]; - x14 = x->input[14]; - x15 = x->input[15]; - - for (i = 20;i > 0;i -= 2) { - QUARTERROUND( x0, x4, x8,x12) - QUARTERROUND( x1, x5, x9,x13) - QUARTERROUND( x2, x6,x10,x14) - QUARTERROUND( x3, x7,x11,x15) - QUARTERROUND( x0, x5,x10,x15) - QUARTERROUND( x1, x6,x11,x12) - QUARTERROUND( x2, x7, x8,x13) - QUARTERROUND( x3, x4, x9,x14) - } - - U32TO8_LITTLE(c + 0,x0); - U32TO8_LITTLE(c + 4,x1); - U32TO8_LITTLE(c + 8,x2); - U32TO8_LITTLE(c + 12,x3); - U32TO8_LITTLE(c + 16,x12); - U32TO8_LITTLE(c + 20,x13); - U32TO8_LITTLE(c + 24,x14); - U32TO8_LITTLE(c + 28,x15); -} diff --git a/trezor-crypto/crypto/chacha20poly1305/poly1305-donna.c b/trezor-crypto/crypto/chacha20poly1305/poly1305-donna.c deleted file mode 100644 index 682a2ca5443..00000000000 --- a/trezor-crypto/crypto/chacha20poly1305/poly1305-donna.c +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include - -void -poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - size_t i = 0; - - /* handle leftover */ - if (st->leftover) { - size_t want = (poly1305_block_size - st->leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - st->buffer[st->leftover + i] = m[i]; - bytes -= want; - m += want; - st->leftover += want; - if (st->leftover < poly1305_block_size) - return; - poly1305_blocks(st, st->buffer, poly1305_block_size); - st->leftover = 0; - } - - /* process full blocks */ - if (bytes >= poly1305_block_size) { - size_t want = (bytes & ~(poly1305_block_size - 1)); - poly1305_blocks(st, m, want); - m += want; - bytes -= want; - } - - /* store leftover */ - if (bytes) { - for (i = 0; i < bytes; i++) - st->buffer[st->leftover + i] = m[i]; - st->leftover += bytes; - } -} - -void -poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]) { - poly1305_context ctx = {0}; - poly1305_init(&ctx, key); - poly1305_update(&ctx, m, bytes); - poly1305_finish(&ctx, mac); -} - -int -poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]) { - size_t i = 0; - unsigned int dif = 0; - for (i = 0; i < 16; i++) - dif |= (mac1[i] ^ mac2[i]); - dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1); - return (dif & 1); -} - - -/* test a few basic operations */ -int -poly1305_power_on_self_test(void) { - /* example from nacl */ - 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, - }; - - 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 - }; - - 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 */ - 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, - }; - - const unsigned char wrap_msg[16] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff - }; - - 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 - */ - 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 - }; - - const unsigned char total_mac[16] = { - 0x64,0xaf,0xe2,0xe8,0xd6,0xad,0x7b,0xbd, - 0xd2,0x87,0xf9,0x7c,0x44,0x62,0x3d,0x39 - }; - - poly1305_context ctx = {0}; - poly1305_context total_ctx = {0}; - unsigned char all_key[32] = {0}; - unsigned char all_msg[256] = {0}; - unsigned char mac[16] = {0}; - size_t i = 0, j = 0; - int result = 1; - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key); - result &= poly1305_verify(nacl_mac, mac); - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_init(&ctx, nacl_key); - poly1305_update(&ctx, nacl_msg + 0, 32); - poly1305_update(&ctx, nacl_msg + 32, 64); - poly1305_update(&ctx, nacl_msg + 96, 16); - poly1305_update(&ctx, nacl_msg + 112, 8); - poly1305_update(&ctx, nacl_msg + 120, 4); - poly1305_update(&ctx, nacl_msg + 124, 2); - poly1305_update(&ctx, nacl_msg + 126, 1); - poly1305_update(&ctx, nacl_msg + 127, 1); - poly1305_update(&ctx, nacl_msg + 128, 1); - poly1305_update(&ctx, nacl_msg + 129, 1); - poly1305_update(&ctx, nacl_msg + 130, 1); - poly1305_finish(&ctx, mac); - result &= poly1305_verify(nacl_mac, mac); - - for (i = 0; i < sizeof(mac); i++) - mac[i] = 0; - poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key); - result &= poly1305_verify(wrap_mac, mac); - - poly1305_init(&total_ctx, total_key); - for (i = 0; i < 256; i++) { - /* set key and message to 'i,i,i..' */ - for (j = 0; j < sizeof(all_key); j++) - all_key[j] = i; - for (j = 0; j < i; j++) - all_msg[j] = i; - poly1305_auth(mac, all_msg, i, all_key); - poly1305_update(&total_ctx, mac, 16); - } - poly1305_finish(&total_ctx, mac); - result &= poly1305_verify(total_mac, mac); - - return result; -} diff --git a/trezor-crypto/crypto/chacha20poly1305/rfc7539.c b/trezor-crypto/crypto/chacha20poly1305/rfc7539.c deleted file mode 100644 index aa6c1ab6f3e..00000000000 --- a/trezor-crypto/crypto/chacha20poly1305/rfc7539.c +++ /dev/null @@ -1,48 +0,0 @@ -// Implementation of the ChaCha20 + Poly1305 AEAD construction -// as described in RFC 7539. - -#include -#include -#include - -// 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); -} diff --git a/trezor-crypto/crypto/chacha_drbg.c b/trezor-crypto/crypto/chacha_drbg.c deleted file mode 100644 index e8027ffe939..00000000000 --- a/trezor-crypto/crypto/chacha_drbg.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of the Trezor project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include -#include -#include - -#include -#include -#include - -#define CHACHA_DRBG_KEY_LENGTH 32 -#define CHACHA_DRBG_COUNTER_LENGTH 8 -#define CHACHA_DRBG_IV_LENGTH 8 -#define CHACHA_DRBG_SEED_LENGTH \ - (CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH + CHACHA_DRBG_IV_LENGTH) - -#define MAX(a, b) (a) > (b) ? (a) : (b) - -static void derivation_function(const uint8_t *input1, size_t input1_length, - const uint8_t *input2, size_t input2_length, - uint8_t *output, size_t output_length) { - // Implementation of Hash_df from NIST SP 800-90A - uint32_t block_count = (output_length - 1) / SHA256_DIGEST_LENGTH + 1; - size_t partial_block_length = output_length % SHA256_DIGEST_LENGTH; - assert(block_count <= 255); - - uint32_t output_length_bits = output_length * 8; -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(output_length_bits, output_length_bits); -#endif - - SHA256_CTX ctx = {0}; - - for (uint8_t counter = 1; counter <= block_count; counter++) { - sha256_Init(&ctx); - sha256_Update(&ctx, &counter, sizeof(counter)); - sha256_Update(&ctx, (uint8_t *)&output_length_bits, - sizeof(output_length_bits)); - sha256_Update(&ctx, input1, input1_length); - sha256_Update(&ctx, input2, input2_length); - - if (counter != block_count || partial_block_length == 0) { - sha256_Final(&ctx, output); - output += SHA256_DIGEST_LENGTH; - } else { // last block is partial - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - sha256_Final(&ctx, digest); - memcpy(output, digest, partial_block_length); - memzero(digest, sizeof(digest)); - } - } - - memzero(&ctx, sizeof(ctx)); -} - -void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *nonce, - size_t nonce_length) { - uint8_t buffer[MAX(CHACHA_DRBG_KEY_LENGTH, CHACHA_DRBG_IV_LENGTH)] = {0}; - ECRYPT_keysetup(&ctx->chacha_ctx, buffer, CHACHA_DRBG_KEY_LENGTH * 8, - CHACHA_DRBG_IV_LENGTH * 8); - ECRYPT_ivsetup(&ctx->chacha_ctx, buffer); - - chacha_drbg_reseed(ctx, entropy, entropy_length, nonce, nonce_length); -} - -static void chacha_drbg_update(CHACHA_DRBG_CTX *ctx, - const uint8_t data[CHACHA_DRBG_SEED_LENGTH]) { - uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; - - if (data) - ECRYPT_encrypt_bytes(&ctx->chacha_ctx, data, seed, CHACHA_DRBG_SEED_LENGTH); - else - ECRYPT_keystream_bytes(&ctx->chacha_ctx, seed, CHACHA_DRBG_SEED_LENGTH); - - ECRYPT_keysetup(&ctx->chacha_ctx, seed, CHACHA_DRBG_KEY_LENGTH * 8, - CHACHA_DRBG_IV_LENGTH * 8); - - ECRYPT_ivsetup(&ctx->chacha_ctx, - seed + CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_COUNTER_LENGTH); - - ECRYPT_ctrsetup(&ctx->chacha_ctx, seed + CHACHA_DRBG_KEY_LENGTH); - - memzero(seed, sizeof(seed)); -} - -void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, - size_t output_length) { - assert(output_length < 65536); - assert(ctx->reseed_counter + 1 != 0); - - ECRYPT_keystream_bytes(&ctx->chacha_ctx, output, output_length); - chacha_drbg_update(ctx, NULL); - ctx->reseed_counter++; -} - -void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *additional_input, - size_t additional_input_length) { - uint8_t seed[CHACHA_DRBG_SEED_LENGTH] = {0}; - derivation_function(entropy, entropy_length, additional_input, - additional_input_length, seed, sizeof(seed)); - chacha_drbg_update(ctx, seed); - memzero(seed, sizeof(seed)); - - ctx->reseed_counter = 1; -} diff --git a/trezor-crypto/crypto/curves.c b/trezor-crypto/crypto/curves.c deleted file mode 100644 index a6221a9943f..00000000000 --- a/trezor-crypto/crypto/curves.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 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 -#include - -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_SEED_NAME[] = "ed25519 seed"; -#if USE_CARDANO -const char ED25519_CARDANO_NAME[] = "ed25519 cardano seed"; -#endif -const char ED25519_SHA3_NAME[] = "ed25519-sha3"; -#if USE_KECCAK -const char ED25519_KECCAK_NAME[] = "ed25519-keccak"; -#endif -const char CURVE25519_NAME[] = "curve25519"; - -const char ED25519_BLAKE2B_NANO_NAME[] = "ed25519-blake2b-nano"; // [wallet-core] diff --git a/trezor-crypto/crypto/ecdsa.c b/trezor-crypto/crypto/ecdsa.c deleted file mode 100644 index 445f29aa549..00000000000 --- a/trezor-crypto/crypto/ecdsa.c +++ /dev/null @@ -1,1251 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * Copyright (c) 2015 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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Set cp2 = cp1 -void point_copy(const curve_point *cp1, curve_point *cp2) { *cp2 = *cp1; } - -// cp2 = cp1 + cp2 -void point_add(const ecdsa_curve *curve, const curve_point *cp1, - curve_point *cp2) { - bignum256 lambda = {0}, inv = {0}, xr = {0}, yr = {0}; - - if (point_is_infinity(cp1)) { - return; - } - if (point_is_infinity(cp2)) { - point_copy(cp1, cp2); - return; - } - if (point_is_equal(cp1, cp2)) { - point_double(curve, cp2); - return; - } - if (point_is_negative_of(cp1, cp2)) { - point_set_infinity(cp2); - return; - } - - // lambda = (y2 - y1) / (x2 - x1) - bn_subtractmod(&(cp2->x), &(cp1->x), &inv, &curve->prime); - bn_inverse(&inv, &curve->prime); - bn_subtractmod(&(cp2->y), &(cp1->y), &lambda, &curve->prime); - bn_multiply(&inv, &lambda, &curve->prime); - - // xr = lambda^2 - x1 - x2 - xr = lambda; - bn_multiply(&xr, &xr, &curve->prime); - yr = cp1->x; - bn_addmod(&yr, &(cp2->x), &curve->prime); - bn_subtractmod(&xr, &yr, &xr, &curve->prime); - bn_fast_mod(&xr, &curve->prime); - bn_mod(&xr, &curve->prime); - - // yr = lambda (x1 - xr) - y1 - bn_subtractmod(&(cp1->x), &xr, &yr, &curve->prime); - bn_multiply(&lambda, &yr, &curve->prime); - bn_subtractmod(&yr, &(cp1->y), &yr, &curve->prime); - bn_fast_mod(&yr, &curve->prime); - bn_mod(&yr, &curve->prime); - - cp2->x = xr; - cp2->y = yr; -} - -// cp = cp + cp -void point_double(const ecdsa_curve *curve, curve_point *cp) { - bignum256 lambda = {0}, xr = {0}, yr = {0}; - - if (point_is_infinity(cp)) { - return; - } - if (bn_is_zero(&(cp->y))) { - point_set_infinity(cp); - return; - } - - // lambda = (3 x^2 + a) / (2 y) - lambda = cp->y; - bn_mult_k(&lambda, 2, &curve->prime); - bn_fast_mod(&lambda, &curve->prime); - bn_mod(&lambda, &curve->prime); - bn_inverse(&lambda, &curve->prime); - - xr = cp->x; - bn_multiply(&xr, &xr, &curve->prime); - bn_mult_k(&xr, 3, &curve->prime); - bn_subi(&xr, -curve->a, &curve->prime); - bn_multiply(&xr, &lambda, &curve->prime); - - // xr = lambda^2 - 2*x - xr = lambda; - bn_multiply(&xr, &xr, &curve->prime); - yr = cp->x; - bn_lshift(&yr); - bn_subtractmod(&xr, &yr, &xr, &curve->prime); - bn_fast_mod(&xr, &curve->prime); - bn_mod(&xr, &curve->prime); - - // yr = lambda (x - xr) - y - bn_subtractmod(&(cp->x), &xr, &yr, &curve->prime); - bn_multiply(&lambda, &yr, &curve->prime); - bn_subtractmod(&yr, &(cp->y), &yr, &curve->prime); - bn_fast_mod(&yr, &curve->prime); - bn_mod(&yr, &curve->prime); - - cp->x = xr; - cp->y = yr; -} - -// set point to internal representation of point at infinity -void point_set_infinity(curve_point *p) { - bn_zero(&(p->x)); - bn_zero(&(p->y)); -} - -// return true iff p represent point at infinity -// both coords are zero in internal representation -int point_is_infinity(const curve_point *p) { - return bn_is_zero(&(p->x)) && bn_is_zero(&(p->y)); -} - -// return true iff both points are equal -int point_is_equal(const curve_point *p, const curve_point *q) { - return bn_is_equal(&(p->x), &(q->x)) && bn_is_equal(&(p->y), &(q->y)); -} - -// returns true iff p == -q -// expects p and q be valid points on curve other than point at infinity -int point_is_negative_of(const curve_point *p, const curve_point *q) { - // if P == (x, y), then -P would be (x, -y) on this curve - if (!bn_is_equal(&(p->x), &(q->x))) { - return 0; - } - - // we shouldn't hit this for a valid point - if (bn_is_zero(&(p->y))) { - return 0; - } - - return !bn_is_equal(&(p->y), &(q->y)); -} - -typedef struct jacobian_curve_point { - bignum256 x, y, z; -} jacobian_curve_point; - -// generate random K for signing/side-channel noise -static void generate_k_random(bignum256 *k, const bignum256 *prime) { - do { - int i = 0; - for (i = 0; i < 8; i++) { - k->val[i] = random32() & ((1u << BN_BITS_PER_LIMB) - 1); - } - k->val[8] = random32() & ((1u << BN_BITS_LAST_LIMB) - 1); - // check that k is in range and not zero. - } while (bn_is_zero(k) || !bn_is_less(k, prime)); -} - -void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp, - const bignum256 *prime) { - // randomize z coordinate - generate_k_random(&jp->z, prime); - - jp->x = jp->z; - bn_multiply(&jp->z, &jp->x, prime); - // x = z^2 - jp->y = jp->x; - bn_multiply(&jp->z, &jp->y, prime); - // y = z^3 - - bn_multiply(&p->x, &jp->x, prime); - bn_multiply(&p->y, &jp->y, prime); -} - -void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p, - const bignum256 *prime) { - p->y = jp->z; - bn_inverse(&p->y, prime); - // p->y = z^-1 - p->x = p->y; - bn_multiply(&p->x, &p->x, prime); - // p->x = z^-2 - bn_multiply(&p->x, &p->y, prime); - // p->y = z^-3 - bn_multiply(&jp->x, &p->x, prime); - // p->x = jp->x * z^-2 - bn_multiply(&jp->y, &p->y, prime); - // p->y = jp->y * z^-3 - bn_mod(&p->x, prime); - bn_mod(&p->y, prime); -} - -void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, - const ecdsa_curve *curve) { - bignum256 r = {0}, h = {0}, r2 = {0}; - bignum256 hcby = {0}, hsqx = {0}; - bignum256 xz = {0}, yz = {0}, az = {0}; - int is_doubling = 0; - const bignum256 *prime = &curve->prime; - int a = curve->a; - - assert(-3 <= a && a <= 0); - - /* First we bring p1 to the same denominator: - * x1' := x1 * z2^2 - * y1' := y1 * z2^3 - */ - /* - * lambda = ((y1' - y2)/z2^3) / ((x1' - x2)/z2^2) - * = (y1' - y2) / (x1' - x2) z2 - * x3/z3^2 = lambda^2 - (x1' + x2)/z2^2 - * y3/z3^3 = 1/2 lambda * (2x3/z3^2 - (x1' + x2)/z2^2) + (y1'+y2)/z2^3 - * - * For the special case x1=x2, y1=y2 (doubling) we have - * lambda = 3/2 ((x2/z2^2)^2 + a) / (y2/z2^3) - * = 3/2 (x2^2 + a*z2^4) / y2*z2) - * - * to get rid of fraction we write lambda as - * lambda = r / (h*z2) - * with r = is_doubling ? 3/2 x2^2 + az2^4 : (y1 - y2) - * h = is_doubling ? y1+y2 : (x1 - x2) - * - * With z3 = h*z2 (the denominator of lambda) - * we get x3 = lambda^2*z3^2 - (x1' + x2)/z2^2*z3^2 - * = r^2 - h^2 * (x1' + x2) - * and y3 = 1/2 r * (2x3 - h^2*(x1' + x2)) + h^3*(y1' + y2) - */ - - /* h = x1 - x2 - * r = y1 - y2 - * x3 = r^2 - h^3 - 2*h^2*x2 - * y3 = r*(h^2*x2 - x3) - h^3*y2 - * z3 = h*z2 - */ - - xz = p2->z; - bn_multiply(&xz, &xz, prime); // xz = z2^2 - yz = p2->z; - bn_multiply(&xz, &yz, prime); // yz = z2^3 - - if (a != 0) { - az = xz; - bn_multiply(&az, &az, prime); // az = z2^4 - bn_mult_k(&az, -a, prime); // az = -az2^4 - } - - bn_multiply(&p1->x, &xz, prime); // xz = x1' = x1*z2^2; - h = xz; - bn_subtractmod(&h, &p2->x, &h, prime); - bn_fast_mod(&h, prime); - // h = x1' - x2; - - bn_add(&xz, &p2->x); - // xz = x1' + x2 - - // check for h == 0 % prime. Note that h never normalizes to - // zero, since h = x1' + 2*prime - x2 > 0 and a positive - // multiple of prime is always normalized to prime by - // bn_fast_mod. - is_doubling = bn_is_equal(&h, prime); - - bn_multiply(&p1->y, &yz, prime); // yz = y1' = y1*z2^3; - bn_subtractmod(&yz, &p2->y, &r, prime); - // r = y1' - y2; - - bn_add(&yz, &p2->y); - // yz = y1' + y2 - - r2 = p2->x; - bn_multiply(&r2, &r2, prime); - bn_mult_k(&r2, 3, prime); - - if (a != 0) { - // subtract -a z2^4, i.e, add a z2^4 - bn_subtractmod(&r2, &az, &r2, prime); - } - bn_cmov(&r, is_doubling, &r2, &r); - bn_cmov(&h, is_doubling, &yz, &h); - - // hsqx = h^2 - hsqx = h; - bn_multiply(&hsqx, &hsqx, prime); - - // hcby = h^3 - hcby = h; - bn_multiply(&hsqx, &hcby, prime); - - // hsqx = h^2 * (x1 + x2) - bn_multiply(&xz, &hsqx, prime); - - // hcby = h^3 * (y1 + y2) - bn_multiply(&yz, &hcby, prime); - - // z3 = h*z2 - bn_multiply(&h, &p2->z, prime); - - // x3 = r^2 - h^2 (x1 + x2) - p2->x = r; - bn_multiply(&p2->x, &p2->x, prime); - bn_subtractmod(&p2->x, &hsqx, &p2->x, prime); - bn_fast_mod(&p2->x, prime); - - // y3 = 1/2 (r*(h^2 (x1 + x2) - 2x3) - h^3 (y1 + y2)) - bn_subtractmod(&hsqx, &p2->x, &p2->y, prime); - bn_subtractmod(&p2->y, &p2->x, &p2->y, prime); - bn_multiply(&r, &p2->y, prime); - bn_subtractmod(&p2->y, &hcby, &p2->y, prime); - bn_mult_half(&p2->y, prime); - bn_fast_mod(&p2->y, prime); -} - -void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) { - bignum256 az4 = {0}, m = {0}, msq = {0}, ysq = {0}, xysq = {0}; - const bignum256 *prime = &curve->prime; - - assert(-3 <= curve->a && curve->a <= 0); - /* usual algorithm: - * - * lambda = (3((x/z^2)^2 + a) / 2y/z^3) = (3x^2 + az^4)/2yz - * x3/z3^2 = lambda^2 - 2x/z^2 - * y3/z3^3 = lambda * (x/z^2 - x3/z3^2) - y/z^3 - * - * to get rid of fraction we set - * m = (3 x^2 + az^4) / 2 - * Hence, - * lambda = m / yz = m / z3 - * - * With z3 = yz (the denominator of lambda) - * we get x3 = lambda^2*z3^2 - 2*x/z^2*z3^2 - * = m^2 - 2*xy^2 - * and y3 = (lambda * (x/z^2 - x3/z3^2) - y/z^3) * z3^3 - * = m * (xy^2 - x3) - y^4 - */ - - /* m = (3*x^2 + a z^4) / 2 - * x3 = m^2 - 2*xy^2 - * y3 = m*(xy^2 - x3) - 8y^4 - * z3 = y*z - */ - - m = p->x; - bn_multiply(&m, &m, prime); - bn_mult_k(&m, 3, prime); - - az4 = p->z; - bn_multiply(&az4, &az4, prime); - bn_multiply(&az4, &az4, prime); - bn_mult_k(&az4, -curve->a, prime); - bn_subtractmod(&m, &az4, &m, prime); - bn_mult_half(&m, prime); - - // msq = m^2 - msq = m; - bn_multiply(&msq, &msq, prime); - // ysq = y^2 - ysq = p->y; - bn_multiply(&ysq, &ysq, prime); - // xysq = xy^2 - xysq = p->x; - bn_multiply(&ysq, &xysq, prime); - - // z3 = yz - bn_multiply(&p->y, &p->z, prime); - - // x3 = m^2 - 2*xy^2 - p->x = xysq; - bn_lshift(&p->x); - bn_fast_mod(&p->x, prime); - bn_subtractmod(&msq, &p->x, &p->x, prime); - bn_fast_mod(&p->x, prime); - - // y3 = m*(xy^2 - x3) - y^4 - bn_subtractmod(&xysq, &p->x, &p->y, prime); - bn_multiply(&m, &p->y, prime); - bn_multiply(&ysq, &ysq, prime); - bn_subtractmod(&p->y, &ysq, &p->y, prime); - bn_fast_mod(&p->y, prime); -} - -// res = k * p -// returns 0 on success -int point_multiply(const ecdsa_curve *curve, const bignum256 *k, - const curve_point *p, curve_point *res) { - // this algorithm is loosely based on - // Katsuyuki Okeya and Tsuyoshi Takagi, The Width-w NAF Method Provides - // Small Memory and Fast Elliptic Scalar Multiplications Secure against - // Side Channel Attacks. - if (!bn_is_less(k, &curve->order)) { - return 1; - } - - int i = 0, j = 0; - CONFIDENTIAL bignum256 a; - uint32_t *aptr = NULL; - uint32_t abits = 0; - int ashift = 0; - uint32_t is_even = (k->val[0] & 1) - 1; - uint32_t bits = {0}, sign = {0}, nsign = {0}; - CONFIDENTIAL jacobian_curve_point jres; - curve_point pmult[8] = {0}; - const bignum256 *prime = &curve->prime; - - // is_even = 0xffffffff if k is even, 0 otherwise. - - // add 2^256. - // make number odd: subtract curve->order if even - uint32_t tmp = 1; - uint32_t is_non_zero = 0; - for (j = 0; j < 8; j++) { - is_non_zero |= k->val[j]; - tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); - a.val[j] = tmp & (BN_BASE - 1); - tmp >>= BN_BITS_PER_LIMB; - } - is_non_zero |= k->val[j]; - a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); - assert((a.val[0] & 1) != 0); - - // special case 0*p: just return zero. We don't care about constant time. - if (!is_non_zero) { - point_set_infinity(res); - return 1; - } - - // Now a = k + 2^256 (mod curve->order) and a is odd. - // - // The idea is to bring the new a into the form. - // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. - // a[0] is odd, since a is odd. If a[i] would be even, we can - // add 1 to it and subtract 16 from a[i-1]. Afterwards, - // a[64] = 1, which is the 2^256 that we added before. - // - // Since k = a - 2^256 (mod curve->order), we can compute - // k*p = sum_{i=0..63} a[i] 16^i * p - // - // We compute |a[i]| * p in advance for all possible - // values of |a[i]| * p. pmult[i] = (2*i+1) * p - // We compute p, 3*p, ..., 15*p and store it in the table pmult. - // store p^2 temporarily in pmult[7] - pmult[7] = *p; - point_double(curve, &pmult[7]); - // compute 3*p, etc by repeatedly adding p^2. - pmult[0] = *p; - for (i = 1; i < 8; i++) { - pmult[i] = pmult[7]; - point_add(curve, &pmult[i - 1], &pmult[i]); - } - - // now compute res = sum_{i=0..63} a[i] * 16^i * p step by step, - // starting with i = 63. - // initialize jres = |a[63]| * p. - // Note that a[i] = a>>(4*i) & 0xf if (a&0x10) != 0 - // and - (16 - (a>>(4*i) & 0xf)) otherwise. We can compute this as - // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 - // since a is odd. - aptr = &a.val[8]; - abits = *aptr; - ashift = 256 - (BN_BITS_PER_LIMB * 8) - 4; - bits = abits >> ashift; - sign = (bits >> 4) - 1; - bits ^= sign; - bits &= 15; - curve_to_jacobian(&pmult[bits >> 1], &jres, prime); - for (i = 62; i >= 0; i--) { - // sign = sign(a[i+1]) (0xffffffff for negative, 0 for positive) - // invariant jres = (-1)^sign sum_{j=i+1..63} (a[j] * 16^{j-i-1} * p) - // abits >> (ashift - 4) = lowbits(a >> (i*4)) - - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - point_jacobian_double(&jres, curve); - - // get lowest 5 bits of a >> (i*4). - ashift -= 4; - if (ashift < 0) { - // the condition only depends on the iteration number and - // leaks no private information to a side-channel. - bits = abits << (-ashift); - abits = *(--aptr); - ashift += BN_BITS_PER_LIMB; - bits |= abits >> ashift; - } else { - bits = abits >> ashift; - } - bits &= 31; - nsign = (bits >> 4) - 1; - bits ^= nsign; - bits &= 15; - - // negate last result to make signs of this round and the - // last round equal. - bn_cnegate((sign ^ nsign) & 1, &jres.z, prime); - - // add odd factor - point_jacobian_add(&pmult[bits >> 1], &jres, curve); - sign = nsign; - } - bn_cnegate(sign & 1, &jres.z, prime); - jacobian_to_curve(&jres, res, prime); - memzero(&a, sizeof(a)); - memzero(&jres, sizeof(jres)); - - return 0; -} - -#if USE_PRECOMPUTED_CP - -// res = k * G -// k must be a normalized number with 0 <= k < curve->order -// returns 0 on success -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res) { - if (!bn_is_less(k, &curve->order)) { - return 1; - } - - int i = {0}, j = {0}; - CONFIDENTIAL bignum256 a; - uint32_t is_even = (k->val[0] & 1) - 1; - uint32_t lowbits = 0; - CONFIDENTIAL jacobian_curve_point jres; - const bignum256 *prime = &curve->prime; - - // is_even = 0xffffffff if k is even, 0 otherwise. - - // add 2^256. - // make number odd: subtract curve->order if even - uint32_t tmp = 1; - uint32_t is_non_zero = 0; - for (j = 0; j < 8; j++) { - is_non_zero |= k->val[j]; - tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even); - a.val[j] = tmp & (BN_BASE - 1); - tmp >>= BN_BITS_PER_LIMB; - } - is_non_zero |= k->val[j]; - a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even); - assert((a.val[0] & 1) != 0); - - // special case 0*G: just return zero. We don't care about constant time. - if (!is_non_zero) { - point_set_infinity(res); - return 0; - } - - // Now a = k + 2^256 (mod curve->order) and a is odd. - // - // The idea is to bring the new a into the form. - // sum_{i=0..64} a[i] 16^i, where |a[i]| < 16 and a[i] is odd. - // a[0] is odd, since a is odd. If a[i] would be even, we can - // add 1 to it and subtract 16 from a[i-1]. Afterwards, - // a[64] = 1, which is the 2^256 that we added before. - // - // Since k = a - 2^256 (mod curve->order), we can compute - // k*G = sum_{i=0..63} a[i] 16^i * G - // - // We have a big table curve->cp that stores all possible - // values of |a[i]| 16^i * G. - // curve->cp[i][j] = (2*j+1) * 16^i * G - - // now compute res = sum_{i=0..63} a[i] * 16^i * G step by step. - // initial res = |a[0]| * G. Note that a[0] = a & 0xf if (a&0x10) != 0 - // and - (16 - (a & 0xf)) otherwise. We can compute this as - // ((a ^ (((a >> 4) & 1) - 1)) & 0xf) >> 1 - // since a is odd. - lowbits = a.val[0] & ((1 << 5) - 1); - lowbits ^= (lowbits >> 4) - 1; - lowbits &= 15; - curve_to_jacobian(&curve->cp[0][lowbits >> 1], &jres, prime); - for (i = 1; i < 64; i++) { - // invariant res = sign(a[i-1]) sum_{j=0..i-1} (a[j] * 16^j * G) - - // shift a by 4 places. - for (j = 0; j < 8; j++) { - a.val[j] = - (a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << (BN_BITS_PER_LIMB - 4)); - } - a.val[j] >>= 4; - // a = old(a)>>(4*i) - // a is even iff sign(a[i-1]) = -1 - - lowbits = a.val[0] & ((1 << 5) - 1); - lowbits ^= (lowbits >> 4) - 1; - lowbits &= 15; - // negate last result to make signs of this round and the - // last round equal. - bn_cnegate(~lowbits & 1, &jres.y, prime); - - // add odd factor - point_jacobian_add(&curve->cp[i][lowbits >> 1], &jres, curve); - } - bn_cnegate(~(a.val[0] >> 4) & 1, &jres.y, prime); - jacobian_to_curve(&jres, res, prime); - memzero(&a, sizeof(a)); - memzero(&jres, sizeof(jres)); - - return 0; -} - -#else - -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res) { - return point_multiply(curve, k, &curve->G, res); -} - -#endif - -int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *pub_key, uint8_t *session_key) { - curve_point point = {0}; - if (!ecdsa_read_pubkey(curve, pub_key, &point)) { - return 1; - } - - bignum256 k = {0}; - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - return 2; - } - - point_multiply(curve, &k, &point, &point); - memzero(&k, sizeof(k)); - - session_key[0] = 0x04; - bn_write_be(&point.x, session_key + 1); - bn_write_be(&point.y, session_key + 33); - memzero(&point, sizeof(point)); - - return 0; -} - -// msg is a data to be signed -// msg_len is the message length -int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, - uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])) { - uint8_t hash[32] = {0}; - hasher_Raw(hasher_sign, msg, msg_len, hash); - int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical); - memzero(hash, sizeof(hash)); - return res; -} - -// uses secp256k1 curve -// priv_key is a 32 byte big endian stored number -// sig is 64 bytes long array for the signature -// digest is 32 bytes of digest -// is_canonical is an optional function that checks if the signature -// conforms to additional coin-specific rules. -int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *digest, uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])) { - int i = 0; - curve_point R = {0}; - bignum256 k = {0}, z = {0}, randk = {0}; - bignum256 *s = &R.y; - uint8_t by; // signature recovery byte - -#if USE_RFC6979 - rfc6979_state rng = {0}; - init_rfc6979(priv_key, digest, curve, &rng); -#endif - - bn_read_be(digest, &z); - if (bn_is_zero(&z)) { - // The probability of the digest being all-zero by chance is infinitesimal, - // so this is most likely an indication of a bug. Furthermore, the signature - // has no value, because in this case it can be easily forged for any public - // key, see ecdsa_verify_digest(). - return 1; - } - - for (i = 0; i < 10000; i++) { -#if USE_RFC6979 - // generate K deterministically - generate_k_rfc6979(&k, &rng); - // if k is too big or too small, we don't like it - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - continue; - } -#else - // generate random number k - generate_k_random(&k, &curve->order); -#endif - - // compute k*G - scalar_multiply(curve, &k, &R); - by = R.y.val[0] & 1; - // r = (rx mod n) - if (!bn_is_less(&R.x, &curve->order)) { - bn_subtract(&R.x, &curve->order, &R.x); - by |= 2; - } - // if r is zero, we retry - if (bn_is_zero(&R.x)) { - continue; - } - - bn_read_be(priv_key, s); - if (bn_is_zero(s) || !bn_is_less(s, &curve->order)) { - // Invalid private key. - return 2; - } - - // randomize operations to counter side-channel attacks - generate_k_random(&randk, &curve->order); - bn_multiply(&randk, &k, &curve->order); // k*rand - bn_inverse(&k, &curve->order); // (k*rand)^-1 - bn_multiply(&R.x, s, &curve->order); // R.x*priv - bn_add(s, &z); // R.x*priv + z - bn_multiply(&k, s, &curve->order); // (k*rand)^-1 (R.x*priv + z) - bn_multiply(&randk, s, &curve->order); // k^-1 (R.x*priv + z) - bn_mod(s, &curve->order); - // if s is zero, we retry - if (bn_is_zero(s)) { - continue; - } - - // if S > order/2 => S = -S - if (bn_is_less(&curve->order_half, s)) { - bn_subtract(&curve->order, s, s); - by ^= 1; - } - // we are done, R.x and s is the result signature - bn_write_be(&R.x, sig); - bn_write_be(s, sig + 32); - - // check if the signature is acceptable or retry - if (is_canonical && !is_canonical(by, sig)) { - continue; - } - - if (pby) { - *pby = by; - } - - memzero(&k, sizeof(k)); - memzero(&randk, sizeof(randk)); -#if USE_RFC6979 - memzero(&rng, sizeof(rng)); -#endif - return 0; - } - - // Too many retries without a valid signature - // -> fail with an error - memzero(&k, sizeof(k)); - memzero(&randk, sizeof(randk)); -#if USE_RFC6979 - memzero(&rng, sizeof(rng)); -#endif - return -1; -} - -// returns 0 on success -int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key) { - curve_point R = {0}; - bignum256 k = {0}; - - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - memzero(pub_key, 33); - return -1; - } - - // compute k*G - if (scalar_multiply(curve, &k, &R) != 0) { - memzero(&k, sizeof(k)); - return 1; - } - pub_key[0] = 0x02 | (R.y.val[0] & 0x01); - bn_write_be(&R.x, pub_key + 1); - memzero(&R, sizeof(R)); - memzero(&k, sizeof(k)); - return 0; -} - -// returns 0 on success -int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key) { - curve_point R = {0}; - bignum256 k = {0}; - - bn_read_be(priv_key, &k); - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - // Invalid private key. - memzero(pub_key, 65); - return -1; - } - - // compute k*G - if (scalar_multiply(curve, &k, &R) != 0) { - memzero(&k, sizeof(k)); - return 1; - } - pub_key[0] = 0x04; - bn_write_be(&R.x, pub_key + 1); - bn_write_be(&R.y, pub_key + 33); - memzero(&R, sizeof(R)); - memzero(&k, sizeof(k)); - return 0; -} - -int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - uint8_t *uncompressed) { - curve_point pub = {0}; - - if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { - return 0; - } - - uncompressed[0] = 4; - bn_write_be(&pub.x, uncompressed + 1); - bn_write_be(&pub.y, uncompressed + 33); - - return 1; -} - -void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, - uint8_t *pubkeyhash) { - uint8_t h[HASHER_DIGEST_LENGTH] = {0}; - if (pub_key[0] == 0x04) { // uncompressed format - hasher_Raw(hasher_pubkey, pub_key, 65, h); - } else if (pub_key[0] == 0x00) { // point at infinity - hasher_Raw(hasher_pubkey, pub_key, 1, h); - } else { // expecting compressed format - hasher_Raw(hasher_pubkey, pub_key, 33, h); - } - memcpy(pubkeyhash, h, 20); - memzero(h, sizeof(h)); -} - -void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, uint8_t *addr_raw) { - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, addr_raw); - ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, addr_raw + prefix_len); -} - -void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, HasherType hasher_base58, - char *addr, int addrsize) { - uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - ecdsa_get_address_raw(pub_key, version, hasher_pubkey, raw); - base58_encode_check(raw, 20 + prefix_len, hasher_base58, addr, addrsize); - // not as important to clear this one, but we might as well - memzero(raw, sizeof(raw)); -} - -void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - uint8_t *addr_raw) { - uint8_t buf[32 + 2] = {0}; - buf[0] = 0; // version byte - buf[1] = 20; // push 20 bytes - ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, buf + 2); - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, addr_raw); - hasher_Raw(hasher_pubkey, buf, 22, addr_raw + prefix_len); -} - -void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize) { - uint8_t raw[MAX_ADDR_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - ecdsa_get_address_segwit_p2sh_raw(pub_key, version, hasher_pubkey, raw); - base58_encode_check(raw, prefix_len + 20, hasher_base58, addr, addrsize); - memzero(raw, sizeof(raw)); -} - -void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, - HasherType hasher_base58, char *wif, int wifsize) { - uint8_t wif_raw[MAX_WIF_RAW_SIZE] = {0}; - size_t prefix_len = address_prefix_bytes_len(version); - address_write_prefix_bytes(version, wif_raw); - memcpy(wif_raw + prefix_len, priv_key, 32); - wif_raw[prefix_len + 32] = 0x01; - base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_base58, wif, - wifsize); - // private keys running around our stack can cause trouble - memzero(wif_raw, sizeof(wif_raw)); -} - -int ecdsa_address_decode(const char *addr, uint32_t version, - HasherType hasher_base58, uint8_t *out) { - if (!addr) return 0; - int prefix_len = address_prefix_bytes_len(version); - return base58_decode_check(addr, hasher_base58, out, 20 + prefix_len) == - 20 + prefix_len && - address_check_prefix(out, version); -} - -void compress_coords(const curve_point *cp, uint8_t *compressed) { - compressed[0] = bn_is_odd(&cp->y) ? 0x03 : 0x02; - bn_write_be(&cp->x, compressed + 1); -} - -void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, - const bignum256 *x, bignum256 *y) { - // y^2 = x^3 + a*x + b - memcpy(y, x, sizeof(bignum256)); // y is x - bn_multiply(x, y, &curve->prime); // y is x^2 - bn_subi(y, -curve->a, &curve->prime); // y is x^2 + a - bn_multiply(x, y, &curve->prime); // y is x^3 + ax - bn_add(y, &curve->b); // y is x^3 + ax + b - bn_sqrt(y, &curve->prime); // y = sqrt(y) - if ((odd & 0x01) != (y->val[0] & 1)) { - bn_subtract(&curve->prime, y, y); // y = -y - } -} - -int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - curve_point *pub) { - if (!curve) { - curve = &secp256k1; - } - if (pub_key[0] == 0x04) { - bn_read_be(pub_key + 1, &(pub->x)); - bn_read_be(pub_key + 33, &(pub->y)); - return ecdsa_validate_pubkey(curve, pub); - } - if (pub_key[0] == 0x02 || pub_key[0] == 0x03) { // compute missing y coords - bn_read_be(pub_key + 1, &(pub->x)); - uncompress_coords(curve, pub_key[0], &(pub->x), &(pub->y)); - return ecdsa_validate_pubkey(curve, pub); - } - // error - return 0; -} - -// Verifies that: -// - pub is not the point at infinity. -// - pub->x and pub->y are in range [0,p-1]. -// - pub is on the curve. -// We assume that all curves using this code have cofactor 1, so there is no -// need to verify that pub is a scalar multiple of G. -int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub) { - bignum256 y_2 = {0}, x3_ax_b = {0}; - - if (point_is_infinity(pub)) { - return 0; - } - - if (!bn_is_less(&(pub->x), &curve->prime) || - !bn_is_less(&(pub->y), &curve->prime)) { - return 0; - } - - memcpy(&y_2, &(pub->y), sizeof(bignum256)); - memcpy(&x3_ax_b, &(pub->x), sizeof(bignum256)); - - // y^2 - bn_multiply(&(pub->y), &y_2, &curve->prime); - bn_mod(&y_2, &curve->prime); - - // x^3 + ax + b - bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^2 - bn_subi(&x3_ax_b, -curve->a, &curve->prime); // x^2 + a - bn_multiply(&(pub->x), &x3_ax_b, &curve->prime); // x^3 + ax - bn_addmod(&x3_ax_b, &curve->b, &curve->prime); // x^3 + ax + b - bn_mod(&x3_ax_b, &curve->prime); - - if (!bn_is_equal(&x3_ax_b, &y_2)) { - return 0; - } - - return 1; -} - -// uses secp256k1 curve -// pub_key - 65 bytes uncompressed key -// signature - 64 bytes signature -// msg is a data that was signed -// msg_len is the message length - -int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, - uint32_t msg_len) { - uint8_t hash[32] = {0}; - hasher_Raw(hasher_sign, msg, msg_len, hash); - int res = ecdsa_verify_digest(curve, pub_key, sig, hash); - memzero(hash, sizeof(hash)); - return res; -} - -// Compute public key from signature and recovery id. -// returns 0 if the key is successfully recovered -int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest, - int recid) { - bignum256 r = {0}, s = {0}, e = {0}; - curve_point cp = {0}, cp2 = {0}; - - // read r and s - bn_read_be(sig, &r); - bn_read_be(sig + 32, &s); - if (!bn_is_less(&r, &curve->order) || bn_is_zero(&r)) { - return 1; - } - if (!bn_is_less(&s, &curve->order) || bn_is_zero(&s)) { - return 1; - } - // cp = R = k * G (k is secret nonce when signing) - memcpy(&cp.x, &r, sizeof(bignum256)); - if (recid & 2) { - bn_add(&cp.x, &curve->order); - if (!bn_is_less(&cp.x, &curve->prime)) { - return 1; - } - } - // compute y from x - uncompress_coords(curve, recid & 1, &cp.x, &cp.y); - if (!ecdsa_validate_pubkey(curve, &cp)) { - return 1; - } - // e = -digest - bn_read_be(digest, &e); - bn_mod(&e, &curve->order); - bn_subtract(&curve->order, &e, &e); - // r = r^-1 - bn_inverse(&r, &curve->order); - // e = -digest * r^-1 - bn_multiply(&r, &e, &curve->order); - bn_mod(&e, &curve->order); - // s = s * r^-1 - bn_multiply(&r, &s, &curve->order); - bn_mod(&s, &curve->order); - // cp = s * r^-1 * k * G - point_multiply(curve, &s, &cp, &cp); - // cp2 = -digest * r^-1 * G - scalar_multiply(curve, &e, &cp2); - // cp = (s * r^-1 * k - digest * r^-1) * G = Pub - point_add(curve, &cp2, &cp); - // The point at infinity is not considered to be a valid public key. - if (point_is_infinity(&cp)) { - return 1; - } - pub_key[0] = 0x04; - bn_write_be(&cp.x, pub_key + 1); - bn_write_be(&cp.y, pub_key + 33); - return 0; -} - -// returns 0 if verification succeeded -int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest) { - curve_point pub = {0}, res = {0}; - bignum256 r = {0}, s = {0}, z = {0}; - int result = 0; - - if (!ecdsa_read_pubkey(curve, pub_key, &pub)) { - result = 1; - } - - if (result == 0) { - bn_read_be(sig, &r); - bn_read_be(sig + 32, &s); - bn_read_be(digest, &z); - if (bn_is_zero(&r) || bn_is_zero(&s) || (!bn_is_less(&r, &curve->order)) || - (!bn_is_less(&s, &curve->order))) { - result = 2; - } - if (bn_is_zero(&z)) { - // The digest was all-zero. The probability of this happening by chance is - // infinitesimal, but it could be induced by a fault injection. In this - // case the signature (r,s) can be forged by taking r := (t * Q).x mod n - // and s := r * t^-1 mod n for any t in [1, n-1]. We fail verification, - // because there is no guarantee that the signature was created by the - // owner of the private key. - result = 3; - } - } - - if (result == 0) { - bn_inverse(&s, &curve->order); // s = s^-1 - bn_multiply(&s, &z, &curve->order); // z = z * s [u1 = z * s^-1 mod n] - bn_mod(&z, &curve->order); - } - - if (result == 0) { - bn_multiply(&r, &s, &curve->order); // s = r * s [u2 = r * s^-1 mod n] - bn_mod(&s, &curve->order); - scalar_multiply(curve, &z, &res); // res = z * G [= u1 * G] - point_multiply(curve, &s, &pub, &pub); // pub = s * pub [= u2 * Q] - point_add(curve, &pub, &res); // res = pub + res [R = u1 * G + u2 * Q] - if (point_is_infinity(&res)) { - // R == Infinity - result = 4; - } - } - - if (result == 0) { - bn_mod(&(res.x), &curve->order); - if (!bn_is_equal(&res.x, &r)) { - // R.x != r - // signature does not match - result = 5; - } - } - - memzero(&pub, sizeof(pub)); - memzero(&res, sizeof(res)); - memzero(&r, sizeof(r)); - memzero(&s, sizeof(s)); - memzero(&z, sizeof(z)); - - // all OK - return result; -} - -int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der) { - int i = 0; - uint8_t *p = der, *len = NULL, *len1 = NULL, *len2 = NULL; - *p = 0x30; - p++; // sequence - *p = 0x00; - len = p; - p++; // len(sequence) - - *p = 0x02; - p++; // integer - *p = 0x00; - len1 = p; - p++; // len(integer) - - // process R - i = 0; - while (i < 31 && sig[i] == 0) { - i++; - } // skip leading zeroes - if (sig[i] >= 0x80) { // put zero in output if MSB set - *p = 0x00; - p++; - *len1 = *len1 + 1; - } - while (i < 32) { // copy bytes to output - *p = sig[i]; - p++; - *len1 = *len1 + 1; - i++; - } - - *p = 0x02; - p++; // integer - *p = 0x00; - len2 = p; - p++; // len(integer) - - // process S - i = 32; - while (i < 63 && sig[i] == 0) { - i++; - } // skip leading zeroes - if (sig[i] >= 0x80) { // put zero in output if MSB set - *p = 0x00; - p++; - *len2 = *len2 + 1; - } - while (i < 64) { // copy bytes to output - *p = sig[i]; - p++; - *len2 = *len2 + 1; - i++; - } - - *len = *len1 + *len2 + 4; - return *len + 2; -} - -// Parse a DER-encoded signature. We don't check whether the encoded integers -// satisfy DER requirements regarding leading zeros. -int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]) { - memzero(sig, 64); - - // Check sequence header. - if (der_len < 2 || der_len > 72 || der[0] != 0x30 || der[1] != der_len - 2) { - return 1; - } - - // Read two DER-encoded integers. - size_t pos = 2; - for (int i = 0; i < 2; ++i) { - // Check integer header. - if (der_len < pos + 2 || der[pos] != 0x02) { - return 1; - } - - // Locate the integer. - size_t int_len = der[pos + 1]; - pos += 2; - if (pos + int_len > der_len) { - return 1; - } - - // Skip a possible leading zero. - if (int_len != 0 && der[pos] == 0) { - int_len--; - pos++; - } - - // Copy the integer to the output, making sure it fits. - if (int_len > 32) { - return 1; - } - memcpy(sig + 32 * (i + 1) - int_len, der + pos, int_len); - - // Move on to the next one. - pos += int_len; - } - - // Check that there are no trailing elements in the sequence. - if (pos != der_len) { - return 1; - } - - return 0; -} diff --git a/trezor-crypto/crypto/ed25519-donna/README.md b/trezor-crypto/crypto/ed25519-donna/README.md deleted file mode 100644 index 71b643485de..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/README.md +++ /dev/null @@ -1,183 +0,0 @@ -[ed25519](https://ed25519.cr.yp.to) is an -[Elliptic Curve Digital Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm), -developed by [Dan Bernstein](https://cr.yp.to/djb.html), -[Niels Duif](https://www.nielsduif.nl), -[Tanja Lange](https://hyperelliptic.org/tanja), -[Peter Schwabe](https://cryptojedi.org/peter), -and [Bo-Yin Yang](https://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 - - - - - - - - - - - -
ImplementationSigngcciccclangVerifygcciccclang
ed25519-donna 64bit 100k110k137k327k (144k) 342k (163k) 422k (194k)
amd64-64-24k 102k 355k (158k)
ed25519-donna-sse2 64bit108k111k116k353k (155k) 345k (154k) 360k (161k)
amd64-51-32k 116k 380k (175k)
ed25519-donna-sse2 32bit147k147k156k380k (178k) 381k (173k) 430k (192k)
ed25519-donna 32bit 597k335k380k1693k (720k)1052k (453k)1141k (493k)
- -##### E3-1270 @ 3.4ghz, march=corei7-avx - - - - - - - - - - - -
ImplementationSigngcciccclangVerifygcciccclang
amd64-64-24k 68k 225k (104k)
ed25519-donna 64bit 71k 75k 90k226k (105k) 226k (112k) 277k (125k)
amd64-51-32k 72k 218k (107k)
ed25519-donna-sse2 64bit 79k 82k 92k252k (122k) 259k (124k) 282k (131k)
ed25519-donna-sse2 32bit 94k 95k103k296k (146k) 294k (137k) 306k (147k)
ed25519-donna 32bit 525k299k316k1502k (645k)959k (418k) 954k (416k)
- -#### Compilation - -No configuration is needed **if you are compiling against OpenSSL**. - -##### Hash Options - -If you are not compiling against 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 against 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](https://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](https://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](https://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 implementations 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](https://ed25519.cr.yp.to/papers.html) diff --git a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-32bit.c b/trezor-crypto/crypto/ed25519-donna/curve25519-donna-32bit.c deleted file mode 100644 index c81e66a4fd7..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-32bit.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - 32 bit integer curve25519 implementation -*/ - -#include - -const uint32_t reduce_mask_25 = (1 << 25) - 1; -const uint32_t reduce_mask_26 = (1 << 26) - 1; - -/* out = in */ -void curve25519_copy(bignum25519 out, const bignum25519 in) { - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; - out[4] = in[4]; - out[5] = in[5]; - out[6] = in[6]; - out[7] = in[7]; - out[8] = in[8]; - out[9] = in[9]; -} - -/* out = a + b */ -void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - out[6] = a[6] + b[6]; - out[7] = a[7] + b[7]; - out[8] = a[8] + b[8]; - out[9] = a[9] + b[9]; -} - -void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* multiples of p */ -const uint32_t twoP0 = 0x07ffffda; -const uint32_t twoP13579 = 0x03fffffe; -const uint32_t twoP2468 = 0x07fffffe; -const uint32_t fourP0 = 0x0fffffb4; -const uint32_t fourP13579 = 0x07fffffc; -const uint32_t fourP2468 = 0x0ffffffc; - -/* out = a - b */ -void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = twoP2468 + a[4] - b[4] + c; - out[5] = twoP13579 + a[5] - b[5] ; - out[6] = twoP2468 + a[6] - b[6] ; - out[7] = twoP13579 + a[7] - b[7] ; - out[8] = twoP2468 + a[8] - b[8] ; - out[9] = twoP13579 + a[9] - b[9] ; -} - -/* out = in * scalar */ -void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar) { - uint64_t a = 0; - uint32_t c = 0; - a = mul32x32_64(in[0], scalar); out[0] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[1], scalar) + c; out[1] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[2], scalar) + c; out[2] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[3], scalar) + c; out[3] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[4], scalar) + c; out[4] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[5], scalar) + c; out[5] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[6], scalar) + c; out[6] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[7], scalar) + c; out[7] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - a = mul32x32_64(in[8], scalar) + c; out[8] = (uint32_t)a & reduce_mask_26; c = (uint32_t)(a >> 26); - a = mul32x32_64(in[9], scalar) + c; out[9] = (uint32_t)a & reduce_mask_25; c = (uint32_t)(a >> 25); - out[0] += c * 19; -} - -/* out = a - b, where a is the result of a basic op (add,sub) */ -void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t c = 0; - out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* out = -a */ -void curve25519_neg(bignum25519 out, const bignum25519 a) { - uint32_t c = 0; - out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -/* out = a * b */ -#define curve25519_mul_noinline curve25519_mul -void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t s0 = 0, s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0, s6 = 0, s7 = 0, s8 = 0, s9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = b[0]; - r1 = b[1]; - r2 = b[2]; - r3 = b[3]; - r4 = b[4]; - r5 = b[5]; - r6 = b[6]; - r7 = b[7]; - r8 = b[8]; - r9 = b[9]; - - s0 = a[0]; - s1 = a[1]; - s2 = a[2]; - s3 = a[3]; - s4 = a[4]; - s5 = a[5]; - s6 = a[6]; - s7 = a[7]; - s8 = a[8]; - s9 = a[9]; - - m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); - m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); - m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); - m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); - m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); - - r1 *= 2; - r3 *= 2; - r5 *= 2; - r7 *= 2; - - m0 = mul32x32_64(r0, s0); - m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); - m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); - m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); - m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); - - r1 *= 19; - r2 *= 19; - r3 = (r3 / 2) * 19; - r4 *= 19; - r5 = (r5 / 2) * 19; - r6 *= 19; - r7 = (r7 / 2) * 19; - r8 *= 19; - r9 *= 19; - - m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); - m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); - m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); - m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); - - r3 *= 2; - r5 *= 2; - r7 *= 2; - r9 *= 2; - - m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); - m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); - m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); - m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); - m8 += (mul32x32_64(r9, s9)); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* out = in * in */ -void curve25519_square(bignum25519 out, const bignum25519 in) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - r5 = in[5]; - r6 = in[6]; - r7 = in[7]; - r8 = in[8]; - r9 = in[9]; - - m0 = mul32x32_64(r0, r0); - r0 *= 2; - m1 = mul32x32_64(r0, r1); - m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); - r1 *= 2; - m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); - m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); - r2 *= 2; - m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); - m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); - r3 *= 2; - m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); - m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); - m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); - - d6 = r6 * 19; - d7 = r7 * 2 * 19; - d8 = r8 * 19; - d9 = r9 * 2 * 19; - - m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); - m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); - m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); - m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); - m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); - m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); - m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); - m7 += (mul32x32_64(d9, r8 )); - m8 += (mul32x32_64(d9, r9 )); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* out = in ^ (2 * count) */ -void curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { - uint32_t r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0; - uint32_t d6 = 0, d7 = 0, d8 = 0, d9 = 0; - uint64_t m0 = 0, m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0, m8 = 0, m9 = 0, c = 0; - uint32_t p = 0; - - r0 = in[0]; - r1 = in[1]; - r2 = in[2]; - r3 = in[3]; - r4 = in[4]; - r5 = in[5]; - r6 = in[6]; - r7 = in[7]; - r8 = in[8]; - r9 = in[9]; - - do { - m0 = mul32x32_64(r0, r0); - r0 *= 2; - m1 = mul32x32_64(r0, r1); - m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); - r1 *= 2; - m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); - m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); - r2 *= 2; - m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); - m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); - r3 *= 2; - m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); - m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); - m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); - - d6 = r6 * 19; - d7 = r7 * 2 * 19; - d8 = r8 * 19; - d9 = r9 * 2 * 19; - - m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); - m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); - m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); - m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); - m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); - m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); - m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); - m7 += (mul32x32_64(d9, r8 )); - m8 += (mul32x32_64(d9, r9 )); - - r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); - m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); - m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); - m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); - m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); - m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); - m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); - m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); - m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); - m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); - m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); - r1 += p; - } while (--count); - - out[0] = r0; - out[1] = r1; - out[2] = r2; - out[3] = r3; - out[4] = r4; - out[5] = r5; - out[6] = r6; - out[7] = r7; - out[8] = r8; - out[9] = r9; -} - -/* Take a little-endian, 32-byte number and expand it into polynomial form */ -void curve25519_expand(bignum25519 out, const unsigned char in[32]) { - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; - #define F(s) \ - ((((uint32_t)in[s + 0]) ) | \ - (((uint32_t)in[s + 1]) << 8) | \ - (((uint32_t)in[s + 2]) << 16) | \ - (((uint32_t)in[s + 3]) << 24)) - x0 = F(0); - x1 = F(4); - x2 = F(8); - x3 = F(12); - x4 = F(16); - x5 = F(20); - x6 = F(24); - x7 = F(28); - #undef F - - out[0] = ( x0 ) & reduce_mask_26; - out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; - out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; - out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; - out[4] = (( x3) >> 6) & reduce_mask_26; - out[5] = ( x4 ) & reduce_mask_25; - out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; - out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; - out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; - out[9] = (( x7) >> 6) & reduce_mask_25; /* ignore the top bit */ -} - -/* Take a fully reduced polynomial form number and contract it into a - * little-endian, 32-byte array - */ -void curve25519_contract(unsigned char out[32], const bignum25519 in) { - bignum25519 f = {0}; - curve25519_copy(f, in); - - #define carry_pass() \ - f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ - f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ - f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ - f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ - f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ - f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ - f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ - f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ - f[9] += f[8] >> 26; f[8] &= reduce_mask_26; - - #define carry_pass_full() \ - carry_pass() \ - f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; - - #define carry_pass_final() \ - carry_pass() \ - f[9] &= reduce_mask_25; - - carry_pass_full() - carry_pass_full() - - /* now t is between 0 and 2^255-1, properly carried. */ - /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ - f[0] += 19; - carry_pass_full() - - /* now between 19 and 2^255-1 in both cases, and offset by 19. */ - f[0] += (reduce_mask_26 + 1) - 19; - f[1] += (reduce_mask_25 + 1) - 1; - f[2] += (reduce_mask_26 + 1) - 1; - f[3] += (reduce_mask_25 + 1) - 1; - f[4] += (reduce_mask_26 + 1) - 1; - f[5] += (reduce_mask_25 + 1) - 1; - f[6] += (reduce_mask_26 + 1) - 1; - f[7] += (reduce_mask_25 + 1) - 1; - f[8] += (reduce_mask_26 + 1) - 1; - f[9] += (reduce_mask_25 + 1) - 1; - - /* now between 2^255 and 2^256-20, and offset by 2^255. */ - carry_pass_final() - - #undef carry_pass - #undef carry_full - #undef carry_final - - f[1] <<= 2; - f[2] <<= 3; - f[3] <<= 5; - f[4] <<= 6; - f[6] <<= 1; - f[7] <<= 3; - f[8] <<= 4; - f[9] <<= 6; - - #define F(i, s) \ - out[s+0] |= (unsigned char )(f[i] & 0xff); \ - out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \ - out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \ - out[s+3] = (unsigned char )((f[i] >> 24) & 0xff); - - out[0] = 0; - out[16] = 0; - F(0,0); - F(1,3); - F(2,6); - F(3,9); - F(4,12); - F(5,16); - F(6,19); - F(7,22); - F(8,25); - F(9,28); - #undef F -} - -/* if (iswap) swap(a, b) */ -void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) { - const uint32_t swap = (uint32_t)(-(int32_t)iswap); - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0, x8 = 0, x9 = 0; - - x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; - x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; - x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; - x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; - x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; - x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5; - x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6; - x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7; - x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8; - x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9; -} - -void curve25519_set(bignum25519 r, uint32_t x){ - r[0] = x & reduce_mask_26; x >>= 26; - r[1] = x & reduce_mask_25; - r[2] = 0; - r[3] = 0; - r[4] = 0; - r[5] = 0; - r[6] = 0; - r[7] = 0; - r[8] = 0; - r[9] = 0; -} - -void curve25519_set_d(bignum25519 r){ - curve25519_copy(r, ge25519_ecd); -} - -void curve25519_set_2d(bignum25519 r){ - curve25519_copy(r, ge25519_ec2d); -} - -void curve25519_set_sqrtneg1(bignum25519 r){ - curve25519_copy(r, ge25519_sqrtneg1); -} - -int curve25519_isnegative(const bignum25519 f) { - unsigned char s[32] = {0}; - curve25519_contract(s, f); - return s[0] & 1; -} - -int curve25519_isnonzero(const bignum25519 f) { - unsigned char s[32] = {0}; - curve25519_contract(s, f); - return ((((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | - s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | - s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | - s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1) & 0x1; -} - -void curve25519_reduce(bignum25519 out, const bignum25519 in) { - uint32_t c = 0; - out[0] = in[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; - out[1] = in[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; - out[2] = in[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; - out[3] = in[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; - out[4] = in[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; - out[5] = in[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; - out[6] = in[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; - out[7] = in[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; - out[8] = in[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; - out[9] = in[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; - out[0] += 19 * c; -} - -void curve25519_divpowm1(bignum25519 r, const bignum25519 u, const bignum25519 v) { - bignum25519 v3={0}, uv7={0}, t0={0}, t1={0}, t2={0}; - int i = 0; - - curve25519_square(v3, v); - curve25519_mul(v3, v3, v); /* v3 = v^3 */ - curve25519_square(uv7, v3); - curve25519_mul(uv7, uv7, v); - curve25519_mul(uv7, uv7, u); /* uv7 = uv^7 */ - - /*fe_pow22523(uv7, uv7);*/ - /* From fe_pow22523.c */ - - curve25519_square(t0, uv7); - curve25519_square(t1, t0); - curve25519_square(t1, t1); - curve25519_mul(t1, uv7, t1); - curve25519_mul(t0, t0, t1); - curve25519_square(t0, t0); - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 4; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 9; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t1, t1, t0); - curve25519_square(t2, t1); - for (i = 0; i < 19; ++i) { - curve25519_square(t2, t2); - } - curve25519_mul(t1, t2, t1); - for (i = 0; i < 10; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t1, t0); - for (i = 0; i < 49; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t1, t1, t0); - curve25519_square(t2, t1); - for (i = 0; i < 99; ++i) { - curve25519_square(t2, t2); - } - curve25519_mul(t1, t2, t1); - for (i = 0; i < 50; ++i) { - curve25519_square(t1, t1); - } - curve25519_mul(t0, t1, t0); - curve25519_square(t0, t0); - curve25519_square(t0, t0); - curve25519_mul(t0, t0, uv7); - - /* End fe_pow22523.c */ - /* t0 = (uv^7)^((q-5)/8) */ - curve25519_mul(t0, t0, v3); - curve25519_mul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ -} - -void curve25519_expand_reduce(bignum25519 out, const unsigned char in[32]) { - uint32_t x0 = 0, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0, x7 = 0; -#define F(s) \ - ((((uint32_t)in[s + 0]) ) | \ - (((uint32_t)in[s + 1]) << 8) | \ - (((uint32_t)in[s + 2]) << 16) | \ - (((uint32_t)in[s + 3]) << 24)) - x0 = F(0); - x1 = F(4); - x2 = F(8); - x3 = F(12); - x4 = F(16); - x5 = F(20); - x6 = F(24); - x7 = F(28); -#undef F - - out[0] = ( x0 ) & reduce_mask_26; - out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & reduce_mask_25; - out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & reduce_mask_26; - out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & reduce_mask_25; - out[4] = (( x3) >> 6) & reduce_mask_26; - out[5] = ( x4 ) & reduce_mask_25; - out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & reduce_mask_26; - out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & reduce_mask_25; - out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & reduce_mask_26; - out[9] = (( x7) >> 6); // & reduce_mask_25; /* ignore the top bit */ - out[0] += 19 * (out[9] >> 25); - out[9] &= reduce_mask_25; -} diff --git a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-helpers.c b/trezor-crypto/crypto/ed25519-donna/curve25519-donna-helpers.c deleted file mode 100644 index 3dadd62f48a..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-helpers.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - Curve25519 implementation agnostic helpers -*/ - -#include - -/* - * 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); -} diff --git a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c b/trezor-crypto/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c deleted file mode 100644 index e6cbd6cb418..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/curve25519-donna-scalarmult-base.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -/* Calculates nQ where Q is the x-coordinate of a point on the curve - * - * mypublic: the packed little endian x coordinate of the resulting curve point - * n: a little endian, 32-byte number - * basepoint: a packed little endian point of the curve - */ - -void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint) { - bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx = {0}; - bignum25519 q = {0}, qx = {0}, qpqx = {0}, qqx = {0}, zzz = {0}, zmone = {0}; - size_t bit = 0, lastbit = 0; - int32_t i = 0; - - curve25519_expand(q, basepoint); - curve25519_copy(nqx, q); - - /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and - start pre-swapped on bit 254 */ - lastbit = 1; - - /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */ - for (i = 253; i >= 2; i--) { - curve25519_add(qx, nqx, nqz); - curve25519_sub(nqz, nqx, nqz); - curve25519_add(qpqx, nqpqx, nqpqz); - curve25519_sub(nqpqz, nqpqx, nqpqz); - curve25519_mul(nqpqx, qpqx, nqz); - curve25519_mul(nqpqz, qx, nqpqz); - curve25519_add(qqx, nqpqx, nqpqz); - curve25519_sub(nqpqz, nqpqx, nqpqz); - curve25519_square(nqpqz, nqpqz); - curve25519_square(nqpqx, qqx); - curve25519_mul(nqpqz, nqpqz, q); - curve25519_square(qx, qx); - curve25519_square(nqz, nqz); - curve25519_mul(nqx, qx, nqz); - curve25519_sub(nqz, qx, nqz); - curve25519_scalar_product(zzz, nqz, 121665); - curve25519_add(zzz, zzz, qx); - curve25519_mul(nqz, nqz, zzz); - - bit = (n[i/8] >> (i & 7)) & 1; - curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit); - curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit); - lastbit = bit; - } - - /* the final 3 bits are always zero, so we only need to double */ - for (i = 0; i < 3; i++) { - curve25519_add(qx, nqx, nqz); - curve25519_sub(nqz, nqx, nqz); - curve25519_square(qx, qx); - curve25519_square(nqz, nqz); - curve25519_mul(nqx, qx, nqz); - curve25519_sub(nqz, qx, nqz); - curve25519_scalar_product(zzz, nqz, 121665); - curve25519_add(zzz, zzz, qx); - curve25519_mul(nqz, nqz, zzz); - } - - curve25519_recip(zmone, nqz); - curve25519_mul(nqz, nqx, zmone); - curve25519_contract(mypublic, nqz); -} diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-blake2b.c b/trezor-crypto/crypto/ed25519-donna/ed25519-blake2b.c deleted file mode 100644 index f22d8c75797..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-blake2b.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#include -#include - -#define ED25519_SUFFIX _blake2b - -#include "ed25519.c" diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-32bit-tables.c b/trezor-crypto/crypto/ed25519-donna/ed25519-donna-32bit-tables.c deleted file mode 100644 index 2d95839432d..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-32bit-tables.c +++ /dev/null @@ -1,63 +0,0 @@ -#include - -const ge25519 ALIGN(16) ge25519_basepoint = { - {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db}, - {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999}, - {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}, - {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c} -}; - -/* - d -*/ - -const bignum25519 ALIGN(16) ge25519_ecd = { - 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3 -}; - -const bignum25519 ALIGN(16) ge25519_ec2d = { - 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67 -}; - -/* - sqrt(-1) -*/ - -const bignum25519 ALIGN(16) ge25519_sqrtneg1 = { - 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92 -}; - -const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = { - {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}}, - {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}}, - {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}}, - {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}}, - {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}}, - {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}}, - {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}}, - {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}}, - {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}}, - {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}}, - {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}}, - {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}}, - {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}}, - {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}}, - {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}}, - {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}}, - {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}}, - {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}}, - {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}}, - {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}}, - {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}}, - {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}}, - {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}}, - {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}}, - {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}}, - {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}}, - {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}}, - {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}}, - {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}}, - {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}}, - {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}}, - {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}} -}; diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-basepoint-table.c b/trezor-crypto/crypto/ed25519-donna/ed25519-donna-basepoint-table.c deleted file mode 100644 index e3b2e7ecff7..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-basepoint-table.c +++ /dev/null @@ -1,261 +0,0 @@ -#include - -/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ -const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = { - {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, - {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, - {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, - {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, - {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, - {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, - {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, - {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, - {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, - {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, - {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, - {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, - {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, - {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, - {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, - {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, - {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, - {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, - {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, - {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, - {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, - {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, - {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, - {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, - {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, - {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, - {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, - {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, - {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, - {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, - {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, - {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, - {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, - {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, - {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, - {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, - {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, - {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, - {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, - {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, - {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, - {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, - {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, - {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, - {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, - {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, - {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, - {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, - {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, - {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, - {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, - {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, - {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, - {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, - {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, - {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, - {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, - {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, - {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, - {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, - {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, - {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, - {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, - {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, - {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, - {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, - {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, - {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, - {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, - {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, - {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, - {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, - {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, - {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, - {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, - {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, - {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, - {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, - {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, - {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, - {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, - {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, - {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, - {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, - {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, - {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, - {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, - {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, - {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, - {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, - {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, - {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, - {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, - {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, - {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, - {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, - {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, - {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, - {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, - {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, - {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, - {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, - {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, - {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, - {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, - {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, - {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, - {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, - {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, - {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, - {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, - {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, - {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, - {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, - {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, - {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, - {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, - {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, - {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, - {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, - {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, - {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, - {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, - {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, - {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, - {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, - {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, - {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, - {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, - {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, - {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, - {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, - {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, - {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, - {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, - {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, - {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, - {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, - {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, - {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, - {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, - {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, - {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, - {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, - {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, - {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, - {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, - {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, - {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, - {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, - {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, - {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, - {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, - {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, - {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, - {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, - {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, - {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, - {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, - {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, - {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, - {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, - {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, - {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, - {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, - {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, - {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, - {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, - {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, - {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, - {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, - {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, - {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, - {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, - {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, - {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, - {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, - {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, - {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, - {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, - {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, - {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, - {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, - {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, - {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, - {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, - {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, - {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, - {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, - {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, - {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, - {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, - {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, - {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, - {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, - {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, - {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, - {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, - {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, - {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, - {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, - {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, - {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, - {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, - {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, - {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, - {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, - {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, - {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, - {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, - {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, - {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, - {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, - {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, - {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, - {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, - {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, - {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, - {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, - {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, - {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, - {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, - {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, - {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, - {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, - {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, - {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, - {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, - {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, - {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, - {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, - {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, - {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, - {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, - {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, - {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, - {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, - {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, - {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, - {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, - {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, - {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, - {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, - {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, - {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, - {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, - {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, - {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, - {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, - {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, - {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, - {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, - {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, - {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, - {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, - {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} -}; diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-impl-base.c b/trezor-crypto/crypto/ed25519-donna/ed25519-donna-impl-base.c deleted file mode 100644 index d43a522c5a4..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-donna-impl-base.c +++ /dev/null @@ -1,730 +0,0 @@ -#include -#include -#include - -/* 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) -const bignum25519 ALIGN(16) fe_d = { - 0x35978a3, 0x0d37284, 0x3156ebd, 0x06a0a0e, 0x001c029, 0x179e898, 0x3a03cbb, 0x1ce7198, 0x2e2b6ff, 0x1480db3}; /* d */ -#endif -const bignum25519 ALIGN(16) fe_sqrtm1 = { - 0x20ea0b0, 0x186c9d2, 0x08f189d, 0x035697f, 0x0bd0c60, 0x1fbd7a7, 0x2804c9e, 0x1e16569, 0x004fc1d, 0x0ae0c92}; /* sqrt(-1) */ -//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 */ -const bignum25519 ALIGN(16) fe_ma2 = { - 0x33de3c9, 0x1fff236, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff}; /* -A^2 */ -const bignum25519 ALIGN(16) fe_ma = { - 0x3f892e7, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff}; /* -A */ -const bignum25519 ALIGN(16) fe_fffb1 = { - 0x1e3bdff, 0x025a2b3, 0x18e5bab, 0x0ba36ac, 0x0b9afed, 0x004e61c, 0x31d645f, 0x09d1bea, 0x102529e, 0x0063810}; /* sqrt(-2 * A * (A + 2)) */ -const bignum25519 ALIGN(16) fe_fffb2 = { - 0x383650d, 0x066df27, 0x10405a4, 0x1cfdd48, 0x2b887f2, 0x1e9a041, 0x1d7241f, 0x0612dc5, 0x35fba5d, 0x0cbe787}; /* sqrt(2 * A * (A + 2)) */ -const bignum25519 ALIGN(16) fe_fffb3 = { - 0x0cfd387, 0x1209e3a, 0x3bad4fc, 0x18ad34d, 0x2ff6c02, 0x0f25d12, 0x15cdfe0, 0x0e208ed, 0x32eb3df, 0x062d7bb}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ -const bignum25519 ALIGN(16) fe_fffb4 = { - 0x2b39186, 0x14640ed, 0x14930a7, 0x04509fa, 0x3b91bf0, 0x0f7432e, 0x07a443f, 0x17f24d8, 0x031067d, 0x0690fcc}; /* sqrt(sqrt(-1) * A * (A + 2)) */ - - -/* - Timing safe memory compare -*/ -int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) { - size_t differentbits = 0; - while (len--) - differentbits |= (*x++ ^ *y++); - return (int) (1 & ((differentbits - 1) >> 8)); -} - -/* - conversions -*/ - -void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { - curve25519_mul(r->x, p->x, p->t); - curve25519_mul(r->y, p->y, p->z); - curve25519_mul(r->z, p->z, p->t); -} - -void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { - curve25519_mul(r->x, p->x, p->t); - curve25519_mul(r->y, p->y, p->z); - curve25519_mul(r->z, p->z, p->t); - curve25519_mul(r->t, p->x, p->y); -} - -void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { - curve25519_sub(p->ysubx, r->y, r->x); - curve25519_add(p->xaddy, r->y, r->x); - curve25519_copy(p->z, r->z); - curve25519_mul(p->t2d, r->t, ge25519_ec2d); -} - -/* - adding & doubling -*/ - -void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_square(a, p->x); - curve25519_square(b, p->y); - curve25519_square(c, p->z); - curve25519_add_reduce(c, c, c); - curve25519_add(r->x, p->x, p->y); - curve25519_square(r->x, r->x); - curve25519_add(r->y, b, a); - curve25519_sub(r->z, b, a); - curve25519_sub_after_basic(r->x, r->x, r->y); - curve25519_sub_after_basic(r->t, c, r->z); -} - -#ifndef ED25519_NO_PRECOMP -void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) { - const bignum25519 *qb = (const bignum25519 *)q; - bignum25519 *rb = (bignum25519 *)r; - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ - curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ - curve25519_add(r->y, r->x, a); - curve25519_sub(r->x, r->x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_add_reduce(r->t, p->z, p->z); - curve25519_copy(r->z, r->t); - curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ - curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ -} -#endif - -void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) { - const bignum25519 *qb = (const bignum25519 *)q; - bignum25519 *rb = (bignum25519 *)r; - bignum25519 a = {0}, b = {0}, c = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ - curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ - curve25519_add(r->y, r->x, a); - curve25519_sub(r->x, r->x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_mul(r->t, p->z, q->z); - curve25519_add_reduce(r->t, r->t, r->t); - curve25519_copy(r->z, r->t); - curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ - curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ -} - -void ge25519_double_partial(ge25519 *r, const ge25519 *p) { - ge25519_p1p1 t = {0}; - ge25519_double_p1p1(&t, p); - ge25519_p1p1_to_partial(r, &t); -} - -void ge25519_double(ge25519 *r, const ge25519 *p) { - ge25519_p1p1 t = {0}; - ge25519_double_p1p1(&t, p); - ge25519_p1p1_to_full(r, &t); -} - -void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { - bignum25519 a = {0}, b = {0}, c = {0}, e = {0}, f = {0}, g = {0}, h = {0}; - - curve25519_sub(a, r->y, r->x); - curve25519_add(b, r->y, r->x); - curve25519_mul(a, a, q->ysubx); - curve25519_mul(e, b, q->xaddy); - curve25519_add(h, e, a); - curve25519_sub(e, e, a); - curve25519_mul(c, r->t, q->t2d); - curve25519_add(f, r->z, r->z); - curve25519_add_after_basic(g, f, c); - curve25519_sub_after_basic(f, f, c); - curve25519_mul(r->x, e, f); - curve25519_mul(r->y, h, g); - curve25519_mul(r->z, g, f); - curve25519_mul(r->t, e, h); -} - -void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { - bignum25519 a = {0}, b = {0}, c = {0}, x = {0}, y = {0}, z = {0}, t = {0}; - - curve25519_sub(a, p->y, p->x); - curve25519_add(b, p->y, p->x); - curve25519_mul(a, a, q->ysubx); - curve25519_mul(x, b, q->xaddy); - curve25519_add(y, x, a); - curve25519_sub(x, x, a); - curve25519_mul(c, p->t, q->t2d); - curve25519_mul(t, p->z, q->z); - curve25519_add(t, t, t); - curve25519_add_after_basic(z, t, c); - curve25519_sub_after_basic(t, t, c); - curve25519_mul(r->xaddy, x, t); - curve25519_mul(r->ysubx, y, z); - curve25519_mul(r->z, z, t); - curve25519_mul(r->t2d, x, y); - curve25519_copy(y, r->ysubx); - curve25519_sub(r->ysubx, r->ysubx, r->xaddy); - curve25519_add(r->xaddy, r->xaddy, y); - curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); -} - - -/* - pack & unpack -*/ - -void ge25519_pack(unsigned char r[32], const ge25519 *p) { - bignum25519 tx = {0}, ty = {0}, zi = {0}; - unsigned char parity[32] = {0}; - curve25519_recip(zi, p->z); - curve25519_mul(tx, p->x, zi); - curve25519_mul(ty, p->y, zi); - curve25519_contract(r, ty); - curve25519_contract(parity, tx); - r[31] ^= ((parity[0] & 1) << 7); -} - -int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) { - const unsigned char zero[32] = {0}; - const bignum25519 one = {1}; - unsigned char parity = p[31] >> 7; - unsigned char check[32] = {0}; - bignum25519 t = {0}, root = {0}, num = {0}, den = {0}, d3 = {0}; - - curve25519_expand(r->y, p); - curve25519_copy(r->z, one); - curve25519_square(num, r->y); /* x = y^2 */ - curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ - curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ - curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ - - /* Computation of sqrt(num/den) */ - /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ - curve25519_square(t, den); - curve25519_mul(d3, t, den); - curve25519_square(r->x, d3); - curve25519_mul(r->x, r->x, den); - curve25519_mul(r->x, r->x, num); - curve25519_pow_two252m3(r->x, r->x); - - /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ - curve25519_mul(r->x, r->x, d3); - curve25519_mul(r->x, r->x, num); - - /* 3. Check if either of the roots works: */ - curve25519_square(t, r->x); - curve25519_mul(t, t, den); - curve25519_sub_reduce(root, t, num); - curve25519_contract(check, root); - if (!ed25519_verify(check, zero, 32)) { - curve25519_add_reduce(t, t, num); - curve25519_contract(check, t); - if (!ed25519_verify(check, zero, 32)) - return 0; - curve25519_mul(r->x, r->x, ge25519_sqrtneg1); - } - - curve25519_contract(check, r->x); - if ((check[0] & 1) == parity) { - curve25519_copy(t, r->x); - curve25519_neg(r->x, t); - } - curve25519_mul(r->t, r->x, r->y); - return 1; -} - -/* - scalarmults -*/ - -void ge25519_set_neutral(ge25519 *r) -{ - memzero(r, sizeof(ge25519)); - r->y[0] = 1; - r->z[0] = 1; -} - -#define S1_SWINDOWSIZE 5 -#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) -#ifdef ED25519_NO_PRECOMP -#define S2_SWINDOWSIZE 5 -#else -#define S2_SWINDOWSIZE 7 -#endif -#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) - -/* computes [s1]p1 + [s2]base */ -void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { - signed char slide1[256] = {0}, slide2[256] = {0}; - ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; -#ifdef ED25519_NO_PRECOMP - ge25519_pniels pre2[S2_TABLE_SIZE] = {0}; -#endif - ge25519 dp = {0}; - ge25519_p1p1 t = {0}; - int32_t i = 0; - - memzero(&t, sizeof(ge25519_p1p1)); - contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); - contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); - - ge25519_double(&dp, p1); - ge25519_full_to_pniels(pre1, p1); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre1[i+1], &dp, &pre1[i]); - -#ifdef ED25519_NO_PRECOMP - ge25519_double(&dp, &ge25519_basepoint); - ge25519_full_to_pniels(pre2, &ge25519_basepoint); - for (i = 0; i < S2_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre2[i+1], &dp, &pre2[i]); -#endif - - ge25519_set_neutral(r); - - i = 255; - while ((i >= 0) && !(slide1[i] | slide2[i])) - i--; - - for (; i >= 0; i--) { - ge25519_double_p1p1(&t, r); - - if (slide1[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); - } - - if (slide2[i]) { - ge25519_p1p1_to_full(r, &t); -#ifdef ED25519_NO_PRECOMP - ge25519_pnielsadd_p1p1(&t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); -#else - ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); -#endif - } - - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); - memzero(slide2, sizeof(slide2)); -} - -/* computes [s1]p1 + [s2]p2 */ -#if USE_MONERO -void ge25519_double_scalarmult_vartime2(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2) { - signed char slide1[256] = {0}, slide2[256] = {0}; - ge25519_pniels pre1[S1_TABLE_SIZE] = {0}; - ge25519_pniels pre2[S1_TABLE_SIZE] = {0}; - ge25519 dp = {0}; - ge25519_p1p1 t = {0}; - int32_t i = 0; - - memzero(&t, sizeof(ge25519_p1p1)); - contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); - contract256_slidingwindow_modm(slide2, s2, S1_SWINDOWSIZE); - - ge25519_double(&dp, p1); - ge25519_full_to_pniels(pre1, p1); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre1[i+1], &dp, &pre1[i]); - - ge25519_double(&dp, p2); - ge25519_full_to_pniels(pre2, p2); - for (i = 0; i < S1_TABLE_SIZE - 1; i++) - ge25519_pnielsadd(&pre2[i+1], &dp, &pre2[i]); - - ge25519_set_neutral(r); - - i = 255; - while ((i >= 0) && !(slide1[i] | slide2[i])) - i--; - - for (; i >= 0; i--) { - ge25519_double_p1p1(&t, r); - - if (slide1[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); - } - - if (slide2[i]) { - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre2[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); - } - - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); - memzero(slide2, sizeof(slide2)); -} -#endif - -/* - * The following conditional move stuff uses conditional moves. - * I will check on which compilers this works, and provide suitable - * workarounds for those where it doesn't. - * - * This works on gcc 4.x and above with -O3. Don't use -O2, this will - * cause the code to not generate conditional moves. Don't use any -march= - * with less than i686 on x86 - */ -static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) { - long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; - for(; p= 0; i--) { - int k=abs(slide1[i]); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_p1p1(&t, r); - ge25519_move_conditional_pniels_array(&pre, pre1, k, 9); - ge25519_p1p1_to_full(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre, (unsigned char)slide1[i] >> 7); - ge25519_p1p1_to_partial(r, &t); - } - curve25519_mul(r->t, t.x, t.y); - memzero(slide1, sizeof(slide1)); -} - -void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { - bignum25519 neg = {0}; - uint32_t sign = (uint32_t)((unsigned char)b >> 7); - uint32_t mask = ~(sign - 1); - uint32_t u = (b + mask) ^ mask; - - /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ - uint8_t packed[96] = {0}; - packed[0] = 1; - packed[32] = 1; - - ge25519_move_conditional_niels_array((ge25519_niels *)packed, &table[pos*8], u-1, 8); - - /* expand in to t */ - curve25519_expand(t->ysubx, packed + 0); - curve25519_expand(t->xaddy, packed + 32); - curve25519_expand(t->t2d , packed + 64); - - /* adjust for sign */ - curve25519_swap_conditional(t->ysubx, t->xaddy, sign); - curve25519_neg(neg, t->t2d); - curve25519_swap_conditional(t->t2d, neg, sign); -} - -/* computes [s]basepoint */ -void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) { - signed char b[64] = {0}; - uint32_t i = 0; - ge25519_niels t = {0}; - - contract256_window4_modm(b, s); - - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); - curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); - curve25519_add_reduce(r->y, t.xaddy, t.ysubx); - memzero(r->z, sizeof(bignum25519)); - curve25519_copy(r->t, t.t2d); - r->z[0] = 2; - for (i = 3; i < 64; i += 2) { - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); - ge25519_nielsadd2(r, &t); - } - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double_partial(r, r); - ge25519_double(r, r); - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); - curve25519_mul(t.t2d, t.t2d, ge25519_ecd); - ge25519_nielsadd2(r, &t); - for(i = 2; i < 64; i += 2) { - ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); - ge25519_nielsadd2(r, &t); - } -} - -int ge25519_check(const ge25519 *r){ - /* return (z % q != 0 and - x * y % q == z * t % q and - (y * y - x * x - z * z - ed25519.d * t * t) % q == 0) - */ - - bignum25519 z={0}, lhs={0}, rhs={0}, tmp={0}, res={0}; - curve25519_reduce(z, r->z); - - curve25519_mul(lhs, r->x, r->y); - curve25519_mul(rhs, r->z, r->t); - curve25519_sub_reduce(lhs, lhs, rhs); - - curve25519_square(res, r->y); - curve25519_square(tmp, r->x); - curve25519_sub_reduce(res, res, tmp); - curve25519_square(tmp, r->z); - curve25519_sub_reduce(res, res, tmp); - curve25519_square(tmp, r->t); - curve25519_mul(tmp, tmp, ge25519_ecd); - curve25519_sub_reduce(res, res, tmp); - - const int c1 = curve25519_isnonzero(z); - const int c2 = curve25519_isnonzero(lhs); - const int c3 = curve25519_isnonzero(res); - return c1 & (c2^0x1) & (c3^0x1); -} - -int ge25519_eq(const ge25519 *a, const ge25519 *b){ - int eq = 1; - bignum25519 t1={0}, t2={0}; - - eq &= ge25519_check(a); - eq &= ge25519_check(b); - - curve25519_mul(t1, a->x, b->z); - curve25519_mul(t2, b->x, a->z); - curve25519_sub_reduce(t1, t1, t2); - eq &= curve25519_isnonzero(t1) ^ 1; - - curve25519_mul(t1, a->y, b->z); - curve25519_mul(t2, b->y, a->z); - curve25519_sub_reduce(t1, t1, t2); - eq &= curve25519_isnonzero(t1) ^ 1; - - return eq; -} - -void ge25519_copy(ge25519 *dst, const ge25519 *src){ - curve25519_copy(dst->x, src->x); - curve25519_copy(dst->y, src->y); - curve25519_copy(dst->z, src->z); - curve25519_copy(dst->t, src->t); -} - -void ge25519_set_base(ge25519 *r){ - ge25519_copy(r, &ge25519_basepoint); -} - -void ge25519_mul8(ge25519 *r, const ge25519 *t) { - ge25519_double_partial(r, t); - ge25519_double_partial(r, r); - ge25519_double(r, r); -} - -void ge25519_neg_partial(ge25519 *r){ - curve25519_neg(r->x, r->x); -} - -void ge25519_neg_full(ge25519 *r){ - curve25519_neg(r->x, r->x); - curve25519_neg(r->t, r->t); -} - -void ge25519_reduce(ge25519 *r, const ge25519 *t){ - curve25519_reduce(r->x, t->x); - curve25519_reduce(r->y, t->y); - curve25519_reduce(r->z, t->z); - curve25519_reduce(r->t, t->t); -} - -void ge25519_norm(ge25519 *r, const ge25519 * t){ - bignum25519 zinv = {0}; - curve25519_recip(zinv, t->z); - curve25519_mul(r->x, t->x, zinv); - curve25519_mul(r->y, t->y, zinv); - curve25519_mul(r->t, r->x, r->y); - curve25519_set(r->z, 1); -} - -void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q, unsigned char signbit) { - ge25519_pniels P_ni = {0}; - ge25519_p1p1 P_11 = {0}; - - ge25519_full_to_pniels(&P_ni, q); - ge25519_pnielsadd_p1p1(&P_11, p, &P_ni, signbit); - ge25519_p1p1_to_full(r, &P_11); -} - -void ge25519_fromfe_frombytes_vartime(ge25519 *r, const unsigned char *s){ - bignum25519 u={0}, v={0}, w={0}, x={0}, y={0}, z={0}; - unsigned char sign = 0; - - curve25519_expand_reduce(u, s); - - curve25519_square(v, u); - curve25519_add_reduce(v, v, v); /* 2 * u^2 */ - curve25519_set(w, 1); - curve25519_add_reduce(w, v, w); /* w = 2 * u^2 + 1 */ - - curve25519_square(x, w); /* w^2 */ - curve25519_mul(y, fe_ma2, v); /* -2 * A^2 * u^2 */ - curve25519_add_reduce(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ - - curve25519_divpowm1(r->x, w, x); /* (w / x)^(m + 1) */ - curve25519_square(y, r->x); - curve25519_mul(x, y, x); - curve25519_sub_reduce(y, w, x); - curve25519_copy(z, fe_ma); - - if (curve25519_isnonzero(y)) { - curve25519_add_reduce(y, w, x); - if (curve25519_isnonzero(y)) { - goto negative; - } else { - curve25519_mul(r->x, r->x, fe_fffb1); - } - } else { - curve25519_mul(r->x, r->x, fe_fffb2); - } - curve25519_mul(r->x, r->x, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ - curve25519_mul(z, z, v); /* -2 * A * u^2 */ - sign = 0; - goto setsign; -negative: - curve25519_mul(x, x, fe_sqrtm1); - curve25519_sub_reduce(y, w, x); - if (curve25519_isnonzero(y)) { - assert((curve25519_add_reduce(y, w, x), !curve25519_isnonzero(y))); - curve25519_mul(r->x, r->x, fe_fffb3); - } else { - curve25519_mul(r->x, r->x, fe_fffb4); - } - /* r->x = sqrt(A * (A + 2) * w / x) */ - /* z = -A */ - sign = 1; -setsign: - if (curve25519_isnegative(r->x) != sign) { - assert(curve25519_isnonzero(r->x)); - curve25519_neg(r->x, r->x); - } - curve25519_add_reduce(r->z, z, w); - curve25519_sub_reduce(r->y, z, w); - curve25519_mul(r->x, r->x, r->z); - - // Partial form, saving from T coord computation . - // Later is mul8 discarding T anyway. - // rt = ((rx * ry % q) * inv(rz)) % q - // curve25519_mul(x, r->x, r->y); - // curve25519_recip(z, r->z); - // curve25519_mul(r->t, x, z); - -#if !defined(NDEBUG) - { - bignum25519 check_x={0}, check_y={0}, check_iz={0}, check_v={0}; - curve25519_recip(check_iz, r->z); - curve25519_mul(check_x, r->x, check_iz); - curve25519_mul(check_y, r->y, check_iz); - curve25519_square(check_x, check_x); - curve25519_square(check_y, check_y); - curve25519_mul(check_v, check_x, check_y); - curve25519_mul(check_v, fe_d, check_v); - curve25519_add_reduce(check_v, check_v, check_x); - curve25519_sub_reduce(check_v, check_v, check_y); - curve25519_set(check_x, 1); - curve25519_add_reduce(check_v, check_v, check_x); - assert(!curve25519_isnonzero(check_v)); - } -#endif -} - -int ge25519_unpack_vartime(ge25519 *r, const unsigned char *s){ - int res = ge25519_unpack_negative_vartime(r, s); - ge25519_neg_full(r); - return res; -} - -void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s){ - ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s); -} diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-keccak.c b/trezor-crypto/crypto/ed25519-donna/ed25519-keccak.c deleted file mode 100644 index 4c5ca06ead0..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-keccak.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#include -#include - -#define ED25519_SUFFIX _keccak - -#include "ed25519.c" diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519-sha3.c b/trezor-crypto/crypto/ed25519-donna/ed25519-sha3.c deleted file mode 100644 index 8993ca83fff..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519-sha3.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#include -#include - -#define ED25519_SUFFIX _sha3 - -#include "ed25519.c" diff --git a/trezor-crypto/crypto/ed25519-donna/ed25519.c b/trezor-crypto/crypto/ed25519-donna/ed25519.c deleted file mode 100644 index 6e01c0c1e98..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/ed25519.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - Public domain by Andrew M. - - Ed25519 reference implementation using Ed25519-donna -*/ - - -/* define ED25519_SUFFIX to have it appended to the end of each public function */ -#ifdef ED25519_SUFFIX -#define ED25519_FN3(fn,suffix) fn##suffix -#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix) -#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX) -#else -#define ED25519_FN(fn) fn -#endif - -#include -#include - -#include -#include - -/* - Generates a (extsk[0..31]) and aExt (extsk[32..63]) -*/ -DONNA_INLINE static void -ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { - ed25519_hash(extsk, sk, 32); - extsk[0] &= 248; - extsk[31] &= 127; - extsk[31] |= 64; -} - -static void -ed25519_hram(hash_512bits hram, const ed25519_public_key R, const ed25519_public_key pk, const unsigned char *m, size_t mlen) { - ed25519_hash_context ctx; - ed25519_hash_init(&ctx); - ed25519_hash_update(&ctx, R, 32); - ed25519_hash_update(&ctx, pk, 32); - ed25519_hash_update(&ctx, m, mlen); - ed25519_hash_final(&ctx, hram); -} - -void -ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) { - hash_512bits extsk = {0}; - ed25519_extsk(extsk, sk); - ed25519_publickey_ext(extsk, pk); - memzero(&extsk, sizeof(extsk)); -} - -void -ED25519_FN(ed25519_cosi_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) { - bignum256modm r = {0}, S = {0}, a = {0}; - hash_512bits extsk = {0}, extnonce = {0}, hram = {0}; - - ed25519_extsk(extsk, sk); - ed25519_extsk(extnonce, nonce); - - /* r = nonce */ - expand256_modm(r, extnonce, 32); - memzero(&extnonce, sizeof(extnonce)); - - /* S = H(R,A,m).. */ - ed25519_hram(hram, R, pk, m, mlen); - expand256_modm(S, hram, 64); - - /* S = H(R,A,m)a */ - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - mul256_modm(S, S, a); - memzero(&a, sizeof(a)); - - /* S = (r + H(R,A,m)a) */ - add256_modm(S, S, r); - memzero(&r, sizeof(r)); - - /* S = (r + H(R,A,m)a) mod L */ - contract256_modm(sig, S); -} - -void -ED25519_FN(ed25519_sign_ext) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_signature RS) { - ed25519_hash_context ctx; - bignum256modm r = {0}, S = {0}, a = {0}; - ge25519 ALIGN(16) R = {0}; - ge25519 ALIGN(16) A = {0}; - ed25519_public_key pk = {0}; - hash_512bits extsk = {0}, hashr = {0}, hram = {0}; - - /* we don't stretch the key through hashing first since its already 64 bytes */ - - memcpy(extsk, sk, 32); - memcpy(extsk+32, skext, 32); - - - /* r = H(aExt[32..64], m) */ - ed25519_hash_init(&ctx); - ed25519_hash_update(&ctx, extsk + 32, 32); - ed25519_hash_update(&ctx, m, mlen); - ed25519_hash_final(&ctx, hashr); - expand256_modm(r, hashr, 64); - memzero(&hashr, sizeof(hashr)); - - /* R = rB */ - ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); - ge25519_pack(RS, &R); - - /* a = aExt[0..31] */ - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - - /* A = aB */ - ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); - ge25519_pack(pk, &A); - - /* S = H(R,A,m).. */ - ed25519_hram(hram, RS, pk, m, mlen); - expand256_modm(S, hram, 64); - - /* S = H(R,A,m)a */ - mul256_modm(S, S, a); - memzero(&a, sizeof(a)); - - /* S = (r + H(R,A,m)a) */ - add256_modm(S, S, r); - memzero(&r, sizeof(r)); - - /* S = (r + H(R,A,m)a) mod L */ - contract256_modm(RS + 32, S); -} - -void -ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS) { - hash_512bits extsk = {0}; - ed25519_extsk(extsk, sk); - ED25519_FN(ed25519_sign_ext)(m, mlen, extsk, extsk + 32, RS); - memzero(&extsk, sizeof(extsk)); -} - -int -ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { - ge25519 ALIGN(16) R = {0}, A = {0}; - hash_512bits hash = {0}; - bignum256modm hram = {0}, S = {0}; - unsigned char checkR[32] = {0}; - - if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) - return -1; - - /* hram = H(R,A,m) */ - ed25519_hram(hash, RS, pk, m, mlen); - expand256_modm(hram, hash, 64); - - /* S */ - expand_raw256_modm(S, RS + 32); - if (!is_reduced256_modm(S)) - return -1; - - /* SB - H(R,A,m)A */ - ge25519_double_scalarmult_vartime(&R, &A, hram, S); - ge25519_pack(checkR, &R); - - /* check that R = SB - H(R,A,m)A */ - return ed25519_verify(RS, checkR, 32) ? 0 : -1; -} - -int -ED25519_FN(ed25519_scalarmult) (ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk) { - bignum256modm a = {0}; - ge25519 ALIGN(16) A = {0}, P = {0}; - hash_512bits extsk = {0}; - - ed25519_extsk(extsk, sk); - expand256_modm(a, extsk, 32); - memzero(&extsk, sizeof(extsk)); - - if (!ge25519_unpack_negative_vartime(&P, pk)) { - return -1; - } - - ge25519_scalarmult(&A, &P, a); - memzero(&a, sizeof(a)); - curve25519_neg(A.x, A.x); - ge25519_pack(res, &A); - return 0; -} - - -#ifndef ED25519_SUFFIX - -#include - -void -ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk) { - bignum256modm a = {0}; - ge25519 ALIGN(16) A = {0}; - - expand256_modm(a, extsk, 32); - - /* A = aB */ - ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); - memzero(&a, sizeof(a)); - ge25519_pack(pk, &A); -} - -int -ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) { - size_t i = 0; - ge25519 P = {0}; - ge25519_pniels sump = {0}; - ge25519_p1p1 sump1 = {0}; - - if (n == 1) { - memcpy(res, pks, sizeof(ed25519_public_key)); - return 0; - } - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_full_to_pniels(&sump, &P); - while (i < n - 1) { - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_pnielsadd(&sump, &P, &sump); - } - if (!ge25519_unpack_negative_vartime(&P, pks[i++])) { - return -1; - } - ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0); - ge25519_p1p1_to_partial(&P, &sump1); - curve25519_neg(P.x, P.x); - ge25519_pack(res, &P); - return 0; -} - -void -ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) { - bignum256modm s = {0}, t = {0}; - size_t i = 0; - - expand256_modm(s, sigs[i++], 32); - while (i < n) { - expand256_modm(t, sigs[i++], 32); - add256_modm(s, s, t); - } - memcpy(res, R, 32); - contract256_modm(res + 32, s); -} - -/* - Fast Curve25519 basepoint scalar multiplication -*/ -void -curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) { - curve25519_key ec = {0}; - bignum256modm s = {0}; - bignum25519 ALIGN(16) yplusz = {0}, zminusy = {0}; - ge25519 ALIGN(16) p = {0}; - size_t i = 0; - - /* clamp */ - for (i = 0; i < 32; i++) ec[i] = e[i]; - ec[0] &= 248; - ec[31] &= 127; - ec[31] |= 64; - - expand_raw256_modm(s, ec); - memzero(&ec, sizeof(ec)); - - /* scalar * basepoint */ - ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); - memzero(&s, sizeof(s)); - - /* u = (y + z) / (z - y) */ - curve25519_add(yplusz, p.y, p.z); - curve25519_sub(zminusy, p.z, p.y); - curve25519_recip(zminusy, zminusy); - curve25519_mul(yplusz, yplusz, zminusy); - curve25519_contract(pk, yplusz); -} - -void -curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint) { - curve25519_key e = {0}; - size_t i = 0; - - for (i = 0;i < 32;++i) e[i] = secret[i]; - e[0] &= 0xf8; - e[31] &= 0x7f; - e[31] |= 0x40; - curve25519_scalarmult_donna(mypublic, e, basepoint); - memzero(&e, sizeof(e)); -} - -#endif // ED25519_SUFFIX diff --git a/trezor-crypto/crypto/ed25519-donna/modm-donna-32bit.c b/trezor-crypto/crypto/ed25519-donna/modm-donna-32bit.c deleted file mode 100644 index a2b49ee5c3e..00000000000 --- a/trezor-crypto/crypto/ed25519-donna/modm-donna-32bit.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - Public domain by Andrew M. -*/ - -#include - -/* - 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 -*/ - -const bignum256modm modm_m = { - 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8, - 0x00000014, 0x00000000, 0x00000000, 0x00000000, - 0x00001000 -}; - -const bignum256modm modm_mu = { - 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742, - 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff, - 0x000fffff -}; - -static bignum256modm_element_t -lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { - return (a - b) >> 31; -} - -/* see HAC, Alg. 14.42 Step 4 */ -void reduce256_modm(bignum256modm r) { - bignum256modm t = {0}; - bignum256modm_element_t b = 0, pb = 0, mask = 0; - - /* t = r - m */ - pb = 0; - pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b; - pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b; - pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b; - pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b; - pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b; - pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b; - pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b; - pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b; - pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16)); - - /* keep r if r was smaller than m */ - mask = b - 1; - r[0] ^= mask & (r[0] ^ t[0]); - r[1] ^= mask & (r[1] ^ t[1]); - r[2] ^= mask & (r[2] ^ t[2]); - r[3] ^= mask & (r[3] ^ t[3]); - r[4] ^= mask & (r[4] ^ t[4]); - r[5] ^= mask & (r[5] ^ t[5]); - r[6] ^= mask & (r[6] ^ t[6]); - r[7] ^= mask & (r[7] ^ t[7]); - r[8] ^= mask & (r[8] ^ t[8]); -} - -/* - Barrett reduction, see HAC, Alg. 14.42 - - Instead of passing in x, pre-process in to q1 and r1 for efficiency -*/ -void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { - bignum256modm q3 = {0}, r2 = {0}; - uint64_t c = 0; - bignum256modm_element_t f = 0, b = 0, pb = 0; - - /* q1 = x >> 248 = 264 bits = 9 30 bit elements - q2 = mu * q1 - q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ - c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); - c >>= 30; - c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]); - f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); - f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]); - f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); - f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]); - f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); - f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]); - f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); - f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30; - c += mul32x32_64(modm_mu[8], q1[8]); - f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24); - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(32+1) = x & ((1 << 264) - 1) - r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */ - c = mul32x32_64(modm_m[0], q3[0]); - r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); - r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]); - r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); - r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]); - r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); - r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]); - r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); - r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; - c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]); - r2[8] = (bignum256modm_element_t)(c & 0xffffff); - - /* r = r1 - r2 - if (r < 0) r += (1 << 264) */ - pb = 0; - pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b; - pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b; - pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b; - pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b; - pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b; - pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b; - pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b; - pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b; - pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24)); - - reduce256_modm(r); - reduce256_modm(r); -} - -/* addition modulo m */ -void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm_element_t c = 0; - - c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30; - c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30; - c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30; - c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30; - c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30; - c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30; - c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30; - c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30; - c += x[8] + y[8]; r[8] = c; - - reduce256_modm(r); -} - -/* -x modulo m */ -void neg256_modm(bignum256modm r, const bignum256modm x) { - bignum256modm_element_t b = 0, pb = 0; - - /* r = m - x */ - pb = 0; - pb += x[0]; b = lt_modm(modm_m[0], pb); r[0] = (modm_m[0] - pb + (b << 30)); pb = b; - pb += x[1]; b = lt_modm(modm_m[1], pb); r[1] = (modm_m[1] - pb + (b << 30)); pb = b; - pb += x[2]; b = lt_modm(modm_m[2], pb); r[2] = (modm_m[2] - pb + (b << 30)); pb = b; - pb += x[3]; b = lt_modm(modm_m[3], pb); r[3] = (modm_m[3] - pb + (b << 30)); pb = b; - pb += x[4]; b = lt_modm(modm_m[4], pb); r[4] = (modm_m[4] - pb + (b << 30)); pb = b; - pb += x[5]; b = lt_modm(modm_m[5], pb); r[5] = (modm_m[5] - pb + (b << 30)); pb = b; - pb += x[6]; b = lt_modm(modm_m[6], pb); r[6] = (modm_m[6] - pb + (b << 30)); pb = b; - pb += x[7]; b = lt_modm(modm_m[7], pb); r[7] = (modm_m[7] - pb + (b << 30)); pb = b; - pb += x[8]; b = lt_modm(modm_m[8], pb); r[8] = (modm_m[8] - pb + (b << 16)); - - // if x==0, reduction is required - reduce256_modm(r); -} - -/* consts for subtraction, > p */ -/* Emilia Kasper trick, https://www.imperialviolet.org/2010/12/04/ecc.html */ -const uint32_t twoP[] = { - 0x5cf5d3ed, 0x60498c68, 0x6f79cd64, 0x77be77a7, 0x40000013, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xfff}; - -/* subtraction x-y % m */ -void sub256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm_element_t c = 0; - c = twoP[0] + x[0] - y[0]; r[0] = c & 0x3fffffff; c >>= 30; - c += twoP[1] + x[1] - y[1]; r[1] = c & 0x3fffffff; c >>= 30; - c += twoP[2] + x[2] - y[2]; r[2] = c & 0x3fffffff; c >>= 30; - c += twoP[3] + x[3] - y[3]; r[3] = c & 0x3fffffff; c >>= 30; - c += twoP[4] + x[4] - y[4]; r[4] = c & 0x3fffffff; c >>= 30; - c += twoP[5] + x[5] - y[5]; r[5] = c & 0x3fffffff; c >>= 30; - c += twoP[6] + x[6] - y[6]; r[6] = c & 0x3fffffff; c >>= 30; - c += twoP[7] + x[7] - y[7]; r[7] = c & 0x3fffffff; c >>= 30; - c += twoP[8] + x[8] - y[8]; r[8] = c; - reduce256_modm(r); -} - -/* multiplication modulo m */ -void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { - bignum256modm r1 = {0}, q1 = {0}; - uint64_t c = 0; - bignum256modm_element_t f = 0; - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) - q1 = x >> 248 = 264 bits = 9 30 bit elements */ - c = mul32x32_64(x[0], y[0]); - f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); - f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); - f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]); - f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); - f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); - f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]); - f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); - f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30; - c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); - f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); - f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]); - f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); - f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); - f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]); - f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); - f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); - f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30; - c += mul32x32_64(x[8], y[8]); - f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff; - - barrett_reduce256_modm(r, q1, r1); -} - -void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { - unsigned char work[64] = {0}; - bignum256modm_element_t x[16] = {0}; - bignum256modm q1 = {0}; - - memcpy(work, in, len); - x[0] = U8TO32_LE(work + 0); - x[1] = U8TO32_LE(work + 4); - x[2] = U8TO32_LE(work + 8); - x[3] = U8TO32_LE(work + 12); - x[4] = U8TO32_LE(work + 16); - x[5] = U8TO32_LE(work + 20); - x[6] = U8TO32_LE(work + 24); - x[7] = U8TO32_LE(work + 28); - x[8] = U8TO32_LE(work + 32); - x[9] = U8TO32_LE(work + 36); - x[10] = U8TO32_LE(work + 40); - x[11] = U8TO32_LE(work + 44); - x[12] = U8TO32_LE(work + 48); - x[13] = U8TO32_LE(work + 52); - x[14] = U8TO32_LE(work + 56); - x[15] = U8TO32_LE(work + 60); - - /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ - out[0] = ( x[0]) & 0x3fffffff; - out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; - out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; - out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; - out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; - out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; - out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; - out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; - out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff; - - /* 8*31 = 248 bits, no need to reduce */ - if (len < 32) - return; - - /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ - q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff; - q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff; - q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff; - q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; - q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; - q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; - q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; - q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; - q1[8] = ((x[15] >> 8) ); - - barrett_reduce256_modm(out, q1, out); -} - -void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { - bignum256modm_element_t x[8] = {0}; - - x[0] = U8TO32_LE(in + 0); - x[1] = U8TO32_LE(in + 4); - x[2] = U8TO32_LE(in + 8); - x[3] = U8TO32_LE(in + 12); - x[4] = U8TO32_LE(in + 16); - x[5] = U8TO32_LE(in + 20); - x[6] = U8TO32_LE(in + 24); - x[7] = U8TO32_LE(in + 28); - - out[0] = ( x[0]) & 0x3fffffff; - out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; - out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; - out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; - out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; - out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; - out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; - out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; - out[8] = ((x[ 7] >> 16) ) & 0x0000ffff; -} - -int is_reduced256_modm(const bignum256modm in) -{ - int i = 0; - uint32_t res1 = 0; - uint32_t res2 = 0; - for (i = 8; i >= 0; i--) { - res1 = (res1 << 1) | (in[i] < modm_m[i]); - res2 = (res2 << 1) | (in[i] > modm_m[i]); - } - return res1 > res2; -} - -void contract256_modm(unsigned char out[32], const bignum256modm in) { - U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30)); - U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); - U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); - U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); - U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); - U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); - U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); - U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); -} - -void contract256_window4_modm(signed char r[64], const bignum256modm in) { - char carry = 0; - signed char *quads = r; - bignum256modm_element_t i = 0, j = 0, v = 0; - - for (i = 0; i < 8; i += 2) { - v = in[i]; - for (j = 0; j < 7; j++) { - *quads++ = (v & 15); - v >>= 4; - } - v |= (in[i+1] << 2); - for (j = 0; j < 8; j++) { - *quads++ = (v & 15); - v >>= 4; - } - } - v = in[8]; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - *quads++ = (v & 15); v >>= 4; - - /* making it signed */ - carry = 0; - for(i = 0; i < 63; i++) { - r[i] += carry; - r[i+1] += (r[i] >> 4); - r[i] &= 15; - carry = (r[i] >> 3); - r[i] -= (carry << 4); - } - r[63] += carry; -} - -void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { - int i = 0, j = 0, k = 0, b = 0; - int m = (1 << (windowsize - 1)) - 1, soplen = 256; - signed char *bits = r; - bignum256modm_element_t v = 0; - - /* first put the binary expansion into r */ - for (i = 0; i < 8; i++) { - v = s[i]; - for (j = 0; j < 30; j++, v >>= 1) - *bits++ = (v & 1); - } - v = s[8]; - for (j = 0; j < 16; j++, v >>= 1) - *bits++ = (v & 1); - - /* Making it sliding window */ - for (j = 0; j < soplen; j++) { - if (!r[j]) - continue; - - for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { - if ((r[j] + (r[j + b] << b)) <= m) { - r[j] += r[j + b] << b; - r[j + b] = 0; - } else if ((r[j] - (r[j + b] << b)) >= -m) { - r[j] -= r[j + b] << b; - for (k = j + b; k < soplen; k++) { - if (!r[k]) { - r[k] = 1; - break; - } - r[k] = 0; - } - } else if (r[j + b]) { - break; - } - } - } -} - -void set256_modm(bignum256modm r, uint64_t v) { - r[0] = (bignum256modm_element_t) (v & 0x3fffffff); v >>= 30; - r[1] = (bignum256modm_element_t) (v & 0x3fffffff); v >>= 30; - r[2] = (bignum256modm_element_t) (v & 0x3fffffff); - r[3] = 0; - r[4] = 0; - r[5] = 0; - r[6] = 0; - r[7] = 0; - r[8] = 0; -} - -int get256_modm(uint64_t * v, const bignum256modm r){ - *v = 0; - int con1 = 0; - -#define NONZ(x) ((((((int64_t)(x)) - 1) >> 32) + 1) & 1) - bignum256modm_element_t c = 0; - c = r[0]; *v += (uint64_t)c & 0x3fffffff; c >>= 30; // 30 - c += r[1]; *v += ((uint64_t)c & 0x3fffffff) << 30; c >>= 30; // 60 - c += r[2]; *v += ((uint64_t)c & 0xf) << 60; con1 |= NONZ(c>>4); c >>= 30; // 64 bits - c += r[3]; con1 |= NONZ(c); c >>= 30; - c += r[4]; con1 |= NONZ(c); c >>= 30; - c += r[5]; con1 |= NONZ(c); c >>= 30; - c += r[6]; con1 |= NONZ(c); c >>= 30; - c += r[7]; con1 |= NONZ(c); c >>= 30; - c += r[8]; con1 |= NONZ(c); c >>= 30; - con1 |= NONZ(c); -#undef NONZ - - return con1 ^ 1; -} - -int eq256_modm(const bignum256modm x, const bignum256modm y){ - size_t differentbits = 0; - int len = bignum256modm_limb_size; - while (len--) { - differentbits |= (*x++ ^ *y++); - } - return (int) (1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); -} - -int cmp256_modm(const bignum256modm x, const bignum256modm y){ - int len = 2*bignum256modm_limb_size; - uint32_t a_gt = 0; - uint32_t b_gt = 0; - - // 16B chunks - while (len--) { - const uint32_t ln = (const uint32_t) len; - const uint32_t a = (x[ln>>1] >> 16*(ln & 1)) & 0xffff; - const uint32_t b = (y[ln>>1] >> 16*(ln & 1)) & 0xffff; - - const uint32_t limb_a_gt = ((b - a) >> 16) & 1; - const uint32_t limb_b_gt = ((a - b) >> 16) & 1; - a_gt |= limb_a_gt & ~b_gt; - b_gt |= limb_b_gt & ~a_gt; - } - - return a_gt - b_gt; -} - -int iszero256_modm(const bignum256modm x){ - size_t differentbits = 0; - int len = bignum256modm_limb_size; - while (len--) { - differentbits |= (*x++); - } - return (int) (1 & ((differentbits - 1) >> bignum256modm_bits_per_limb)); -} - -void copy256_modm(bignum256modm r, const bignum256modm x){ - r[0] = x[0]; - r[1] = x[1]; - r[2] = x[2]; - r[3] = x[3]; - r[4] = x[4]; - r[5] = x[5]; - r[6] = x[6]; - r[7] = x[7]; - r[8] = x[8]; -} - -int check256_modm(const bignum256modm x){ - int ok = 1; - bignum256modm t={0}, z={0}; - - ok &= iszero256_modm(x) ^ 1; - barrett_reduce256_modm(t, z, x); - ok &= eq256_modm(t, x); - return ok; -} - -void mulsub256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c){ - //(cc - aa * bb) % l - bignum256modm t={0}; - mul256_modm(t, a, b); - sub256_modm(r, c, t); -} - -void muladd256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c){ - //(cc + aa * bb) % l - bignum256modm t={0}; - mul256_modm(t, a, b); - add256_modm(r, c, t); -} diff --git a/trezor-crypto/crypto/groestl.c b/trezor-crypto/crypto/groestl.c deleted file mode 100644 index 12d88d877b7..00000000000 --- a/trezor-crypto/crypto/groestl.c +++ /dev/null @@ -1,783 +0,0 @@ -/* Groestl hash from https://github.com/Groestlcoin/vanitygen - * Trezor adaptation by Yura Pakhuchiy . */ -/* - * 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 - */ - -#include -#include - -#include -#include -#include - - -#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))) - - -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) -}; - -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) -}; - -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) -}; - -const sph_u32 T1dn[] = { - C32e(0xa5f497a5), C32e(0x8497eb84), C32e(0x99b0c799), C32e(0x8d8cf78d), - C32e(0x0d17e50d), C32e(0xbddcb7bd), C32e(0xb1c8a7b1), C32e(0x54fc3954), - C32e(0x50f0c050), C32e(0x03050403), C32e(0xa9e087a9), C32e(0x7d87ac7d), - C32e(0x192bd519), C32e(0x62a67162), C32e(0xe6319ae6), C32e(0x9ab5c39a), - C32e(0x45cf0545), C32e(0x9dbc3e9d), C32e(0x40c00940), C32e(0x8792ef87), - C32e(0x153fc515), C32e(0xeb267feb), C32e(0xc94007c9), C32e(0x0b1ded0b), - C32e(0xec2f82ec), C32e(0x67a97d67), C32e(0xfd1cbefd), C32e(0xea258aea), - C32e(0xbfda46bf), C32e(0xf702a6f7), C32e(0x96a1d396), C32e(0x5bed2d5b), - C32e(0xc25deac2), C32e(0x1c24d91c), C32e(0xaee97aae), C32e(0x6abe986a), - C32e(0x5aeed85a), C32e(0x41c3fc41), C32e(0x0206f102), C32e(0x4fd11d4f), - C32e(0x5ce4d05c), C32e(0xf407a2f4), C32e(0x345cb934), C32e(0x0818e908), - C32e(0x93aedf93), C32e(0x73954d73), C32e(0x53f5c453), C32e(0x3f41543f), - C32e(0x0c14100c), C32e(0x52f63152), C32e(0x65af8c65), C32e(0x5ee2215e), - C32e(0x28786028), C32e(0xa1f86ea1), C32e(0x0f11140f), C32e(0xb5c45eb5), - C32e(0x091b1c09), C32e(0x365a4836), C32e(0x9bb6369b), C32e(0x3d47a53d), - C32e(0x266a8126), C32e(0x69bb9c69), C32e(0xcd4cfecd), C32e(0x9fbacf9f), - C32e(0x1b2d241b), C32e(0x9eb93a9e), C32e(0x749cb074), C32e(0x2e72682e), - C32e(0x2d776c2d), C32e(0xb2cda3b2), C32e(0xee2973ee), C32e(0xfb16b6fb), - C32e(0xf60153f6), C32e(0x4dd7ec4d), C32e(0x61a37561), C32e(0xce49face), - C32e(0x7b8da47b), C32e(0x3e42a13e), C32e(0x7193bc71), C32e(0x97a22697), - C32e(0xf50457f5), C32e(0x68b86968), C32e(0x00000000), C32e(0x2c74992c), - C32e(0x60a08060), C32e(0x1f21dd1f), C32e(0xc843f2c8), C32e(0xed2c77ed), - C32e(0xbed9b3be), C32e(0x46ca0146), C32e(0xd970ced9), C32e(0x4bdde44b), - C32e(0xde7933de), C32e(0xd4672bd4), C32e(0xe8237be8), C32e(0x4ade114a), - C32e(0x6bbd6d6b), C32e(0x2a7e912a), C32e(0xe5349ee5), C32e(0x163ac116), - C32e(0xc55417c5), C32e(0xd7622fd7), C32e(0x55ffcc55), C32e(0x94a72294), - C32e(0xcf4a0fcf), C32e(0x1030c910), C32e(0x060a0806), C32e(0x8198e781), - C32e(0xf00b5bf0), C32e(0x44ccf044), C32e(0xbad54aba), C32e(0xe33e96e3), - C32e(0xf30e5ff3), C32e(0xfe19bafe), C32e(0xc05b1bc0), C32e(0x8a850a8a), - C32e(0xadec7ead), C32e(0xbcdf42bc), C32e(0x48d8e048), C32e(0x040cf904), - C32e(0xdf7ac6df), C32e(0xc158eec1), C32e(0x759f4575), C32e(0x63a58463), - C32e(0x30504030), C32e(0x1a2ed11a), C32e(0x0e12e10e), C32e(0x6db7656d), - C32e(0x4cd4194c), C32e(0x143c3014), C32e(0x355f4c35), C32e(0x2f719d2f), - C32e(0xe13867e1), C32e(0xa2fd6aa2), C32e(0xcc4f0bcc), C32e(0x394b5c39), - C32e(0x57f93d57), C32e(0xf20daaf2), C32e(0x829de382), C32e(0x47c9f447), - C32e(0xacef8bac), C32e(0xe7326fe7), C32e(0x2b7d642b), C32e(0x95a4d795), - C32e(0xa0fb9ba0), C32e(0x98b33298), C32e(0xd16827d1), C32e(0x7f815d7f), - C32e(0x66aa8866), C32e(0x7e82a87e), C32e(0xabe676ab), C32e(0x839e1683), - C32e(0xca4503ca), C32e(0x297b9529), C32e(0xd36ed6d3), C32e(0x3c44503c), - C32e(0x798b5579), C32e(0xe23d63e2), C32e(0x1d272c1d), C32e(0x769a4176), - C32e(0x3b4dad3b), C32e(0x56fac856), C32e(0x4ed2e84e), C32e(0x1e22281e), - C32e(0xdb763fdb), C32e(0x0a1e180a), C32e(0x6cb4906c), C32e(0xe4376be4), - C32e(0x5de7255d), C32e(0x6eb2616e), C32e(0xef2a86ef), C32e(0xa6f193a6), - C32e(0xa8e372a8), C32e(0xa4f762a4), C32e(0x3759bd37), C32e(0x8b86ff8b), - C32e(0x3256b132), C32e(0x43c50d43), C32e(0x59ebdc59), C32e(0xb7c2afb7), - C32e(0x8c8f028c), C32e(0x64ac7964), C32e(0xd26d23d2), C32e(0xe03b92e0), - C32e(0xb4c7abb4), C32e(0xfa1543fa), C32e(0x0709fd07), C32e(0x256f8525), - C32e(0xafea8faf), C32e(0x8e89f38e), C32e(0xe9208ee9), C32e(0x18282018), - C32e(0xd564ded5), C32e(0x8883fb88), C32e(0x6fb1946f), C32e(0x7296b872), - C32e(0x246c7024), C32e(0xf108aef1), C32e(0xc752e6c7), C32e(0x51f33551), - C32e(0x23658d23), C32e(0x7c84597c), C32e(0x9cbfcb9c), C32e(0x21637c21), - C32e(0xdd7c37dd), C32e(0xdc7fc2dc), C32e(0x86911a86), C32e(0x85941e85), - C32e(0x90abdb90), C32e(0x42c6f842), C32e(0xc457e2c4), C32e(0xaae583aa), - C32e(0xd8733bd8), C32e(0x050f0c05), C32e(0x0103f501), C32e(0x12363812), - C32e(0xa3fe9fa3), C32e(0x5fe1d45f), C32e(0xf91047f9), C32e(0xd06bd2d0), - C32e(0x91a82e91), C32e(0x58e82958), C32e(0x27697427), C32e(0xb9d04eb9), - C32e(0x3848a938), C32e(0x1335cd13), C32e(0xb3ce56b3), C32e(0x33554433), - C32e(0xbbd6bfbb), C32e(0x70904970), C32e(0x89800e89), C32e(0xa7f266a7), - C32e(0xb6c15ab6), C32e(0x22667822), C32e(0x92ad2a92), C32e(0x20608920), - C32e(0x49db1549), C32e(0xff1a4fff), C32e(0x7888a078), C32e(0x7a8e517a), - C32e(0x8f8a068f), C32e(0xf813b2f8), C32e(0x809b1280), C32e(0x17393417), - C32e(0xda75cada), C32e(0x3153b531), C32e(0xc65113c6), C32e(0xb8d3bbb8), - C32e(0xc35e1fc3), C32e(0xb0cb52b0), C32e(0x7799b477), C32e(0x11333c11), - C32e(0xcb46f6cb), C32e(0xfc1f4bfc), C32e(0xd661dad6), C32e(0x3a4e583a) -}; - -#define DECL_STATE_SMALL \ - sph_u32 H[16] = {0}; - -#define READ_STATE_SMALL(sc) do { \ - memcpy(H, (sc)->state.narrow, sizeof H); \ - } while (0) - -#define WRITE_STATE_SMALL(sc) do { \ - memcpy((sc)->state.narrow, H, sizeof H); \ - } while (0) - -#define XCAT(x, y) XCAT_(x, y) -#define XCAT_(x, y) x ## y - -#define RSTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ - t[d0] = T0up[B32_0(a[b0])] \ - ^ T1up[B32_1(a[b1])] \ - ^ T2up[B32_2(a[b2])] \ - ^ T3up[B32_3(a[b3])] \ - ^ T0dn[B32_0(a[b4])] \ - ^ T1dn[B32_1(a[b5])] \ - ^ T2dn[B32_2(a[b6])] \ - ^ T3dn[B32_3(a[b7])]; \ - t[d1] = T0dn[B32_0(a[b0])] \ - ^ T1dn[B32_1(a[b1])] \ - ^ T2dn[B32_2(a[b2])] \ - ^ T3dn[B32_3(a[b3])] \ - ^ T0up[B32_0(a[b4])] \ - ^ T1up[B32_1(a[b5])] \ - ^ T2up[B32_2(a[b6])] \ - ^ T3up[B32_3(a[b7])]; \ - } while (0) - -#define ROUND_SMALL_P(a, r) do { \ - sph_u32 t[16]; \ - a[0x0] ^= PC32up(0x00, r); \ - a[0x1] ^= PC32dn(0x00, r); \ - a[0x2] ^= PC32up(0x10, r); \ - a[0x3] ^= PC32dn(0x10, r); \ - a[0x4] ^= PC32up(0x20, r); \ - a[0x5] ^= PC32dn(0x20, r); \ - a[0x6] ^= PC32up(0x30, r); \ - a[0x7] ^= PC32dn(0x30, r); \ - a[0x8] ^= PC32up(0x40, r); \ - a[0x9] ^= PC32dn(0x40, r); \ - a[0xA] ^= PC32up(0x50, r); \ - a[0xB] ^= PC32dn(0x50, r); \ - a[0xC] ^= PC32up(0x60, r); \ - a[0xD] ^= PC32dn(0x60, r); \ - a[0xE] ^= PC32up(0x70, r); \ - a[0xF] ^= PC32dn(0x70, r); \ - RSTT(0x0, 0x1, a, 0x0, 0x2, 0x4, 0x6, 0x9, 0xB, 0xD, 0xF); \ - RSTT(0x2, 0x3, a, 0x2, 0x4, 0x6, 0x8, 0xB, 0xD, 0xF, 0x1); \ - RSTT(0x4, 0x5, a, 0x4, 0x6, 0x8, 0xA, 0xD, 0xF, 0x1, 0x3); \ - RSTT(0x6, 0x7, a, 0x6, 0x8, 0xA, 0xC, 0xF, 0x1, 0x3, 0x5); \ - RSTT(0x8, 0x9, a, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7); \ - RSTT(0xA, 0xB, a, 0xA, 0xC, 0xE, 0x0, 0x3, 0x5, 0x7, 0x9); \ - RSTT(0xC, 0xD, a, 0xC, 0xE, 0x0, 0x2, 0x5, 0x7, 0x9, 0xB); \ - RSTT(0xE, 0xF, a, 0xE, 0x0, 0x2, 0x4, 0x7, 0x9, 0xB, 0xD); \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define ROUND_SMALL_Q(a, r) do { \ - sph_u32 t[16]; \ - a[0x0] ^= QC32up(0x00, r); \ - a[0x1] ^= QC32dn(0x00, r); \ - a[0x2] ^= QC32up(0x10, r); \ - a[0x3] ^= QC32dn(0x10, r); \ - a[0x4] ^= QC32up(0x20, r); \ - a[0x5] ^= QC32dn(0x20, r); \ - a[0x6] ^= QC32up(0x30, r); \ - a[0x7] ^= QC32dn(0x30, r); \ - a[0x8] ^= QC32up(0x40, r); \ - a[0x9] ^= QC32dn(0x40, r); \ - a[0xA] ^= QC32up(0x50, r); \ - a[0xB] ^= QC32dn(0x50, r); \ - a[0xC] ^= QC32up(0x60, r); \ - a[0xD] ^= QC32dn(0x60, r); \ - a[0xE] ^= QC32up(0x70, r); \ - a[0xF] ^= QC32dn(0x70, r); \ - RSTT(0x0, 0x1, a, 0x2, 0x6, 0xA, 0xE, 0x1, 0x5, 0x9, 0xD); \ - RSTT(0x2, 0x3, a, 0x4, 0x8, 0xC, 0x0, 0x3, 0x7, 0xB, 0xF); \ - RSTT(0x4, 0x5, a, 0x6, 0xA, 0xE, 0x2, 0x5, 0x9, 0xD, 0x1); \ - RSTT(0x6, 0x7, a, 0x8, 0xC, 0x0, 0x4, 0x7, 0xB, 0xF, 0x3); \ - RSTT(0x8, 0x9, a, 0xA, 0xE, 0x2, 0x6, 0x9, 0xD, 0x1, 0x5); \ - RSTT(0xA, 0xB, a, 0xC, 0x0, 0x4, 0x8, 0xB, 0xF, 0x3, 0x7); \ - RSTT(0xC, 0xD, a, 0xE, 0x2, 0x6, 0xA, 0xD, 0x1, 0x5, 0x9); \ - RSTT(0xE, 0xF, a, 0x0, 0x4, 0x8, 0xC, 0xF, 0x3, 0x7, 0xB); \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define PERM_SMALL_P(a) do { \ - int r; \ - for (r = 0; r < 10; r ++) \ - ROUND_SMALL_P(a, r); \ - } while (0) - -#define PERM_SMALL_Q(a) do { \ - int r; \ - for (r = 0; r < 10; r ++) \ - ROUND_SMALL_Q(a, r); \ - } while (0) - - -#define COMPRESS_SMALL do { \ - sph_u32 g[16], m[16]; \ - size_t u; \ - for (u = 0; u < 16; u ++) { \ - m[u] = dec32e_aligned(buf + (u << 2)); \ - g[u] = m[u] ^ H[u]; \ - } \ - PERM_SMALL_P(g); \ - PERM_SMALL_Q(m); \ - for (u = 0; u < 16; u ++) \ - H[u] ^= g[u] ^ m[u]; \ - } while (0) - -#define FINAL_SMALL do { \ - sph_u32 x[16]; \ - size_t u; \ - memcpy(x, H, sizeof x); \ - PERM_SMALL_P(x); \ - for (u = 0; u < 16; u ++) \ - H[u] ^= x[u]; \ - } while (0) - -#define DECL_STATE_BIG \ - sph_u32 H[32] = {0}; - -#define READ_STATE_BIG(sc) do { \ - memcpy(H, (sc)->state.narrow, sizeof H); \ - } while (0) - -#define WRITE_STATE_BIG(sc) do { \ - memcpy((sc)->state.narrow, H, sizeof H); \ - } while (0) - - -#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ - sph_u32 fu2 = T0up[B32_2(a[b2])]; \ - sph_u32 fd2 = T0dn[B32_2(a[b2])]; \ - sph_u32 fu3 = T1up[B32_3(a[b3])]; \ - sph_u32 fd3 = T1dn[B32_3(a[b3])]; \ - sph_u32 fu6 = T0up[B32_2(a[b6])]; \ - sph_u32 fd6 = T0dn[B32_2(a[b6])]; \ - sph_u32 fu7 = T1up[B32_3(a[b7])]; \ - sph_u32 fd7 = T1dn[B32_3(a[b7])]; \ - t[d0] = T0up[B32_0(a[b0])] \ - ^ T1up[B32_1(a[b1])] \ - ^ R32u(fu2, fd2) \ - ^ R32u(fu3, fd3) \ - ^ T0dn[B32_0(a[b4])] \ - ^ T1dn[B32_1(a[b5])] \ - ^ R32d(fu6, fd6) \ - ^ R32d(fu7, fd7); \ - t[d1] = T0dn[B32_0(a[b0])] \ - ^ T1dn[B32_1(a[b1])] \ - ^ R32d(fu2, fd2) \ - ^ R32d(fu3, fd3) \ - ^ T0up[B32_0(a[b4])] \ - ^ T1up[B32_1(a[b5])] \ - ^ R32u(fu6, fd6) \ - ^ R32u(fu7, fd7); \ - } while (0) - - -#define ROUND_BIG_P(a, r) do { \ - sph_u32 t[32]; \ - size_t u; \ - a[0x00] ^= PC32up(0x00, r); \ - a[0x01] ^= PC32dn(0x00, r); \ - a[0x02] ^= PC32up(0x10, r); \ - a[0x03] ^= PC32dn(0x10, r); \ - a[0x04] ^= PC32up(0x20, r); \ - a[0x05] ^= PC32dn(0x20, r); \ - a[0x06] ^= PC32up(0x30, r); \ - a[0x07] ^= PC32dn(0x30, r); \ - a[0x08] ^= PC32up(0x40, r); \ - a[0x09] ^= PC32dn(0x40, r); \ - a[0x0A] ^= PC32up(0x50, r); \ - a[0x0B] ^= PC32dn(0x50, r); \ - a[0x0C] ^= PC32up(0x60, r); \ - a[0x0D] ^= PC32dn(0x60, r); \ - a[0x0E] ^= PC32up(0x70, r); \ - a[0x0F] ^= PC32dn(0x70, r); \ - a[0x10] ^= PC32up(0x80, r); \ - a[0x11] ^= PC32dn(0x80, r); \ - a[0x12] ^= PC32up(0x90, r); \ - a[0x13] ^= PC32dn(0x90, r); \ - a[0x14] ^= PC32up(0xA0, r); \ - a[0x15] ^= PC32dn(0xA0, r); \ - a[0x16] ^= PC32up(0xB0, r); \ - a[0x17] ^= PC32dn(0xB0, r); \ - a[0x18] ^= PC32up(0xC0, r); \ - a[0x19] ^= PC32dn(0xC0, r); \ - a[0x1A] ^= PC32up(0xD0, r); \ - a[0x1B] ^= PC32dn(0xD0, r); \ - a[0x1C] ^= PC32up(0xE0, r); \ - a[0x1D] ^= PC32dn(0xE0, r); \ - a[0x1E] ^= PC32up(0xF0, r); \ - a[0x1F] ^= PC32dn(0xF0, r); \ - for (u = 0; u < 32; u += 8) { \ - RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ - u + 0x00, (u + 0x02) & 0x1F, \ - (u + 0x04) & 0x1F, (u + 0x06) & 0x1F, \ - (u + 0x09) & 0x1F, (u + 0x0B) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x17) & 0x1F); \ - RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ - u + 0x02, (u + 0x04) & 0x1F, \ - (u + 0x06) & 0x1F, (u + 0x08) & 0x1F, \ - (u + 0x0B) & 0x1F, (u + 0x0D) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x19) & 0x1F); \ - RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ - u + 0x04, (u + 0x06) & 0x1F, \ - (u + 0x08) & 0x1F, (u + 0x0A) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x0F) & 0x1F, \ - (u + 0x11) & 0x1F, (u + 0x1B) & 0x1F); \ - RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ - u + 0x06, (u + 0x08) & 0x1F, \ - (u + 0x0A) & 0x1F, (u + 0x0C) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x11) & 0x1F, \ - (u + 0x13) & 0x1F, (u + 0x1D) & 0x1F); \ - } \ - memcpy(a, t, sizeof t); \ - } while (0) - -#define ROUND_BIG_Q(a, r) do { \ - sph_u32 t[32]; \ - size_t u; \ - a[0x00] ^= QC32up(0x00, r); \ - a[0x01] ^= QC32dn(0x00, r); \ - a[0x02] ^= QC32up(0x10, r); \ - a[0x03] ^= QC32dn(0x10, r); \ - a[0x04] ^= QC32up(0x20, r); \ - a[0x05] ^= QC32dn(0x20, r); \ - a[0x06] ^= QC32up(0x30, r); \ - a[0x07] ^= QC32dn(0x30, r); \ - a[0x08] ^= QC32up(0x40, r); \ - a[0x09] ^= QC32dn(0x40, r); \ - a[0x0A] ^= QC32up(0x50, r); \ - a[0x0B] ^= QC32dn(0x50, r); \ - a[0x0C] ^= QC32up(0x60, r); \ - a[0x0D] ^= QC32dn(0x60, r); \ - a[0x0E] ^= QC32up(0x70, r); \ - a[0x0F] ^= QC32dn(0x70, r); \ - a[0x10] ^= QC32up(0x80, r); \ - a[0x11] ^= QC32dn(0x80, r); \ - a[0x12] ^= QC32up(0x90, r); \ - a[0x13] ^= QC32dn(0x90, r); \ - a[0x14] ^= QC32up(0xA0, r); \ - a[0x15] ^= QC32dn(0xA0, r); \ - a[0x16] ^= QC32up(0xB0, r); \ - a[0x17] ^= QC32dn(0xB0, r); \ - a[0x18] ^= QC32up(0xC0, r); \ - a[0x19] ^= QC32dn(0xC0, r); \ - a[0x1A] ^= QC32up(0xD0, r); \ - a[0x1B] ^= QC32dn(0xD0, r); \ - a[0x1C] ^= QC32up(0xE0, r); \ - a[0x1D] ^= QC32dn(0xE0, r); \ - a[0x1E] ^= QC32up(0xF0, r); \ - a[0x1F] ^= QC32dn(0xF0, r); \ - for (u = 0; u < 32; u += 8) { \ - RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ - (u + 0x02) & 0x1F, (u + 0x06) & 0x1F, \ - (u + 0x0A) & 0x1F, (u + 0x16) & 0x1F, \ - (u + 0x01) & 0x1F, (u + 0x05) & 0x1F, \ - (u + 0x09) & 0x1F, (u + 0x0D) & 0x1F); \ - RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ - (u + 0x04) & 0x1F, (u + 0x08) & 0x1F, \ - (u + 0x0C) & 0x1F, (u + 0x18) & 0x1F, \ - (u + 0x03) & 0x1F, (u + 0x07) & 0x1F, \ - (u + 0x0B) & 0x1F, (u + 0x0F) & 0x1F); \ - RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ - (u + 0x06) & 0x1F, (u + 0x0A) & 0x1F, \ - (u + 0x0E) & 0x1F, (u + 0x1A) & 0x1F, \ - (u + 0x05) & 0x1F, (u + 0x09) & 0x1F, \ - (u + 0x0D) & 0x1F, (u + 0x11) & 0x1F); \ - RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ - (u + 0x08) & 0x1F, (u + 0x0C) & 0x1F, \ - (u + 0x10) & 0x1F, (u + 0x1C) & 0x1F, \ - (u + 0x07) & 0x1F, (u + 0x0B) & 0x1F, \ - (u + 0x0F) & 0x1F, (u + 0x13) & 0x1F); \ - } \ - memcpy(a, t, sizeof t); \ - } while (0) - - -#define PERM_BIG_P(a) do { \ - int r; \ - for (r = 0; r < 14; r ++) \ - ROUND_BIG_P(a, r); \ - } while (0) - -#define PERM_BIG_Q(a) do { \ - int r; \ - for (r = 0; r < 14; r ++) \ - ROUND_BIG_Q(a, r); \ - } while (0) - - -#define COMPRESS_BIG do { \ - sph_u32 g[32], m[32]; \ - size_t uu; \ - for (uu = 0; uu < 32; uu ++) { \ - m[uu] = dec32e_aligned(buf + (uu << 2)); \ - g[uu] = m[uu] ^ H[uu]; \ - } \ - PERM_BIG_P(g); \ - PERM_BIG_Q(m); \ - for (uu = 0; uu < 32; uu ++) \ - H[uu] ^= g[uu] ^ m[uu]; \ - } while (0) - -#define FINAL_BIG do { \ - sph_u32 x[32]; \ - size_t uu; \ - memcpy(x, H, sizeof x); \ - PERM_BIG_P(x); \ - for (uu = 0; uu < 32; uu ++) \ - H[uu] ^= x[uu]; \ - } while (0) - - -static void -groestl_big_init(sph_groestl_big_context *sc, unsigned out_size) -{ - size_t u = 0; - - sc->ptr = 0; - for (u = 0; u < 31; u ++) - sc->state.narrow[u] = 0; - sc->state.narrow[31] = ((sph_u32)(out_size & 0xFF) << 24) - | ((sph_u32)(out_size & 0xFF00) << 8); - sc->count = 0; -} - -static void -groestl_big_core(sph_groestl_big_context *sc, const void *data, size_t len) -{ - unsigned char *buf = NULL; - size_t ptr = 0; - DECL_STATE_BIG - - buf = sc->buf; - ptr = sc->ptr; - if (len < (sizeof sc->buf) - ptr) { - memcpy(buf + ptr, data, len); - ptr += len; - sc->ptr = ptr; - return; - } - - READ_STATE_BIG(sc); - while (len > 0) { - size_t clen = 0; - - clen = (sizeof sc->buf) - ptr; - if (clen > len) - clen = len; - memcpy(buf + ptr, data, clen); - ptr += clen; - data = (const unsigned char *)data + clen; - len -= clen; - if (ptr == sizeof sc->buf) { - COMPRESS_BIG; - sc->count ++; - ptr = 0; - } - } - WRITE_STATE_BIG(sc); - sc->ptr = ptr; -} - -static void -groestl_big_close(sph_groestl_big_context *sc, - unsigned ub, unsigned n, void *dst, size_t out_len) -{ - unsigned char pad[136] = {0}; - size_t ptr = 0, pad_len = 0, u2 = 0; - sph_u64 count = 0; - unsigned z = 0; - DECL_STATE_BIG - - ptr = sc->ptr; - z = 0x80 >> n; - pad[0] = ((ub & -z) | z) & 0xFF; - if (ptr < 120) { - pad_len = 128 - ptr; - count = SPH_T64(sc->count + 1); - } else { - pad_len = 256 - ptr; - count = SPH_T64(sc->count + 2); - } - memzero(pad + 1, pad_len - 9); - sph_enc64be(pad + pad_len - 8, count); - groestl_big_core(sc, pad, pad_len); - READ_STATE_BIG(sc); - FINAL_BIG; - for (u2 = 0; u2 < 16; u2 ++) - enc32e(pad + (u2 << 2), H[u2 + 16]); - memcpy(dst, pad + 64 - out_len, out_len); - groestl_big_init(sc, (unsigned)out_len << 3); -} - -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] = {0}; - - groestl512_Final(cc, buf); - groestl512_Update(cc, buf, sizeof(buf)); - groestl512_Final(cc, buf); - memcpy(dst, buf, 32); -} diff --git a/trezor-crypto/crypto/hasher.c b/trezor-crypto/crypto/hasher.c deleted file mode 100644 index 59c10181497..00000000000 --- a/trezor-crypto/crypto/hasher.c +++ /dev/null @@ -1,147 +0,0 @@ -/** - * 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 -#include - -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: - tc_blake2b_Init(&hasher->ctx.blake2b, 32); - break; - case HASHER_BLAKE2B_PERSONAL: - tc_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: - tc_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: - tc_blake2b_Final(&hasher->ctx.blake2b, hash, 32); - break; - } -} - -void hasher_Raw(HasherType type, const uint8_t *data, size_t length, - uint8_t hash[HASHER_DIGEST_LENGTH]) { - Hasher hasher = {0}; - - hasher_Init(&hasher, type); - hasher_Update(&hasher, data, length); - hasher_Final(&hasher, hash); -} diff --git a/trezor-crypto/crypto/hmac.c b/trezor-crypto/crypto/hmac.c deleted file mode 100644 index 6d77e8a9317..00000000000 --- a/trezor-crypto/crypto/hmac.c +++ /dev/null @@ -1,176 +0,0 @@ -/** - * 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 - -#include -#include -#include - -void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, - const uint32_t keylen) { - 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) { - 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) { - CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; - - memzero(key_pad, sizeof(key_pad)); - if (keylen > SHA256_BLOCK_LENGTH) { - CONFIDENTIAL SHA256_CTX context; - sha256_Init(&context); - sha256_Update(&context, key, keylen); - sha256_Final(&context, (uint8_t *)key_pad); - } else { - memcpy(key_pad, key, keylen); - } - - /* compute o_key_pad and its digest */ - for (int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) { - uint32_t data = 0; -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(key_pad[i], data); -#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) { - 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 = {0}; - hmac_sha512_Init(&hctx, key, keylen); - hmac_sha512_Update(&hctx, msg, msglen); - hmac_sha512_Final(&hctx, hmac); -} - -void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, - uint64_t *opad_digest, uint64_t *ipad_digest) { - CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; - - memzero(key_pad, sizeof(key_pad)); - if (keylen > SHA512_BLOCK_LENGTH) { - CONFIDENTIAL SHA512_CTX context; - sha512_Init(&context); - sha512_Update(&context, key, keylen); - sha512_Final(&context, (uint8_t *)key_pad); - } else { - memcpy(key_pad, key, keylen); - } - - /* compute o_key_pad and its digest */ - for (int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) { - uint64_t data = 0; -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE64(key_pad[i], data); -#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)); -} diff --git a/trezor-crypto/crypto/hmac_drbg.c b/trezor-crypto/crypto/hmac_drbg.c deleted file mode 100644 index 08032bfd74d..00000000000 --- a/trezor-crypto/crypto/hmac_drbg.c +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Copyright (c) 2019 Andrew R. Kozlik - * - * 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 -#include -#include -#include - -static void update_k(HMAC_DRBG_CTX *ctx, uint8_t domain, const uint8_t *data1, - size_t len1, const uint8_t *data2, size_t len2) { - // Computes K = HMAC(K, V || domain || data1 || data 2). - - // First hash operation of HMAC. - uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - if (len1 + len2 == 0) { - ctx->v[8] = 0x00800000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; - sha256_Transform(ctx->idig, ctx->v, h); - ctx->v[8] = 0x80000000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - } else { - SHA256_CTX sha_ctx = {0}; - memcpy(sha_ctx.state, ctx->idig, SHA256_DIGEST_LENGTH); - for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(ctx->v[i], sha_ctx.buffer[i]); -#else - sha_ctx.buffer[i] = ctx->v[i]; -#endif - } - ((uint8_t *)sha_ctx.buffer)[SHA256_DIGEST_LENGTH] = domain; - sha_ctx.bitcount = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH + 1) * 8; - sha256_Update(&sha_ctx, data1, len1); - sha256_Update(&sha_ctx, data2, len2); - sha256_Final(&sha_ctx, (uint8_t *)h); -#if BYTE_ORDER == LITTLE_ENDIAN - for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) - REVERSE32(h[i], h[i]); -#endif - } - - // Second hash operation of HMAC. - h[8] = 0x80000000; - h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - sha256_Transform(ctx->odig, h, h); - - // Precompute the inner digest and outer digest of K. - h[8] = 0; - h[15] = 0; - for (size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { - h[i] ^= 0x36363636; - } - sha256_Transform(sha256_initial_hash_value, h, ctx->idig); - - for (size_t i = 0; i < SHA256_BLOCK_LENGTH / sizeof(uint32_t); i++) { - h[i] = h[i] ^ 0x36363636 ^ 0x5c5c5c5c; - } - sha256_Transform(sha256_initial_hash_value, h, ctx->odig); - memzero(h, sizeof(h)); -} - -static void update_v(HMAC_DRBG_CTX *ctx) { - sha256_Transform(ctx->idig, ctx->v, ctx->v); - sha256_Transform(ctx->odig, ctx->v, ctx->v); -} - -void hmac_drbg_init(HMAC_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_len, const uint8_t *nonce, - size_t nonce_len) { - uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - - // Precompute the inner digest and outer digest of K = 0x00 ... 0x00. - memset(h, 0x36, sizeof(h)); - sha256_Transform(sha256_initial_hash_value, h, ctx->idig); - memset(h, 0x5c, sizeof(h)); - sha256_Transform(sha256_initial_hash_value, h, ctx->odig); - - // Let V = 0x01 ... 0x01. - memset(ctx->v, 1, SHA256_DIGEST_LENGTH); - for (size_t i = 9; i < 15; i++) ctx->v[i] = 0; - ctx->v[8] = 0x80000000; - ctx->v[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - - hmac_drbg_reseed(ctx, entropy, entropy_len, nonce, nonce_len); - - memzero(h, sizeof(h)); -} - -void hmac_drbg_reseed(HMAC_DRBG_CTX *ctx, const uint8_t *entropy, size_t len, - const uint8_t *addin, size_t addin_len) { - update_k(ctx, 0, entropy, len, addin, addin_len); - update_v(ctx); - if (len == 0) return; - update_k(ctx, 1, entropy, len, addin, addin_len); - update_v(ctx); -} - -void hmac_drbg_generate(HMAC_DRBG_CTX *ctx, uint8_t *buf, size_t len) { - size_t i = 0; - while (i < len) { - update_v(ctx); - for (size_t j = 0; j < 8 && i < len; j++) { - uint32_t r = ctx->v[j]; - for (int k = 24; k >= 0 && i < len; k -= 8) { - buf[i++] = (r >> k) & 0xFF; - } - } - } - update_k(ctx, 0, NULL, 0, NULL, 0); - update_v(ctx); -} diff --git a/trezor-crypto/crypto/monero/base58.c b/trezor-crypto/crypto/monero/base58.c deleted file mode 100644 index 422e32885b1..00000000000 --- a/trezor-crypto/crypto/monero/base58.c +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) 2014-2018, 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 - -#include -#include -#include -#include -#include -#include "int-util.h" -#include - -const size_t alphabet_size = 58; // sizeof(b58digits_ordered) - 1; -const size_t encoded_block_sizes[] = {0, 2, 3, 5, 6, 7, 9, 10, 11}; -const size_t full_block_size = sizeof(encoded_block_sizes) / sizeof(encoded_block_sizes[0]) - 1; -const size_t full_encoded_block_size = 11; // encoded_block_sizes[full_block_size]; -const size_t addr_checksum_size = 4; -const int decoded_block_sizes[] = {0, -1, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8}; -#define reverse_alphabet(letter) ((int8_t) b58digits_map[(int)letter]) - - -uint64_t uint_8be_to_64(const uint8_t* data, size_t size) -{ - assert(1 <= size && size <= sizeof(uint64_t)); - - uint64_t res = 0; - switch (9 - size) - { - case 1: res |= *data++; /* FALLTHRU */ - case 2: res <<= 8; res |= *data++; /* FALLTHRU */ - case 3: res <<= 8; res |= *data++; /* FALLTHRU */ - case 4: res <<= 8; res |= *data++; /* FALLTHRU */ - case 5: res <<= 8; res |= *data++; /* FALLTHRU */ - case 6: res <<= 8; res |= *data++; /* FALLTHRU */ - case 7: res <<= 8; res |= *data++; /* FALLTHRU */ - case 8: res <<= 8; res |= *data; break; - default: assert(false); - } - - return res; -} - -void uint_64_to_8be(uint64_t num, size_t size, uint8_t* data) -{ - assert(1 <= size && size <= sizeof(uint64_t)); - - uint64_t num_be = SWAP64(num); - memcpy(data, (uint8_t*)(&num_be) + sizeof(uint64_t) - size, size); -} - -void encode_block(const char* block, size_t size, char* res) -{ - assert(1 <= size && size <= full_block_size); - - uint64_t num = uint_8be_to_64((uint8_t*)(block), size); - int i = ((int)(encoded_block_sizes[size])) - 1; - while (0 <= i) - { - uint64_t remainder = num % alphabet_size; - num /= alphabet_size; - res[i] = b58digits_ordered[remainder]; - --i; - } -} - -bool decode_block(const char* block, size_t size, char* res) -{ - assert(1 <= size && size <= full_encoded_block_size); - - int res_size = decoded_block_sizes[size]; - if (res_size <= 0) - return false; // Invalid block size - - uint64_t res_num = 0; - uint64_t order = 1; - for (size_t i = size - 1; i < size; --i) - { - if (block[i] & 0x80) - return false; // Invalid symbol - int digit = reverse_alphabet(block[i]); - if (digit < 0) - return false; // Invalid symbol - - uint64_t product_hi = 0; - uint64_t tmp = res_num + mul128(order, (uint64_t) digit, &product_hi); - if (tmp < res_num || 0 != product_hi) - return false; // Overflow - - res_num = tmp; - order *= alphabet_size; // Never overflows, 58^10 < 2^64 - } - - if ((size_t)res_size < full_block_size && (UINT64_C(1) << (8 * res_size)) <= res_num) - return false; // Overflow - - uint_64_to_8be(res_num, res_size, (uint8_t*)(res)); - - return true; -} - - -bool xmr_base58_encode(char *b58, size_t *b58sz, const void *data, size_t binsz) -{ - if (binsz==0) - return true; - - const char * data_bin = data; - size_t full_block_count = binsz / full_block_size; - size_t last_block_size = binsz % full_block_size; - size_t res_size = full_block_count * full_encoded_block_size + encoded_block_sizes[last_block_size]; - - if (b58sz){ - if (res_size >= *b58sz){ - return false; - } - *b58sz = res_size; - } - - for (size_t i = 0; i < full_block_count; ++i) - { - encode_block(data_bin + i * full_block_size, full_block_size, b58 + i * full_encoded_block_size); - } - - if (0 < last_block_size) - { - encode_block(data_bin + full_block_count * full_block_size, last_block_size, b58 + full_block_count * full_encoded_block_size); - } - - return true; -} - -bool xmr_base58_decode(const char *b58, size_t b58sz, void *data, size_t *binsz) -{ - if (b58sz == 0) { - *binsz = 0; - return true; - } - - size_t full_block_count = b58sz / full_encoded_block_size; - size_t last_block_size = b58sz % full_encoded_block_size; - int last_block_decoded_size = decoded_block_sizes[last_block_size]; - if (last_block_decoded_size < 0) { - *binsz = 0; - return false; // Invalid enc length - } - - size_t data_size = full_block_count * full_block_size + last_block_decoded_size; - if (*binsz < data_size){ - *binsz = 0; - return false; - } - - char * data_bin = data; - for (size_t i = 0; i < full_block_count; ++i) - { - if (!decode_block(b58 + i * full_encoded_block_size, full_encoded_block_size, data_bin + i * full_block_size)) - return false; - } - - if (0 < last_block_size) - { - if (!decode_block(b58 + full_block_count * full_encoded_block_size, last_block_size, - data_bin + full_block_count * full_block_size)) - return false; - } - - return true; -} - -int xmr_base58_addr_encode_check(uint64_t tag, const uint8_t *data, size_t binsz, char *b58, size_t b58sz) -{ - if (binsz > 128 || tag > 127) { // tag varint - return false; - } - - size_t b58size = b58sz; - uint8_t buf[(binsz + 1) + HASHER_DIGEST_LENGTH]; - memset(buf, 0, sizeof(buf)); - uint8_t *hash = buf + binsz + 1; - buf[0] = (uint8_t) tag; - memcpy(buf + 1, data, binsz); - hasher_Raw(HASHER_SHA3K, buf, binsz + 1, hash); - - bool r = xmr_base58_encode(b58, &b58size, buf, binsz + 1 + addr_checksum_size); - return (int) (!r ? 0 : b58size); -} - -int xmr_base58_addr_decode_check(const char *addr, size_t sz, uint64_t *tag, void *data, size_t datalen) -{ - size_t buflen = 1 + 64 + addr_checksum_size; - uint8_t buf[buflen]; - memset(buf, 0, sizeof(buf)); - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - - if (!xmr_base58_decode(addr, sz, buf, &buflen)){ - return 0; - } - - size_t res_size = buflen - addr_checksum_size - 1; - if (datalen < res_size){ - return 0; - } - - if (buflen <= addr_checksum_size+1) { - return 0; - } - - hasher_Raw(HASHER_SHA3K, buf, buflen - addr_checksum_size, hash); - if (memcmp(hash, buf + buflen - addr_checksum_size, addr_checksum_size) != 0){ - return 0; - } - - *tag = buf[0]; - if (*tag > 127){ - return false; // varint - } - - memcpy(data, buf+1, res_size); - return (int) res_size; -} diff --git a/trezor-crypto/crypto/monero/base58.h b/trezor-crypto/crypto/monero/base58.h deleted file mode 100644 index 66a08f8f5ae..00000000000 --- a/trezor-crypto/crypto/monero/base58.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2014-2018, 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 __XMR_BASE58_H__ -#define __XMR_BASE58_H__ - -#include -#include -#include - -int xmr_base58_addr_encode_check(uint64_t tag, const uint8_t *data, size_t binsz, char *b58, size_t b58sz); -int xmr_base58_addr_decode_check(const char *addr, size_t sz, uint64_t *tag, void *data, size_t datalen); -bool xmr_base58_encode(char *b58, size_t *b58sz, const void *data, size_t binsz); -bool xmr_base58_decode(const char *b58, size_t b58sz, void *data, size_t *binsz); - -#endif diff --git a/trezor-crypto/crypto/monero/int-util.h b/trezor-crypto/crypto/monero/int-util.h deleted file mode 100644 index 9cba47a8ba5..00000000000 --- a/trezor-crypto/crypto/monero/int-util.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include - -static inline uint64_t hi_dword(uint64_t val) { - return val >> 32; -} - -static inline uint64_t lo_dword(uint64_t val) { - return val & 0xFFFFFFFF; -} - -static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = hi_dword(multiplier); - uint64_t b = lo_dword(multiplier); - uint64_t c = hi_dword(multiplicand); - uint64_t d = lo_dword(multiplicand); - - uint64_t ac = a * c; - uint64_t ad = a * d; - uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + bc; - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - assert(ac <= *product_hi); - - return product_lo; -} - -#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \ - (((uint64_t) (x) & 0x000000000000ff00) << 40) | \ - (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \ - (((uint64_t) (x) & 0x00000000ff000000) << 8) | \ - (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \ - (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \ - (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \ - (((uint64_t) (x) & 0xff00000000000000) >> 56)) diff --git a/trezor-crypto/crypto/monero/monero.h b/trezor-crypto/crypto/monero/monero.h deleted file mode 100644 index 7b088f21670..00000000000 --- a/trezor-crypto/crypto/monero/monero.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#ifndef TREZOR_CRYPTO_MONERO_H -#define TREZOR_CRYPTO_MONERO_H - -#if !USE_MONERO -#error "Compile with -DUSE_MONERO=1" -#endif - -#if !USE_KECCAK -#error "Compile with -DUSE_KECCAK=1" -#endif - -#include -#include "range_proof.h" -#include "serialize.h" -#include "xmr.h" - -#endif // TREZOR_CRYPTO_MONERO_H diff --git a/trezor-crypto/crypto/monero/range_proof.c b/trezor-crypto/crypto/monero/range_proof.c deleted file mode 100644 index e3fd9b6a278..00000000000 --- a/trezor-crypto/crypto/monero/range_proof.c +++ /dev/null @@ -1,115 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#include "range_proof.h" - -static void xmr_hash_ge25519_to_scalar(bignum256modm r, const ge25519 *p) { - unsigned char buff[32] = {0}; - ge25519_pack(buff, p); - xmr_hash_to_scalar(r, buff, sizeof(buff)); -} - -void xmr_gen_range_sig(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask, - xmr_amount amount, bignum256modm *last_mask) { - bignum256modm ai[64] = {0}; - bignum256modm alpha[64] = {0}; - xmr_gen_range_sig_ex(sig, C, mask, amount, last_mask, ai, alpha); -} - -void xmr_gen_range_sig_ex(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask, - xmr_amount amount, bignum256modm *last_mask, - bignum256modm ai[64], bignum256modm alpha[64]) { - const unsigned n = XMR_ATOMS; - bignum256modm a = {0}; - bignum256modm si = {0}; - bignum256modm c = {0}; - bignum256modm ee = {0}; - unsigned char buff[32] = {0}; - - Hasher kck = {0}; - xmr_hasher_init(&kck); - - ge25519 C_acc = {0}; - ge25519 C_h = {0}; - ge25519 C_tmp = {0}; - ge25519 L = {0}; - ge25519 Zero = {0}; - - ge25519_set_neutral(&Zero); - ge25519_set_neutral(&C_acc); - ge25519_set_xmr_h(&C_h); - set256_modm(a, 0); - -#define BB(i) ((amount >> (i)) & 1) - - // First pass, generates: ai, alpha, Ci, ee, s1 - for (unsigned ii = 0; ii < n; ++ii) { - xmr_random_scalar(ai[ii]); - if (last_mask != NULL && ii == n - 1) { - sub256_modm(ai[ii], *last_mask, a); - } - - add256_modm(a, a, ai[ii]); // creating the total mask since you have to - // pass this to receiver... - xmr_random_scalar(alpha[ii]); - - ge25519_scalarmult_base_niels(&L, ge25519_niels_base_multiples, alpha[ii]); - ge25519_scalarmult_base_niels(&C_tmp, ge25519_niels_base_multiples, ai[ii]); - - // C_tmp += &Zero if BB(ii) == 0 else &C_h - ge25519_add(&C_tmp, &C_tmp, BB(ii) == 0 ? &Zero : &C_h, 0); - ge25519_add(&C_acc, &C_acc, &C_tmp, 0); - - // Set Ci[ii] to sigs - ge25519_pack(sig->Ci[ii], &C_tmp); - - if (BB(ii) == 0) { - xmr_random_scalar(si); - xmr_hash_ge25519_to_scalar(c, &L); - - ge25519_add(&C_tmp, &C_tmp, &C_h, 1); // Ci[ii] -= c_h - xmr_add_keys2_vartime(&L, si, c, &C_tmp); - - // Set s1[ii] to sigs - contract256_modm(sig->asig.s1[ii], si); - } - - ge25519_pack(buff, &L); - xmr_hasher_update(&kck, buff, sizeof(buff)); - - ge25519_double(&C_h, &C_h); // c_H = crypto.scalarmult(c_H, 2) - } - - // Compute ee - xmr_hasher_final(&kck, buff); - expand256_modm(ee, buff, sizeof(buff)); - - ge25519_set_xmr_h(&C_h); - - // Second pass, s0, s1 - for (unsigned ii = 0; ii < n; ++ii) { - if (BB(ii) == 0) { - mulsub256_modm(si, ai[ii], ee, alpha[ii]); - contract256_modm(sig->asig.s0[ii], si); - - } else { - xmr_random_scalar(si); - contract256_modm(sig->asig.s0[ii], si); - - ge25519_unpack_vartime(&C_tmp, sig->Ci[ii]); - xmr_add_keys2_vartime(&L, si, ee, &C_tmp); - xmr_hash_ge25519_to_scalar(c, &L); - - mulsub256_modm(si, ai[ii], c, alpha[ii]); - contract256_modm(sig->asig.s1[ii], si); - } - - ge25519_double(&C_h, &C_h); // c_H = crypto.scalarmult(c_H, 2) - } - - ge25519_copy(C, &C_acc); - copy256_modm(mask, a); - contract256_modm(sig->asig.ee, ee); -#undef BB -} diff --git a/trezor-crypto/crypto/monero/range_proof.h b/trezor-crypto/crypto/monero/range_proof.h deleted file mode 100644 index f614ab04e76..00000000000 --- a/trezor-crypto/crypto/monero/range_proof.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#ifndef TREZOR_CRYPTO_RANGE_PROOF_H -#define TREZOR_CRYPTO_RANGE_PROOF_H - -#include "xmr.h" -#define XMR_ATOMS 64 - -typedef uint64_t xmr_amount; -typedef xmr_key_t xmr_key64_t[64]; - -typedef struct xmr_boro_sig { - xmr_key64_t s0; - xmr_key64_t s1; - xmr_key_t ee; -} xmr_boro_sig_t; - -typedef struct range_sig { - xmr_boro_sig_t asig; - xmr_key64_t Ci; -} xmr_range_sig_t; - -void xmr_gen_range_sig(xmr_range_sig_t* sig, ge25519* C, bignum256modm mask, - xmr_amount amount, bignum256modm* last_mask); -void xmr_gen_range_sig_ex(xmr_range_sig_t* sig, ge25519* C, bignum256modm mask, - xmr_amount amount, bignum256modm* last_mask, - bignum256modm ai[64], bignum256modm alpha[64]); - -#endif // TREZOR_CRYPTO_RANGE_PROOF_H diff --git a/trezor-crypto/crypto/monero/serialize.c b/trezor-crypto/crypto/monero/serialize.c deleted file mode 100644 index 4d4cbd8bbeb..00000000000 --- a/trezor-crypto/crypto/monero/serialize.c +++ /dev/null @@ -1,53 +0,0 @@ -// -// Created by Dusan Klinec on 02/05/2018. -// - -#include "serialize.h" - -int xmr_size_varint(uint64_t num) { - int ctr = 1; - while (num >= 0x80) { - ++ctr; - num >>= 7; - } - return ctr; -} - -int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num) { - unsigned ctr = 0; - while (num >= 0x80 && ctr < buff_size) { - *buff = (uint8_t)(((num)&0x7f) | 0x80); - ++buff; - ++ctr; - num >>= 7; - } - - /* writes the last one to dest */ - if (ctr < buff_size) { - *buff = (uint8_t)num; - ++ctr; - } - return ctr <= buff_size ? (int)ctr : -1; -} - -int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val) { - unsigned read = 0; - int finished_ok = 0; - *val = 0; - - for (int shift = 0; read < buff_size; shift += 7, ++read) { - uint8_t byte = buff[read]; - if ((byte == 0 && shift != 0) || (shift >= 63 && byte > 1)) { - return -1; - } - - *val |= (uint64_t)(byte & 0x7f) << shift; - - /* If there is no next */ - if ((byte & 0x80) == 0) { - finished_ok = 1; - break; - } - } - return finished_ok ? (int)read + 1 : -2; -} diff --git a/trezor-crypto/crypto/monero/serialize.h b/trezor-crypto/crypto/monero/serialize.h deleted file mode 100644 index 8d3499007fa..00000000000 --- a/trezor-crypto/crypto/monero/serialize.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Created by Dusan Klinec on 02/05/2018. -// - -#ifndef TREZOR_XMR_SERIALIZE_H -#define TREZOR_XMR_SERIALIZE_H - -#include -#include - -int xmr_size_varint(uint64_t num); -int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num); -int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val); - -#endif // TREZOR_XMR_SERIALIZE_H diff --git a/trezor-crypto/crypto/monero/xmr.c b/trezor-crypto/crypto/monero/xmr.c deleted file mode 100644 index 45f7ea05223..00000000000 --- a/trezor-crypto/crypto/monero/xmr.c +++ /dev/null @@ -1,143 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#include "xmr.h" -#include "int-util.h" -#include -#include "serialize.h" - -const ge25519 ALIGN(16) xmr_h = { - {0x1861ec7, 0x1ceac77, 0x2f11626, 0x1f261d3, 0x346107c, 0x06d8c4a, - 0x254201d, 0x1675c09, 0x1301c3f, 0x0211d73}, - {0x326feb4, 0x12e30cc, 0x0cf54b4, 0x1117305, 0x318f5d5, 0x06cf754, - 0x2e578a1, 0x1daf058, 0x34430a1, 0x04410e9}, - {0x0fde4d2, 0x0774049, 0x22ca951, 0x05aec2b, 0x07a36a5, 0x1394f13, - 0x3c5385c, 0x1adb924, 0x2b6c581, 0x0a55fa4}, - {0x24517f7, 0x05ee936, 0x3acf5d9, 0x14b08aa, 0x3363738, 0x1051745, - 0x360601e, 0x0f3f2c9, 0x1ead2cd, 0x1d3e3df}}; - -void ge25519_set_xmr_h(ge25519 *r) { ge25519_copy(r, &xmr_h); } - -void xmr_random_scalar(bignum256modm m) { - unsigned char buff[32] = {0}; - random_buffer(buff, sizeof(buff)); - expand256_modm(m, buff, sizeof(buff)); -} - -void xmr_fast_hash(uint8_t *hash, const void *data, size_t length) { - hasher_Raw(HASHER_SHA3K, data, length, hash); -} - -void xmr_hasher_init(Hasher *hasher) { hasher_Init(hasher, HASHER_SHA3K); } - -void xmr_hasher_update(Hasher *hasher, const void *data, size_t length) { - hasher_Update(hasher, data, length); -} - -void xmr_hasher_final(Hasher *hasher, uint8_t *hash) { - hasher_Final(hasher, hash); -} - -void xmr_hasher_copy(Hasher *dst, const Hasher *src) { - memcpy(dst, src, sizeof(Hasher)); -} - -void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length) { - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - hasher_Raw(HASHER_SHA3K, data, length, hash); - expand256_modm(r, hash, HASHER_DIGEST_LENGTH); -} - -void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length) { - ge25519 point2 = {0}; - uint8_t hash[HASHER_DIGEST_LENGTH] = {0}; - hasher_Raw(HASHER_SHA3K, data, length, hash); - - ge25519_fromfe_frombytes_vartime(&point2, hash); - ge25519_mul8(P, &point2); -} - -void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p, - uint32_t output_index) { - uint8_t buff[32 + 8] = {0}; - ge25519_pack(buff, p); - int written = xmr_write_varint(buff + 32, 8, output_index); - xmr_hash_to_scalar(s, buff, 32u + written); -} - -void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A, - const bignum256modm b) { - ge25519 bA = {0}; - ge25519_scalarmult(&bA, A, b); - ge25519_mul8(r, &bA); -} - -void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx, - const bignum256modm base) { - xmr_derivation_to_scalar(s, deriv, idx); - add256_modm(s, s, base); -} - -void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx, - const ge25519 *base) { - bignum256modm s = {0}; - ge25519 p2 = {0}; - - xmr_derivation_to_scalar(s, deriv, idx); - ge25519_scalarmult_base_niels(&p2, ge25519_niels_base_multiples, s); - ge25519_add(r, base, &p2, 0); -} - -void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b, - const ge25519 *B) { - // aG + bB, G is basepoint - ge25519 aG = {0}, bB = {0}; - ge25519_scalarmult_base_niels(&aG, ge25519_niels_base_multiples, a); - ge25519_scalarmult(&bB, B, b); - ge25519_add(r, &aG, &bB, 0); -} - -void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a, - const bignum256modm b, const ge25519 *B) { - // aG + bB, G is basepoint - ge25519_double_scalarmult_vartime(r, B, b, a); -} - -void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B) { - // aA + bB - ge25519 aA = {0}, bB = {0}; - ge25519_scalarmult(&aA, A, a); - ge25519_scalarmult(&bB, B, b); - ge25519_add(r, &aA, &bB, 0); -} - -void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B) { - // aA + bB - ge25519_double_scalarmult_vartime2(r, A, a, B, b); -} - -void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, - uint32_t minor, const bignum256modm m) { - const char prefix[] = "SubAddr"; - unsigned char buff[32] = {0}; - contract256_modm(buff, m); - - char data[sizeof(prefix) + sizeof(buff) + 2 * sizeof(uint32_t)] = {0}; - memcpy(data, prefix, sizeof(prefix)); - memcpy(data + sizeof(prefix), buff, sizeof(buff)); - memcpy(data + sizeof(prefix) + sizeof(buff), &major, sizeof(uint32_t)); - memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor, - sizeof(uint32_t)); - - xmr_hash_to_scalar(r, data, sizeof(data)); -} - -void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount) { - // C = aG + bH - bignum256modm b = {0}; - set256_modm(b, amount); - xmr_add_keys2(r, a, b, &xmr_h); -} diff --git a/trezor-crypto/crypto/monero/xmr.h b/trezor-crypto/crypto/monero/xmr.h deleted file mode 100644 index 18654126465..00000000000 --- a/trezor-crypto/crypto/monero/xmr.h +++ /dev/null @@ -1,76 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#ifndef TREZOR_CRYPTO_XMR_H -#define TREZOR_CRYPTO_XMR_H - -#include -#include - -extern const ge25519 ALIGN(16) xmr_h; - -typedef unsigned char xmr_key_t[32]; - -typedef struct xmr_ctkey { - xmr_key_t dest; - xmr_key_t mask; -} xmr_ctkey_t; - -/* sets H point to r */ -void ge25519_set_xmr_h(ge25519 *r); - -/* random scalar value */ -void xmr_random_scalar(bignum256modm m); - -/* cn_fast_hash */ -void xmr_fast_hash(uint8_t *hash, const void *data, size_t length); - -/* incremental hashing wrappers */ -void xmr_hasher_init(Hasher *hasher); -void xmr_hasher_update(Hasher *hasher, const void *data, size_t length); -void xmr_hasher_final(Hasher *hasher, uint8_t *hash); -void xmr_hasher_copy(Hasher *dst, const Hasher *src); - -/* H_s(buffer) */ -void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length); - -/* H_p(buffer) */ -void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length); - -/* derivation to scalar value */ -void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p, - uint32_t output_index); - -/* derivation */ -void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A, - const bignum256modm b); - -/* H_s(derivation || varint(output_index)) + base */ -void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx, - const bignum256modm base); - -/* H_s(derivation || varint(output_index))G + base */ -void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx, - const ge25519 *base); - -/* aG + bB, G is basepoint */ -void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b, - const ge25519 *B); -void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a, - const bignum256modm b, const ge25519 *B); - -/* aA + bB */ -void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B); -void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A, - const bignum256modm b, const ge25519 *B); - -/* subaddress secret */ -void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, - uint32_t minor, const bignum256modm m); - -/* Generates Pedersen commitment C = aG + bH */ -void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount); - -#endif // TREZOR_CRYPTO_XMR_H diff --git a/trezor-crypto/crypto/nano.c b/trezor-crypto/crypto/nano.c deleted file mode 100644 index 54f4968d1ef..00000000000 --- a/trezor-crypto/crypto/nano.c +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright (c) 2019 Mart Roosmaa - * - * 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 -#include -#include - -#include - -const char *BASE32_ALPHABET_NANO = "13456789abcdefghijkmnopqrstuwxyz"; - -#define NANO_ADDRESS_BASE_LENGTH 60 -#define NANO_CHECKSUM_LEN 5 - -typedef union { - uint8_t bytes[40]; - struct { - uint8_t padding[3]; - ed25519_public_key public_key; - uint8_t checksum[NANO_CHECKSUM_LEN]; - } data; -} nano_address_raw; - -typedef union { - char chars[65]; - struct { - char padding[4]; // 1111 - char address[NANO_ADDRESS_BASE_LENGTH]; - char terminator; // \0 - } data; -} nano_address_encoded; - -size_t nano_get_address( - const ed25519_public_key public_key, - const char *prefix, - const size_t prefix_len, - char *out, - size_t out_len -) { - if (out_len < prefix_len + NANO_ADDRESS_BASE_LENGTH + 1) { - return 0; - } - - // Construct raw address which is going to be base32 encoded - nano_address_raw raw; - memset(&raw, 0, sizeof(nano_address_raw)); - - uint8_t checksum[NANO_CHECKSUM_LEN]; - blake2b_state hash; - tc_blake2b_Init(&hash, NANO_CHECKSUM_LEN); - tc_blake2b_Update(&hash, public_key, sizeof(ed25519_public_key)); - tc_blake2b_Final(&hash, checksum, NANO_CHECKSUM_LEN); - - for (int i = 0; i < NANO_CHECKSUM_LEN; i++) { - raw.data.checksum[NANO_CHECKSUM_LEN - (i + 1)] = checksum[i]; - } - memcpy(raw.data.public_key, public_key, sizeof(ed25519_public_key)); - - // Encode the address into a buffer and compose the final output - nano_address_encoded encoded; - memset(&encoded, 0, sizeof(nano_address_encoded)); - char *ret = base32_encode( - raw.bytes, sizeof(nano_address_raw), - encoded.chars, sizeof(encoded.chars), - BASE32_ALPHABET_NANO); - if (ret == NULL) { - return 0; - } - - size_t w = 0; - memcpy(&out[w], prefix, prefix_len); - w += prefix_len; - memcpy(&out[w], encoded.data.address, NANO_ADDRESS_BASE_LENGTH); - w += NANO_ADDRESS_BASE_LENGTH; - out[w] = 0; - w += 1; - return w; -} - -bool nano_validate_address( - const char *prefix, - const size_t prefix_len, - const char *address, - const size_t address_len, - ed25519_public_key out_public_key -) { - if (address_len != prefix_len + NANO_ADDRESS_BASE_LENGTH) { - return false; - } - - // Validate that the prefix matches - if (memcmp(address, prefix, prefix_len) != 0) { - return false; - } - - // Try to decode the address - nano_address_encoded encoded; - memcpy(encoded.data.padding, "1111", sizeof(encoded.data.padding)); - memcpy(encoded.data.address, &address[prefix_len], NANO_ADDRESS_BASE_LENGTH); - encoded.data.terminator = '\0'; - - nano_address_raw raw; - memset(&raw, 0, sizeof(nano_address_raw)); - uint8_t *ret = base32_decode( - encoded.chars, strlen(encoded.chars), - raw.bytes, sizeof(nano_address_raw), - BASE32_ALPHABET_NANO - ); - if (ret == NULL) { - return false; - } - - // Validate the checksum - uint8_t checksum[NANO_CHECKSUM_LEN]; - blake2b_state hash; - tc_blake2b_Init(&hash, NANO_CHECKSUM_LEN); - tc_blake2b_Update(&hash, raw.data.public_key, sizeof(ed25519_public_key)); - tc_blake2b_Final(&hash, checksum, NANO_CHECKSUM_LEN); - - for (int i = 0; i < NANO_CHECKSUM_LEN; i++) { - if (raw.data.checksum[NANO_CHECKSUM_LEN - (i + 1)] != checksum[i]) { - return false; - } - } - - // Output the public key if the caller is interested in it - if (out_public_key != NULL) { - memcpy(out_public_key, raw.data.public_key, sizeof(ed25519_public_key)); - } - - return true; -} diff --git a/trezor-crypto/crypto/nem.c b/trezor-crypto/crypto/nem.c deleted file mode 100644 index 66de5cfa9e6..00000000000 --- a/trezor-crypto/crypto/nem.c +++ /dev/null @@ -1,507 +0,0 @@ -/** - * 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 - -#include - -#include -#include -#include -#include -#include - -#define CAN_WRITE(NEEDED) ((ctx->offset + (NEEDED)) <= ctx->size) - -#define SERIALIZE_U32(DATA) \ - do { \ - if (!nem_write_u32(ctx, (DATA))) return false; \ - } while (0) -#define SERIALIZE_U64(DATA) \ - do { \ - if (!nem_write_u64(ctx, (DATA))) return false; \ - } while (0) -#define SERIALIZE_TAGGED(DATA, LENGTH) \ - do { \ - if (!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; \ - } while (0) - -const char *nem_network_name(uint8_t network) { - switch (network) { - case NEM_NETWORK_MAINNET: - return "NEM Mainnet"; - case NEM_NETWORK_TESTNET: - return "NEM Testnet"; - case NEM_NETWORK_MIJIN: - return "Mijin"; - default: - return NULL; - } -} - -static inline bool nem_write_checked(nem_transaction_ctx *ctx, - const uint8_t *data, uint32_t length) { - if (!CAN_WRITE(length)) { - return false; - } - - memcpy(&ctx->buffer[ctx->offset], data, length); - ctx->offset += length; - return true; -} - -static inline bool nem_write_u32(nem_transaction_ctx *ctx, uint32_t data) { - if (!CAN_WRITE(4)) { - return false; - } - - ctx->buffer[ctx->offset++] = (data >> 0) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 8) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 16) & 0xff; - ctx->buffer[ctx->offset++] = (data >> 24) & 0xff; - - return true; -} - -static inline bool nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) { - SERIALIZE_U32((data >> 0) & 0xffffffff); - SERIALIZE_U32((data >> 32) & 0xffffffff); - - return true; -} - -static inline bool nem_write_tagged(nem_transaction_ctx *ctx, - const uint8_t *data, uint32_t length) { - SERIALIZE_U32(length); - - return nem_write_checked(ctx, data, length); -} - -static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, - const char *name, const char *value) { - uint32_t name_length = strlen(name); - uint32_t value_length = strlen(value); - - SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + - value_length); - SERIALIZE_TAGGED((const uint8_t *)name, name_length); - SERIALIZE_TAGGED((const uint8_t *)value, value_length); - - return true; -} - -static inline bool nem_write_mosaic_bool(nem_transaction_ctx *ctx, - const char *name, bool value) { - return nem_write_mosaic_str(ctx, name, value ? "true" : "false"); -} - -static inline bool nem_write_mosaic_u64(nem_transaction_ctx *ctx, - const char *name, uint64_t value) { - char buffer[21] = {0}; - - if (bn_format_uint64(value, NULL, NULL, 0, 0, false, buffer, - sizeof(buffer)) == 0) { - return false; - } - - return nem_write_mosaic_str(ctx, name, buffer); -} - -void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, - uint8_t *address) { - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - - /* 1. Perform 256-bit Sha3 on the public key */ - keccak_256(public_key, sizeof(ed25519_public_key), hash); - - /* 2. Perform 160-bit Ripemd of hash resulting from step 1. */ - ripemd160(hash, SHA3_256_DIGEST_LENGTH, &address[1]); - - /* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */ - address[0] = version; - - /* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a - * checksum */ - keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); - - /* 5. Concatenate output of step 3 and the checksum from step 4 */ - memcpy(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4); - - memzero(hash, sizeof(hash)); -} - -bool nem_get_address(const ed25519_public_key public_key, uint8_t version, - char *address) { - uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; - - nem_get_address_raw(public_key, version, pubkeyhash); - - char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address, - NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648); - - memzero(pubkeyhash, sizeof(pubkeyhash)); - return (ret != NULL); -} - -bool nem_validate_address_raw(const uint8_t *address, uint8_t network) { - if (!nem_network_name(network) || address[0] != network) { - return false; - } - - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - - keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash); - bool valid = (memcmp(&address[1 + RIPEMD160_DIGEST_LENGTH], hash, 4) == 0); - - memzero(hash, sizeof(hash)); - return valid; -} - -bool nem_validate_address(const char *address, uint8_t network) { - uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW] = {0}; - - if (strlen(address) != NEM_ADDRESS_SIZE) { - return false; - } - - uint8_t *ret = base32_decode(address, NEM_ADDRESS_SIZE, pubkeyhash, - sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648); - bool valid = (ret != NULL) && nem_validate_address_raw(pubkeyhash, network); - - memzero(pubkeyhash, sizeof(pubkeyhash)); - return valid; -} - -void nem_transaction_start(nem_transaction_ctx *ctx, - const ed25519_public_key public_key, uint8_t *buffer, - size_t size) { - memcpy(ctx->public_key, public_key, sizeof(ctx->public_key)); - - ctx->buffer = buffer; - ctx->offset = 0; - ctx->size = size; -} - -size_t nem_transaction_end(nem_transaction_ctx *ctx, - const ed25519_secret_key private_key, - ed25519_signature signature) { - if (private_key != NULL && signature != NULL) { - ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, signature); - } - - return ctx->offset; -} - -bool nem_transaction_write_common(nem_transaction_ctx *ctx, uint32_t type, - uint32_t version, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, - uint32_t deadline) { - SERIALIZE_U32(type); - SERIALIZE_U32(version); - SERIALIZE_U32(timestamp); - SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); - SERIALIZE_U64(fee); - SERIALIZE_U32(deadline); - - return true; -} - -bool nem_transaction_create_transfer(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const char *recipient, uint64_t amount, - const uint8_t *payload, uint32_t length, - bool encrypted, uint32_t mosaics) { - if (!signer) { - signer = ctx->public_key; - } - - if (!payload) { - length = 0; - } - - bool ret = - nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_TRANSFER, - (uint32_t)network << 24 | (mosaics ? 2 : 1), - timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_TAGGED((const uint8_t *)recipient, NEM_ADDRESS_SIZE); - SERIALIZE_U64(amount); - - if (length) { - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + length); - SERIALIZE_U32(encrypted ? 0x02 : 0x01); - SERIALIZE_TAGGED(payload, length); - } else { - SERIALIZE_U32(0); - } - - if (mosaics) { - SERIALIZE_U32(mosaics); - } - - return true; -} - -bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, - const char *namespace, const char *mosaic, - uint64_t quantity) { - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length); - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_U64(quantity); - - return true; -} - -bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_MULTISIG, - (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_TAGGED(inner->buffer, inner->offset); - - return true; -} - -bool nem_transaction_create_multisig_signature( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE, (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - char address[NEM_ADDRESS_SIZE + 1] = {0}; - nem_get_address(inner->public_key, network, address); - - uint8_t hash[SHA3_256_DIGEST_LENGTH] = {0}; - keccak_256(inner->buffer, inner->offset, hash); - - SERIALIZE_U32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH); - SERIALIZE_TAGGED(hash, SHA3_256_DIGEST_LENGTH); - SERIALIZE_TAGGED((const uint8_t *)address, NEM_ADDRESS_SIZE); - - return true; -} - -bool nem_transaction_create_provision_namespace( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *parent, const char *rental_sink, - uint64_t rental_fee) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - if (parent) { - SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(rental_fee); - SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace)); - SERIALIZE_TAGGED((const uint8_t *)parent, strlen(parent)); - } else { - SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(rental_fee); - SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace)); - SERIALIZE_U32(0xffffffff); - } - - return true; -} - -bool nem_transaction_create_mosaic_creation( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, const char *description, - uint32_t divisibility, uint64_t supply, bool mutable_supply, - bool transferable, uint32_t levy_type, uint64_t levy_fee, - const char *levy_address, const char *levy_namespace, - const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MOSAIC_CREATION, (uint32_t)network << 24 | 1, - timestamp, signer, fee, deadline); - if (!ret) return false; - - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - // This length will be rewritten later on - nem_transaction_ctx state = {0}; - memcpy(&state, ctx, sizeof(state)); - - SERIALIZE_U32(0); - SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key)); - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_TAGGED((const uint8_t *)description, strlen(description)); - SERIALIZE_U32(4); // Number of properties - - if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false; - if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false; - if (!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply)) - return false; - if (!nem_write_mosaic_bool(ctx, "transferable", transferable)) return false; - - if (levy_type) { - size_t levy_namespace_length = strlen(levy_namespace); - size_t levy_mosaic_length = strlen(levy_mosaic); - size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + - sizeof(uint32_t) + levy_mosaic_length; - - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + - sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t)); - SERIALIZE_U32(levy_type); - SERIALIZE_TAGGED((const uint8_t *)levy_address, NEM_ADDRESS_SIZE); - SERIALIZE_U32(levy_identifier_length); - SERIALIZE_TAGGED((const uint8_t *)levy_namespace, levy_namespace_length); - SERIALIZE_TAGGED((const uint8_t *)levy_mosaic, levy_mosaic_length); - SERIALIZE_U64(levy_fee); - } else { - SERIALIZE_U32(0); - } - - // Rewrite length - nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t)); - - SERIALIZE_TAGGED((const uint8_t *)creation_sink, NEM_ADDRESS_SIZE); - SERIALIZE_U64(creation_fee); - - return true; -} - -bool nem_transaction_create_mosaic_supply_change( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, uint32_t type, uint64_t delta) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - size_t namespace_length = strlen(namespace); - size_t mosaic_length = strlen(mosaic); - size_t identifier_length = - sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length; - - SERIALIZE_U32(identifier_length); - SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length); - SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length); - SERIALIZE_U32(type); - SERIALIZE_U64(delta); - - return true; -} - -bool nem_transaction_create_aggregate_modification( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t modifications, bool relative_change) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION, - (uint32_t)network << 24 | (relative_change ? 2 : 1), timestamp, signer, - fee, deadline); - if (!ret) return false; - - SERIALIZE_U32(modifications); - - return true; -} - -bool nem_transaction_write_cosignatory_modification( - nem_transaction_ctx *ctx, uint32_t type, - const ed25519_public_key cosignatory) { - SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + - sizeof(ed25519_public_key)); - SERIALIZE_U32(type); - SERIALIZE_TAGGED(cosignatory, sizeof(ed25519_public_key)); - - return true; -} - -bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, - int32_t relative_change) { - SERIALIZE_U32(sizeof(uint32_t)); - SERIALIZE_U32((uint32_t)relative_change); - - return true; -} - -bool nem_transaction_create_importance_transfer( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t mode, const ed25519_public_key remote) { - if (!signer) { - signer = ctx->public_key; - } - - bool ret = nem_transaction_write_common( - ctx, NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER, - (uint32_t)network << 24 | 1, timestamp, signer, fee, deadline); - if (!ret) return false; - - SERIALIZE_U32(mode); - SERIALIZE_TAGGED(remote, sizeof(ed25519_public_key)); - - return true; -} diff --git a/trezor-crypto/crypto/nist256p1.c b/trezor-crypto/crypto/nist256p1.c deleted file mode 100644 index 3d7246d228e..00000000000 --- a/trezor-crypto/crypto/nist256p1.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * 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 - -const ecdsa_curve nist256p1 = { - /* .prime */ {/*.val =*/{0x1fffffff, 0x1fffffff, 0x1fffffff, 0x000001ff, - 0x00000000, 0x00000000, 0x00040000, 0x1fe00000, - 0xffffff}}, - - /* G */ - {/*.x =*/{/*.val =*/{0x1898c296, 0x0509ca2e, 0x1acce83d, 0x06fb025b, - 0x040f2770, 0x1372b1d2, 0x091fe2f3, 0x1e5c2588, - 0x6b17d1}}, - /*.y =*/{/*.val =*/{0x17bf51f5, 0x1db20341, 0x0c57b3b2, 0x1c66aed6, - 0x19e162bc, 0x15a53e07, 0x1e6e3b9f, 0x1c5fc34f, - 0x4fe342}}}, - - /* order */ - {/*.val =*/{0x1c632551, 0x1dce5617, 0x05e7a13c, 0x0df55b4e, 0x1ffffbce, - 0x1fffffff, 0x0003ffff, 0x1fe00000, 0xffffff}}, - - /* order_half */ - {/*.val =*/{0x1e3192a8, 0x0ee72b0b, 0x02f3d09e, 0x06faada7, 0x1ffffde7, - 0x1fffffff, 0x0001ffff, 0x1ff00000, 0x7fffff}}, - - /* a */ -3, - - /* b */ - {/*.val =*/{0x07d2604b, 0x1e71e1f1, 0x14ec3d8e, 0x1a0d6198, 0x086bc651, - 0x1eaabb4c, 0x0f9ecfae, 0x1b154752, 0x005ac635}} - -#if USE_PRECOMPUTED_CP - , - /* cp */ - { -#include "nist256p1.table" - } -#endif -}; - -const curve_info nist256p1_info = { - .bip32_name = "Nist256p1 seed", - .params = &nist256p1, - .hasher_base58 = HASHER_SHA2D, - .hasher_sign = HASHER_SHA2D, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; diff --git a/trezor-crypto/crypto/nist256p1.table b/trezor-crypto/crypto/nist256p1.table deleted file mode 100644 index 6be01b4d625..00000000000 --- a/trezor-crypto/crypto/nist256p1.table +++ /dev/null @@ -1,1664 +0,0 @@ - { - /* 1*16^0*G: */ - {{{0x1898c296, 0x0509ca2e, 0x1acce83d, 0x06fb025b, 0x040f2770, 0x1372b1d2, 0x091fe2f3, 0x1e5c2588, 0x6b17d1}}, - {{0x17bf51f5, 0x1db20341, 0x0c57b3b2, 0x1c66aed6, 0x19e162bc, 0x15a53e07, 0x1e6e3b9f, 0x1c5fc34f, 0x4fe342}}}, - /* 3*16^0*G: */ - {{{0x06e7fd6c, 0x1a0b30de, 0x0b6a617e, 0x0d6e43df, 0x1f165e6c, 0x17ca8ea5, 0x091323df, 0x1a34c661, 0x5ecbe4}}, - {{0x027d5032, 0x13cd893d, 0x13ee0f66, 0x15606c70, 0x0a2ecd82, 0x03670d32, 0x1df8dd2c, 0x0189331f, 0x873464}}}, - /* 5*16^0*G: */ - {{{0x03d033ed, 0x0aaa506e, 0x16f94908, 0x1905fa3e, 0x08fdfef8, 0x042b0433, 0x034b5e13, 0x0f4a2a28, 0x51590b}}, - {{0x1da16da4, 0x0e85da27, 0x16022234, 0x025e01a9, 0x079260d0, 0x1f9b5fc5, 0x09f62b86, 0x1512094e, 0xe0c17d}}}, - /* 7*16^0*G: */ - {{{0x1187b2a3, 0x00314381, 0x03fbd6cc, 0x13f17150, 0x1fb607ef, 0x18333e00, 0x0d1896ec, 0x0df417ef, 0x8e533b}}, - {{0x01f400b4, 0x0af0d436, 0x0106c871, 0x0e6c6796, 0x1900053c, 0x0fc1d37a, 0x00d9b41a, 0x17bc0663, 0x73eb1d}}}, - /* 9*16^0*G: */ - {{{0x10949ee0, 0x1cf4525c, 0x1b7e2cf5, 0x15971858, 0x1f8729e0, 0x1c6a8eb8, 0x0dc61e24, 0x16dfdbe1, 0xea68d7}}, - {{0x0dd048fa, 0x02d11252, 0x17a08ffa, 0x029fd549, 0x0a0c84d7, 0x054b2547, 0x139e1c05, 0x192e593f, 0x2a2744}}}, - /* 11*16^0*G: */ - {{{0x14bc21d1, 0x199c8e9b, 0x14122fd0, 0x085da04a, 0x01cda167, 0x1bced861, 0x116418e0, 0x16f10769, 0x3ed113}}, - {{0x082a3740, 0x17c777e7, 0x062276b8, 0x1a09b4bd, 0x0c68a090, 0x01d7d27a, 0x02889321, 0x13599899, 0x909920}}}, - /* 13*16^0*G: */ - {{{0x06072c01, 0x070aecea, 0x1ab562a6, 0x1c5096cb, 0x0e2fc792, 0x0ef96c2f, 0x05698601, 0x0f5c1589, 0x177c83}}, - {{0x0fc7bfd8, 0x021ddf17, 0x1ed37ce7, 0x1c298743, 0x14e7226e, 0x08d6da07, 0x15628902, 0x19a9d7d4, 0x63bb58}}}, - /* 15*16^0*G: */ - {{{0x059b9d5f, 0x1b34631f, 0x0e83bc58, 0x075f25bc, 0x08265ae0, 0x1bc4ccc4, 0x0b9eb7ec, 0x18d2e357, 0xf0454d}}, - {{0x0d034f36, 0x1f2ce6f0, 0x0d7e8fd1, 0x16439ceb, 0x043e62a3, 0x0a728fcb, 0x147d3996, 0x1c6b25c5, 0xb5b93e}}} - }, - { - /* 1*16^1*G: */ - {{{0x01277c6e, 0x0f5a3c3f, 0x1b280e29, 0x10725dfe, 0x0315fcd2, 0x0e314c1b, 0x06162e08, 0x02714d68, 0x76a94d}}, - {{0x0b8c5110, 0x14eeeb92, 0x11e2ea83, 0x1340081f, 0x08720859, 0x10daf08f, 0x1839b2c2, 0x0c2683e4, 0xa985fe}}}, - /* 3*16^1*G: */ - {{{0x1e4536ca, 0x1fdcee34, 0x0806986a, 0x1d252c14, 0x0cda11c2, 0x1a2df038, 0x07b23339, 0x01c924a7, 0x9482fb}}, - {{0x158cc1c8, 0x1d6c31df, 0x01efeec7, 0x1abc52ae, 0x14e63f63, 0x11c653a9, 0x1fe46975, 0x14e8be2a, 0x351d9c}}}, - /* 5*16^1*G: */ - {{{0x15ecff13, 0x0d8ed714, 0x1418cf12, 0x0c9439b7, 0x01eeb637, 0x0d28a984, 0x04656e0d, 0x182f5d26, 0xb2e1b7}}, - {{0x12187d44, 0x1dd24c4d, 0x17a8b9a8, 0x1435302f, 0x158c387d, 0x10d1556b, 0x0f33c8ce, 0x0262747d, 0xe6c044}}}, - /* 7*16^1*G: */ - {{{0x0ef87286, 0x05dd99a7, 0x08c2790e, 0x07d0fbf8, 0x0ee34070, 0x0bbee5e3, 0x0f0b2cd0, 0x05cfe36d, 0xb43346}}, - {{0x041496d9, 0x16023fb4, 0x0b3a92de, 0x1c4100d4, 0x12e6f9dc, 0x073960b4, 0x17f8e0fd, 0x0a4dda56, 0xa0da54}}}, - /* 9*16^1*G: */ - {{{0x19794381, 0x1cc35ad8, 0x0c31d806, 0x02b10ebd, 0x07b19189, 0x1482daab, 0x0933061b, 0x19c9a7b4, 0xa47420}}, - {{0x02769c52, 0x0b671d3f, 0x1dab1e1a, 0x0b811b73, 0x07afff3a, 0x1c9b0ccb, 0x1f839cf7, 0x1bef7c37, 0x2ebbff}}}, - /* 11*16^1*G: */ - {{{0x09a5185a, 0x03a23324, 0x179bcafb, 0x0e15913e, 0x1a3195b8, 0x0a009586, 0x05217fb3, 0x03373a12, 0x5ba7a}}, - {{0x01de3a4e, 0x0a1e4470, 0x016b8005, 0x0c441792, 0x1d48e760, 0x011f1271, 0x025b919e, 0x16bd0583, 0x30e0d2}}}, - /* 13*16^1*G: */ - {{{0x199b85fe, 0x151cc5af, 0x0e977f56, 0x1dfd355c, 0x1e0b79c0, 0x06c8c041, 0x0bf5a5e6, 0x193a1bfc, 0xb29f74}}, - {{0x0da604dc, 0x1d3214bb, 0x1d67a036, 0x1ec7a617, 0x1c6d92de, 0x18974b6b, 0x1e175741, 0x1874d852, 0xa3ce5b}}}, - /* 15*16^1*G: */ - {{{0x07e030ef, 0x1b3a2b74, 0x1543a589, 0x16560af9, 0x02b08576, 0x1f81f924, 0x13d41db2, 0x15517237, 0x99299b}}, - {{0x18d9aa9a, 0x0c735bee, 0x10021113, 0x0258933e, 0x0aa7957c, 0x0080d367, 0x1862fcce, 0x1a6667f1, 0x5cc2e3}}} - }, - { - /* 1*16^2*G: */ - {{{0x12d0441b, 0x0d971af8, 0x1a95930b, 0x1a16e21a, 0x1ed61190, 0x08a94301, 0x19661fff, 0x14760122, 0x34a2d4}}, - {{0x1e93b146, 0x01273c22, 0x1776076d, 0x0ecd73bd, 0x17fc0e7d, 0x1882373b, 0x0f08af29, 0x0d4a743c, 0xbeaaed}}}, - /* 3*16^2*G: */ - {{{0x1da08424, 0x0725719d, 0x1d912a77, 0x1f6f56e9, 0x123ed3ab, 0x02ffd4ae, 0x06a86d63, 0x00f5b86b, 0xa98b0a}}, - {{0x0831800c, 0x10943d07, 0x17d60b4d, 0x17d01741, 0x11320752, 0x0f46470e, 0x0d9b94c6, 0x08e44933, 0x4754c6}}}, - /* 5*16^2*G: */ - {{{0x083c2d6a, 0x096bf2f4, 0x0f4a6ced, 0x1f231b03, 0x0696dd22, 0x15bc642d, 0x0b17486d, 0x013911b5, 0xa034f0}}, - {{0x02c30e72, 0x019b7796, 0x099f9f3d, 0x0c06be2c, 0x0eb06be0, 0x1c2a2e76, 0x107ec336, 0x06d95133, 0xfe1b00}}}, - /* 7*16^2*G: */ - {{{0x08be8c78, 0x0b528ee9, 0x1e4f935c, 0x12d9f056, 0x0e9a14a0, 0x115a04b1, 0x100681db, 0x1fe633a8, 0xb52226}}, - {{0x11686903, 0x019b3e52, 0x0d63fcc8, 0x1eff91cb, 0x0851a819, 0x1b34bf49, 0x1503286c, 0x193ea73e, 0x701ee0}}}, - /* 9*16^2*G: */ - {{{0x0058b5a4, 0x0207f205, 0x0c65e6dc, 0x08c9f0f2, 0x04713de4, 0x07667e66, 0x16cf65a3, 0x0c30d1c0, 0xa3e388}}, - {{0x07113aef, 0x19836c87, 0x1c68a523, 0x1d08b76e, 0x1e68f3ce, 0x1359d74b, 0x04b0e123, 0x110fbe1a, 0xcfd457}}}, - /* 11*16^2*G: */ - {{{0x04a08314, 0x02faf648, 0x11f7fde8, 0x1c6db65b, 0x1197a82f, 0x055cd110, 0x14e4ccf3, 0x094263f4, 0x209954}}, - {{0x07573ccc, 0x1fc64e2f, 0x1f3fa5b9, 0x0dcb4e6d, 0x048dfd40, 0x1472e5c8, 0x0c6243ee, 0x1fa55467, 0xa5cf3d}}}, - /* 13*16^2*G: */ - {{{0x09078c18, 0x017fca57, 0x1b7a4a54, 0x018795dd, 0x1d39b99e, 0x1739556f, 0x11c0c23d, 0x0275981d, 0x751d65}}, - {{0x0ece0d67, 0x0c6b74ae, 0x1816b1e6, 0x12918397, 0x02a4ef00, 0x05d7b515, 0x056214d5, 0x1fb94948, 0xba9c3f}}}, - /* 15*16^2*G: */ - {{{0x1e86d900, 0x167e6ae4, 0x08f6d124, 0x1dc13a2f, 0x03b36405, 0x0184501d, 0x00445ed2, 0x044b88f0, 0x5be0f5}}, - {{0x158a5755, 0x066eb4df, 0x0cd3d6b1, 0x02e4a483, 0x1423df92, 0x11d273da, 0x108b4d1f, 0x1cdbfe58, 0x83d1d9}}} - }, - { - /* 1*16^3*G: */ - {{{0x0245573f, 0x03bf46d5, 0x1f42993c, 0x0cede5e9, 0x16bd2508, 0x04b39736, 0x193665de, 0x1a59e0d3, 0xe716ae}}, - {{0x069218d1, 0x02fe135a, 0x01f26cd4, 0x1a1be5f4, 0x1a851d13, 0x183343dc, 0x0aad644a, 0x1cd29f8e, 0x353663}}}, - /* 3*16^3*G: */ - {{{0x057008ac, 0x1cc3c983, 0x0a7b7edf, 0x1c3d9dc6, 0x1a22d19c, 0x0ac5260e, 0x13a19395, 0x11adea0f, 0xd2bf89}}, - {{0x127beb55, 0x088a9a53, 0x1fc1e620, 0x19c2156b, 0x10c56679, 0x0aed9fd4, 0x1ea8fe06, 0x196b4d6e, 0x69c0b1}}}, - /* 5*16^3*G: */ - {{{0x182f1580, 0x086be54b, 0x080fadff, 0x09bbdc48, 0x064f8b0e, 0x0b9c8f98, 0x19821fe9, 0x09dcb079, 0x4d8830}}, - {{0x1616edd7, 0x007d8b6a, 0x1ac78443, 0x19477ad1, 0x16518aaf, 0x00044c7e, 0x0db3a35a, 0x0e13560c, 0x28a94e}}}, - /* 7*16^3*G: */ - {{{0x00c38e11, 0x1c261ed7, 0x1b89ae97, 0x0c8437d4, 0x1af9e715, 0x1cc90172, 0x1bacc99c, 0x04f91f81, 0x17c727}}, - {{0x0e90decd, 0x0c1b35dd, 0x0336b8f3, 0x07328b4c, 0x1802e7e5, 0x17e67480, 0x0cf10180, 0x1e9fccc9, 0x95c5a4}}}, - /* 9*16^3*G: */ - {{{0x032f36ea, 0x0aafec57, 0x0d5070f6, 0x1e8d4e52, 0x0b8b3cd4, 0x18e7e426, 0x02a2118e, 0x15588e8a, 0x7e03fd}}, - {{0x0a68b8af, 0x16611fe4, 0x140275a2, 0x1d2f3498, 0x0af99419, 0x158b80c2, 0x03699a39, 0x1e240245, 0xdcf6d5}}}, - /* 11*16^3*G: */ - {{{0x1953baa9, 0x01f29536, 0x18637a35, 0x0b5d0c93, 0x0b214261, 0x1d60ee50, 0x1c1d858d, 0x0d096379, 0x8ce6da}}, - {{0x152689e5, 0x073ae147, 0x0a4d075e, 0x0730d76d, 0x1b56807f, 0x1de48030, 0x082f9a6c, 0x171f5262, 0x3d9f4f}}}, - /* 13*16^3*G: */ - {{{0x0f22a96a, 0x15c6c29d, 0x1aae3e52, 0x03753b38, 0x0e2b008b, 0x1aa4badd, 0x15288294, 0x06081b80, 0xb570e7}}, - {{0x085d1b00, 0x199fb30e, 0x15732732, 0x1376f4b0, 0x0cfbda7c, 0x1bb4dae0, 0x1dfc0a30, 0x0c71ee3c, 0xdcd8a2}}}, - /* 15*16^3*G: */ - {{{0x189a7509, 0x12075ca2, 0x1ea01527, 0x0e172c83, 0x1f20de12, 0x0d1f3ae3, 0x10ec1284, 0x04797572, 0x44d943}}, - {{0x00437234, 0x10515cdb, 0x137449b8, 0x07c3fbe2, 0x193586f9, 0x1de693bd, 0x1c280d08, 0x10010803, 0xb2c5b3}}} - }, - { - /* 1*16^4*G: */ - {{{0x0eade3c4, 0x1f4232e3, 0x014a8140, 0x156e9392, 0x186b4714, 0x1219a072, 0x04363971, 0x0de9d23d, 0xa01836}}, - {{0x0b26e8d0, 0x02e21013, 0x1853cdfd, 0x0e509c88, 0x18369d5f, 0x12bc1a4e, 0x0c59f1b3, 0x02e28221, 0xe2bbec}}}, - /* 3*16^4*G: */ - {{{0x19e0af06, 0x10e6f562, 0x1b65635b, 0x07314ac5, 0x1055c92f, 0x1dad36a2, 0x059142f4, 0x001711b1, 0x9cdf1f}}, - {{0x0216ade7, 0x0bd196db, 0x1f2951a3, 0x0a45b832, 0x194b0828, 0x05de6e46, 0x15993656, 0x1fda7e55, 0x916d25}}}, - /* 5*16^4*G: */ - {{{0x1305097e, 0x09b95c9c, 0x0ee94660, 0x0c2e1d08, 0x0448338d, 0x0d9682a0, 0x0fb6adac, 0x1aba34cc, 0x45bfd9}}, - {{0x108ddc04, 0x05d02c74, 0x14b05655, 0x173a677f, 0x0e908683, 0x0182a386, 0x14aeeb62, 0x0250ab5f, 0x9d1dc}}}, - /* 7*16^4*G: */ - {{{0x163bd6df, 0x098f8d05, 0x19abb0f3, 0x184785ba, 0x15e6fd1f, 0x0fce0144, 0x04ed9c7a, 0x02ac8ecd, 0xb599ad}}, - {{0x0efa09ac, 0x150e751c, 0x04d2d163, 0x0189ed22, 0x1c4166a4, 0x1b05c591, 0x0cc918dc, 0x1bd89f56, 0x6979d1}}}, - /* 9*16^4*G: */ - {{{0x07142d62, 0x1c309f99, 0x0ef09b6b, 0x14d46bf0, 0x054c11d9, 0x158913f4, 0x103a4998, 0x1e2ce655, 0xf4dca1}}, - {{0x1a618fc9, 0x04f66603, 0x134f5feb, 0x0f359dfb, 0x1c659bb9, 0x1c0dc8d5, 0x151b527c, 0x1cb69699, 0x551167}}}, - /* 11*16^4*G: */ - {{{0x015fae61, 0x1658ffa3, 0x0e57e087, 0x0b8fb89e, 0x0bb5a7f1, 0x1120738b, 0x0d9b6713, 0x141cdc13, 0xf07278}}, - {{0x096376f9, 0x1e865ba4, 0x0dfaaf3d, 0x0e0e2b70, 0x0f7d42c2, 0x10410c4c, 0x1a97df5e, 0x056294e3, 0x1a681b}}}, - /* 13*16^4*G: */ - {{{0x0466591f, 0x027020a9, 0x11a35a83, 0x0e5d51ff, 0x058ccbe1, 0x15a99dd4, 0x16c3c50e, 0x0af5e141, 0x1fc524}}, - {{0x196f8cdb, 0x077f7ab9, 0x1b1e0891, 0x11958465, 0x14e1629f, 0x1b7f2da1, 0x1047a7b1, 0x070113d7, 0x489c18}}}, - /* 15*16^4*G: */ - {{{0x122a8ebc, 0x12e85c61, 0x1e59c544, 0x039b6e31, 0x056d5a29, 0x05ad9865, 0x17d3f5fc, 0x16634918, 0xfa2501}}, - {{0x0a8a775b, 0x06c93dad, 0x0f20cc60, 0x11c11cd9, 0x1a8cbea5, 0x0f330d37, 0x0588ce14, 0x1629f0b1, 0x71c932}}} - }, - { - /* 1*16^5*G: */ - {{{0x1d96dff1, 0x1bee765b, 0x157f3fa3, 0x08638355, 0x198d530e, 0x105ab866, 0x153ffbda, 0x10a283fc, 0xec738}}, - {{0x1c7b552c, 0x16420d63, 0x1b5e2aa7, 0x04c99d0f, 0x052511d5, 0x0277ac03, 0x1d7646b3, 0x09d0f5d0, 0xd6224f}}}, - /* 3*16^5*G: */ - {{{0x088d58e9, 0x0e192558, 0x18c60e14, 0x14b838c9, 0x0a7b6e94, 0x12353e21, 0x0a1ba64a, 0x1fb8e0c9, 0x96dac3}}, - {{0x0ebebc5e, 0x01a49895, 0x01f9b8e0, 0x17d13729, 0x0c439685, 0x024a49c1, 0x06b615b3, 0x1e75a8d8, 0xcb1faf}}}, - /* 5*16^5*G: */ - {{{0x0db29f92, 0x0a956899, 0x11ecb162, 0x03a4e372, 0x18f811d2, 0x0e1bc575, 0x0c4a8417, 0x079d629e, 0xe297b2}}, - {{0x05e58ddb, 0x0794a645, 0x1b505058, 0x079d770b, 0x19149122, 0x0dd5dc66, 0x02d2d203, 0x041f196e, 0xe13725}}}, - /* 7*16^5*G: */ - {{{0x0ad88c33, 0x0ca1dbdc, 0x1d1af2bf, 0x15c729b2, 0x0da97d91, 0x1e490692, 0x12d9ac1a, 0x071f6572, 0x1cd223}}, - {{0x048fb1b2, 0x14753c21, 0x12879258, 0x1ca262bd, 0x0bc2713f, 0x1205589b, 0x02c25b21, 0x1f071569, 0xfc3acd}}}, - /* 9*16^5*G: */ - {{{0x1b26aa73, 0x09d644e1, 0x18e8383d, 0x0fc23618, 0x11ee0cdf, 0x16986ffd, 0x0eff2c72, 0x15b73d3f, 0xf462d7}}, - {{0x18479e73, 0x02f560bb, 0x140b3289, 0x11c14600, 0x13c7a49e, 0x1d253439, 0x0c50354e, 0x034f068a, 0x406a0d}}}, - /* 11*16^5*G: */ - {{{0x1cd015e3, 0x170f0155, 0x194089cf, 0x01d2b2fc, 0x15168af9, 0x1f59e544, 0x12bdd6f6, 0x04ba7ee1, 0xe0f689}}, - {{0x12157cce, 0x15126a16, 0x0a4daef6, 0x116a723c, 0x0c77c55b, 0x14b6393a, 0x0aa54d89, 0x0621c907, 0x8531e}}}, - /* 13*16^5*G: */ - {{{0x0bb76b12, 0x1362188a, 0x0649da47, 0x1cecee7c, 0x15a00ea8, 0x1598957b, 0x15ff0760, 0x182aa57e, 0x28e4ad}}, - {{0x0c4747bd, 0x1f229d3f, 0x058a3fd5, 0x014c1e2e, 0x0a3f703a, 0x1b2db5cf, 0x06cfd392, 0x09dfb340, 0x14d74c}}}, - /* 15*16^5*G: */ - {{{0x076ff697, 0x1fac00ff, 0x01d918a2, 0x16d10ca4, 0x097c6369, 0x16d5d9d0, 0x017b49c7, 0x04f29750, 0x85a0ba}}, - {{0x12142721, 0x04f6a6d2, 0x02962e4c, 0x12fff4f2, 0x1aa551de, 0x0869ee76, 0x0929551e, 0x0c3d587c, 0xadf32e}}} - }, - { - /* 1*16^6*G: */ - {{{0x0392d805, 0x192e2ee7, 0x1501750d, 0x1500d30e, 0x1449aa87, 0x06d57d51, 0x0f5e9295, 0x19e98d52, 0xf8f5dc}}, - {{0x0cda02fa, 0x1330ca8b, 0x0850ee80, 0x07b4c94a, 0x1327351f, 0x1f19b230, 0x0150e274, 0x19ecdac6, 0xe58176}}}, - /* 3*16^6*G: */ - {{{0x1fa046f7, 0x0ea598b3, 0x01cc2746, 0x021e7204, 0x02d45171, 0x05644a37, 0x0ea53821, 0x0950cb10, 0xe12c8e}}, - {{0x012646ad, 0x1d2ad145, 0x0c464d14, 0x1809c226, 0x126f6dd0, 0x1f6a9c98, 0x0bcd0cec, 0x0c21fb34, 0x7cec04}}}, - /* 5*16^6*G: */ - {{{0x02853c43, 0x0d893f46, 0x08b919ae, 0x0cd8af5c, 0x13236481, 0x1177f1e8, 0x0824f423, 0x0e82f2d2, 0x394bd4}}, - {{0x0064469d, 0x0bc14665, 0x03f3c32c, 0x1ece25b2, 0x00767d52, 0x1fe178eb, 0x1ae481f8, 0x0a42a3b8, 0x2b4d6d}}}, - /* 7*16^6*G: */ - {{{0x1c722e94, 0x016eb9cf, 0x0162587b, 0x102072da, 0x004334ed, 0x132b62ca, 0x0ba51171, 0x1be71bd0, 0xca8538}}, - {{0x1049a527, 0x105316f8, 0x02c9a90e, 0x12a75149, 0x19f12f20, 0x189350fd, 0x170c479c, 0x085d73c0, 0x3b27fc}}}, - /* 9*16^6*G: */ - {{{0x1cad6309, 0x18ba314e, 0x0e7fd221, 0x143f85e4, 0x07b3dd31, 0x1a312653, 0x0dd686ed, 0x0b3e46af, 0x663e1a}}, - {{0x09981f28, 0x19435d1c, 0x1ad4af54, 0x0fa88805, 0x0f918b90, 0x00c1e58e, 0x030f040b, 0x07700cd5, 0x292fb7}}}, - /* 11*16^6*G: */ - {{{0x02c23d03, 0x13ad9229, 0x11ffc924, 0x03609b1f, 0x1eeab3ba, 0x1611b83d, 0x19c25b0d, 0x1ce60c6c, 0xa2d9ef}}, - {{0x1085db74, 0x01726027, 0x0e77d144, 0x134fd2b0, 0x01b92ea0, 0x021b6388, 0x0e3c554c, 0x05199083, 0x1cc852}}}, - /* 13*16^6*G: */ - {{{0x07d4c6d1, 0x1aafcb38, 0x167ffec5, 0x059aa335, 0x135d0f66, 0x085a939f, 0x07bf82e4, 0x05691635, 0x5657e1}}, - {{0x0106bdec, 0x0181f94c, 0x14b05062, 0x1346b428, 0x06a0abff, 0x1c8799d7, 0x07e6b3ec, 0x1e971ba9, 0x72b5be}}}, - /* 15*16^6*G: */ - {{{0x1933564a, 0x032a6eaa, 0x18ebd13e, 0x1169f5db, 0x18d2b7a6, 0x16e333b6, 0x00042193, 0x02ba815c, 0x5b6862}}, - {{0x0204ef63, 0x1af822c4, 0x1e21a7ce, 0x15dc4510, 0x195de392, 0x062a68ce, 0x19154b4c, 0x0d39e744, 0x76b5ea}}} - }, - { - /* 1*16^7*G: */ - {{{0x0f922dbd, 0x025118bb, 0x064863e6, 0x0c622c3f, 0x171b91ca, 0x1556c726, 0x1cc4fe17, 0x17ffa9b5, 0x6d28b6}}, - {{0x00ef3cff, 0x055ff815, 0x1368a651, 0x09d3e170, 0x14a1c4c2, 0x10d30e65, 0x0be903ef, 0x00a283ba, 0xaf39d9}}}, - /* 3*16^7*G: */ - {{{0x1b168b64, 0x0c86ffcc, 0x01b2102d, 0x07a0558b, 0x0467ea15, 0x0482fe0a, 0x0f774f7c, 0x0f4ff7fc, 0x7cd315}}, - {{0x1abbb16b, 0x0b60695a, 0x180b8d61, 0x189b36e5, 0x1fafb13a, 0x073c5e6d, 0x1188815a, 0x0422e525, 0x9ca08d}}}, - /* 5*16^7*G: */ - {{{0x06ef29e8, 0x158e37d0, 0x166bb8ec, 0x18aa9613, 0x1356264d, 0x018ccea2, 0x03115ac9, 0x1b6be5bf, 0xed860b}}, - {{0x19b90f8f, 0x00d0e24d, 0x036a8cd4, 0x061eb85b, 0x17bb1e76, 0x1b59a020, 0x1ff5f1af, 0x086ebab4, 0xb837e7}}}, - /* 7*16^7*G: */ - {{{0x1636e617, 0x0fc8c59f, 0x1c73d667, 0x19a07783, 0x12c9d47d, 0x0e173f13, 0x090dcd78, 0x11fa3a42, 0x6868cc}}, - {{0x1cbb3d27, 0x046ee79f, 0x0e1335c7, 0x1c619148, 0x13f0a60f, 0x081c3c98, 0x079acf16, 0x14b7237f, 0xeed008}}}, - /* 9*16^7*G: */ - {{{0x113e2a34, 0x1ced1530, 0x0e8478b1, 0x1a5ccb9c, 0x1d318291, 0x1a4f8857, 0x1880b172, 0x0c1d591f, 0xec03b3}}, - {{0x184566d6, 0x01121f75, 0x084dade9, 0x102adccb, 0x122728aa, 0x0f108090, 0x010defbf, 0x1f6c140b, 0x86020f}}}, - /* 11*16^7*G: */ - {{{0x087c1b18, 0x1570672e, 0x12646897, 0x1c596a90, 0x056fa101, 0x01ad2c88, 0x04379a8c, 0x1473cf17, 0xa79464}}, - {{0x1b94809a, 0x15ac284b, 0x158a086f, 0x11bd38e2, 0x089f60d9, 0x0bc3cf4d, 0x03309269, 0x1c7ee50b, 0x1361f4}}}, - /* 13*16^7*G: */ - {{{0x1ed10d26, 0x0a714636, 0x19657d96, 0x157df053, 0x10ccc5a9, 0x0fdb4a79, 0x131e43a4, 0x101551f7, 0x544ef2}}, - {{0x16dafcc2, 0x1e127b93, 0x0b01ab8b, 0x1adf2edc, 0x170d3683, 0x0eff46c6, 0x0b3a75ac, 0x13b88b58, 0x95b91c}}}, - /* 15*16^7*G: */ - {{{0x17ad18e6, 0x04a3cfc5, 0x0f2b5789, 0x1a7cf31a, 0x0ff9b57a, 0x1e4235a5, 0x18853794, 0x110be698, 0xe2c26c}}, - {{0x0554cfad, 0x0d7f28d5, 0x0607792b, 0x0a2b94e3, 0x1ba113bc, 0x1337508b, 0x06214738, 0x0509e910, 0xb2121b}}} - }, - { - /* 1*16^8*G: */ - {{{0x185a5943, 0x12d4f110, 0x1977ed8e, 0x12326cb8, 0x071da1ab, 0x15991316, 0x1e248595, 0x0815e455, 0x7fe36b}}, - {{0x099ca101, 0x0868a963, 0x02bc84b5, 0x07ab0cf7, 0x0a6f174b, 0x1a0203ee, 0x18927c27, 0x0b04b6c6, 0xe697d4}}}, - /* 3*16^8*G: */ - {{{0x1f0922a8, 0x153c048e, 0x173e365d, 0x01d3a4a8, 0x18b808e9, 0x072b0117, 0x15ce0249, 0x080b69c5, 0x4b656a}}, - {{0x199a80bb, 0x0d6e562c, 0x0143da53, 0x0773c573, 0x0c4d6d47, 0x06612aec, 0x00e48341, 0x03a25cef, 0xee1ea3}}}, - /* 5*16^8*G: */ - {{{0x09d07e9e, 0x0827c443, 0x09830dad, 0x1cf943ed, 0x18e5ea09, 0x15f07d9e, 0x04f64f6c, 0x0dd7acbc, 0x9d7895}}, - {{0x03d8c8ee, 0x06eb0ad6, 0x0531ecbd, 0x0145b477, 0x010ce746, 0x144e0e99, 0x0335950a, 0x0dde91d5, 0xd5149e}}}, - /* 7*16^8*G: */ - {{{0x1dc4950f, 0x13ba8433, 0x0e5081d9, 0x03655b7a, 0x16316574, 0x1423726d, 0x1ea55c8d, 0x0e5c26a7, 0x4acb12}}, - {{0x03d8b4df, 0x16372223, 0x019ab159, 0x1c85016b, 0x1e29fdf9, 0x0c7b6638, 0x16b633ca, 0x01f6e879, 0x726cd2}}}, - /* 9*16^8*G: */ - {{{0x0d7e8cbd, 0x0063d3df, 0x01f605bd, 0x0cff15e0, 0x1464a2a6, 0x09aa8640, 0x1ed08d11, 0x17e34d62, 0x640c5e}}, - {{0x1ec5a5db, 0x171481e5, 0x1fe6c081, 0x0d3f6319, 0x0ab9eba0, 0x0375b80f, 0x14bcaba7, 0x1fb0539f, 0xd6ae88}}}, - /* 11*16^8*G: */ - {{{0x1e86bddc, 0x18502583, 0x1738f57d, 0x04d72f2e, 0x16b9bf1d, 0x116486ed, 0x0cc91455, 0x16368509, 0x8bba04}}, - {{0x09e349c4, 0x111e2d0f, 0x065b97d4, 0x19fbc9e8, 0x1437ac6a, 0x1c90b34c, 0x1afd966f, 0x18138411, 0xc34099}}}, - /* 13*16^8*G: */ - {{{0x0257f582, 0x0b873c02, 0x10e89634, 0x1213d5bd, 0x05fe41f9, 0x0a1fbe2d, 0x1f88429a, 0x089fd9a6, 0x8b0a57}}, - {{0x17372d4b, 0x00bff6f9, 0x0581d992, 0x168d74f6, 0x17d4656d, 0x0ad09bf1, 0x1ce598a8, 0x09d81ad8, 0x9e57a4}}}, - /* 15*16^8*G: */ - {{{0x185e797e, 0x18a24fcc, 0x0f0c5a0f, 0x1c449e5c, 0x078a6f06, 0x17a49ecb, 0x025c7e15, 0x12f84c8f, 0xa13ff}}, - {{0x139d666f, 0x193d5cfa, 0x0030e4a0, 0x1ede14eb, 0x1dc3ff27, 0x00c747d0, 0x0f5645f6, 0x09644b90, 0xeb1a96}}} - }, - { - /* 1*16^9*G: */ - {{{0x1dde3445, 0x17fa7f0f, 0x0ba9e05e, 0x1753bb45, 0x0519e76b, 0x0ff3ff93, 0x079a14dc, 0x0709ae0c, 0x6965b6}}, - {{0x18855113, 0x0621c4f0, 0x17e6765f, 0x19cc0a34, 0x12dbef47, 0x04b31c39, 0x1444c979, 0x1c738904, 0xd1bcda}}}, - /* 3*16^9*G: */ - {{{0x088acfc5, 0x0f207cb4, 0x1a25e27d, 0x1eb1366c, 0x11a71b1e, 0x1eedea04, 0x1f6809f9, 0x03bbceb8, 0xe1cbc5}}, - {{0x0249a225, 0x1e2ff6ad, 0x0fee948e, 0x065257dd, 0x1e23ce7d, 0x1b27fedc, 0x0bb6cc49, 0x12f9bcfb, 0xec6783}}}, - /* 5*16^9*G: */ - {{{0x0107ccc6, 0x0c7529ff, 0x0f208a1d, 0x112fc2a8, 0x100481d3, 0x0e9422d4, 0x0a85cc7a, 0x0f2e2271, 0x9c3f26}}, - {{0x1dea9152, 0x003ca669, 0x1e6c61a1, 0x11fa9d2b, 0x06eca51a, 0x1afa5f9f, 0x16722f8d, 0x036c96a3, 0xdaee0c}}}, - /* 7*16^9*G: */ - {{{0x15a449e7, 0x0e2f5a1c, 0x0f0af908, 0x054069ca, 0x0922b2fa, 0x160bd8a0, 0x15c9e5be, 0x0aef8d65, 0x5c30d9}}, - {{0x0e2677d0, 0x1875240d, 0x139e439d, 0x1c80a787, 0x192d0b75, 0x12fbcce2, 0x0e48592d, 0x16b611c3, 0x8025e3}}}, - /* 9*16^9*G: */ - {{{0x0b8ceb07, 0x12ac6014, 0x1b89c73e, 0x124a57ff, 0x0d995537, 0x11583f54, 0x1a0abf93, 0x046191d2, 0xaa3bbf}}, - {{0x1fd83984, 0x0d423174, 0x0cfe7ae6, 0x036578f5, 0x162ec3b7, 0x187f2648, 0x09a11372, 0x161383d8, 0xe6320c}}}, - /* 11*16^9*G: */ - {{{0x03bfd1f1, 0x00752aac, 0x1595ccb9, 0x0db86a2b, 0x001943a3, 0x07e4c8a0, 0x0605e798, 0x0a226668, 0xab4a32}}, - {{0x08e1c233, 0x089cb086, 0x07a633c8, 0x1b26484f, 0x1e057a57, 0x1de82097, 0x19a2d3ac, 0x17606d90, 0xea6c64}}}, - /* 13*16^9*G: */ - {{{0x0b1d6d3f, 0x02036bc0, 0x1baee242, 0x0ecd149d, 0x1a8105f3, 0x1fae6c52, 0x15dfdccd, 0x0b3bbdab, 0xdba9b2}}, - {{0x09cd8133, 0x01749414, 0x0af64f31, 0x1b3788a2, 0x1871448b, 0x0ca7a7f5, 0x0ded6b2a, 0x07eaea6b, 0xb3862d}}}, - /* 15*16^9*G: */ - {{{0x11fa2a6a, 0x1cd01c01, 0x0392c959, 0x183ab0b6, 0x1cdfe34f, 0x0ba158d1, 0x1d141eb7, 0x1885d304, 0x1998f4}}, - {{0x06415142, 0x03f6da5e, 0x1c962d58, 0x180470f6, 0x0a1e94c6, 0x1c0045bc, 0x08425c03, 0x0da3215f, 0x2ebb41}}} - }, - { - /* 1*16^10*G: */ - {{{0x0d9aefbd, 0x0c7e5362, 0x0e55dd49, 0x1c8f64e7, 0x043dc1ef, 0x0f86a0de, 0x15d8cb2a, 0x03918cd3, 0xfbc34}}, - {{0x13e71ca0, 0x09db754e, 0x02a7fc7b, 0x160d3c40, 0x1d3d3950, 0x058ea4ab, 0x18ff9005, 0x0c65e6c1, 0xbd8022}}}, - /* 3*16^10*G: */ - {{{0x09434837, 0x1cb6fff7, 0x08306ee1, 0x0628170c, 0x1b06dadb, 0x0e37fda7, 0x0bb6c4d0, 0x1578950f, 0xd76d18}}, - {{0x1b215b4c, 0x1d5027cd, 0x0df33093, 0x08b1ceeb, 0x1933290a, 0x010a7bd5, 0x19137839, 0x1465db2c, 0xf6bc4d}}}, - /* 5*16^10*G: */ - {{{0x1c07f222, 0x1744f90c, 0x183f9f40, 0x0438c758, 0x153d1c5e, 0x0e8d0f8b, 0x1d813d20, 0x0a0c2cff, 0xd5c0c6}}, - {{0x0c6ffd57, 0x177b48f0, 0x004ea1b8, 0x07ea34f1, 0x175b9baf, 0x063bfa4f, 0x02143378, 0x10c102f7, 0x15a30b}}}, - /* 7*16^10*G: */ - {{{0x0e93bfa6, 0x1238b512, 0x084d8a92, 0x1a52b413, 0x09fe0d39, 0x05d335a6, 0x18b39527, 0x09c948de, 0x734c36}}, - {{0x18d10774, 0x037d3ccc, 0x00a5f13f, 0x026c4112, 0x05f48eca, 0x00f1a906, 0x141277a6, 0x007554f3, 0x99515}}}, - /* 9*16^10*G: */ - {{{0x1fa194ae, 0x075a8bfa, 0x0152bb3c, 0x00523b34, 0x0b149064, 0x0ece954f, 0x0a24045d, 0x1b40f6cd, 0x79a3d9}}, - {{0x1fcf634b, 0x1e32f4e4, 0x1e6f1353, 0x084be65e, 0x103d86bd, 0x18dc2c57, 0x06cd2cd9, 0x194e4a96, 0x84e1db}}}, - /* 11*16^10*G: */ - {{{0x01e8b7fe, 0x16483001, 0x016c9a9a, 0x01c5c2ef, 0x098e05dd, 0x06556e7e, 0x160a28f9, 0x0129ab60, 0x3393fd}}, - {{0x023c6821, 0x00a12210, 0x06e52dc3, 0x0d661515, 0x0668d8e5, 0x1576ce2d, 0x1ae0babf, 0x17d90cf7, 0x130437}}}, - /* 13*16^10*G: */ - {{{0x01528cf6, 0x04abceab, 0x141a53a8, 0x004a15ec, 0x10a52e6a, 0x02c3772d, 0x1f85786d, 0x10c268c4, 0xa16b28}}, - {{0x1ce93f3b, 0x05c907cf, 0x132004e0, 0x07f79027, 0x150f4349, 0x16bcec08, 0x166644f3, 0x15d0a6f5, 0xf40598}}}, - /* 15*16^10*G: */ - {{{0x0c8db2e0, 0x0885335c, 0x035cd60d, 0x197b82be, 0x074f6473, 0x04d5d4ad, 0x1d32fdb2, 0x04031c68, 0xd317ce}}, - {{0x074bc9a9, 0x0d9a5159, 0x0e183ce9, 0x04e9a045, 0x19136caa, 0x01f471cb, 0x112e670b, 0x01521270, 0xd61a21}}} - }, - { - /* 1*16^11*G: */ - {{{0x03fe67b2, 0x1718cbd5, 0x0b8cce31, 0x117fce14, 0x123b234a, 0x15cdd4b9, 0x1772f199, 0x086ee790, 0x6608c2}}, - {{0x05b47a28, 0x091ff2e7, 0x1150c206, 0x162b3e81, 0x0e03fc22, 0x1206d3a3, 0x05a211bd, 0x17d8a438, 0xa1a916}}}, - /* 3*16^11*G: */ - {{{0x0bc73e02, 0x1f375569, 0x194c4b04, 0x0cc29dd6, 0x18631849, 0x0c08beab, 0x108c81aa, 0x1c54d8bb, 0xf0956a}}, - {{0x0611219d, 0x0967b4cc, 0x0ba515cb, 0x1a091b77, 0x19356672, 0x02c57941, 0x00f1db88, 0x0c02289c, 0x433fe6}}}, - /* 5*16^11*G: */ - {{{0x1c5fe45c, 0x0f116f28, 0x1f03d65f, 0x05035070, 0x1283488b, 0x124ebe7b, 0x183294bc, 0x1d479454, 0xdb98eb}}, - {{0x1ef45a22, 0x05380e21, 0x12038711, 0x06409f54, 0x12c8ce98, 0x094eec48, 0x168b7854, 0x016eb7b0, 0xe0c0f3}}}, - /* 7*16^11*G: */ - {{{0x02128eac, 0x1acf306f, 0x0bc732eb, 0x0eb1ab99, 0x051690c4, 0x159dbeb5, 0x17d086e9, 0x02c15bb4, 0xa73c0}}, - {{0x04f1180d, 0x02c948eb, 0x1576728e, 0x0eb3e2ee, 0x10a7c793, 0x1b6eca7a, 0x0e329572, 0x0ac089d0, 0x443fda}}}, - /* 9*16^11*G: */ - {{{0x03ccbc30, 0x12d4998b, 0x0d258631, 0x1fcba43a, 0x197249ed, 0x1bb33d04, 0x1c8dc3b4, 0x1868f969, 0x378720}}, - {{0x1315729e, 0x110193f8, 0x0d23e11a, 0x19f2aba2, 0x19b6d16b, 0x05605553, 0x0e324c46, 0x1739ee4a, 0x8f1bdd}}}, - /* 11*16^11*G: */ - {{{0x03bb1b6b, 0x12546f2a, 0x1f0afea9, 0x1fde65e8, 0x1a621575, 0x08c6082a, 0x09867660, 0x03b6f163, 0xfe8fd2}}, - {{0x10eaaf93, 0x1daecdd1, 0x0afe2265, 0x09bb9fe1, 0x113c00f1, 0x074afad6, 0x18dda78a, 0x15d864ad, 0x791e22}}}, - /* 13*16^11*G: */ - {{{0x144b7cea, 0x002acce5, 0x1b3e1f7a, 0x08d28122, 0x1dcca474, 0x00113c59, 0x18bba081, 0x1aaf3f6f, 0x2c331f}}, - {{0x15d1c9c2, 0x1e15a356, 0x0c2501df, 0x04a23fe2, 0x1d650619, 0x19ec61de, 0x19dbf3cf, 0x0399c0c3, 0x20567b}}}, - /* 15*16^11*G: */ - {{{0x0112278c, 0x1c94d9bc, 0x03668563, 0x02c93a15, 0x04b66dd0, 0x1a643fc2, 0x0c828d22, 0x0d88ca34, 0x509bc0}}, - {{0x0e178f66, 0x043ae4c4, 0x0d7e517b, 0x0bfd0dce, 0x164570f6, 0x1a78bdc7, 0x1bb05d83, 0x1856e448, 0xb4b168}}} - }, - { - /* 1*16^12*G: */ - {{{0x17e55104, 0x175d7c00, 0x03a71c70, 0x1506bf77, 0x1561cf73, 0x09e1a6c5, 0x1cdd8f7a, 0x0a44f6f0, 0xd8de76}}, - {{0x052e08cd, 0x10177c07, 0x1036c6ca, 0x0e7f9c32, 0x0f924c2f, 0x114568ee, 0x0b457131, 0x0cb7c27e, 0x2fd294}}}, - /* 3*16^12*G: */ - {{{0x0987bfd3, 0x09ce163f, 0x110a131a, 0x0a8e5fe9, 0x1d19187c, 0x1df57d6e, 0x18cd5477, 0x0df7aa31, 0xe3a578}}, - {{0x0cc23e7d, 0x1698db64, 0x0a38205f, 0x19e5d9b2, 0x0210ca3d, 0x1cffa56c, 0x039a11de, 0x012a6b08, 0xf74bad}}}, - /* 5*16^12*G: */ - {{{0x02d5056e, 0x13ca8e91, 0x11e81f2d, 0x196b4fc4, 0x05e480ed, 0x0ffe74b7, 0x03504549, 0x083d94a4, 0x42a970}}, - {{0x10f7db11, 0x020a6e45, 0x07f47f52, 0x1c907add, 0x03b26b64, 0x16e935ab, 0x1c19bb0d, 0x0cd9e010, 0xf2fc7f}}}, - /* 7*16^12*G: */ - {{{0x13dafd3b, 0x13a2fc8e, 0x12ce55b1, 0x1133e05b, 0x179d66fb, 0x16176b29, 0x1933f88c, 0x036384f2, 0xd6ca7}}, - {{0x1a6fe6e8, 0x156f8a10, 0x021dc6b5, 0x049157dd, 0x1de58a02, 0x0a501383, 0x04f67f92, 0x1671fbc5, 0xa85130}}}, - /* 9*16^12*G: */ - {{{0x11131f8b, 0x15fce3ff, 0x0883537d, 0x08d2c19f, 0x11fb4696, 0x116fce21, 0x0f65f530, 0x0f5b0cb4, 0x5edca}}, - {{0x1a6f779f, 0x167858cd, 0x1a275243, 0x04a00be1, 0x071be335, 0x0b8daf81, 0x1af00727, 0x03c91d10, 0x9e5888}}}, - /* 11*16^12*G: */ - {{{0x0b597e4d, 0x047cfa0f, 0x1f468c67, 0x09e64bce, 0x11c11497, 0x02d19dbb, 0x0290486d, 0x0ac178f4, 0x5a13c0}}, - {{0x041856e0, 0x1bf2434f, 0x04d9992b, 0x1d0f56b2, 0x173ce7bd, 0x0c507916, 0x1ffd47f4, 0x027121f2, 0xc9e73c}}}, - /* 13*16^12*G: */ - {{{0x0260faf0, 0x153c4b0a, 0x1a564d76, 0x17a68b2f, 0x1272ea2b, 0x070d3407, 0x19d50c51, 0x0ac02f6d, 0x96b256}}, - {{0x0366d412, 0x07212907, 0x1f53d6b0, 0x177f30e0, 0x199e1890, 0x072b99df, 0x12b002b6, 0x1400366f, 0xdcf8a6}}}, - /* 15*16^12*G: */ - {{{0x0ad13276, 0x04d0df25, 0x1010f1e9, 0x06a1d5d3, 0x171a3ca6, 0x15959c3b, 0x18909bc4, 0x0218839b, 0xb9719}}, - {{0x0a84dadb, 0x19c79a10, 0x1c3eb8ec, 0x1af25304, 0x0811f593, 0x122d9dfb, 0x1bef538b, 0x0dde00dd, 0xac2848}}} - }, - { - /* 1*16^13*G: */ - {{{0x071e5c83, 0x1535e490, 0x10a82fbb, 0x04fe330a, 0x0e5b18bd, 0x02db952c, 0x1cfc82a1, 0x082a04da, 0x54ccc9}}, - {{0x140916a1, 0x1e8477b8, 0x03b925b3, 0x1c1798bb, 0x0bf22929, 0x038aed69, 0x14c8ea3e, 0x08b68a28, 0x1c433f}}}, - /* 3*16^13*G: */ - {{{0x0f76167c, 0x02f1b115, 0x1d19ce53, 0x1e845988, 0x0d9f22f2, 0x163496e6, 0x1e54e708, 0x1b96e7df, 0x87582e}}, - {{0x0f4d7ff6, 0x037ddb0b, 0x065efa1b, 0x051e0cee, 0x036a8880, 0x0161e1b9, 0x09eff784, 0x06a15ac9, 0x75b94}}}, - /* 5*16^13*G: */ - {{{0x14de6611, 0x1391f743, 0x0087ec11, 0x0cae7297, 0x0f11e33f, 0x1b9b1ab3, 0x1b6c7096, 0x1943e4e6, 0x4a107a}}, - {{0x18a805fe, 0x1ac75f72, 0x084cab00, 0x1aa8f4b8, 0x0052e075, 0x12747b80, 0x1ce4d339, 0x0a200c7d, 0x809b26}}}, - /* 7*16^13*G: */ - {{{0x0dcfecb0, 0x05d27683, 0x0a3611bf, 0x07fa3a61, 0x149f6e98, 0x0706a4df, 0x1f259528, 0x166e555b, 0xfd402e}}, - {{0x0da08de8, 0x02c9f9ef, 0x19979e44, 0x1698497b, 0x1a86b1a4, 0x131c4dd5, 0x088ba698, 0x061bb4c7, 0xd6b340}}}, - /* 9*16^13*G: */ - {{{0x154659ed, 0x1a6eb07a, 0x17659b96, 0x1c7a4432, 0x1d0a07fa, 0x0703ff64, 0x145577ee, 0x08c8c30e, 0x467bb3}}, - {{0x0800cf83, 0x1903e859, 0x004f8026, 0x17821b9a, 0x02cd3701, 0x06ac36dc, 0x03a287cb, 0x1a0b552f, 0xd01eff}}}, - /* 11*16^13*G: */ - {{{0x1c97e515, 0x1324c256, 0x021697fb, 0x09ad8673, 0x0c7e5691, 0x0db1874f, 0x0391b21e, 0x11f19bb8, 0xcf66b9}}, - {{0x006c8a51, 0x0c10a754, 0x0400cea5, 0x00e8b1b3, 0x06a7b33f, 0x1a081a76, 0x04847096, 0x0f72088c, 0xa7071}}}, - /* 13*16^13*G: */ - {{{0x186154e5, 0x1d295080, 0x0be8374e, 0x0054cd35, 0x06770864, 0x04a9d6a4, 0x08d1d472, 0x18c1f7f5, 0x3d9252}}, - {{0x1603a8a2, 0x1fe49fb4, 0x1f75c1dd, 0x03f6faf8, 0x14cf3aea, 0x19a144b5, 0x15ff1124, 0x1b9a5f53, 0x3d0d01}}}, - /* 15*16^13*G: */ - {{{0x0a4a8daa, 0x1db1db15, 0x029728f4, 0x00c01de5, 0x0968ce51, 0x1ada47a5, 0x1a71d83a, 0x164d112e, 0x2bbe38}}, - {{0x1236e49b, 0x1043ba74, 0x1adb9f5f, 0x056749c7, 0x00850990, 0x1f7c8fcb, 0x0dbd78b3, 0x1ec01a76, 0xf85707}}} - }, - { - /* 1*16^14*G: */ - {{{0x02d32936, 0x187dbb89, 0x011fc070, 0x19a05c65, 0x17f38e40, 0x03e8a89e, 0x11f67db3, 0x0b2f0294, 0xc5440c}}, - {{0x07cabfd4, 0x1217d1ba, 0x19079766, 0x0da50c63, 0x0f4acd8a, 0x0f0e91f6, 0x1e9cbb70, 0x174707c3, 0xd27ee9}}}, - /* 3*16^14*G: */ - {{{0x1989a8e1, 0x0c280f63, 0x1b92f75f, 0x1b2de6e9, 0x0fe0a7c1, 0x1023cdce, 0x1e6dd403, 0x188b9bf4, 0x3e4d03}}, - {{0x041c240a, 0x03c89c42, 0x0f59d026, 0x1e31abe7, 0x0a719ffa, 0x0be56be5, 0x11d6ab04, 0x1a102b4c, 0x12f744}}}, - /* 5*16^14*G: */ - {{{0x19bb7902, 0x09cd4686, 0x0df1cfda, 0x04d8e50d, 0x05e9fd8c, 0x124f4a24, 0x00d66a68, 0x09367ac2, 0x1b684}}, - {{0x003ee653, 0x0bfa258f, 0x00d9a0b3, 0x164c08e3, 0x11581fce, 0x0c72e1b6, 0x10f82fc6, 0x143d26f3, 0xe59063}}}, - /* 7*16^14*G: */ - {{{0x0371d9fe, 0x14dab6a6, 0x0675aef0, 0x166ad833, 0x13a4cf04, 0x0ad3e1d5, 0x1288cd65, 0x16359993, 0x952c3c}}, - {{0x0189a13f, 0x1b673692, 0x0231d7b5, 0x08c9e230, 0x0e5d0664, 0x089b7b76, 0x1c1a9f7e, 0x08defac5, 0x59b985}}}, - /* 9*16^14*G: */ - {{{0x0bc2c885, 0x03ffe3b4, 0x19395f21, 0x03dceea4, 0x1cde5155, 0x002285cb, 0x1ab21626, 0x1c2b62cd, 0xdfcb4e}}, - {{0x1345d92e, 0x0ea53218, 0x0afa5d5d, 0x0e7128f7, 0x00f411c7, 0x1e136416, 0x0e854f13, 0x12aaa0c2, 0x536a23}}}, - /* 11*16^14*G: */ - {{{0x1510208e, 0x1c5c295f, 0x15e50e1c, 0x199c5b09, 0x097bbdb8, 0x179d023e, 0x00322a1e, 0x18137cca, 0x157966}}, - {{0x0d207357, 0x10777128, 0x1690f7f5, 0x1f8c8865, 0x0be07008, 0x1bdbddc6, 0x193aaf7f, 0x0b56e244, 0x40446d}}}, - /* 13*16^14*G: */ - {{{0x0b96fe13, 0x04fe65f4, 0x014baa07, 0x0495a769, 0x16e23e49, 0x147fc09f, 0x042b5b86, 0x078963d3, 0xc6b21e}}, - {{0x17bb1417, 0x0035cb57, 0x19b4b5a8, 0x0aa122f3, 0x128a2ff6, 0x1c0f1a75, 0x1523952d, 0x1b186669, 0x335bcd}}}, - /* 15*16^14*G: */ - {{{0x03936565, 0x1b2c0cd6, 0x1fe931f0, 0x0f66db2e, 0x122d997a, 0x054ea9ca, 0x05bc2d2f, 0x188f18e5, 0xa231e4}}, - {{0x15ec5f19, 0x172b5031, 0x1c5509a2, 0x0adc012d, 0x1cf942ba, 0x07634401, 0x1a470365, 0x117d8ff7, 0x80e0c9}}} - }, - { - /* 1*16^15*G: */ - {{{0x1066fd48, 0x1cfa0b95, 0x05c560ef, 0x0e203971, 0x0dca61c3, 0x0dcbd35d, 0x07141b1e, 0x0f4844fe, 0x241c56}}, - {{0x12857b08, 0x1be9633c, 0x08d9815f, 0x10e2715d, 0x003a48ea, 0x00be0219, 0x152e4d8e, 0x127a8605, 0x40a62d}}}, - /* 3*16^15*G: */ - {{{0x0df9591d, 0x10fbedc8, 0x0d320aa1, 0x18758485, 0x07218dce, 0x09e25599, 0x03a72e83, 0x07704d2f, 0xde2fd2}}, - {{0x0457ad84, 0x070cb9e8, 0x100da92d, 0x15143f11, 0x12ebbda9, 0x1bf6425c, 0x0fcc17b2, 0x02676c48, 0x400d71}}}, - /* 5*16^15*G: */ - {{{0x1562282c, 0x15412a57, 0x1ef0ddcb, 0x1e75f271, 0x11340f02, 0x04581270, 0x0f7664e5, 0x16060999, 0x8df889}}, - {{0x01d195cd, 0x12b55ecb, 0x1e6ec55c, 0x1ee0899d, 0x0f35e247, 0x0f318c45, 0x1bb5b1d0, 0x0ce640b9, 0x74525b}}}, - /* 7*16^15*G: */ - {{{0x0dddb2dd, 0x0ea944a8, 0x0b0369be, 0x10c99b98, 0x0f245078, 0x1c0678a9, 0x03e0007e, 0x119b3170, 0xa0fd75}}, - {{0x13ede6b2, 0x1eca7fc3, 0x10269f1f, 0x19d2df12, 0x08f311c8, 0x0fe989d8, 0x0357e1a4, 0x06b8266d, 0x53e5d8}}}, - /* 9*16^15*G: */ - {{{0x0f542e36, 0x0465d502, 0x0d0570b8, 0x05ff5f42, 0x135d84e2, 0x0933ca31, 0x03d9f796, 0x108e5a34, 0x3170c5}}, - {{0x163288b5, 0x1623ad77, 0x066f86f1, 0x1eead2b3, 0x1773d006, 0x0849ff5c, 0x1f88dd45, 0x025f874f, 0xb20836}}}, - /* 11*16^15*G: */ - {{{0x1c7548e9, 0x0cd91d2e, 0x04b5531e, 0x1b500e11, 0x03fe5d8d, 0x00b4a783, 0x180a76d2, 0x152145a7, 0x92fab0}}, - {{0x0917758f, 0x03896682, 0x0b421223, 0x01b8d1de, 0x079ffc8a, 0x18a70613, 0x1af3d0c5, 0x0d019648, 0x55e7b4}}}, - /* 13*16^15*G: */ - {{{0x1498f7f8, 0x06c0285c, 0x104588b8, 0x1ecfa64c, 0x08712c4d, 0x108d8c96, 0x145e742f, 0x17c3006a, 0x91b065}}, - {{0x1f23195b, 0x03a06cf1, 0x0258e78f, 0x18f684af, 0x1e264df2, 0x19a4800b, 0x1883fe7f, 0x0eff6ce2, 0x35b6f}}}, - /* 15*16^15*G: */ - {{{0x0060e322, 0x0ee5f712, 0x113452d4, 0x1b8e6f53, 0x0b9923ec, 0x034ba44d, 0x0cea70e4, 0x09995939, 0x8e4a1f}}, - {{0x104619d7, 0x110c1e6c, 0x13eff813, 0x01531b2a, 0x07bc4fb0, 0x0f692037, 0x1dd4bec1, 0x0bd6651a, 0x4936b7}}} - }, - { - /* 1*16^16*G: */ - {{{0x0e14db63, 0x073ae5a4, 0x1947dfa4, 0x1277555a, 0x025de294, 0x0c971937, 0x0a961249, 0x17850235, 0xfa822}}, - {{0x1f462ee7, 0x008922a2, 0x1fa0bd79, 0x034ca0a1, 0x1188b34b, 0x0a5e59ef, 0x0035bd2b, 0x1d1ebb75, 0xbff44a}}}, - /* 3*16^16*G: */ - {{{0x1db3cdec, 0x096229fb, 0x0a3afd5d, 0x1e742564, 0x04bc8dbe, 0x122f3df5, 0x1d739659, 0x0c9ff225, 0x85b2c0}}, - {{0x0a03f81f, 0x1a684102, 0x133e3823, 0x101669cc, 0x06d00dc9, 0x1d1697e6, 0x14d98f1f, 0x11e73a22, 0xf64b27}}}, - /* 5*16^16*G: */ - {{{0x0607b030, 0x0452d724, 0x01359cca, 0x15fec7cb, 0x0f29c24d, 0x1dd6760b, 0x119de147, 0x0ed88042, 0x110b03}}, - {{0x13617c3a, 0x01d50895, 0x0a61d27d, 0x1c2aadf6, 0x1c70c87b, 0x1c4fc230, 0x19cd31ba, 0x10a631dc, 0x84432b}}}, - /* 7*16^16*G: */ - {{{0x15a76f08, 0x076ec0e3, 0x0efb5395, 0x0be4a717, 0x0aaf8329, 0x1092158e, 0x075c53db, 0x0893ec8e, 0x18784e}}, - {{0x0b824993, 0x19cb02eb, 0x02894c82, 0x1ae94f4c, 0x1e671fc9, 0x147ed638, 0x0b9c5dde, 0x0fe943c3, 0x8d76ed}}}, - /* 9*16^16*G: */ - {{{0x1a6fad81, 0x14719e4f, 0x032c0fb3, 0x06cae918, 0x0037d9c3, 0x16ebb81d, 0x1ae6bbd5, 0x1c0fa0bc, 0x58a2f9}}, - {{0x1b109594, 0x00030af1, 0x0c02e095, 0x1765a65a, 0x1a6bd798, 0x017c38bf, 0x038306da, 0x18b58aac, 0x6ab64}}}, - /* 11*16^16*G: */ - {{{0x1eb52583, 0x191788fc, 0x03304ebe, 0x15339d82, 0x1676fea8, 0x16dd93c7, 0x0e8903b9, 0x1b99cfd7, 0x1ef020}}, - {{0x1a3f17ae, 0x0d93c0cb, 0x04b532d5, 0x0601f2e0, 0x095306ac, 0x1607a5cb, 0x12c025fd, 0x164b4f42, 0x594476}}}, - /* 13*16^16*G: */ - {{{0x10a1958f, 0x0e11f60f, 0x0d5990ed, 0x136a48df, 0x1a32c4f3, 0x0a267d5f, 0x084e5774, 0x0c783ad4, 0x4e4a81}}, - {{0x08636f8a, 0x01d9fa8a, 0x110f59a9, 0x0810bf65, 0x06fa8400, 0x051f714e, 0x03440cfd, 0x0b6f3d19, 0x2574a4}}}, - /* 15*16^16*G: */ - {{{0x04935db5, 0x013ad423, 0x1af6c3ba, 0x0f304c38, 0x0519e281, 0x1f076aca, 0x04138cc9, 0x02d5bac2, 0xf6966a}}, - {{0x1d166838, 0x11a41b60, 0x006fc04e, 0x08a74688, 0x0755e2d7, 0x172b961e, 0x16cb0697, 0x00f52063, 0xba0de3}}} - }, - { - /* 1*16^17*G: */ - {{{0x176a6987, 0x07a0982d, 0x1690ffda, 0x10356887, 0x01b3f2b4, 0x14c46bf7, 0x0551f771, 0x1af53313, 0x54bc18}}, - {{0x1b9aae49, 0x122be682, 0x1cec467f, 0x171da976, 0x1e2fd52e, 0x1c28dd39, 0x0bcdce46, 0x02423cdd, 0x4b2c8c}}}, - /* 3*16^17*G: */ - {{{0x1d1fd820, 0x05fa3faf, 0x1d9d400e, 0x0f0a8c90, 0x1271b788, 0x08113158, 0x14aaa18d, 0x1ed01838, 0xbafbbc}}, - {{0x1bf074f0, 0x176d6a90, 0x07f2b5ba, 0x18694246, 0x1c0fde81, 0x1fad644d, 0x1604b39e, 0x0f93b69b, 0x148799}}}, - /* 5*16^17*G: */ - {{{0x14299b7e, 0x08b84094, 0x01b8343a, 0x0f3e5a13, 0x020ec24e, 0x1dfe3ae1, 0x07f8a8f0, 0x1ee20671, 0x9b1938}}, - {{0x047b84de, 0x0bd942ba, 0x1ae08cb1, 0x1bd0a3f0, 0x03ec90ac, 0x14c70e55, 0x0a0cc503, 0x0dde2e20, 0xfb12aa}}}, - /* 7*16^17*G: */ - {{{0x110cc4c4, 0x0a083a06, 0x094f683f, 0x1a6b4589, 0x01b2cb71, 0x0fee033b, 0x1641f0e0, 0x10b9802e, 0xa67719}}, - {{0x1c976570, 0x1079d91b, 0x1fcc2530, 0x08aee74d, 0x19c3dbc7, 0x0b300f2e, 0x1663ca6f, 0x10beea1b, 0x855061}}}, - /* 9*16^17*G: */ - {{{0x14242a28, 0x0084016a, 0x0f29dc55, 0x1796424a, 0x14eca455, 0x17bc25bb, 0x1f0427a2, 0x0a6d61d5, 0x88b7ed}}, - {{0x194ed8ce, 0x1cb40f63, 0x00f8d1fe, 0x0cd4391f, 0x1bd934e3, 0x1cee9ac3, 0x11791fef, 0x040c48a6, 0x22b053}}}, - /* 11*16^17*G: */ - {{{0x1bc1a94c, 0x0b0a2764, 0x1c76be00, 0x0e3a567c, 0x08757516, 0x1958112f, 0x0f4814b5, 0x002550d6, 0x37114}}, - {{0x0fc2073c, 0x00605b67, 0x110920e3, 0x03186c55, 0x05335c85, 0x10d2a568, 0x0e43be30, 0x07aa3bae, 0x4d1d69}}}, - /* 13*16^17*G: */ - {{{0x077f88ba, 0x1de8f04c, 0x06fb4dbb, 0x100ef3dd, 0x02cc3509, 0x11974275, 0x04f8d2d6, 0x09913085, 0xcc9821}}, - {{0x07885278, 0x123177e4, 0x0d531382, 0x0c1cfdde, 0x163abeff, 0x053233be, 0x1ea44531, 0x1d1ca4b5, 0x4ebb4}}}, - /* 15*16^17*G: */ - {{{0x1d70187c, 0x0b98ca6f, 0x19031fc5, 0x1590c536, 0x15bf8751, 0x12f01487, 0x043e6053, 0x00534854, 0xad3ae}}, - {{0x1fc775a7, 0x0ffe7a59, 0x18a83d9f, 0x09f6102c, 0x1b33dd03, 0x0af82fd5, 0x1b8de171, 0x1a8eb108, 0x2af040}}} - }, - { - /* 1*16^18*G: */ - {{{0x10aae231, 0x0557d68b, 0x1e5adf18, 0x0970a4f3, 0x1756f519, 0x0411c933, 0x0fca17c9, 0x0d32ec3c, 0x1d35c9}}, - {{0x0cd6ac71, 0x033831d6, 0x0699bc56, 0x0b1548e5, 0x1f810edf, 0x055b1175, 0x008c7598, 0x16c5bec1, 0xc7226c}}}, - /* 3*16^18*G: */ - {{{0x0cfa3fac, 0x1069ff0c, 0x0ae064f3, 0x1b0d3f86, 0x1803023a, 0x1da2eb06, 0x0d338b3a, 0x08f4da44, 0xdf3d40}}, - {{0x0fc7d419, 0x03136c9c, 0x020a5d7d, 0x0c79c92d, 0x19dbfafd, 0x10f94e07, 0x036c92a8, 0x0a453fa8, 0x48fa6f}}}, - /* 5*16^18*G: */ - {{{0x1f1322d4, 0x16c92d70, 0x13372eeb, 0x14d28095, 0x1f822cb0, 0x16265188, 0x0513a879, 0x0d563f2c, 0xdbb2af}}, - {{0x0a8c5311, 0x12495a7a, 0x1f8e97ea, 0x1f92f0f6, 0x13f9d9a9, 0x068f6b21, 0x186a86d8, 0x1725e26a, 0xebae75}}}, - /* 7*16^18*G: */ - {{{0x01138f7b, 0x034d19e5, 0x1cba3cbc, 0x03927c5b, 0x15f0bc4c, 0x05133fcd, 0x1f532bea, 0x0b2fe4c3, 0x1dba7b}}, - {{0x039bf268, 0x0416c63d, 0x008cb037, 0x0dcd6f33, 0x007f5813, 0x08035dc0, 0x1f18eb86, 0x07cbbcfd, 0x6aaf7d}}}, - /* 9*16^18*G: */ - {{{0x179a70af, 0x0d43bb80, 0x1937ca23, 0x1a853536, 0x105c6ec9, 0x1416afa9, 0x0674c6ef, 0x0884c4d2, 0x348a2e}}, - {{0x07b66e82, 0x142430a4, 0x184f96b2, 0x0f858b6f, 0x10105b2a, 0x1de70011, 0x1a0231d1, 0x0f3eab47, 0xa1b9fa}}}, - /* 11*16^18*G: */ - {{{0x04d3a201, 0x1a3b6bb6, 0x06e7bbf1, 0x124d49fb, 0x0df5f36e, 0x07dfc98d, 0x1872a1a9, 0x0a333393, 0x3a4ec8}}, - {{0x08635f89, 0x0c2cb7bb, 0x0f3556f7, 0x063cb5ee, 0x14a8b27d, 0x1e08d23b, 0x0b79a780, 0x1f05ec4c, 0xc99a2e}}}, - /* 13*16^18*G: */ - {{{0x1c978567, 0x17d7397e, 0x1707e607, 0x1b4d1081, 0x1f60be15, 0x1aeb17f8, 0x115e13a4, 0x1b10669a, 0xb1ba52}}, - {{0x162dc291, 0x1fd24151, 0x1f35029d, 0x08d96175, 0x1b78fd9a, 0x1e7b89ed, 0x0e9df17d, 0x18f50d28, 0xa46bae}}}, - /* 15*16^18*G: */ - {{{0x12350da1, 0x11477528, 0x1d7c10f4, 0x0298ef82, 0x12c2f194, 0x1bdcb4b0, 0x0bf49c62, 0x07b1de55, 0xae6eb}}, - {{0x10a14bc3, 0x19f04f9b, 0x10f692f1, 0x08d1e1da, 0x189b566d, 0x1a7bfe20, 0x12b8b740, 0x13f6c00d, 0x99cdee}}} - }, - { - /* 1*16^19*G: */ - {{{0x150e4f5f, 0x0b957543, 0x19f83995, 0x0b95354a, 0x0f29acbf, 0x187bd501, 0x0bbce23f, 0x0b30896b, 0x55d9a9}}, - {{0x1ca97db0, 0x02c75bb5, 0x0b46c572, 0x10218c67, 0x0ec524c9, 0x0ba7de64, 0x080dd9b5, 0x1354bb5a, 0x69cb7f}}}, - /* 3*16^19*G: */ - {{{0x1eb142e9, 0x0354c43f, 0x01ff3ef0, 0x0dd60c8c, 0x0d480c17, 0x0341c7d7, 0x1845e536, 0x1d7c8de7, 0x4b0043}}, - {{0x02c68552, 0x0596296b, 0x04962201, 0x06521e74, 0x02d870f2, 0x04231b11, 0x106b6c5e, 0x047461b5, 0x173ccf}}}, - /* 5*16^19*G: */ - {{{0x17f1aa96, 0x16ea5738, 0x1fd9207d, 0x0f4bee69, 0x063c513d, 0x06e5db9a, 0x1f08c9ca, 0x0f3255ad, 0x79ead2}}, - {{0x0b0a3fb7, 0x05d38e72, 0x0ce556a0, 0x09ae2223, 0x16542de8, 0x01c9ab12, 0x0afc69b9, 0x19ff755b, 0xa95de9}}}, - /* 7*16^19*G: */ - {{{0x193a9ae6, 0x002e5397, 0x1dfe2b72, 0x01540b38, 0x1743f8ee, 0x0f1b18d6, 0x073ad49e, 0x0a1e49b4, 0x318e00}}, - {{0x1c447d79, 0x025ab4a6, 0x14ea3b86, 0x06dfb75d, 0x04bd0945, 0x1e528f28, 0x0a67d345, 0x022339d2, 0x2792ee}}}, - /* 9*16^19*G: */ - {{{0x1d30585a, 0x1bca2da6, 0x14052544, 0x1f143546, 0x0a4b495f, 0x197a4860, 0x10eee200, 0x0e3a5e3c, 0x6bbc54}}, - {{0x148b05f3, 0x17cbf779, 0x1e7ab65a, 0x00850205, 0x026be09f, 0x1158af91, 0x07c12a7b, 0x136182a5, 0x467b18}}}, - /* 11*16^19*G: */ - {{{0x00136275, 0x1127c046, 0x01dd4d49, 0x0f8002e7, 0x00d78a64, 0x0d487bbb, 0x144626d4, 0x18c2183f, 0x940148}}, - {{0x1997aa47, 0x0b1d088a, 0x13869097, 0x1675cac0, 0x1d6695d4, 0x06255a82, 0x13ddea89, 0x0be26cf4, 0x6967f9}}}, - /* 13*16^19*G: */ - {{{0x1f0fe850, 0x1d09ee9c, 0x0469ef70, 0x1a4617ca, 0x1f98e864, 0x164946d2, 0x127246d5, 0x124c0736, 0xc41833}}, - {{0x1d38666d, 0x1ac7a235, 0x0682bc04, 0x14fd93c0, 0x1d558065, 0x0aea1357, 0x1debae02, 0x19391a81, 0x3537fe}}}, - /* 15*16^19*G: */ - {{{0x14937fbe, 0x1f2209bb, 0x146e9bb3, 0x009bbbe0, 0x0f546c0b, 0x0000d7cb, 0x15c38305, 0x1ec4f8cf, 0x2baba3}}, - {{0x173a1df4, 0x1c872aba, 0x0b204424, 0x1b896321, 0x0abc9ec2, 0x1866c927, 0x0e235e0e, 0x0cb64411, 0x77e5c7}}} - }, - { - /* 1*16^20*G: */ - {{{0x0351964c, 0x069e96f2, 0x1504b075, 0x12486ede, 0x15c08346, 0x1e50c2ba, 0x11feb96a, 0x0b37c518, 0x6e29f9}}, - {{0x163fd88f, 0x0c4125ea, 0x02fed8c4, 0x0818a4f4, 0x0246def6, 0x163660c2, 0x0bd9414b, 0x13ea01e6, 0x34565d}}}, - /* 3*16^20*G: */ - {{{0x0c0e49cc, 0x1ca8081c, 0x1150034f, 0x065b50b7, 0x140ed412, 0x046f65db, 0x1dbb760a, 0x152f12e1, 0xd691d4}}, - {{0x100f4152, 0x085da60e, 0x1410fcb7, 0x17c3a055, 0x00c52ac5, 0x1edabb1f, 0x0e5fdfee, 0x10e96f1e, 0x7a79e7}}}, - /* 5*16^20*G: */ - {{{0x0b9b930a, 0x0c3b5cf9, 0x0c3d63cf, 0x026a548a, 0x1bc49deb, 0x1befbd3d, 0x1f177b96, 0x08d45c1a, 0x2a5d68}}, - {{0x1b2caeca, 0x17f9a2f9, 0x09c5a161, 0x16e686bc, 0x0ab58ea5, 0x181c81e2, 0x1db79733, 0x012d0ec8, 0xdc3d7c}}}, - /* 7*16^20*G: */ - {{{0x016959ef, 0x13ee5e94, 0x076d66be, 0x13a0ace8, 0x15df8767, 0x18a09713, 0x1498bc10, 0x0d471376, 0x876449}}, - {{0x00cd5010, 0x10188e5f, 0x1e78fc59, 0x0d5a82e5, 0x1961f285, 0x0093cb76, 0x1ff6782d, 0x1ac3a005, 0x599b69}}}, - /* 9*16^20*G: */ - {{{0x1aef0f84, 0x1ca04e71, 0x071d6e58, 0x16a0d50e, 0x1b8cab0b, 0x1fd60bd6, 0x06c4cf78, 0x1790248e, 0x94d393}}, - {{0x178ba7c1, 0x0d730dc9, 0x0b3c4aa1, 0x1e804ca1, 0x19a07dd3, 0x1e1c3591, 0x0fc87872, 0x169d696c, 0x5a826a}}}, - /* 11*16^20*G: */ - {{{0x0ffed1b7, 0x0a2abc27, 0x12a8ed3b, 0x17a24cac, 0x0bd2ee2d, 0x04b8169a, 0x18b745d4, 0x141113c9, 0x4a72b5}}, - {{0x1601dc5f, 0x0f94fec4, 0x1366116d, 0x0c971d8e, 0x0ea9685e, 0x1fe023e4, 0x038b230c, 0x1d4943a4, 0x3531e6}}}, - /* 13*16^20*G: */ - {{{0x10467317, 0x1021f92e, 0x16461a80, 0x03b883b1, 0x07900914, 0x13797d6f, 0x18569e19, 0x1f8b46e3, 0xd7f01c}}, - {{0x0f7d014e, 0x05cabeae, 0x1fef6257, 0x002e86d2, 0x1ef5728a, 0x10a0360a, 0x109bb1cd, 0x1b30ee4d, 0x888dbb}}}, - /* 15*16^20*G: */ - {{{0x1dea02c1, 0x1ebac853, 0x1d021f0e, 0x17736f8e, 0x11206e4f, 0x1fcec8f1, 0x1c6efa02, 0x173eef86, 0x7e50a0}}, - {{0x0d45c201, 0x1e4a36ff, 0x0386ca0c, 0x07269e2b, 0x19517742, 0x178eedc5, 0x0a7185b1, 0x0789c1fc, 0xc3405d}}} - }, - { - /* 1*16^21*G: */ - {{{0x0cb71280, 0x053ea088, 0x1158c44a, 0x0384b350, 0x1458ec14, 0x17783cb7, 0x1b67003c, 0x13d657fd, 0xff046a}}, - {{0x1ec33919, 0x161938fa, 0x0a121e9f, 0x16dcdd7a, 0x0fcc9012, 0x16edeea6, 0x085c2807, 0x159812a7, 0x432f55}}}, - /* 3*16^21*G: */ - {{{0x13ca3ce3, 0x193c1551, 0x1a9df897, 0x1630cb56, 0x0231fef2, 0x1e0fa989, 0x134c6a56, 0x0ba29a7b, 0xf717c4}}, - {{0x10ed88e9, 0x04a666da, 0x05db7c1a, 0x07c57bb8, 0x1ee55af5, 0x0a768556, 0x04b72a6d, 0x0ed1932a, 0x422c40}}}, - /* 5*16^21*G: */ - {{{0x1b28cd88, 0x1b42186a, 0x0a6f66b0, 0x1c12ea05, 0x1b32c738, 0x1ab13fc8, 0x0c830bfa, 0x169e66e1, 0x60e269}}, - {{0x0be2066c, 0x14dd4521, 0x1211ac38, 0x0ac2718d, 0x0df76024, 0x08c44b94, 0x02a58248, 0x0b4caf3e, 0xfe0017}}}, - /* 7*16^21*G: */ - {{{0x061cc594, 0x09d8c994, 0x1414dac5, 0x17ba2e09, 0x06855964, 0x1d02fe5a, 0x05242a96, 0x143cce73, 0x799297}}, - {{0x0f8d309e, 0x14888490, 0x0b1ba427, 0x150d5c17, 0x1e50127d, 0x088c3c4f, 0x06c3841a, 0x119aa479, 0x132ff1}}}, - /* 9*16^21*G: */ - {{{0x172d0aba, 0x04623d12, 0x1f86c5b7, 0x03215b8e, 0x1241dd8d, 0x0775aa80, 0x01c1e7b8, 0x09dfc850, 0x2d9be9}}, - {{0x11fa0876, 0x07b98fd9, 0x0dc439be, 0x038cf311, 0x1d91bbad, 0x1c9a5b0c, 0x0288a57b, 0x16bd3d13, 0xa9708d}}}, - /* 11*16^21*G: */ - {{{0x155e8732, 0x0603da41, 0x1b478c78, 0x0c5dbca0, 0x0c243cfa, 0x03298a49, 0x0859832f, 0x13d91048, 0x212703}}, - {{0x00cacc07, 0x0c91afa3, 0x15ef5a35, 0x07e7e775, 0x10a5cd69, 0x1cedddbf, 0x16a80652, 0x0de475c6, 0x85219c}}}, - /* 13*16^21*G: */ - {{{0x12083347, 0x0489a067, 0x0694c898, 0x15c7ccee, 0x0b42b9e1, 0x07ad5d01, 0x03ae5eb4, 0x09657b1c, 0xfab5b5}}, - {{0x1d38fd2f, 0x0664e6c1, 0x09a6bea7, 0x1c6f4c2d, 0x03eafc05, 0x15791305, 0x0540f21e, 0x02c30da8, 0x5758d1}}}, - /* 15*16^21*G: */ - {{{0x1f572554, 0x1b3930a7, 0x1d36adcf, 0x085c8e31, 0x0a56ff38, 0x0b3b85bf, 0x1f295e42, 0x0ae4f2e3, 0x685d27}}, - {{0x00979e03, 0x18d7b685, 0x1d33292d, 0x15545581, 0x0377cc58, 0x0e4020f0, 0x17f01b8e, 0x18441568, 0xa82f89}}} - }, - { - /* 1*16^22*G: */ - {{{0x05852e50, 0x1e859266, 0x15c33171, 0x18fcc79e, 0x07eff8b2, 0x1511a4f7, 0x016307e6, 0x1bffd576, 0xe486c7}}, - {{0x0ecf107d, 0x15d1e56d, 0x04baf619, 0x08c7ac67, 0x1e05a694, 0x052e4fa8, 0x04ba7ba2, 0x1daac0d4, 0x51fd75}}}, - /* 3*16^22*G: */ - {{{0x1c881907, 0x1355322a, 0x002c76b1, 0x190ce6b6, 0x00415142, 0x02e63357, 0x0df25904, 0x1771c5ff, 0x4acf44}}, - {{0x163cdafc, 0x0935a2b7, 0x1612c94a, 0x0a565ef9, 0x05457993, 0x142d6885, 0x01ecd510, 0x1fc1ffab, 0xad99a8}}}, - /* 5*16^22*G: */ - {{{0x1439383f, 0x15d7034b, 0x0068aaa0, 0x1f4ac56c, 0x14eec34f, 0x11496411, 0x192775ea, 0x10683114, 0x4ddf22}}, - {{0x03d52337, 0x197d40c1, 0x07e09a58, 0x0ba08a26, 0x00c6b3dd, 0x174be9c6, 0x00f5d2ae, 0x0f61b231, 0xe71c62}}}, - /* 7*16^22*G: */ - {{{0x1822b4f4, 0x16e440aa, 0x1977e3c9, 0x0a75f9f0, 0x1f39ba53, 0x14f03cbd, 0x1e784cd3, 0x0f226f30, 0x58b065}}, - {{0x0c60fbca, 0x103d4108, 0x13949659, 0x0940edf8, 0x0836c1ca, 0x12af8131, 0x10dc09f2, 0x14828b45, 0x55a98a}}}, - /* 9*16^22*G: */ - {{{0x14fe39b0, 0x195e8861, 0x0d37b452, 0x02e79ae9, 0x01f358a3, 0x020e119c, 0x14a5d8e9, 0x0b14c966, 0xa345e0}}, - {{0x0baf79dc, 0x184a405d, 0x0da77d4d, 0x18d4eb56, 0x1d949ce8, 0x02ad947c, 0x1c3e47c2, 0x14dab954, 0x7c6dd5}}}, - /* 11*16^22*G: */ - {{{0x126695fb, 0x1df03dcc, 0x0eb7b84f, 0x01773fc8, 0x0ccb6afd, 0x05c3a36b, 0x0b20806b, 0x10603214, 0x3a10bf}}, - {{0x04eb7e47, 0x0ae39595, 0x1514a21d, 0x1fd4d887, 0x065c5f28, 0x1c243445, 0x1c55d880, 0x167d8344, 0xb5d585}}}, - /* 13*16^22*G: */ - {{{0x1d2c8614, 0x00d474b3, 0x16116589, 0x012c14c0, 0x12876a7b, 0x1ad61848, 0x10cf2973, 0x1f592020, 0x12fbdd}}, - {{0x18b0b174, 0x03bde0ea, 0x067d257c, 0x04b04738, 0x0cfb54d4, 0x08a14669, 0x01a0cff6, 0x1a5204f0, 0xa5ff20}}}, - /* 15*16^22*G: */ - {{{0x0d9aeeaf, 0x1fbb2181, 0x16bf2194, 0x00f29940, 0x19a3005d, 0x11d0fd7c, 0x01ddee2b, 0x0b34572f, 0x8bece8}}, - {{0x05f9eb5e, 0x0d06d1e4, 0x02603dd5, 0x04071edf, 0x1c368bb2, 0x0885877f, 0x07f3eee2, 0x1898a0ca, 0x35f933}}} - }, - { - /* 1*16^23*G: */ - {{{0x0b519178, 0x05b5c761, 0x0f47f161, 0x17333148, 0x0ee0ab63, 0x067c5af1, 0x10c33f82, 0x0976bca0, 0xf41d7f}}, - {{0x0a6a3551, 0x1d0b32ee, 0x06787e69, 0x135986d2, 0x02347ab4, 0x16f1fd54, 0x035bc411, 0x17d7b35f, 0xe6a669}}}, - /* 3*16^23*G: */ - {{{0x1e3501d9, 0x138989f0, 0x187f22c6, 0x1059c376, 0x13e611be, 0x0b48eb16, 0x19fccccb, 0x0fdac5a9, 0xd65f82}}, - {{0x0b55759e, 0x1ca23637, 0x1cc2f86a, 0x02755aba, 0x187fc61c, 0x1e528b35, 0x03f94ded, 0x1f9e1352, 0xf24b60}}}, - /* 5*16^23*G: */ - {{{0x0f2ed84e, 0x1b17f120, 0x18ba84b2, 0x129be6bf, 0x0c0ade79, 0x045abc16, 0x10e17b9b, 0x16dbd60b, 0x55a9b5}}, - {{0x146495a3, 0x1cee2a82, 0x08363c15, 0x1f69ae25, 0x1f43ae8f, 0x068c876b, 0x06aca45d, 0x12d593e3, 0xc4f221}}}, - /* 7*16^23*G: */ - {{{0x075495a2, 0x1e967c38, 0x0f002ca6, 0x1c3d6c91, 0x08bc49fd, 0x0b05312a, 0x07687dfb, 0x0db8fb6e, 0x79de57}}, - {{0x0aec6fb8, 0x01646355, 0x04e9d1a0, 0x09ea12c9, 0x079c6831, 0x16d723ee, 0x0809e179, 0x01cd630d, 0x3b2d3d}}}, - /* 9*16^23*G: */ - {{{0x02d1e7bb, 0x17495664, 0x0465933b, 0x07ff206a, 0x1e55524c, 0x19b4acab, 0x12db8992, 0x0642c480, 0x8fe04e}}, - {{0x1a62e84f, 0x13acd686, 0x011aa336, 0x02c8c8de, 0x1b34e5b9, 0x0752bd46, 0x163f975b, 0x0a045ec6, 0x3987db}}}, - /* 11*16^23*G: */ - {{{0x09f7c360, 0x00d25763, 0x00217084, 0x19aaefc9, 0x024e24ef, 0x0531b469, 0x03c542a5, 0x012afdbf, 0x3af499}}, - {{0x087d7a7b, 0x1cee1553, 0x18225734, 0x0a9bac4e, 0x13c33485, 0x03241739, 0x04754c7e, 0x061a763b, 0xd17060}}}, - /* 13*16^23*G: */ - {{{0x170373be, 0x0d291d73, 0x18f4ed4e, 0x1a0c4424, 0x07c4e213, 0x0179ff11, 0x01db0696, 0x0b8c4790, 0x31a7e0}}, - {{0x090950a8, 0x16bc3c87, 0x08950c23, 0x105732a3, 0x1db1e8ce, 0x05571a11, 0x199c086c, 0x1e7f1a3b, 0xc23d2e}}}, - /* 15*16^23*G: */ - {{{0x0b923b45, 0x0130876e, 0x0f892f6d, 0x153f7fe2, 0x18458a33, 0x09a316ec, 0x08fb4554, 0x09026ada, 0x740a66}}, - {{0x11ecaa5f, 0x0609f1c2, 0x121202ea, 0x0f32720f, 0x006cfa89, 0x03c453ab, 0x08fcbd39, 0x1184b9aa, 0x7f6d04}}} - }, - { - /* 1*16^24*G: */ - {{{0x1512218e, 0x025549cb, 0x1280506a, 0x0a4360e9, 0x0e902e9a, 0x059d0c51, 0x1e995e20, 0x0cc254ce, 0x4a5b50}}, - {{0x0c4f3840, 0x1f56d3d2, 0x189b6742, 0x1b62a833, 0x07d40626, 0x027df0b1, 0x07c71098, 0x039d5811, 0xeb1346}}}, - /* 3*16^24*G: */ - {{{0x118473fd, 0x177a0712, 0x05cce454, 0x1204d78d, 0x0a9e3bbb, 0x155ccb94, 0x0e8214a4, 0x06466631, 0x106406}}, - {{0x185cf805, 0x1d30b173, 0x08740e6b, 0x1c321a18, 0x1883ccfb, 0x014f32c2, 0x0b63239e, 0x10477174, 0x9c6832}}}, - /* 5*16^24*G: */ - {{{0x053f30f3, 0x0b3f7643, 0x088e374d, 0x047da5db, 0x03f212b4, 0x0086aa04, 0x1efd7b69, 0x11fe0be4, 0x38c8ad}}, - {{0x0be9217b, 0x03073a4f, 0x1677cde8, 0x07f53052, 0x1641f658, 0x0b2a6ede, 0x045bce42, 0x0f0edb96, 0x83c261}}}, - /* 7*16^24*G: */ - {{{0x16ef1584, 0x01f3488d, 0x04832fd5, 0x1345471f, 0x1184277a, 0x1df1fe9a, 0x0c256163, 0x179d0c17, 0x6fcb8c}}, - {{0x1d3110f2, 0x1e4fbe10, 0x0290c970, 0x05edad25, 0x0459d599, 0x0411d618, 0x15db5530, 0x07b16e43, 0xa8f1a8}}}, - /* 9*16^24*G: */ - {{{0x062255ef, 0x07a89a02, 0x1901e33a, 0x0e3a68ce, 0x1b0ee50d, 0x0e486f22, 0x0af5cd45, 0x1727eedc, 0x7811d0}}, - {{0x1be3252e, 0x0c5f7cd8, 0x150dda29, 0x1da0a275, 0x05132f51, 0x174a00dc, 0x11e95300, 0x06e176b5, 0x99bb76}}}, - /* 11*16^24*G: */ - {{{0x153d2ea7, 0x1f088789, 0x1ea19424, 0x1a104747, 0x16f2a9ee, 0x194eafc0, 0x033831ed, 0x1289516a, 0xc3583d}}, - {{0x0b667bbd, 0x18c1f4f0, 0x17c710ca, 0x124b4ca2, 0x1cccdd6c, 0x113f7c4f, 0x043d6591, 0x1812723d, 0x53967a}}}, - /* 13*16^24*G: */ - {{{0x102e3099, 0x16ef8702, 0x01005963, 0x04274cc5, 0x0d00d53f, 0x180c5dbd, 0x1407ce83, 0x05079bdc, 0xd591cf}}, - {{0x055ac5af, 0x1de13b2a, 0x045bf58c, 0x05dff116, 0x1c5825cf, 0x19869a85, 0x1b913944, 0x19f88f1c, 0x87ebe5}}}, - /* 15*16^24*G: */ - {{{0x12a940a5, 0x1932b231, 0x0539ac4a, 0x06bd6b48, 0x1e8714a4, 0x00f0d27c, 0x17130049, 0x0c25e646, 0xa0aa0d}}, - {{0x0b950422, 0x1fc41534, 0x146fe4e4, 0x1239bb4f, 0x01f3e6c6, 0x067cd00c, 0x10a066cd, 0x174edeec, 0x22340e}}} - }, - { - /* 1*16^25*G: */ - {{{0x008e2df0, 0x1146c1b8, 0x0a397dd9, 0x0764ae86, 0x00f5032c, 0x14efc5df, 0x065404b0, 0x017bc557, 0x2eb391}}, - {{0x1274eaae, 0x08866276, 0x1d97d242, 0x01a241d9, 0x0999f954, 0x1e9a46d2, 0x0ce9df4d, 0x0466e8e9, 0x3f29c0}}}, - /* 3*16^25*G: */ - {{{0x082867f0, 0x1815c25b, 0x06428e6f, 0x084dc436, 0x100f0a21, 0x08b53c04, 0x1388aaaf, 0x111cc98f, 0xf6e9db}}, - {{0x0f1861ea, 0x1ad9d788, 0x1c2d88d1, 0x08374bf2, 0x0d5b1270, 0x1dbb7460, 0x0dd20764, 0x016f5a55, 0x53ca79}}}, - /* 5*16^25*G: */ - {{{0x120d6102, 0x16e821c7, 0x114e5026, 0x1aa6f146, 0x19a5ef06, 0x0adcdb0c, 0x1275e170, 0x070ec1c8, 0xfd1ddb}}, - {{0x0e003b7c, 0x1053248d, 0x144e60f6, 0x1c322422, 0x1b700163, 0x0f8fbc41, 0x0e2bb6a8, 0x0e720a0c, 0xcb54b8}}}, - /* 7*16^25*G: */ - {{{0x02c77cb7, 0x1fb9a0ee, 0x17056dbc, 0x1b281205, 0x0698fef6, 0x139f32f7, 0x00767f92, 0x1844b332, 0x61a273}}, - {{0x1ddb25ed, 0x0a308fc0, 0x0b87dd21, 0x0b5b34e1, 0x10cc9c5c, 0x10cfaf75, 0x0f4fd3a8, 0x0669a75a, 0x5bbacd}}}, - /* 9*16^25*G: */ - {{{0x177d8976, 0x0cc6ab71, 0x03ca4b6e, 0x0e7471c6, 0x104b55e1, 0x164c114e, 0x06d932c0, 0x0cbdeec0, 0xcd2e8e}}, - {{0x0867bc22, 0x0b4b7a0e, 0x10a30144, 0x1dbc1e6a, 0x0ff68f60, 0x074796a3, 0x0c7ff0c7, 0x06c46854, 0xf58ead}}}, - /* 11*16^25*G: */ - {{{0x0c67c998, 0x04d98361, 0x13c6e198, 0x160fd547, 0x04c259a9, 0x0f545218, 0x1bed0089, 0x13870447, 0x9bd61f}}, - {{0x08199514, 0x1a057ce1, 0x1092c630, 0x1b383d20, 0x050fa927, 0x104b4b4a, 0x1d71723c, 0x01322d8d, 0x77b204}}}, - /* 13*16^25*G: */ - {{{0x0aafa568, 0x122f0bdf, 0x07889d9a, 0x1af52ee0, 0x1a016b4c, 0x13d2088b, 0x1dd44ab8, 0x09ef2e0e, 0x7afaeb}}, - {{0x01c1f2df, 0x16a9d17c, 0x14e408cf, 0x1cd28653, 0x1365a972, 0x0a09a820, 0x09f62574, 0x03267f7a, 0xc6efe6}}}, - /* 15*16^25*G: */ - {{{0x0e59ddeb, 0x1f381f28, 0x07a62a2d, 0x1cc5395a, 0x10c3b483, 0x0a60a4b5, 0x0be41876, 0x044fc482, 0xd9a002}}, - {{0x0f0af5a4, 0x19c9ffc0, 0x17c63397, 0x05517956, 0x10581856, 0x07c521b3, 0x08b10f18, 0x1f276f40, 0x975eb2}}} - }, - { - /* 1*16^26*G: */ - {{{0x1ecca7e0, 0x19cd2f51, 0x10cccfb1, 0x05931ece, 0x19428a7d, 0x119a9126, 0x08303fbd, 0x078b8f25, 0x7ef2ee}}, - {{0x152ac094, 0x015916ea, 0x0f4f480c, 0x0428a1bf, 0x009db81b, 0x1fa8eaf3, 0x004693d9, 0x04e61598, 0xafb686}}}, - /* 3*16^26*G: */ - {{{0x033f0ffa, 0x179ac1ed, 0x001e905c, 0x09958c23, 0x1c641cae, 0x12bb64ec, 0x0b35d892, 0x04e2d10f, 0x370457}}, - {{0x00fa35ac, 0x1f69fe33, 0x02fcbf17, 0x147d6f55, 0x1ff4c57b, 0x1a5dc44a, 0x1d3e106e, 0x18c34e3c, 0x5c6408}}}, - /* 5*16^26*G: */ - {{{0x12603513, 0x037cc329, 0x1280254f, 0x0c9b8d02, 0x1b697f6c, 0x15216045, 0x0dc8b47a, 0x1ca8531b, 0xc2a979}}, - {{0x1c3505b9, 0x0baad961, 0x05451265, 0x0ccdbe90, 0x1ce7e8cc, 0x0040c9ad, 0x1721509e, 0x0943cdd6, 0xef9dd7}}}, - /* 7*16^26*G: */ - {{{0x19fdee3e, 0x1237fd8e, 0x0c0b8079, 0x1f2ee2d8, 0x1afb9681, 0x18ae6d8b, 0x07845cae, 0x0d563f8b, 0xc9f418}}, - {{0x0ced22e7, 0x0f33662e, 0x1637d3d4, 0x02a638f6, 0x1214344e, 0x18a15c41, 0x0d0437dc, 0x0fe79674, 0x9420a}}}, - /* 9*16^26*G: */ - {{{0x0814f217, 0x0659f33a, 0x15b3febc, 0x147ef70e, 0x1b6a4a9d, 0x00127c1d, 0x095ac228, 0x0b700900, 0x27dcf5}}, - {{0x0cf2ed4c, 0x064a5ac4, 0x07f0efc5, 0x1d1f5632, 0x02a380a4, 0x1d584a50, 0x17b82f22, 0x09ea91ab, 0xbe18f5}}}, - /* 11*16^26*G: */ - {{{0x1b9e310c, 0x0d1527ea, 0x133f529d, 0x19cb7370, 0x19187313, 0x125619ca, 0x092e7234, 0x00764add, 0x3b8b02}}, - {{0x0d19fc9b, 0x0a0b302d, 0x0cc160e6, 0x1f009705, 0x117a6a8f, 0x171bbe20, 0x056f585d, 0x09d6066c, 0x91117c}}}, - /* 13*16^26*G: */ - {{{0x07615b36, 0x18f0f15d, 0x1cf057e3, 0x1fe3d18f, 0x0c3372a4, 0x12037c8a, 0x00e84170, 0x118b7982, 0xa5e739}}, - {{0x09136d80, 0x0cc171ca, 0x0d84f013, 0x1f8326e1, 0x1f8c547f, 0x06f7950a, 0x1339190e, 0x11b92e9c, 0x1f3ff5}}}, - /* 15*16^26*G: */ - {{{0x0d3e10db, 0x1bd82197, 0x0e1c566e, 0x065c3591, 0x161fa477, 0x021ffa75, 0x0caf7b81, 0x06ab592a, 0xaad218}}, - {{0x0fa05fb3, 0x1a9ad5eb, 0x072e89d8, 0x064ee566, 0x18b4a720, 0x0f147eaf, 0x18ece9f7, 0x1dd75f05, 0x793b1e}}} - }, - { - /* 1*16^27*G: */ - {{{0x0c49e853, 0x180f8487, 0x1d781299, 0x16a6a532, 0x1a77aa9c, 0x12aa75af, 0x0bad5e00, 0x0c842c81, 0xe5141}}, - {{0x16405cb2, 0x1b71e89b, 0x127b8d8c, 0x10728321, 0x1030df56, 0x1a529d48, 0x11a49e3a, 0x1d4cb20a, 0xcf331c}}}, - /* 3*16^27*G: */ - {{{0x1dc6afad, 0x0511f8e0, 0x1e03d1b1, 0x07b2452b, 0x0c6771bd, 0x092fb260, 0x1c977a3b, 0x0cecb959, 0x977ba0}}, - {{0x1d7faa09, 0x0b166e28, 0x16868553, 0x0b42483b, 0x1d9992f7, 0x1d506840, 0x1e8a20cf, 0x0875db71, 0x1bc3bc}}}, - /* 5*16^27*G: */ - {{{0x1d81983b, 0x0fba2ebe, 0x03aade19, 0x041fa05f, 0x1facc102, 0x1b03b8ff, 0x0af930f2, 0x0c254247, 0x3bc328}}, - {{0x11a637b6, 0x0ccf9428, 0x0ee1236f, 0x0910b51f, 0x00a7f433, 0x182e5578, 0x0880942c, 0x0dbda191, 0xa6b582}}}, - /* 7*16^27*G: */ - {{{0x17c8537b, 0x0fbb60ff, 0x07e0185d, 0x19596e88, 0x16c21ca8, 0x17f0e57c, 0x12b146eb, 0x1d1d3d80, 0x67cba4}}, - {{0x185726da, 0x075a82b9, 0x100fdb87, 0x1e087da0, 0x1cc047bd, 0x030f97d8, 0x06128787, 0x1dbd4391, 0x5b65ed}}}, - /* 9*16^27*G: */ - {{{0x0b6a1226, 0x14114672, 0x15194e4d, 0x13d39156, 0x0f3922af, 0x1eb43234, 0x064c681c, 0x14daae93, 0xc5958e}}, - {{0x066961d4, 0x00803446, 0x08422e47, 0x0edb7d74, 0x1bd82968, 0x0cb8cea2, 0x175fb2f8, 0x105ee1ef, 0xa031a8}}}, - /* 11*16^27*G: */ - {{{0x13713a52, 0x06f1fc2d, 0x0f1505f9, 0x0eb718d0, 0x05fa025c, 0x0061e3a5, 0x129f07f3, 0x1f05c84b, 0x83f07b}}, - {{0x1fb0ffb6, 0x088939fc, 0x1ed174a8, 0x0b6ec1c3, 0x1d3cfcab, 0x0a648963, 0x0ee4125e, 0x02144b71, 0xf2ec4f}}}, - /* 13*16^27*G: */ - {{{0x01ba21b0, 0x16cd0489, 0x109954e6, 0x0bb1a401, 0x00076d85, 0x00343757, 0x0b539bda, 0x09f36b48, 0x938dba}}, - {{0x0d5b4325, 0x1a6ccaf2, 0x0ada5f0d, 0x0377dc7e, 0x0b90bcbf, 0x16dee89b, 0x1959ba6a, 0x15135eea, 0x48afc0}}}, - /* 15*16^27*G: */ - {{{0x1f2b24f1, 0x09f24d31, 0x19daf3ed, 0x1d8c9ebf, 0x09779cfa, 0x0d5679da, 0x079cea07, 0x16ed9406, 0x7efa89}}, - {{0x0f8e4b83, 0x12ee2ea5, 0x15291575, 0x15be758a, 0x0ab211db, 0x09117e0b, 0x1bfde33b, 0x1d8c3e95, 0xa99ff3}}} - }, - { - /* 1*16^28*G: */ - {{{0x02f2b734, 0x034cdfcf, 0x007499fc, 0x0776b6aa, 0x0445779c, 0x13c3788b, 0x066818d2, 0x0533dd99, 0x224a02}}, - {{0x11ec7fdf, 0x007ac2a4, 0x11ebf421, 0x0e096ce7, 0x17fff07b, 0x0456c38e, 0x0ad05268, 0x1a536da4, 0xfa41a8}}}, - /* 3*16^28*G: */ - {{{0x1d254033, 0x0f497a3a, 0x091c1eb2, 0x0d050185, 0x0f240783, 0x0fd3445b, 0x1167f36b, 0x1dc2a79d, 0xe63502}}, - {{0x08f05e3f, 0x1455444b, 0x1f3cd81f, 0x02b41897, 0x1ce482c9, 0x14078384, 0x1846b5d3, 0x0f63ec43, 0xa7c583}}}, - /* 5*16^28*G: */ - {{{0x01e08f33, 0x1cb04d7f, 0x060b328a, 0x1ac63b97, 0x000e2b1f, 0x02e299f8, 0x1a1c4aad, 0x184e5d72, 0x5648de}}, - {{0x0269f1c9, 0x1776cd62, 0x045e5449, 0x0577e5c0, 0x1a2693e7, 0x1ae326bb, 0x010fd1e3, 0x0e0e11ee, 0x95fddc}}}, - /* 7*16^28*G: */ - {{{0x1ab98c43, 0x1dc1005f, 0x0fa2a938, 0x14aeeafc, 0x08f03c5b, 0x17c765f6, 0x149a5454, 0x13e6701d, 0x1941c1}}, - {{0x02abe217, 0x1d1086d1, 0x17d58e63, 0x0c5a7b71, 0x18c53d8f, 0x0d95247d, 0x0adb8adb, 0x068b2bb6, 0x8e66b8}}}, - /* 9*16^28*G: */ - {{{0x02d8c2f4, 0x13386882, 0x07006279, 0x064373ef, 0x18a0bd73, 0x1def1b26, 0x0f59fe9c, 0x063a2169, 0xfc5864}}, - {{0x1cfd274a, 0x08c6447f, 0x10ce2d00, 0x05960bd7, 0x1b4ab29e, 0x013cf35e, 0x055928cf, 0x0a59d15b, 0x99fade}}}, - /* 11*16^28*G: */ - {{{0x11ff0f18, 0x1583bf8e, 0x12690b44, 0x0179ce0a, 0x0d6c207e, 0x1d67cd79, 0x077aa6fe, 0x14d6189e, 0xee993b}}, - {{0x050782ad, 0x009c3b65, 0x03cb2c60, 0x0b901bee, 0x1bcfeb43, 0x0eac6742, 0x0cb07db1, 0x1b28af1b, 0xd87fd4}}}, - /* 13*16^28*G: */ - {{{0x0fdde3fc, 0x03d3fbaa, 0x18a33279, 0x11113c0a, 0x131fbe5a, 0x0e20d297, 0x090a3683, 0x0f55d3fc, 0xba4951}}, - {{0x0fcb7d01, 0x1f7e9197, 0x0a4b2aa8, 0x1c3903c6, 0x1359adfd, 0x121bb009, 0x16542d3b, 0x1c39528a, 0xa88fb6}}}, - /* 15*16^28*G: */ - {{{0x1d14da68, 0x0449517b, 0x14805cde, 0x0983f09b, 0x012b54a6, 0x07c139bb, 0x06e9378b, 0x02e8455e, 0xd3398f}}, - {{0x15a90e3d, 0x183b18da, 0x10514e8f, 0x0f4f245a, 0x0b020afc, 0x0968f451, 0x1583adc9, 0x1a9a3fa7, 0xa34ad4}}} - }, - { - /* 1*16^29*G: */ - {{{0x1789b84d, 0x13032d6b, 0x010738ba, 0x1abdc9a2, 0x093fe167, 0x0888dab2, 0x0d3336d7, 0x028ae6e9, 0x4a89a6}}, - {{0x018e3ea8, 0x1cdbebf8, 0x1c46667b, 0x1c500c68, 0x077e6a72, 0x154bcff3, 0x1570230b, 0x10fda901, 0x45b04e}}}, - /* 3*16^29*G: */ - {{{0x02e14c34, 0x13b591ba, 0x0c9d64db, 0x18bd7c0e, 0x177c9834, 0x19873c09, 0x1e4a8aa6, 0x09150e1d, 0xcc9f96}}, - {{0x14be556b, 0x0490abd4, 0x031f8162, 0x122fe305, 0x089db299, 0x1319edf3, 0x05bd0c45, 0x0596bf19, 0x829bff}}}, - /* 5*16^29*G: */ - {{{0x15de4837, 0x1ef3642c, 0x1979d3a1, 0x050d905b, 0x18a758d4, 0x060e856c, 0x106bd3d6, 0x143f55a0, 0x5c618d}}, - {{0x034a7dee, 0x05c2c1db, 0x089e32b0, 0x06cc92c8, 0x19671ecd, 0x071c24fe, 0x067622e0, 0x02f79e74, 0x4c7191}}}, - /* 7*16^29*G: */ - {{{0x16635396, 0x0c49a132, 0x029b0309, 0x15c2b46d, 0x1c11ef2c, 0x116ef338, 0x1a8b9617, 0x0d522b40, 0xab8a88}}, - {{0x1fc92c23, 0x11c7d351, 0x14b5ab5f, 0x0c0b07ef, 0x0d5abb93, 0x1fc1245e, 0x0c6559a3, 0x0f8fb508, 0xe773cf}}}, - /* 9*16^29*G: */ - {{{0x01df49c3, 0x0121f2c4, 0x01a68d6b, 0x11210cda, 0x1604aa9e, 0x125c5b4a, 0x0e337b19, 0x0a284830, 0x62b7c8}}, - {{0x16341c21, 0x1f1b407f, 0x1f2d5426, 0x0a76c270, 0x122db8fb, 0x0b5746a4, 0x0cd56522, 0x042a55c0, 0xa71ed6}}}, - /* 11*16^29*G: */ - {{{0x044f47d0, 0x178a3717, 0x07c00bce, 0x13ebbd29, 0x1c9791b5, 0x0f8434ef, 0x0717e5d4, 0x17f48b91, 0x4897bd}}, - {{0x0e1320bf, 0x0f280d56, 0x1c046560, 0x1b400351, 0x1093f526, 0x1654a0bd, 0x0e30d3a3, 0x01ef5f82, 0xe77dc2}}}, - /* 13*16^29*G: */ - {{{0x11581bd3, 0x10de74db, 0x0641e1b9, 0x14631bec, 0x02f2ecbf, 0x103ded39, 0x15db1147, 0x16aac90c, 0xeb1cfc}}, - {{0x1cd98a09, 0x1e746cc2, 0x0f469916, 0x19e6338b, 0x16e3cb39, 0x002f5f26, 0x14814110, 0x0eae3f29, 0xfd47ce}}}, - /* 15*16^29*G: */ - {{{0x073a3111, 0x00915edb, 0x132063e4, 0x105c82f6, 0x176a018b, 0x05617392, 0x18270355, 0x177c91c3, 0xa1fd8b}}, - {{0x18c704ef, 0x043f3285, 0x15445a6e, 0x18928b7f, 0x116c0c7e, 0x1f03de04, 0x015a6f5d, 0x11469461, 0xad215d}}} - }, - { - /* 1*16^30*G: */ - {{{0x12bd05a0, 0x01c64253, 0x07f2034d, 0x0466fa16, 0x11f90ba8, 0x1ccaf9b6, 0x0173b70b, 0x06c74631, 0xe5e892}}, - {{0x01a69f5d, 0x09b6f15f, 0x14266bb2, 0x0732b739, 0x15c3eca7, 0x1580f3cd, 0x1f484c07, 0x1c9b4370, 0x77439d}}}, - /* 3*16^30*G: */ - {{{0x01467d6b, 0x184a9408, 0x0892d453, 0x1ae252a5, 0x0f1d8357, 0x0308b216, 0x13d74406, 0x1bf286b9, 0x5d2393}}, - {{0x11bc5458, 0x1e339e35, 0x011cea01, 0x0e0f4ea2, 0x0f46d72a, 0x0c2d96ad, 0x1df5eb2f, 0x1e4c7fa1, 0xe66e63}}}, - /* 5*16^30*G: */ - {{{0x1d159f7a, 0x058f49e4, 0x10b9643c, 0x127539e4, 0x1873fecf, 0x1d95e97f, 0x04fceb73, 0x14a75571, 0x453657}}, - {{0x0a02fb78, 0x0e115b84, 0x07769766, 0x0937a9d0, 0x1c7286f9, 0x18489d00, 0x171768bb, 0x1ff10047, 0xbfb5ae}}}, - /* 7*16^30*G: */ - {{{0x146cb42a, 0x0f6f6f9e, 0x08e424cc, 0x0a50a74e, 0x173e7bc0, 0x16f5509e, 0x11193452, 0x1960f609, 0x435b54}}, - {{0x1af72dd0, 0x1f126f6e, 0x0e5269ad, 0x1898f286, 0x0585d5ed, 0x12a660f0, 0x086927d2, 0x063c8e31, 0xd726c0}}}, - /* 9*16^30*G: */ - {{{0x1d2fc263, 0x0beca0d8, 0x19755eea, 0x1f027cb6, 0x1da0e89c, 0x023e2709, 0x15f867ef, 0x033c29db, 0x1805b8}}, - {{0x10870ec7, 0x132385a7, 0x147b2bc9, 0x1835f1ca, 0x131489c8, 0x0d5435e5, 0x05c56163, 0x05012870, 0x101f64}}}, - /* 11*16^30*G: */ - {{{0x0076d1df, 0x1158db86, 0x1fe86ce6, 0x1c410284, 0x15f45f41, 0x1d45153b, 0x053d0185, 0x086cda63, 0xc73aaf}}, - {{0x05ad6605, 0x13cea8b7, 0x024dc834, 0x16af4a3b, 0x0dcfef75, 0x00df1dde, 0x05bbe738, 0x0d3d99f2, 0x9201ec}}}, - /* 13*16^30*G: */ - {{{0x05a745c7, 0x1b41fbcc, 0x1fab01f4, 0x144e7182, 0x152c1bc8, 0x0db57b0e, 0x1b49dc62, 0x11efab86, 0xe3ddee}}, - {{0x178efcc2, 0x1cf84a03, 0x1409ec68, 0x1185e2f7, 0x1d8f47c2, 0x0dc3553d, 0x0e1c6f94, 0x1a723265, 0x487199}}}, - /* 15*16^30*G: */ - {{{0x0d4170b3, 0x06399f42, 0x0e8d61fd, 0x0882adf8, 0x0a1d5401, 0x1508c360, 0x0796bda2, 0x1b8406be, 0x45c78d}}, - {{0x111faa1d, 0x177d1f6a, 0x08331cc5, 0x008cc0c8, 0x13a512cb, 0x14e8a27d, 0x1032c386, 0x08c471ab, 0x11af99}}} - }, - { - /* 1*16^31*G: */ - {{{0x1ab5c2cf, 0x0abccc97, 0x0c213788, 0x05e1843f, 0x090a4531, 0x03a0827d, 0x1d41c79d, 0x0863c443, 0xe4107e}}, - {{0x0b955c2b, 0x014201f9, 0x1ec90434, 0x1125b9fe, 0x02b323c7, 0x03343a0e, 0x1268e523, 0x1cd9ee03, 0x1e5f11}}}, - /* 3*16^31*G: */ - {{{0x09b67b7e, 0x1dadb1e0, 0x070f5216, 0x16f65722, 0x01142766, 0x0b80ef5e, 0x1df6ab3e, 0x0cbdc2f3, 0x85df9a}}, - {{0x030a36e3, 0x059c34f4, 0x0f1ba962, 0x15293a3f, 0x0297386f, 0x1eaf7f87, 0x0c22edad, 0x154735ec, 0xa6b4b7}}}, - /* 5*16^31*G: */ - {{{0x0b3510d3, 0x13e7ef30, 0x0875b904, 0x062cce09, 0x1292885d, 0x10c32e16, 0x1422a362, 0x1fcff3f9, 0x23c493}}, - {{0x1ae89a47, 0x1a317621, 0x0e76f5c4, 0x13c6bc4d, 0x1e6d8f79, 0x0ecf277f, 0x108c309d, 0x153c8682, 0xadf456}}}, - /* 7*16^31*G: */ - {{{0x0b49a71f, 0x06348c04, 0x089f0e6b, 0x0dd6d8c8, 0x035ddac3, 0x09f5d579, 0x03b77966, 0x016629ba, 0x94406d}}, - {{0x10b249a9, 0x18e0ca26, 0x18f3e511, 0x04e4c394, 0x1e897d0e, 0x1e484837, 0x05e73481, 0x0fd0c9be, 0x61aae7}}}, - /* 9*16^31*G: */ - {{{0x00e50c32, 0x0e6f19e3, 0x11a1cff9, 0x0212e5d1, 0x08d3877f, 0x1b6fadf7, 0x1050cdc4, 0x087bd10d, 0x3c2ebf}}, - {{0x0a93c124, 0x117c48be, 0x1a326627, 0x1a118735, 0x028e7be2, 0x1c9e9017, 0x06719496, 0x14d8bd07, 0xa703d9}}}, - /* 11*16^31*G: */ - {{{0x03a2355a, 0x041ecef6, 0x1812641c, 0x0a37e6b8, 0x15f12996, 0x12dc4f62, 0x1ae7ce47, 0x1ae4f281, 0x987536}}, - {{0x1bd05276, 0x063ae260, 0x0eb7337c, 0x1ed8f8d0, 0x17b48b85, 0x18e0a4f2, 0x05c90f82, 0x1ace9e22, 0x12f19a}}}, - /* 13*16^31*G: */ - {{{0x12f3ec22, 0x0782a3e2, 0x0a3e29ac, 0x10db9ee3, 0x0ddddd1f, 0x1c58bf79, 0x11a3c674, 0x08134988, 0xd515ac}}, - {{0x05a2863b, 0x10a31759, 0x06e01bb2, 0x0afbe006, 0x0bd464cd, 0x12420029, 0x0cb87a97, 0x02844893, 0x51c048}}}, - /* 15*16^31*G: */ - {{{0x1971c857, 0x0cd0f4d2, 0x19824fe9, 0x133cdb57, 0x1cf3ddec, 0x1e61c5b0, 0x02eb8914, 0x0930bcb6, 0x70b9d}}, - {{0x0ac8dfc1, 0x1ce5b1ee, 0x15186abf, 0x107b43d8, 0x13cfb33a, 0x0857231b, 0x09421ae0, 0x037fe96c, 0xed8046}}} - }, - { - /* 1*16^32*G: */ - {{{0x1789bd85, 0x1e427e4e, 0x05fab0d5, 0x0bfefb85, 0x0766efc3, 0x17eac463, 0x199fee60, 0x137ddb6b, 0x447d73}}, - {{0x12e25b32, 0x03f19e4b, 0x1eb94003, 0x09372b4f, 0x0aff73d3, 0x0eca9d25, 0x07bb84ba, 0x15706826, 0x2d4825}}}, - /* 3*16^32*G: */ - {{{0x1ea6db68, 0x1f0ccc76, 0x098cb09c, 0x15b0ac10, 0x0f4f6ddf, 0x06fcb2ef, 0x05fd62c5, 0x07c07940, 0xf8b653}}, - {{0x0e760da9, 0x0de92d85, 0x17283b5a, 0x1ae1bb38, 0x03ec66bb, 0x16ed2855, 0x1218bc11, 0x1ebd888a, 0xc30f4e}}}, - /* 5*16^32*G: */ - {{{0x1924e753, 0x16aea75f, 0x1e1c9f19, 0x02e60e59, 0x1fb755f0, 0x18c394f6, 0x11f1523b, 0x1a6ab050, 0xf35289}}, - {{0x0b13a20c, 0x122dae17, 0x0b43c12a, 0x05f8ae52, 0x01bd8c56, 0x0450da87, 0x0fee4f7c, 0x03d8bd82, 0x75c178}}}, - /* 7*16^32*G: */ - {{{0x1018017e, 0x1cae5b39, 0x17c8f5c8, 0x083fffad, 0x14e01af1, 0x0c2fdb39, 0x1c5920d0, 0x0e9b4882, 0xcfd06b}}, - {{0x0e0dff50, 0x0573df26, 0x1de5dde8, 0x0060f0d6, 0x07950003, 0x19cac3ed, 0x044e040e, 0x1536e575, 0xb647b7}}}, - /* 9*16^32*G: */ - {{{0x192db860, 0x0640c82b, 0x06891ec1, 0x11251065, 0x1dbe9810, 0x0b68478a, 0x1344544b, 0x09895abb, 0x755e7}}, - {{0x00d09849, 0x0b3006dd, 0x109dde9f, 0x06e8c99f, 0x15bc2b29, 0x196c11c0, 0x19374926, 0x14ea75b3, 0xfe16af}}}, - /* 11*16^32*G: */ - {{{0x0a26ba6b, 0x0f7b4aaf, 0x1684b0ea, 0x1945492d, 0x0bbdedd2, 0x0606bf58, 0x05a5a284, 0x09986e59, 0x88fba8}}, - {{0x044972f8, 0x020a3c0f, 0x033f73a0, 0x153c51c0, 0x0788d484, 0x0d22da8a, 0x183f499b, 0x0c93a737, 0x512aef}}}, - /* 13*16^32*G: */ - {{{0x14720cab, 0x0e245214, 0x0e6c5f8e, 0x1d4ba82e, 0x06f2c1a1, 0x1b73aaae, 0x0fae3943, 0x197d80ab, 0xe1a0ac}}, - {{0x14b185c9, 0x16a29fab, 0x000953a9, 0x1454e3a1, 0x0bcbf084, 0x1c183bf7, 0x015060db, 0x1f6fd319, 0xe07968}}}, - /* 15*16^32*G: */ - {{{0x0c26c42a, 0x14147eff, 0x0c46ed8a, 0x17f6fc8d, 0x1e6a0249, 0x1ac498f3, 0x11f9436c, 0x10dcd4e7, 0xae93b}}, - {{0x19f808ca, 0x08319a1d, 0x0ab6d924, 0x1473ddeb, 0x00b37278, 0x11f6e0f1, 0x184ea50b, 0x1ba28f0f, 0x7028f6}}} - }, - { - /* 1*16^33*G: */ - {{{0x137de736, 0x15ec5d60, 0x02338907, 0x11aac30d, 0x0c18ea2f, 0x0a15c66f, 0x1cfa24dd, 0x02929399, 0x9022e3}}, - {{0x04c42ecc, 0x077ae042, 0x1a9d95fd, 0x126cd889, 0x0ce087f4, 0x1d822913, 0x0e519b42, 0x09e52094, 0x2fae5e}}}, - /* 3*16^33*G: */ - {{{0x109b01f5, 0x0b8365c6, 0x1cf01464, 0x1e6a3064, 0x1857af73, 0x169f8d7b, 0x0517ec3c, 0x1c60edfd, 0x6e5872}}, - {{0x0bcd5fde, 0x183ac6cd, 0x06a169f0, 0x02f3a9c1, 0x0f0ebc13, 0x0ea579df, 0x05c60330, 0x05d91aee, 0x4213c0}}}, - /* 5*16^33*G: */ - {{{0x0fe45b1f, 0x09cdba3f, 0x185a30ad, 0x02abf65c, 0x1df827bd, 0x0f1a260b, 0x1d412bf4, 0x1634bb47, 0x292220}}, - {{0x134bb026, 0x1f205c5a, 0x17504117, 0x06886099, 0x18d7ff7c, 0x1caffd74, 0x16bb8df1, 0x0a657e2e, 0xe316a0}}}, - /* 7*16^33*G: */ - {{{0x03abd540, 0x14283315, 0x059b790f, 0x0080ca96, 0x13a340e8, 0x07c39084, 0x1c2b0c89, 0x0900f489, 0x3644e1}}, - {{0x155da631, 0x0e37f0e6, 0x1be85378, 0x0ef9db4c, 0x1e293001, 0x02984fd0, 0x05d8470a, 0x0a1b784f, 0xec5a91}}}, - /* 9*16^33*G: */ - {{{0x09142ccb, 0x117e90f4, 0x01fb78c6, 0x0414b58d, 0x1b4824c9, 0x1c7a4c9d, 0x00e3956c, 0x15c2ff9b, 0xedfe7d}}, - {{0x0c593d75, 0x1ca8e98d, 0x14450bae, 0x08856d3a, 0x1beb81da, 0x0e95a7aa, 0x1c858615, 0x0245c1b5, 0xc88692}}}, - /* 11*16^33*G: */ - {{{0x0a41b208, 0x1ed38e32, 0x189c003c, 0x0e8eb9bd, 0x00de8e7f, 0x00135e75, 0x1a5661c5, 0x11680b34, 0x531196}}, - {{0x048e4b69, 0x08f0fcf0, 0x0da1dfda, 0x183b8048, 0x1da113b3, 0x0c0f19d9, 0x05e29b19, 0x0567b845, 0xb78d73}}}, - /* 13*16^33*G: */ - {{{0x095daae7, 0x1e80dae2, 0x1c0cef2c, 0x0dcdd8f8, 0x0e1d5af4, 0x15fb7ab0, 0x1653de88, 0x1e45ff74, 0xf65dd1}}, - {{0x02556738, 0x0a72d4ce, 0x0b366ca3, 0x0c301f3d, 0x04cd0eb0, 0x1f31be7e, 0x1ba0839b, 0x0419c36c, 0x9d71b8}}}, - /* 15*16^33*G: */ - {{{0x1afcf1ee, 0x1f7e0af1, 0x01a6846a, 0x155008e4, 0x007c60af, 0x1a405554, 0x0922d06f, 0x0fdb995c, 0xa6670e}}, - {{0x00c67fc8, 0x1c43855f, 0x0f3ce28d, 0x07312392, 0x1ac131ef, 0x1b97a4ab, 0x0bce8e57, 0x19274a38, 0xa7fd14}}} - }, - { - /* 1*16^34*G: */ - {{{0x04cd3397, 0x008a2e0a, 0x1457ad5d, 0x09820c32, 0x16deddc3, 0x16795a8a, 0x1c8e24e1, 0x00833db4, 0x73baff}}, - {{0x1adcb8e4, 0x0f79509c, 0x0984d250, 0x1df259f0, 0x1825e779, 0x08f460c7, 0x117da803, 0x0c692ef5, 0x1e97de}}}, - /* 3*16^34*G: */ - {{{0x161fb913, 0x1587ca90, 0x14c4a5df, 0x0048c2ad, 0x0d04e3e1, 0x046f225f, 0x0860d10e, 0x01867cc1, 0x45f833}}, - {{0x0c15c3bc, 0x06a40be0, 0x1f0cdcdc, 0x1a10f3ed, 0x07760f06, 0x003b6c5d, 0x01bbe03a, 0x0db7fad2, 0xc212cf}}}, - /* 5*16^34*G: */ - {{{0x0e393654, 0x177cb48f, 0x1b75f1d6, 0x1a97c3e7, 0x15991965, 0x100e45e6, 0x16ad97d6, 0x09359af7, 0x5544dc}}, - {{0x0f53206f, 0x1b085dfc, 0x15639cc8, 0x1dfd2e07, 0x15192241, 0x02dadc49, 0x152b0130, 0x112a10ff, 0xed3e85}}}, - /* 7*16^34*G: */ - {{{0x08a15dfd, 0x1f9acca1, 0x1ea79544, 0x1b75804b, 0x0f695741, 0x176aad71, 0x1dcd2cf4, 0x120c33dc, 0x2757b7}}, - {{0x1042c341, 0x04742067, 0x09c55b7f, 0x112f1479, 0x1500d176, 0x1a909e6a, 0x04b97325, 0x1aaa9856, 0xdf46d2}}}, - /* 9*16^34*G: */ - {{{0x1f840a5b, 0x1f6fa135, 0x0b52613b, 0x195b4ba7, 0x03ccd148, 0x10e6608a, 0x0f236610, 0x0fbca1c5, 0xe87243}}, - {{0x1377e86a, 0x0272c2a8, 0x0e59192e, 0x1468d9f2, 0x08bf5ac3, 0x048fb312, 0x185964ef, 0x11224e52, 0xf984bc}}}, - /* 11*16^34*G: */ - {{{0x136afd6a, 0x0ab54dc5, 0x1e078f52, 0x03f8a142, 0x1334a926, 0x1b6af379, 0x1700e4bb, 0x15749aee, 0xc56cdc}}, - {{0x13f87c26, 0x10435f77, 0x0331c8f9, 0x090764ad, 0x14ef566f, 0x0f58bfac, 0x01c334bb, 0x1c5e70d6, 0xd16056}}}, - /* 13*16^34*G: */ - {{{0x0cfd2cd0, 0x0d6cc069, 0x070304c7, 0x08266883, 0x0abb1239, 0x142c1f24, 0x0a1a73f4, 0x0e71e7fe, 0xd3d6e6}}, - {{0x194ae2dc, 0x02bce3bb, 0x1dbe3c53, 0x1f4ad185, 0x1e59b001, 0x147fb9be, 0x0da14db6, 0x0bf9a2b3, 0xff448f}}}, - /* 15*16^34*G: */ - {{{0x1ab7a64c, 0x0ac442ae, 0x026ade82, 0x011ad474, 0x1d406565, 0x196b911b, 0x101ec0c4, 0x110adc8b, 0x88f977}}, - {{0x1575f103, 0x02f4c708, 0x1b499ce8, 0x06012442, 0x09e5836c, 0x0d792bcb, 0x11d0d14c, 0x1ba8d6ab, 0x4a745c}}} - }, - { - /* 1*16^35*G: */ - {{{0x1fa4e33c, 0x1172fd98, 0x02632cc3, 0x077d8f16, 0x0fb98268, 0x023614bb, 0x16ef25d1, 0x17234984, 0x9cf646}}, - {{0x0e0d4563, 0x0e22f030, 0x10580c86, 0x00b04fd7, 0x01f319e2, 0x0712c5c1, 0x0a247902, 0x09b83ecb, 0x37b062}}}, - /* 3*16^35*G: */ - {{{0x06bf1e67, 0x0c5b0c66, 0x172bd8fa, 0x0cce93fc, 0x04e0f4c5, 0x129c13bb, 0x126675e9, 0x1bc2a36c, 0x83cb43}}, - {{0x099acc97, 0x13f74598, 0x1445a7a8, 0x0884597b, 0x018f8287, 0x00373122, 0x1be3bec6, 0x1449731e, 0xbce28c}}}, - /* 5*16^35*G: */ - {{{0x1c0f057e, 0x1856ba46, 0x154f7608, 0x10c50e03, 0x1022484e, 0x07e0af12, 0x02300cd0, 0x1cac19d6, 0x3ff3b3}}, - {{0x0817965e, 0x0a0fbed5, 0x1c05d88b, 0x0046dd88, 0x07843a01, 0x08b82bc3, 0x1e3dbdff, 0x0de776ca, 0x7f17ad}}}, - /* 7*16^35*G: */ - {{{0x125e69f1, 0x088a5a01, 0x08af2d45, 0x0f51e5a8, 0x0af99636, 0x0ef0b9eb, 0x00ff7686, 0x05bb1ffb, 0x6e9edb}}, - {{0x002b7e9b, 0x1070bf1a, 0x07ca06dc, 0x04e8a8f3, 0x1bff61c7, 0x0b55b2f9, 0x153aacd5, 0x02d9dff2, 0xc08222}}}, - /* 9*16^35*G: */ - {{{0x0288f038, 0x19297b35, 0x17fe082f, 0x0ed129d6, 0x02d32f08, 0x00cef376, 0x112fbeaf, 0x1d009883, 0x5ee280}}, - {{0x16f1ee6e, 0x02d55c35, 0x19b1bd07, 0x0f067531, 0x1eec011d, 0x0c37f664, 0x0e4a1301, 0x1f28cefc, 0xbcd969}}}, - /* 11*16^35*G: */ - {{{0x00c708c8, 0x05f992b6, 0x1c2a1aa8, 0x08609e5e, 0x0288c2c3, 0x1b2ec8ff, 0x15cdb7f8, 0x0dc0b840, 0xe1f016}}, - {{0x1896ed38, 0x18c6b9d9, 0x0d6802b9, 0x0abe45df, 0x13016fb6, 0x1195f451, 0x0d481111, 0x07d22d87, 0xe64765}}}, - /* 13*16^35*G: */ - {{{0x076edefb, 0x10784e52, 0x039f575f, 0x117b0020, 0x1c7badd5, 0x0d5a14bc, 0x1171fc48, 0x10f57ec6, 0x280896}}, - {{0x1d1b0ae0, 0x17a2b914, 0x00e4848b, 0x06360f7c, 0x141c44dd, 0x0cf5ec82, 0x064699f8, 0x1e67a766, 0x5d071c}}}, - /* 15*16^35*G: */ - {{{0x1344897a, 0x096ccde7, 0x1309a774, 0x1da60eb4, 0x1edab7b9, 0x0f429212, 0x132dc161, 0x1bc50320, 0xeb15b0}}, - {{0x05bfe7ee, 0x0cef41e7, 0x1f42e0ab, 0x0d3165f2, 0x12f85814, 0x157c66b9, 0x01c42262, 0x02d384cc, 0x96cdd}}} - }, - { - /* 1*16^36*G: */ - {{{0x123b716d, 0x137d6e02, 0x13869ae0, 0x0712cdee, 0x0df9e0d2, 0x03c9c68c, 0x14d3a297, 0x1c717194, 0xf81f5b}}, - {{0x12632401, 0x120017a8, 0x01e0cc11, 0x0eb0a075, 0x00328660, 0x094e9c07, 0x1b7c755b, 0x065383e0, 0xdc7f49}}}, - /* 3*16^36*G: */ - {{{0x19d19d8a, 0x062b4281, 0x09548561, 0x024f12a3, 0x1490a3b4, 0x161ae0b6, 0x18e16bdb, 0x0a1f6250, 0xa60084}}, - {{0x190d2c4f, 0x0caedd9a, 0x0995cf7f, 0x1c011f4e, 0x1ca84f0f, 0x0a2f3df4, 0x11cb23db, 0x180cf46f, 0x7b4b79}}}, - /* 5*16^36*G: */ - {{{0x096cac9f, 0x14c3d9ca, 0x11379c89, 0x0719d4b8, 0x10e1c59e, 0x04bcc7f5, 0x0d531930, 0x1632cfbe, 0xde5382}}, - {{0x0fa473d3, 0x070417ed, 0x1610455f, 0x07c528e7, 0x19f2bc2e, 0x1804c8e7, 0x06158b0e, 0x0f16d392, 0x9c47b6}}}, - /* 7*16^36*G: */ - {{{0x06807a23, 0x0594b1bc, 0x097fcf9f, 0x0040a2d4, 0x14ec8400, 0x1ccea88c, 0x04214d12, 0x0100fe55, 0xa7227b}}, - {{0x14115894, 0x0238cc1e, 0x0a337247, 0x1f02af6e, 0x075abe7b, 0x023c9050, 0x07a1176a, 0x04ba8ba7, 0xf55075}}}, - /* 9*16^36*G: */ - {{{0x044d14c0, 0x13cbfe10, 0x0a3cd796, 0x1956bf43, 0x01d39005, 0x1f39d1b3, 0x1659196a, 0x11a84688, 0xcd2b2e}}, - {{0x02496315, 0x0b056791, 0x0b33b3a9, 0x16de1973, 0x0f671fdd, 0x0f76ed60, 0x02893541, 0x1bf3610e, 0xf13012}}}, - /* 11*16^36*G: */ - {{{0x199a1566, 0x17a75891, 0x08a3da59, 0x18cab5fe, 0x19dd8f25, 0x1e4dc1ef, 0x1fad33be, 0x0991e1be, 0x11b2e8}}, - {{0x1c56bb73, 0x0d259e02, 0x16025a16, 0x16ab0819, 0x005cc824, 0x0b4c3cba, 0x05d7410b, 0x13b79446, 0x610376}}}, - /* 13*16^36*G: */ - {{{0x1ba6f34a, 0x084f5946, 0x1171be1f, 0x10d41fc4, 0x11485312, 0x1051f7cc, 0x01c1d676, 0x052be574, 0xfb6d19}}, - {{0x0bcf0452, 0x1af9e411, 0x1a16c7e6, 0x19f45b92, 0x191b9ecf, 0x07ea6253, 0x1b7678e2, 0x053af7e8, 0xf29b2d}}}, - /* 15*16^36*G: */ - {{{0x0a435427, 0x06516950, 0x1936d41d, 0x0021304f, 0x06651a69, 0x13b286c8, 0x0f042abd, 0x19820782, 0xff429f}}, - {{0x19853824, 0x12822869, 0x0e8368a3, 0x17dca694, 0x06876205, 0x04e42b0c, 0x16c25350, 0x0cd149d9, 0x2addf9}}} - }, - { - /* 1*16^37*G: */ - {{{0x07354b7a, 0x16ce3f3c, 0x045725e3, 0x1d94ad87, 0x0de1d022, 0x1a31f29e, 0x01208e5f, 0x0e9aefc1, 0x856854}}, - {{0x116e04c6, 0x0aa2015e, 0x15bf6f62, 0x1123b83f, 0x1728706a, 0x089d9537, 0x1edbbaf2, 0x16a17eb0, 0x20b50e}}}, - /* 3*16^37*G: */ - {{{0x1b26165d, 0x1b663fd3, 0x1dc4dfab, 0x07442bec, 0x092dea71, 0x090497e6, 0x199527a7, 0x18ea5647, 0x617344}}, - {{0x06b2a286, 0x04dfee5c, 0x1c5c6931, 0x13582dc6, 0x020b2989, 0x0885e8c1, 0x0d6926df, 0x02f486f0, 0xe99016}}}, - /* 5*16^37*G: */ - {{{0x10442770, 0x10dfbb32, 0x006eb440, 0x11ef4dc2, 0x0fc2e901, 0x00ed4f20, 0x088b6813, 0x1dcabf6d, 0xf8ac03}}, - {{0x1b00c82d, 0x11432788, 0x0107408e, 0x0c057f2a, 0x06d17a97, 0x03a8d9a7, 0x1a3a90db, 0x0cab33a3, 0x5a358e}}}, - /* 7*16^37*G: */ - {{{0x165460de, 0x1f036c37, 0x0fddee3e, 0x07f1a155, 0x08ea60c7, 0x1e5f1866, 0x1719b1b2, 0x16a4b792, 0x8a731f}}, - {{0x1f8dc207, 0x0c2cd0ef, 0x1423b8fa, 0x0cfc78a4, 0x04dc4358, 0x0aa5ffd8, 0x0c663d4a, 0x18bc556c, 0x585855}}}, - /* 9*16^37*G: */ - {{{0x151634a5, 0x0155d6fd, 0x1b549399, 0x1214f06b, 0x1967f3cf, 0x15d0166b, 0x0892fc29, 0x0c26551e, 0xa20b60}}, - {{0x1226afad, 0x1609bcaf, 0x1517b7c9, 0x08eafc79, 0x1315bc67, 0x0ff41b9d, 0x0676b4f5, 0x13ed2fb7, 0x9c43ce}}}, - /* 11*16^37*G: */ - {{{0x13ba54a8, 0x02191225, 0x0eaa5c1c, 0x164c6ac0, 0x1cc0ab58, 0x0761a7e2, 0x1c26450e, 0x127e24ac, 0x16f1f}}, - {{0x064f2889, 0x0be30fd3, 0x08ed39bb, 0x15e4ea8d, 0x0e658d93, 0x188df24e, 0x055dbca6, 0x0822b12a, 0x8bcd3}}}, - /* 13*16^37*G: */ - {{{0x07c16d94, 0x177249e7, 0x0a117f77, 0x103a1540, 0x0c31fe25, 0x1eb3e667, 0x11e23023, 0x0ce17a06, 0xe61586}}, - {{0x114810ab, 0x1a768cd5, 0x0910eefe, 0x0b9a3c8f, 0x0f0ee4e6, 0x15c9fa5b, 0x12fa316c, 0x15d3ce24, 0x65ca03}}}, - /* 15*16^37*G: */ - {{{0x13ce728d, 0x0b6e5332, 0x1c7342f3, 0x1b20fc50, 0x05347f4c, 0x04510b64, 0x08995568, 0x01671aad, 0xdcd37f}}, - {{0x17cacbcb, 0x0be89b4c, 0x076afae3, 0x19a68da5, 0x0d6f3caa, 0x1db159e3, 0x1061cb0d, 0x1aef9b49, 0x6574db}}} - }, - { - /* 1*16^38*G: */ - {{{0x12378c16, 0x0e36e0d8, 0x05588ab7, 0x0c0eaa8c, 0x1597d9e3, 0x1296b5fc, 0x0c46cc67, 0x0b382567, 0x1136b7}}, - {{0x13488127, 0x0facde85, 0x147338de, 0x095451ce, 0x1ecb2961, 0x15e307f4, 0x1f7427c2, 0x19e8a2d1, 0x7dec0f}}}, - /* 3*16^38*G: */ - {{{0x1b299740, 0x18736c13, 0x0f6c4d25, 0x1e8cfae2, 0x0ad48f40, 0x089bc9fd, 0x0cdb312b, 0x16e39ba8, 0x53893e}}, - {{0x1fff7509, 0x0f5378d9, 0x1f7a3354, 0x0265de43, 0x1dc8dd8a, 0x0714753a, 0x0f60e107, 0x0fd290bf, 0x27728a}}}, - /* 5*16^38*G: */ - {{{0x138000fc, 0x059e4ab3, 0x1c0ef04c, 0x1c4ee0f7, 0x0e5604e1, 0x1b5d78fd, 0x089d5f8d, 0x1baea99b, 0xdd64e9}}, - {{0x1df4ac12, 0x1d50e286, 0x07923e2f, 0x0ba04572, 0x079ffbe4, 0x0f1f0ce5, 0x0b25b7e2, 0x1d618526, 0x432193}}}, - /* 7*16^38*G: */ - {{{0x13878c4a, 0x1c10a8b9, 0x1470157b, 0x07a0790a, 0x11b21d88, 0x0e307254, 0x145bcb1a, 0x150fdffa, 0xff9845}}, - {{0x1488df68, 0x1d3423eb, 0x173faf1a, 0x066e8d6c, 0x1e8ddf1f, 0x12476ffa, 0x0a3e3f62, 0x1e949c48, 0x835b9a}}}, - /* 9*16^38*G: */ - {{{0x00f51524, 0x054dc40a, 0x0be1bf23, 0x1d6d42b7, 0x093de5fa, 0x1d184229, 0x0273a1d9, 0x1d17722c, 0x954e13}}, - {{0x05e30a69, 0x0fed9eca, 0x079f2f7a, 0x1d486228, 0x0cbcfa9e, 0x1121a3cf, 0x010764f1, 0x07ff2548, 0xecc836}}}, - /* 11*16^38*G: */ - {{{0x04f77287, 0x1bcc6a9e, 0x0c3678c7, 0x12a786d2, 0x00497412, 0x0862e0ec, 0x0e4f7f35, 0x1edf483f, 0xb2217e}}, - {{0x04e7b5da, 0x1d0253b9, 0x17a4f2e5, 0x13b8e738, 0x0c843d70, 0x1e7c469c, 0x0e8ad77e, 0x1c19cf9e, 0xfb5153}}}, - /* 13*16^38*G: */ - {{{0x05c723e9, 0x17a9cb64, 0x09e05c62, 0x0e775535, 0x15c351f9, 0x175748ae, 0x16b448b1, 0x162f6f37, 0x3c3950}}, - {{0x16834763, 0x11c3bafb, 0x1241ab97, 0x1b596af8, 0x0a8b0b01, 0x1dbf50c3, 0x036ed252, 0x0c441222, 0xb99b73}}}, - /* 15*16^38*G: */ - {{{0x1c18abeb, 0x18beb711, 0x09758a8d, 0x1b9a320e, 0x0a944d59, 0x097c225d, 0x136b477b, 0x0599f2c3, 0x803c7a}}, - {{0x029bfa78, 0x121cdf87, 0x19c8735a, 0x18887854, 0x14409ed7, 0x078b4e25, 0x04a1ac6b, 0x0814f2dd, 0x83fb50}}} - }, - { - /* 1*16^39*G: */ - {{{0x143e832a, 0x03b1778c, 0x01b7dc27, 0x0a15602f, 0x1f18e07e, 0x19d412c4, 0x146a43d5, 0x1174f854, 0xd2bf2}}, - {{0x1b20d37c, 0x0131d78a, 0x15451192, 0x193b72c0, 0x0e7ed27e, 0x10854a5a, 0x02b1c21e, 0x086277a0, 0xcac3f}}}, - /* 3*16^39*G: */ - {{{0x112c9666, 0x0f5625e0, 0x1ff37cd8, 0x118d86cb, 0x1531b1cf, 0x061adbec, 0x00b3f66f, 0x0bd72cff, 0x34e5e8}}, - {{0x192a3666, 0x0d0c29e4, 0x18e949ad, 0x0fdac783, 0x046330f4, 0x12bae65e, 0x0dae0a11, 0x06264434, 0xc0ce68}}}, - /* 5*16^39*G: */ - {{{0x11209502, 0x0b295f1a, 0x16499970, 0x02e4004b, 0x1e154594, 0x09f7848c, 0x018e9b12, 0x198b3e9b, 0x727362}}, - {{0x17042b0d, 0x13be8e9e, 0x09d82ef1, 0x1a6ff376, 0x11d20a18, 0x05c61674, 0x0d627c40, 0x04537575, 0x17b0f4}}}, - /* 7*16^39*G: */ - {{{0x0447f959, 0x0af3c945, 0x1c74da11, 0x0fb57504, 0x1eee9f94, 0x0a625da4, 0x13b25ce8, 0x0c00a94d, 0xa0c3f2}}, - {{0x168b671f, 0x01ce9244, 0x149cb26c, 0x0aa804b1, 0x08208b1b, 0x060865b1, 0x113ce0be, 0x0121c965, 0x508c73}}}, - /* 9*16^39*G: */ - {{{0x1b37e1d3, 0x10fcf812, 0x193788c0, 0x0c37c279, 0x1fd04107, 0x019df20a, 0x09e9032d, 0x063ef2b9, 0x7e81b2}}, - {{0x0155681a, 0x1afe5132, 0x10b8380f, 0x1097e563, 0x07c4e4ec, 0x04b67736, 0x144c497a, 0x0361d37d, 0xf3855a}}}, - /* 11*16^39*G: */ - {{{0x16c051a0, 0x04bb8afa, 0x16cf9b71, 0x1e5248de, 0x12abddcd, 0x0c736d87, 0x1b6128db, 0x038fb004, 0x8035e2}}, - {{0x12d0dd12, 0x00f5d97d, 0x02d88d58, 0x0fb8c613, 0x1d318b3e, 0x1f341bde, 0x0fbcdd76, 0x14896f45, 0xb8810}}}, - /* 13*16^39*G: */ - {{{0x1f12c69e, 0x1006184f, 0x194658f3, 0x0b5deb12, 0x0fcecafe, 0x18008102, 0x14cc1aeb, 0x1bfac314, 0x196908}}, - {{0x1d114831, 0x0998c820, 0x1ee21ae3, 0x05c66e3f, 0x1054eb6b, 0x0ef56e90, 0x18102fb8, 0x0d65f22d, 0x3f65bf}}}, - /* 15*16^39*G: */ - {{{0x0b89c5ed, 0x04c700fe, 0x1e9e31f9, 0x0a619ef2, 0x10f3577b, 0x10e90856, 0x0abd1b9b, 0x1d712c34, 0xdb77fc}}, - {{0x0d25b46e, 0x0ff8e3f7, 0x0266be96, 0x0d8f56d1, 0x1ad411f1, 0x1cdf264c, 0x173bb3cc, 0x070e39dc, 0x7fd1dc}}} - }, - { - /* 1*16^40*G: */ - {{{0x17f82f2a, 0x174e3aef, 0x1f7d0eab, 0x186b0e95, 0x113269e4, 0x16fa1b9b, 0x185fd588, 0x0acdd8e6, 0x8a535f}}, - {{0x023094b7, 0x0fcd0561, 0x031d9a71, 0x0a670c99, 0x092bfcde, 0x140c842d, 0x0f5cdf80, 0x108d1611, 0x455c0}}}, - /* 3*16^40*G: */ - {{{0x0b348fa0, 0x18a790bd, 0x0550777e, 0x1c48b20a, 0x0b4bce0f, 0x1191b612, 0x00b70a88, 0x07bbbd71, 0x86eac9}}, - {{0x0da51cee, 0x171c04aa, 0x13fba293, 0x0db2c6a3, 0x146716c2, 0x17cf46b7, 0x1635690d, 0x0a797789, 0x948f38}}}, - /* 5*16^40*G: */ - {{{0x19222c03, 0x17a0ffe4, 0x197840de, 0x19cefd0f, 0x1f407948, 0x1ebc242c, 0x0ab8fd79, 0x175f3f67, 0x8bf09e}}, - {{0x0a72bb54, 0x0a2fba17, 0x08387528, 0x1d81c3bc, 0x1ba309c9, 0x18edf3f2, 0x09cced22, 0x15fc5c4f, 0x509cba}}}, - /* 7*16^40*G: */ - {{{0x11ae9300, 0x029d160e, 0x1120a02d, 0x188e08eb, 0x1735b5e1, 0x05d6d179, 0x1f18644c, 0x1976fce1, 0xe85e2d}}, - {{0x1546e25e, 0x1506fee8, 0x030c6edc, 0x0fc30bbf, 0x02707deb, 0x1dadc11e, 0x02ff1ee9, 0x14daa39c, 0x451aaf}}}, - /* 9*16^40*G: */ - {{{0x05260cb8, 0x092eaab0, 0x0c854bc9, 0x1e95019d, 0x1dbf6836, 0x13ed0dd3, 0x1e0a8fc0, 0x1e451925, 0x3f5fb0}}, - {{0x1852c964, 0x17da5a20, 0x17b0cc9c, 0x1d0ea3f8, 0x183f2fa3, 0x0f0a9b33, 0x061c38e3, 0x1b5b4933, 0xc55834}}}, - /* 11*16^40*G: */ - {{{0x1a1cd60f, 0x15222216, 0x0c24ba92, 0x0d315398, 0x0002b9f9, 0x083a5a6d, 0x06595ebb, 0x045631b3, 0x336856}}, - {{0x0fd57d67, 0x1fb9bb28, 0x142e2c92, 0x1eb49978, 0x1af175fe, 0x06006f53, 0x1366ea16, 0x13de248f, 0xd42f50}}}, - /* 13*16^40*G: */ - {{{0x17576342, 0x029db75d, 0x06488abc, 0x19110673, 0x179d95b2, 0x1cec4b04, 0x0203df43, 0x0b811e00, 0x4813eb}}, - {{0x17376316, 0x060aaf5c, 0x1aa413d9, 0x1b8cfaa0, 0x1524aca2, 0x0b424719, 0x0903d980, 0x1a846748, 0x043f}}}, - /* 15*16^40*G: */ - {{{0x1f69b2be, 0x1b38b8ef, 0x04447027, 0x03ee9db8, 0x06e56ba4, 0x16ddd71c, 0x05ebc4c8, 0x1f34b5d3, 0x80c3f1}}, - {{0x0102d2f5, 0x0825cbe2, 0x0dea2fe2, 0x16e966b9, 0x15a9bf14, 0x113b2d8e, 0x1a14a603, 0x0814013b, 0xa9321}}} - }, - { - /* 1*16^41*G: */ - {{{0x0476c81d, 0x041bfa7f, 0x194f57a7, 0x06061d33, 0x0a366b7a, 0x06939ed4, 0x08066bdf, 0x1bfb9683, 0xad6090}}, - {{0x0e6705dd, 0x0c55e427, 0x0c1237e0, 0x1fb86c9e, 0x1d8a8393, 0x1ae1662d, 0x047ab335, 0x1ba91e99, 0x77b5d1}}}, - /* 3*16^41*G: */ - {{{0x02725490, 0x11239be7, 0x12d66402, 0x06480c47, 0x1863c4ac, 0x15299d84, 0x05f28ab6, 0x176e35ad, 0xd90b45}}, - {{0x0feb1299, 0x07c27c25, 0x1119b32c, 0x180f7fe7, 0x0cbd80cd, 0x1ab439bc, 0x143c2762, 0x11d83766, 0x332692}}}, - /* 5*16^41*G: */ - {{{0x1e933668, 0x1b59d32b, 0x1aeafc29, 0x05b099f0, 0x106befb0, 0x1c9d7d0f, 0x1f1eb014, 0x02e62427, 0xac2592}}, - {{0x12776fb5, 0x173bfb39, 0x07879e85, 0x0c83138d, 0x0ed7c6f8, 0x009f75ec, 0x02ea143b, 0x070e1b75, 0x6c79a0}}}, - /* 7*16^41*G: */ - {{{0x128de7e3, 0x130be090, 0x1aa65b66, 0x08558757, 0x031bf868, 0x07ded3da, 0x0ea21cc8, 0x095d2f3e, 0x7bc337}}, - {{0x0e6e5e29, 0x1d059975, 0x10333c19, 0x05b67369, 0x1acbd55f, 0x1bd73725, 0x19778031, 0x048c10a9, 0xb431f0}}}, - /* 9*16^41*G: */ - {{{0x035e057d, 0x1659191c, 0x162696d2, 0x1e21b5ed, 0x1119329c, 0x0397e1a0, 0x0ac9a2f2, 0x128a75c0, 0xbf9c14}}, - {{0x0da20fea, 0x1ab25941, 0x1711e6db, 0x173c3038, 0x1a542440, 0x189f82e3, 0x0f83ce14, 0x13e4be47, 0x92acb8}}}, - /* 11*16^41*G: */ - {{{0x021d6584, 0x1566be10, 0x0cf67974, 0x00bac887, 0x1014ef27, 0x1ed1ad6f, 0x1e2a5ba5, 0x0736af09, 0x55bf08}}, - {{0x0ed744ea, 0x0ab27a14, 0x19696a03, 0x1c284055, 0x07dcf089, 0x1fb5d45e, 0x133c9eb2, 0x067c96c3, 0x3d9807}}}, - /* 13*16^41*G: */ - {{{0x01068c5e, 0x0b4efb72, 0x195cf437, 0x0bdcdc97, 0x1d4872a4, 0x10a73c0a, 0x15467cab, 0x02ca66f1, 0xfcf24e}}, - {{0x07c19d75, 0x10fa29f9, 0x052156dd, 0x0ed49650, 0x0e7aee91, 0x0f10dac9, 0x1f8d719d, 0x1ca66dff, 0x186bb0}}}, - /* 15*16^41*G: */ - {{{0x020da860, 0x1becaf83, 0x12744022, 0x08a35490, 0x11f2f843, 0x1b29a1ec, 0x1fb287f6, 0x1a05ea2c, 0x7bc280}}, - {{0x07aac76d, 0x11488208, 0x1058cbaf, 0x03345fb9, 0x0e6e0f2e, 0x15fd382f, 0x07978989, 0x0ef777a6, 0xb33f6d}}} - }, - { - /* 1*16^42*G: */ - {{{0x13c4a205, 0x097961b4, 0x042a1229, 0x15bf13ea, 0x129fcde1, 0x0ab83adc, 0x0f139199, 0x0a2c60b7, 0xb6e06c}}, - {{0x1db36d05, 0x1bfa6c32, 0x0aa7e1d4, 0x13283350, 0x0d73b63f, 0x189373cf, 0x0fd71787, 0x0f843664, 0xbdb427}}}, - /* 3*16^42*G: */ - {{{0x19e27907, 0x17c10fb7, 0x167935a4, 0x15a96711, 0x1bd68771, 0x0eaeb7ef, 0x1139ace5, 0x07f08483, 0xed9e4}}, - {{0x0e78c4fb, 0x09fa7a83, 0x0e86417c, 0x0a39fd71, 0x00e0ce91, 0x07ec7589, 0x0d1fd6f0, 0x095fed64, 0xb5af87}}}, - /* 5*16^42*G: */ - {{{0x15b38f54, 0x1682b929, 0x0bc1f38d, 0x150c1cb9, 0x0e1f92e2, 0x146da47f, 0x1df71549, 0x0200edb1, 0x57a7e4}}, - {{0x045f2809, 0x1d3c0f31, 0x01fae9d7, 0x0edc7352, 0x0dd21dfd, 0x0511de41, 0x14906532, 0x00791d95, 0xfd7f0f}}}, - /* 7*16^42*G: */ - {{{0x07a79593, 0x17f5dfcd, 0x17125e51, 0x14e493a4, 0x05cf3347, 0x0d92c665, 0x16fbd4b6, 0x1c5e7deb, 0x24799a}}, - {{0x10920d55, 0x11c46bae, 0x1ac4e635, 0x086c3f37, 0x1e300999, 0x08d4e9b1, 0x0deccb0f, 0x04c5d90f, 0x9436b5}}}, - /* 9*16^42*G: */ - {{{0x0bf5abdc, 0x010b75a8, 0x02d94198, 0x19a75f7a, 0x15d60456, 0x08e58406, 0x009bb4c4, 0x18d1098e, 0xf15017}}, - {{0x0def85b7, 0x1aef15c5, 0x0e15612d, 0x18ceb84f, 0x1e232cbd, 0x1a0f1fe2, 0x0aa3b360, 0x03858be0, 0xdea7ef}}}, - /* 11*16^42*G: */ - {{{0x1e78e9b1, 0x0f92958f, 0x10507a1a, 0x11cdb89d, 0x0dfcc897, 0x018fba89, 0x1aa9b83e, 0x01f13697, 0xe196e2}}, - {{0x0a77eed7, 0x00bab0fe, 0x1b4d7d11, 0x1a02257d, 0x0ed9a908, 0x045f3b59, 0x1698a990, 0x10bf0350, 0xa5d66d}}}, - /* 13*16^42*G: */ - {{{0x1b1cb64b, 0x17719f2b, 0x02b0f55d, 0x13ca4ac3, 0x1ed14d60, 0x1e6b8a9c, 0x0c0bce5f, 0x1bcd8360, 0x7779f5}}, - {{0x1aba3aab, 0x070c68e5, 0x0aa54cf6, 0x10528479, 0x0e3fae2a, 0x189a53d1, 0x1afab7ea, 0x07e8e987, 0x9a842}}}, - /* 15*16^42*G: */ - {{{0x11d1b492, 0x16c2c3b4, 0x0669bd4f, 0x00c31840, 0x08ce8dfa, 0x16cd5759, 0x0bc4797d, 0x097c8474, 0x8605b9}}, - {{0x18ac6598, 0x18ebbdfb, 0x07a49715, 0x06a4da90, 0x1d1a8ee2, 0x170610a1, 0x1d63cfbd, 0x050fbcea, 0xa8e561}}} - }, - { - /* 1*16^43*G: */ - {{{0x09aa52df, 0x06afa725, 0x0a989fcf, 0x08a56368, 0x1ece618c, 0x00c4ecc8, 0x0fddb6f1, 0x192fec11, 0x45a511}}, - {{0x125ec16c, 0x1a95e890, 0x0a55739e, 0x03364fa4, 0x05ad25a9, 0x19bfe5b1, 0x0db4ff8c, 0x18ee7d53, 0x73be0e}}}, - /* 3*16^43*G: */ - {{{0x0e75bc7f, 0x0b3a9f7d, 0x1dfec7d9, 0x0e2e1b6d, 0x14c7b95c, 0x07890be6, 0x0d0e3bd0, 0x09fce572, 0xb57ac}}, - {{0x0972e9a9, 0x078b96e8, 0x127f1881, 0x12d81c80, 0x094fab1f, 0x1a67d2bf, 0x0ed7ca30, 0x104ef53e, 0xceedbf}}}, - /* 5*16^43*G: */ - {{{0x033125ff, 0x1ba19e7c, 0x16a05084, 0x0aaf60b4, 0x0ae99354, 0x016ce50e, 0x05233d1a, 0x1f6dc97a, 0x1178b3}}, - {{0x18486abd, 0x007cb84e, 0x195346fa, 0x115b9a11, 0x10ed10dc, 0x131bf518, 0x056ce0b7, 0x1d53757b, 0xdfd697}}}, - /* 7*16^43*G: */ - {{{0x1662d955, 0x19b4ae67, 0x033913ce, 0x09ad0b69, 0x15693844, 0x1dbf4693, 0x041fe2a0, 0x104df29d, 0x8ac7a0}}, - {{0x046b3dae, 0x03516df3, 0x1b04e36f, 0x09038b7a, 0x19ad9e3f, 0x1291a65a, 0x0c73275f, 0x1241e664, 0xc80f40}}}, - /* 9*16^43*G: */ - {{{0x088803e5, 0x06c3cd6f, 0x0d1972df, 0x156f9c1a, 0x09e02cc1, 0x1d43802b, 0x08446adf, 0x050b3bbe, 0xc0f48b}}, - {{0x076619ee, 0x14991014, 0x00a3b6e9, 0x1c9c0e17, 0x0d7d3932, 0x12393f30, 0x08da7269, 0x16df1079, 0x3d4326}}}, - /* 11*16^43*G: */ - {{{0x1e1f515c, 0x0b6b384c, 0x194e6bea, 0x09146442, 0x1b8c0e2b, 0x047087fb, 0x19b68067, 0x01e06a2e, 0x2ce870}}, - {{0x052eed6e, 0x08c9b24c, 0x10f54b25, 0x13b9a7c5, 0x15d2ca7a, 0x17a17bf7, 0x129eeb2c, 0x09e76bd8, 0x73879f}}}, - /* 13*16^43*G: */ - {{{0x04dcf274, 0x0d51bbaf, 0x0b3a8911, 0x0400d059, 0x0ca1d807, 0x0dd87ebe, 0x04245178, 0x0c3b96f8, 0xfac442}}, - {{0x112f0472, 0x1b4c3007, 0x11652c58, 0x004f8c4e, 0x097bd732, 0x11eaea77, 0x02a1f31c, 0x18c2acd5, 0x9713fd}}}, - /* 15*16^43*G: */ - {{{0x1dc39d21, 0x1af25b55, 0x06b71a0a, 0x0e7d7a81, 0x12813683, 0x0f21d0cc, 0x18011964, 0x02cb6807, 0xf891e6}}, - {{0x05ca579f, 0x0c8470be, 0x11809535, 0x12fd89ea, 0x1c43b73a, 0x1c54716d, 0x13b462ba, 0x162577bf, 0x129f53}}} - }, - { - /* 1*16^44*G: */ - {{{0x1076f57b, 0x0678d5cc, 0x12b181ca, 0x170dc79d, 0x0a53f030, 0x11a80e79, 0x1e72e49f, 0x0ac91018, 0x20e118}}, - {{0x0da7afe6, 0x0c1df6dd, 0x186dc7a1, 0x01b93681, 0x1e9979fe, 0x01f1fdb6, 0x1bdcc6f7, 0x0a55886f, 0xff67b3}}}, - /* 3*16^44*G: */ - {{{0x0b661da4, 0x04f1d76a, 0x0a129721, 0x14a358c9, 0x01a21940, 0x1fec8183, 0x1b3a3df1, 0x0b770cc0, 0xffca2a}}, - {{0x0f9b8a5a, 0x0c241af5, 0x1a1fdbe2, 0x1f0f5bca, 0x06c8c478, 0x04d0a47a, 0x172294f3, 0x1c656e39, 0xce1cb0}}}, - /* 5*16^44*G: */ - {{{0x1c8cfd22, 0x0560f09c, 0x0daf960f, 0x160ce36c, 0x1354a4e2, 0x1a8a86d6, 0x1aad8d94, 0x1dbff822, 0xff209c}}, - {{0x13bc5535, 0x1c4d8a74, 0x1a12e508, 0x1e972592, 0x1f1c80d4, 0x00e92667, 0x1df881f5, 0x12e8d3a1, 0xad79f3}}}, - /* 7*16^44*G: */ - {{{0x0f4e983e, 0x003f2c2c, 0x05fddf3a, 0x1cdd90e0, 0x14b156d9, 0x0040699d, 0x0ea56181, 0x05a160f3, 0x33d5f0}}, - {{0x11ea37a9, 0x0b86dc3c, 0x18c3255b, 0x035524b2, 0x1a1eb7a7, 0x0b0b2add, 0x1e11cf0f, 0x0eda7388, 0x1eb5a}}}, - /* 9*16^44*G: */ - {{{0x01e52a73, 0x14ad3cfb, 0x01686f2d, 0x0622d92e, 0x15e65d0e, 0x1a6cd6dd, 0x1a42a7a5, 0x07b4c4c2, 0x8f1bd2}}, - {{0x0bea8f2e, 0x1ed0a28f, 0x06142a15, 0x0a05cc96, 0x1eade590, 0x0f2183a1, 0x02e2e1da, 0x0c7275b5, 0x4c7a8f}}}, - /* 11*16^44*G: */ - {{{0x1d2bc078, 0x0217f617, 0x1cfbd696, 0x00ec0a53, 0x080aec4a, 0x0c5bed6c, 0x1fcfb98a, 0x1fdef6c6, 0x963bc9}}, - {{0x1afb8657, 0x0ed918fa, 0x10e8f09f, 0x180851e8, 0x0a4f1c5e, 0x128494c0, 0x188a028f, 0x07f9a3ce, 0x7ed338}}}, - /* 13*16^44*G: */ - {{{0x0fb608ad, 0x038f3b75, 0x03f64e9a, 0x00aca9b1, 0x0bc49748, 0x16ee5be4, 0x011398c6, 0x15b0c3b5, 0x89fe6d}}, - {{0x064d4dad, 0x00a0373c, 0x1c2a1ed8, 0x13aa27c1, 0x1df39aea, 0x1effdb92, 0x03f21ed5, 0x10463e9d, 0x289827}}}, - /* 15*16^44*G: */ - {{{0x19ae4a29, 0x18c4c0d8, 0x08ca82c1, 0x1fb4dd44, 0x06984df2, 0x1d62708b, 0x1d654435, 0x0fe77af2, 0xc34804}}, - {{0x0eb09235, 0x04acd626, 0x126bafcd, 0x05d33e0a, 0x1ae9a842, 0x06e90706, 0x11584f6a, 0x1e40ad43, 0x584781}}} - }, - { - /* 1*16^45*G: */ - {{{0x19273a8f, 0x08a29744, 0x13f552b7, 0x1a8f1cd2, 0x1dac93fd, 0x163fefeb, 0x09ec0c63, 0x1f0e4740, 0x5c9cc4}}, - {{0x1ce80d6e, 0x0ed6534a, 0x06b2ad6b, 0x006ceb42, 0x0af964f0, 0x0c4e9b84, 0x0966a09d, 0x0f43bfda, 0x84efe0}}}, - /* 3*16^45*G: */ - {{{0x0883e382, 0x0464c2a2, 0x154dbce3, 0x009f9dea, 0x07431d06, 0x001ca900, 0x01716f89, 0x12577bfb, 0x5ac8e1}}, - {{0x1dfeaadc, 0x09b9ecde, 0x13674b94, 0x0dd9427a, 0x03976de7, 0x1ff9784b, 0x1200e723, 0x00098f51, 0xfcb7e5}}}, - /* 5*16^45*G: */ - {{{0x0f01a3e8, 0x052183bf, 0x120253af, 0x16ca865c, 0x07362c6e, 0x0ea2706b, 0x0460b545, 0x1316f224, 0x99dc06}}, - {{0x00f61114, 0x14322ff2, 0x1e3ca514, 0x0ce069af, 0x00044b7a, 0x0388b8ec, 0x0af1a5eb, 0x1ba47730, 0x67c69c}}}, - /* 7*16^45*G: */ - {{{0x0cd535ab, 0x01fbd802, 0x1d9370ce, 0x09b107d0, 0x1b9f3772, 0x01abe7e7, 0x18591009, 0x0c31c080, 0xabe2f3}}, - {{0x117b9c1a, 0x0388d9a2, 0x0b237664, 0x1cf43187, 0x1f7957fd, 0x1f959016, 0x0a4f7836, 0x0996eab6, 0x4f02d6}}}, - /* 9*16^45*G: */ - {{{0x0909970c, 0x1a5b359b, 0x19b93836, 0x11b74b33, 0x0099e451, 0x1d8fbbf3, 0x1c84df1b, 0x1af1873c, 0x227cd0}}, - {{0x1f809727, 0x02d25718, 0x0e67b10a, 0x01d87efd, 0x15defa21, 0x043a0e7f, 0x04761f5b, 0x0e390327, 0x2225e7}}}, - /* 11*16^45*G: */ - {{{0x09e65b59, 0x0cd6fe4c, 0x113fddf3, 0x02045efa, 0x1053b7a4, 0x14985466, 0x16da09fb, 0x10415db8, 0x363146}}, - {{0x09b4c2cf, 0x0050b213, 0x116dba72, 0x0792076b, 0x07fc1c14, 0x1c7c9011, 0x0a4a3a09, 0x0c42f12e, 0x1d87db}}}, - /* 13*16^45*G: */ - {{{0x0d4c2506, 0x0bd8ac5e, 0x07a7ebc0, 0x18bb8fe3, 0x11fec5b6, 0x14670c4e, 0x028f9d29, 0x16cd0d63, 0xf65ed6}}, - {{0x1913dfac, 0x0296e129, 0x15950af3, 0x11df8699, 0x0e7bd412, 0x0e17e9bb, 0x0ba14957, 0x0d065175, 0xd6d0bc}}}, - /* 15*16^45*G: */ - {{{0x1b47a80b, 0x0f27cba9, 0x0925d5e0, 0x0f8b4cc8, 0x1dba8ff9, 0x0e13b7d5, 0x0d5ca776, 0x1f423ec2, 0x66a0de}}, - {{0x1f795e8b, 0x1b8cafc7, 0x1bb74803, 0x014850a4, 0x0f474c23, 0x0f92b0d7, 0x09072b63, 0x0dbc6f59, 0x3e24aa}}} - }, - { - /* 1*16^46*G: */ - {{{0x08523eb3, 0x1eecd599, 0x1b1b12b9, 0x1474eaaa, 0x1cde3351, 0x0c22279e, 0x16ad1ab0, 0x1d7f1516, 0xbaffd4}}, - {{0x15acf387, 0x0bc18066, 0x122dbb86, 0x02399f7e, 0x0c09c245, 0x0759bcad, 0x1a0c00ea, 0x18bb792b, 0xfa93d}}}, - /* 3*16^46*G: */ - {{{0x14737641, 0x004cda77, 0x10b84eb4, 0x158182cd, 0x03fb71af, 0x1a891b2b, 0x07b5dde2, 0x04488391, 0x91b445}}, - {{0x0101bbe0, 0x1289594f, 0x01df40fc, 0x0fb8ccdc, 0x1b428c9d, 0x11ad5817, 0x05d8b04c, 0x17a6ffb5, 0x3f4463}}}, - /* 5*16^46*G: */ - {{{0x06dd01df, 0x1515d5c1, 0x03fbee71, 0x1dfeeca7, 0x09165743, 0x1363e434, 0x01ea8dfa, 0x0bbd05b6, 0x296d13}}, - {{0x0a3a0dc8, 0x0a869905, 0x199bd812, 0x15ec31cb, 0x177cadff, 0x094bbb63, 0x1790ae1c, 0x1bb25c28, 0x14054e}}}, - /* 7*16^46*G: */ - {{{0x1650f5dd, 0x13f37836, 0x046cb231, 0x1fc24843, 0x04a9654f, 0x0178f8cf, 0x08c63c4f, 0x1e7226cf, 0x4b0942}}, - {{0x1aeddc6d, 0x1752de63, 0x19ce98b0, 0x18cf05c9, 0x1c25f023, 0x0080ab09, 0x0f038157, 0x14c6cd95, 0x7432aa}}}, - /* 9*16^46*G: */ - {{{0x04e4a96f, 0x11baf478, 0x1956c51e, 0x10c5686a, 0x0e4af188, 0x0dc7e269, 0x046a0cfb, 0x14c5fd98, 0x36377}}, - {{0x11e08cdb, 0x1d7dbf02, 0x0244c9a2, 0x13184286, 0x06263840, 0x062abc2a, 0x1e0e364c, 0x03a6a9fb, 0xa1de19}}}, - /* 11*16^46*G: */ - {{{0x079b5a59, 0x00fe9f0b, 0x1a798a85, 0x03d13d64, 0x03251c62, 0x16ab84ec, 0x058af2ef, 0x1ee61ebc, 0xa1041a}}, - {{0x0c5514a3, 0x0695a011, 0x0b19b676, 0x00d21c3d, 0x02afbfb3, 0x086c39de, 0x0c650899, 0x0d551eb1, 0xad4217}}}, - /* 13*16^46*G: */ - {{{0x0ddd597b, 0x1746d836, 0x015d637a, 0x1262e199, 0x12007d88, 0x0d687cf4, 0x191c0cdc, 0x15a163ca, 0xda2167}}, - {{0x1de7fa04, 0x140b93f1, 0x13e7d189, 0x1c54a428, 0x0ebf6cdd, 0x180753cc, 0x14d87fd9, 0x16c4a8dd, 0xa21992}}}, - /* 15*16^46*G: */ - {{{0x13f7dbb0, 0x09a51115, 0x0fca7026, 0x1c47b84d, 0x0f29df4e, 0x1dc390b2, 0x19e2f218, 0x1846fed8, 0x1c3fdb}}, - {{0x12e16d32, 0x1265ee4b, 0x083e2b75, 0x0c8c7000, 0x118d41f0, 0x129ca525, 0x004fc2ba, 0x0206f253, 0x39260f}}} - }, - { - /* 1*16^47*G: */ - {{{0x1a111101, 0x1a9046c5, 0x16cf17e0, 0x1e1634ed, 0x04c96479, 0x11a692bf, 0x1d9bb48a, 0x0131f9da, 0x6ad2a}}, - {{0x1fb37ef4, 0x0d3dd4ea, 0x03a26bb0, 0x053b056e, 0x162a0de4, 0x000ddcf5, 0x18d56693, 0x038b1f0b, 0x2d5b8b}}}, - /* 3*16^47*G: */ - {{{0x102bef6f, 0x17e1c23b, 0x0c7b90dd, 0x1c9e308a, 0x0d475bba, 0x05eb35ec, 0x15c813de, 0x0aad8779, 0xf1a2ca}}, - {{0x0f6c1ca3, 0x0d968fec, 0x154ad004, 0x08fd503f, 0x00168b0b, 0x0a0bee01, 0x04fb7d15, 0x15e09106, 0xb39b59}}}, - /* 5*16^47*G: */ - {{{0x00455367, 0x030147e5, 0x1584f820, 0x09e59049, 0x11851e6c, 0x00b2c75f, 0x00c3b864, 0x093fc770, 0xe924ad}}, - {{0x08257e92, 0x1e8c67c1, 0x099d4ad7, 0x1463549f, 0x1bb6f52d, 0x029c9eb7, 0x1b55d482, 0x12f34287, 0xfcc97d}}}, - /* 7*16^47*G: */ - {{{0x02f8f1e7, 0x08f849ca, 0x147e78ba, 0x0954ba9b, 0x122f68dd, 0x09a882fd, 0x09be802e, 0x0fb8bee0, 0xf49d9c}}, - {{0x114d9972, 0x1114558c, 0x135ea0e4, 0x0002789c, 0x0f67901b, 0x09d9dcca, 0x12b9ab97, 0x08407c75, 0xf5585d}}}, - /* 9*16^47*G: */ - {{{0x1b219a79, 0x19d4b3bf, 0x0609e9de, 0x19a882fd, 0x189e65c4, 0x01aabaa8, 0x1522c38f, 0x007c8d53, 0x28b04d}}, - {{0x102dbe24, 0x05fbe6c8, 0x0012f97e, 0x0cd99f0c, 0x0206b861, 0x12b90c1f, 0x1c51673f, 0x13cb4299, 0xf658da}}}, - /* 11*16^47*G: */ - {{{0x17774af9, 0x14116ce2, 0x1182b62c, 0x0d74ca22, 0x0efb54c1, 0x01c94435, 0x1a4f5a14, 0x17cf983f, 0x3f4766}}, - {{0x1d4de990, 0x1e6bfb26, 0x0dcc9bfd, 0x1299fbf3, 0x05f511ca, 0x1c483737, 0x12e8eac5, 0x1ad4e663, 0xcc810d}}}, - /* 13*16^47*G: */ - {{{0x08e57705, 0x020cf8f2, 0x1356639e, 0x1d6ff590, 0x1361721c, 0x0d5a0eb7, 0x19e47cab, 0x00581f1d, 0xe3249e}}, - {{0x18caec0c, 0x0a58cf41, 0x1ce10882, 0x128bae2c, 0x06b5a501, 0x1c60f924, 0x141f72dd, 0x10e026d2, 0xa66665}}}, - /* 15*16^47*G: */ - {{{0x125b93ac, 0x1c5e757d, 0x01fe34b1, 0x0404a20b, 0x1b4e917e, 0x13b49efd, 0x1872f7e7, 0x017bf6f2, 0xa68958}}, - {{0x0f589aab, 0x11e8e26b, 0x113f4eba, 0x03f02fb3, 0x19ff2fcf, 0x1780af82, 0x00faa9fc, 0x12969e0f, 0x4657ca}}} - }, - { - /* 1*16^48*G: */ - {{{0x113728be, 0x07907fd9, 0x11ae529b, 0x072b2347, 0x15fc5964, 0x1fc1a218, 0x09d89cdb, 0x0ef4f092, 0xa6d396}}, - {{0x0357f5f4, 0x15d5c19e, 0x010166fc, 0x15241845, 0x1ecdf824, 0x1d5e9693, 0x00599ae2, 0x0e936171, 0x674f84}}}, - /* 3*16^48*G: */ - {{{0x0f15d864, 0x02a5ab4e, 0x13234f30, 0x0dfb8d43, 0x0cf35240, 0x1673df13, 0x0c36bf23, 0x1af8bbdb, 0x7ef66}}, - {{0x140907fe, 0x0312a13b, 0x1392a2d5, 0x0e1c7639, 0x1505e9f4, 0x062910fe, 0x1a941b50, 0x0bb713bc, 0x2db332}}}, - /* 5*16^48*G: */ - {{{0x17c7c05e, 0x14a8a1e0, 0x19505ab1, 0x07972a59, 0x08c0bb28, 0x1397baf9, 0x118053ce, 0x0bf80db8, 0x82df4e}}, - {{0x18fff26b, 0x0b09e816, 0x0b6cc02e, 0x0bb28d08, 0x1cbd1cf1, 0x0b10890b, 0x08289d48, 0x193192c8, 0xe4e188}}}, - /* 7*16^48*G: */ - {{{0x140368b0, 0x0570ea0a, 0x1ba52760, 0x09845f1f, 0x07a62132, 0x0dc69c72, 0x11a9f679, 0x13782561, 0x261efc}}, - {{0x1deb011f, 0x1d692acd, 0x06d74c04, 0x0817c3c7, 0x1ff797e3, 0x02966b27, 0x13a7f722, 0x1b7c70df, 0x8a9d2a}}}, - /* 9*16^48*G: */ - {{{0x15eb8034, 0x0819f4a8, 0x1a3292bc, 0x1666bead, 0x1692df30, 0x1f2cecf3, 0x1e4526a9, 0x1aef4584, 0x6d48df}}, - {{0x1ab0ce30, 0x039843d2, 0x0fa2587a, 0x0421d454, 0x14763080, 0x1cb24f02, 0x04bcf579, 0x08a2cbba, 0x3cb472}}}, - /* 11*16^48*G: */ - {{{0x140535c8, 0x08a1efe2, 0x036c4fad, 0x014ac619, 0x14e6f65f, 0x11fda7e2, 0x048e9244, 0x03cf7731, 0x93a5c0}}, - {{0x1d59b844, 0x04aba041, 0x16fb7ff1, 0x02c40926, 0x1a5c166a, 0x021ac70a, 0x0bd305aa, 0x12093018, 0x2d440e}}}, - /* 13*16^48*G: */ - {{{0x1e2047ba, 0x130d2b34, 0x0c3d94a8, 0x0e0932d7, 0x07031e54, 0x10700beb, 0x0aeecd76, 0x0522c24e, 0x3fb0b9}}, - {{0x1db24158, 0x1ff66a76, 0x1c0274d5, 0x0415cee2, 0x06dc86c4, 0x110e4cb3, 0x1e5329c9, 0x1cd042fb, 0x9d467a}}}, - /* 15*16^48*G: */ - {{{0x02df71c1, 0x05ededd7, 0x0edc8e80, 0x030d7d5f, 0x1e4381c3, 0x1dd4ef19, 0x0f5741d8, 0x073c11d0, 0xdab094}}, - {{0x04c3a1e3, 0x039a4209, 0x0d138eee, 0x0c661949, 0x00b3d6e9, 0x14379069, 0x13bce16b, 0x03ca89c3, 0x763cbc}}} - }, - { - /* 1*16^49*G: */ - {{{0x0514c6fd, 0x177b17fa, 0x0ac04f9b, 0x10769a1b, 0x15936fd6, 0x0dab887f, 0x1380cf53, 0x1001139e, 0xac25da}}, - {{0x05830541, 0x05a9cbb8, 0x0efcde98, 0x1307d048, 0x1338c810, 0x1498950d, 0x11ee20f6, 0x130b9689, 0xebc69d}}}, - /* 3*16^49*G: */ - {{{0x12fd0e3d, 0x0ca0e3f1, 0x09eb5820, 0x03c9b8a8, 0x05547e63, 0x04338f0b, 0x122ed35d, 0x0d893747, 0xeea7e6}}, - {{0x191d5868, 0x0208fb46, 0x0678f304, 0x175b4460, 0x17d985ac, 0x1f93df4d, 0x0984a210, 0x0b73f112, 0x83fed4}}}, - /* 5*16^49*G: */ - {{{0x0ccb63b3, 0x0cf8a793, 0x10239744, 0x1ffcd888, 0x1c67b7dd, 0x0a59aa01, 0x06f6eb46, 0x1a7d27c4, 0x9a3de2}}, - {{0x1df93fcf, 0x0e2994bb, 0x16089800, 0x003b3fde, 0x13c4c49c, 0x139b7740, 0x0b22027c, 0x120c2222, 0x2f809b}}}, - /* 7*16^49*G: */ - {{{0x163f1117, 0x07651a6e, 0x1fdb62f9, 0x12dee174, 0x1adaf348, 0x0698091f, 0x0b6c1440, 0x1e96a772, 0xa7c382}}, - {{0x1934cb9a, 0x091062f0, 0x1129a330, 0x1d6edda7, 0x1cfb5ae4, 0x1bbbb82e, 0x1e201167, 0x022cec37, 0x1b91e5}}}, - /* 9*16^49*G: */ - {{{0x06774a96, 0x05e40e2d, 0x0e38fa14, 0x063fb230, 0x0f497e82, 0x1dfe41d3, 0x084e1c50, 0x1319b0c2, 0x555aa9}}, - {{0x06db0e34, 0x0a04b96c, 0x189be9a7, 0x1aba9791, 0x0bbb89a0, 0x00f389a8, 0x11a66751, 0x0d1a40f7, 0xb05328}}}, - /* 11*16^49*G: */ - {{{0x0f7dac7d, 0x17bf779d, 0x0904848c, 0x0e572422, 0x1c369165, 0x0bc7c6bb, 0x0b5ed633, 0x0b66914f, 0x1a42f}}, - {{0x0195e46e, 0x1c4a518c, 0x13aa5ac9, 0x15e52651, 0x19216172, 0x1caa5c5f, 0x1e04d25f, 0x070aa40e, 0x957a9c}}}, - /* 13*16^49*G: */ - {{{0x002afc36, 0x015d0ea1, 0x0c1c74f8, 0x1bddaa28, 0x1d3a3134, 0x04f78da2, 0x18f4e96c, 0x06fd60b9, 0x4b47f5}}, - {{0x0f8133ff, 0x144fbb53, 0x17ef68d3, 0x1597d364, 0x1f573345, 0x037d0746, 0x1c30b72c, 0x0073390b, 0xf2fc45}}}, - /* 15*16^49*G: */ - {{{0x17d17f68, 0x15f971e3, 0x02eb61aa, 0x0b43bf97, 0x0418f791, 0x0b7a9b57, 0x033b5594, 0x1398a49d, 0x6b3dec}}, - {{0x09232402, 0x1d73d106, 0x1732da33, 0x0552d54d, 0x15d4747f, 0x00da0b66, 0x07bc1426, 0x06ffbdfb, 0xb86539}}} - }, - { - /* 1*16^50*G: */ - {{{0x0fd20bae, 0x0ea71bd1, 0x0d2a0455, 0x06ace5ab, 0x1343a260, 0x1d090bb6, 0x136409ee, 0x1db8779f, 0x285250}}, - {{0x14e0ab97, 0x0ef22ad2, 0x1bfcc8fe, 0x163459e3, 0x0c1716e9, 0x02568823, 0x1aa0fdca, 0x10de95af, 0x7866c0}}}, - /* 3*16^50*G: */ - {{{0x0636a50b, 0x0443b55d, 0x0dd465b3, 0x1dec2d57, 0x0baf65d2, 0x1d097e3c, 0x1d7160db, 0x0ca8bab4, 0xf1e3c5}}, - {{0x0b3128b6, 0x1bbc8a75, 0x0b5e9bb7, 0x1f4aeda4, 0x1f3136b7, 0x1533fb52, 0x139db1cd, 0x0f4dc3df, 0x12b884}}}, - /* 5*16^50*G: */ - {{{0x0e583340, 0x0bf8990a, 0x0d3cec94, 0x1836d6ba, 0x1228cf45, 0x06d5fd4d, 0x129db61f, 0x13903c26, 0x584d72}}, - {{0x14fb24b9, 0x17b72f4b, 0x05301c1c, 0x0ee14cc9, 0x0affa8f1, 0x1e2c9818, 0x02af34c1, 0x148ac1b0, 0x2fdd80}}}, - /* 7*16^50*G: */ - {{{0x0235809b, 0x1641f6f0, 0x1ae05ce4, 0x0e5be16b, 0x03c453c5, 0x0146e11c, 0x1df478b8, 0x001906fb, 0xbaaeae}}, - {{0x0154fd62, 0x0b0ec52e, 0x14b9f973, 0x18788543, 0x1f299835, 0x183de5a4, 0x0e02d288, 0x1067e649, 0x325788}}}, - /* 9*16^50*G: */ - {{{0x0d612268, 0x10021620, 0x17b405bd, 0x1eb3be14, 0x0b8b906c, 0x0f7d21ca, 0x0c69944e, 0x0c6c1842, 0x6c7e4}}, - {{0x060166a0, 0x05a5b009, 0x0b9c262f, 0x1b14b4f0, 0x053ca238, 0x03ae717a, 0x0335d1ff, 0x0bbee5bb, 0xcb6ad5}}}, - /* 11*16^50*G: */ - {{{0x012fbdc8, 0x0a1d1adc, 0x1038a8ef, 0x1c419545, 0x1a36db89, 0x1663db88, 0x10f96f0b, 0x1bd57acc, 0x64131}}, - {{0x09f99380, 0x09ff984d, 0x1ec08297, 0x15c4d163, 0x17598603, 0x006c9a4a, 0x00a3cace, 0x15865ace, 0x882c7f}}}, - /* 13*16^50*G: */ - {{{0x0bac9f32, 0x0f580032, 0x1a26c19d, 0x104398b2, 0x16400443, 0x00b7f0cd, 0x08de2859, 0x15984eb8, 0x366bb7}}, - {{0x1c85d47d, 0x17872e7d, 0x1c09a290, 0x19ca180f, 0x1cfc01fd, 0x01d5c6b0, 0x1c193c1e, 0x0e10f0b5, 0x7d107b}}}, - /* 15*16^50*G: */ - {{{0x06dd27eb, 0x1e5a9294, 0x0ed588c0, 0x18ab86f6, 0x032ecb98, 0x0871cddf, 0x1001ac9f, 0x04af98e7, 0xb767db}}, - {{0x0f65dac4, 0x0a90d23e, 0x1803b505, 0x0e016890, 0x1d85b64b, 0x05c0b5cc, 0x072d73ab, 0x1864c245, 0xdc1308}}} - }, - { - /* 1*16^51*G: */ - {{{0x1e07e4f1, 0x18f9d151, 0x17099f05, 0x0a28fba1, 0x0890e1fc, 0x15e03f7c, 0x19be0637, 0x00c5da06, 0xc472c1}}, - {{0x06b0daa9, 0x18e341ec, 0x0ad76295, 0x076f63c4, 0x067d885f, 0x15ad426b, 0x03a590ca, 0x00328bee, 0x41820e}}}, - /* 3*16^51*G: */ - {{{0x02f8acb1, 0x1b4a9a55, 0x0fc14fd0, 0x1acaa8c2, 0x0c31eb39, 0x1bd25c76, 0x0f5a1786, 0x0732a8bc, 0x86f88f}}, - {{0x05098a19, 0x05821688, 0x05949c45, 0x14c57dd2, 0x1b1214ee, 0x0bc7dac8, 0x035acdf2, 0x0d34d047, 0x2ccfdd}}}, - /* 5*16^51*G: */ - {{{0x1cadab66, 0x041bbdb7, 0x14d580b6, 0x0d46787b, 0x1f9a0e1c, 0x134b306c, 0x19d1f7dd, 0x03f93291, 0xa2a3be}}, - {{0x0c1aeb12, 0x1a509242, 0x002b497b, 0x1bd14a69, 0x15ee1fb2, 0x1f6ba691, 0x199c1941, 0x1cd6a497, 0xa93bd8}}}, - /* 7*16^51*G: */ - {{{0x007c25bf, 0x04e91099, 0x0b6025ee, 0x178eef7c, 0x080be82f, 0x09233be0, 0x16e4d9f8, 0x1daadcf1, 0x354e7c}}, - {{0x1a864211, 0x091d1cca, 0x082a8854, 0x0ead960b, 0x1e5585fd, 0x0c1252e7, 0x01c39baf, 0x1d377328, 0x629d62}}}, - /* 9*16^51*G: */ - {{{0x15e1dad8, 0x13ec1703, 0x112f4b92, 0x014f0b0d, 0x19f498b8, 0x07b90604, 0x016de6d7, 0x155ebbd0, 0xc751c9}}, - {{0x0e4afc8b, 0x09b59b09, 0x02a300b4, 0x112e1474, 0x1a4ffe6f, 0x00feb6e4, 0x178afad3, 0x06ff8f33, 0xcb9864}}}, - /* 11*16^51*G: */ - {{{0x099d9ba2, 0x1890d908, 0x0aa9d5f4, 0x0cafad2f, 0x19ca80cf, 0x09435a87, 0x0085e2ad, 0x08373a3a, 0xaee9cc}}, - {{0x1ed2ad58, 0x06b0241d, 0x05d2439e, 0x1cd1c4d4, 0x0b1f5312, 0x1dfd8063, 0x0dbdefa5, 0x005b6a54, 0xb72cf3}}}, - /* 13*16^51*G: */ - {{{0x094d208d, 0x1ff84124, 0x1ce46918, 0x1b51fe1f, 0x1f0cefb0, 0x1057958f, 0x1b15affd, 0x08d4f225, 0xd0d3f}}, - {{0x1d45d1b1, 0x117a9fbc, 0x0776aff5, 0x0781a34e, 0x09ff0b21, 0x06d32fc8, 0x05a6c11d, 0x1015c3ee, 0xdc371b}}}, - /* 15*16^51*G: */ - {{{0x19cfd890, 0x17411640, 0x01c45171, 0x0d86e6f8, 0x041e1cb3, 0x0c1c3f2a, 0x14d7d1f3, 0x0d68826e, 0x778d14}}, - {{0x16f057f2, 0x0d43fd3e, 0x1482b2b2, 0x148a911d, 0x0cd3796c, 0x18c6cbc3, 0x0bdca949, 0x02676023, 0x3c85ba}}} - }, - { - /* 1*16^52*G: */ - {{{0x039bb85f, 0x10784e1c, 0x14398b0c, 0x03f60d40, 0x13458010, 0x0164cd6a, 0x0cad55d6, 0x11a2ccc8, 0x55d539}}, - {{0x0fed936f, 0x1fb188c2, 0x0cf6787d, 0x1ad4fe30, 0x0a72ad90, 0x154f475d, 0x18b41671, 0x12093ff1, 0x576e22}}}, - /* 3*16^52*G: */ - {{{0x12ea285a, 0x03f15c90, 0x0e443470, 0x0383cdef, 0x0a7a39f0, 0x02c6eee0, 0x022de160, 0x011029f1, 0x1bb464}}, - {{0x107dc702, 0x006453cc, 0x0bea53b7, 0x05469732, 0x0a4fc1e5, 0x0cdc495a, 0x0496903f, 0x17f5f5c2, 0x8a3016}}}, - /* 5*16^52*G: */ - {{{0x1539785a, 0x08094806, 0x0a5fc051, 0x11a0ed70, 0x07a548c8, 0x1f133c31, 0x053b825c, 0x0e1c05f4, 0x4bc4e}}, - {{0x0a62e3bb, 0x1cc823ae, 0x0c9d70d4, 0x002ee4f4, 0x1fb4f877, 0x10e79f9e, 0x130e97d6, 0x04971969, 0x5729f2}}}, - /* 7*16^52*G: */ - {{{0x0114cfb5, 0x096a5d8f, 0x1569a8c4, 0x0c313547, 0x10876d13, 0x1cf0dbef, 0x05cd61dc, 0x1fb83f10, 0xd3e492}}, - {{0x097f7045, 0x075cd52b, 0x1d53bbef, 0x11e0dc8c, 0x1fea39c8, 0x133b5f8a, 0x122c7fb8, 0x014e7f18, 0x3604a7}}}, - /* 9*16^52*G: */ - {{{0x0c55ddff, 0x1133a5dd, 0x152de1c6, 0x1a367ec9, 0x1c1791da, 0x091887e6, 0x094e2939, 0x0ab0c508, 0xbebfc2}}, - {{0x1ea2f303, 0x0a6d8651, 0x02ea9c1b, 0x15045aca, 0x0576c3cc, 0x08e25bbb, 0x133a28e8, 0x0cb812c0, 0x850de2}}}, - /* 11*16^52*G: */ - {{{0x099ead51, 0x0d7a0f26, 0x164893a4, 0x06a87443, 0x184715da, 0x098e8b03, 0x1580beca, 0x1b8e7a41, 0x36e984}}, - {{0x0e0e5e3e, 0x17dcea13, 0x10a02bf1, 0x177d82e0, 0x12b203ba, 0x0fe4d671, 0x017d2fef, 0x08e437e9, 0x143771}}}, - /* 13*16^52*G: */ - {{{0x03093df0, 0x145bbdd9, 0x1d91935e, 0x1c4902ce, 0x193af785, 0x0a3caa6b, 0x12bbcc54, 0x00087ec0, 0x91b675}}, - {{0x12cc9f14, 0x06f461be, 0x12bd9fd7, 0x0d0bf1f3, 0x01c5d933, 0x1d6d4b71, 0x00351df1, 0x03cb0494, 0x7fedb}}}, - /* 15*16^52*G: */ - {{{0x1b7b8dc4, 0x11b3dc37, 0x06ce1228, 0x09260515, 0x02fac5b3, 0x1f0d01b0, 0x00f9f125, 0x18f43891, 0xc5d9c3}}, - {{0x1b2df0ea, 0x0b24bc68, 0x1f524dbb, 0x11ee5fa3, 0x10af3d0d, 0x01c302e2, 0x1e796023, 0x1c4b9fb6, 0x3e59b9}}} - }, - { - /* 1*16^53*G: */ - {{{0x12513926, 0x116de4e1, 0x1b217b31, 0x0d1281df, 0x03383cc2, 0x1d5925fe, 0x1c9a53fa, 0x08c79410, 0x884286}}, - {{0x0fb8a54d, 0x17214155, 0x16f05683, 0x1d6245d7, 0x01207ce0, 0x06d9b2ec, 0x1569a598, 0x1380385b, 0xf77842}}}, - /* 3*16^53*G: */ - {{{0x0520f1f1, 0x095d60cb, 0x1fdf693b, 0x03693cc8, 0x16f4ad7f, 0x1e8b4667, 0x00675697, 0x06deede1, 0x3bad9d}}, - {{0x1698df4d, 0x10cb8392, 0x0d9c961a, 0x1303449d, 0x00e80499, 0x1d3ecef6, 0x1966f367, 0x1c67c49c, 0x49f99d}}}, - /* 5*16^53*G: */ - {{{0x1185ae66, 0x18f22545, 0x09e0f7c2, 0x182db7df, 0x0118ba6e, 0x0fa9e892, 0x11b59e9f, 0x1635b618, 0xa6b3a4}}, - {{0x0bfbf21b, 0x1f5aa9fc, 0x0c92375e, 0x1e14bbeb, 0x1e8d8bcb, 0x148e6cb4, 0x188c4d86, 0x1aec7112, 0xcb6e8}}}, - /* 7*16^53*G: */ - {{{0x0c630e3a, 0x0b426727, 0x1cfc70aa, 0x00c182ff, 0x110c1f61, 0x11d3ec3f, 0x1293889f, 0x0b4d9222, 0x1f848f}}, - {{0x06ca610a, 0x176cffb4, 0x0d65c92b, 0x0724d7fc, 0x1a4264ba, 0x041e8d4e, 0x058e18a7, 0x0599a0df, 0xa02855}}}, - /* 9*16^53*G: */ - {{{0x041bcd10, 0x0ff79e6e, 0x0d138553, 0x12aaec8b, 0x02eb211b, 0x133be365, 0x0d622c68, 0x097d2938, 0xcfd1e5}}, - {{0x0a62e732, 0x000af5cd, 0x154e596b, 0x1322ba10, 0x12fafacd, 0x08dead82, 0x02ee715d, 0x0bec012b, 0xf4e31f}}}, - /* 11*16^53*G: */ - {{{0x028da5fb, 0x1d30ec91, 0x01c39c93, 0x097ebc55, 0x1291b90e, 0x0af1f3b8, 0x19544b1e, 0x01808d93, 0x4b3e73}}, - {{0x1c169e48, 0x1f8531c5, 0x08d1caef, 0x07423938, 0x0b48c65a, 0x1d03dc70, 0x03a7a032, 0x09b446cc, 0x8c4096}}}, - /* 13*16^53*G: */ - {{{0x1f894780, 0x0748d2c4, 0x06bb176e, 0x139946b1, 0x0d8f737e, 0x1c52a5a1, 0x1f9c7552, 0x1bee8871, 0xafe915}}, - {{0x1511d444, 0x1cb4aa9e, 0x102bd14b, 0x1d17ce75, 0x12e36909, 0x01a1199f, 0x1a1aa52d, 0x0811a408, 0x3caec3}}}, - /* 15*16^53*G: */ - {{{0x1182fa6e, 0x0d18fe5e, 0x00722bfd, 0x0c65bad3, 0x1c9e7c0a, 0x11d1b69a, 0x1215619a, 0x05021ff5, 0xc0548}}, - {{0x061cd145, 0x15e7f55b, 0x1db407db, 0x0cc8b096, 0x1602bf5e, 0x05c4a32e, 0x14cf46aa, 0x195a1e3e, 0x2f9cd2}}} - }, - { - /* 1*16^54*G: */ - {{{0x14441fbb, 0x105aead6, 0x1b44578f, 0x150a414b, 0x125559ea, 0x062af6dc, 0x0751fed8, 0x09c43bc4, 0xb4958c}}, - {{0x0add7118, 0x03f1e4fa, 0x118e1053, 0x13ec265a, 0x0b7e12db, 0x00fde1c6, 0x03bf9701, 0x17f32cc8, 0xfcd6e7}}}, - /* 3*16^54*G: */ - {{{0x171f07f1, 0x176b4261, 0x15c31296, 0x19db6e61, 0x0684b878, 0x105b2303, 0x11348cba, 0x0bcf6408, 0xb3a43f}}, - {{0x001dfda5, 0x1e6917a7, 0x12c3b314, 0x10ef419b, 0x15ee7ec7, 0x1139b4cb, 0x1ae1060c, 0x0b6491fa, 0x34c64f}}}, - /* 5*16^54*G: */ - {{{0x0b559d49, 0x1be4bd23, 0x1726d13f, 0x0368d21b, 0x008b148e, 0x17fec260, 0x052b0998, 0x0d348d7c, 0x452e98}}, - {{0x1a0d6ba7, 0x03e30236, 0x07b9095d, 0x050ad876, 0x1ee52598, 0x02bdb3b0, 0x0343d700, 0x11e32bf0, 0x8c5e8a}}}, - /* 7*16^54*G: */ - {{{0x13ce94da, 0x1bd33f5a, 0x00a79814, 0x049e84ad, 0x074ee8bb, 0x106e1d62, 0x0aed4737, 0x1a918dac, 0x19a7f5}}, - {{0x1025e7bb, 0x182238b1, 0x097ac0dc, 0x04a60d5c, 0x0a2e8fb6, 0x08ea2100, 0x170cbda9, 0x14f5260e, 0xa2504b}}}, - /* 9*16^54*G: */ - {{{0x147dc697, 0x0b4b6636, 0x1856e6ee, 0x1c315f6b, 0x06fa417e, 0x18595afe, 0x1370047a, 0x004149e6, 0xbdaf5b}}, - {{0x06a479e2, 0x088e5f3c, 0x0de91dee, 0x045cf10b, 0x1aa08551, 0x1af23dab, 0x0db233d5, 0x0d97bf50, 0x3cec0c}}}, - /* 11*16^54*G: */ - {{{0x0ce05e10, 0x1005c8db, 0x1841880a, 0x1ef93e87, 0x070db8ae, 0x1bff4267, 0x0576ae12, 0x1d2be73a, 0x265dba}}, - {{0x171324f4, 0x1bf80c58, 0x19319fff, 0x07e7267a, 0x15dcb066, 0x0745ab65, 0x1eb7cecf, 0x1a134606, 0x58df63}}}, - /* 13*16^54*G: */ - {{{0x13fe5938, 0x08ade2ad, 0x0db5f37b, 0x10607b6c, 0x068669ec, 0x04ea9d2b, 0x0e5a27dd, 0x07e2fccc, 0xc43e08}}, - {{0x183732f3, 0x13cbab76, 0x1101d1dd, 0x0460e2c4, 0x0402eab6, 0x0181d5e2, 0x1160d424, 0x12473f79, 0x54c602}}}, - /* 15*16^54*G: */ - {{{0x1dd52975, 0x18e387bc, 0x0d106030, 0x1e1fa60d, 0x066ba2bc, 0x086d3bd9, 0x121996b1, 0x0e0147f0, 0x7868f1}}, - {{0x1c626fac, 0x00b76a81, 0x05a4110c, 0x0df3d94d, 0x1276c68f, 0x10e36d88, 0x1b8444fe, 0x19e6242f, 0xe89097}}} - }, - { - /* 1*16^55*G: */ - {{{0x0e12e1df, 0x0127321b, 0x1d87412b, 0x0ffa16fa, 0x0027cd8a, 0x1f89d9a3, 0x0ad904d2, 0x12d11d26, 0xd0e091}}, - {{0x1fd28fbe, 0x132a26dc, 0x11ae37da, 0x19897b30, 0x1f867544, 0x105b48ed, 0x114ad3ad, 0x0b3fcfa2, 0x69c9a}}}, - /* 3*16^55*G: */ - {{{0x084aa098, 0x186c2880, 0x1b8f80ae, 0x02028152, 0x1fa8509c, 0x1ed65fe0, 0x03ace629, 0x0a942661, 0xb517a4}}, - {{0x0540efbf, 0x0025acfa, 0x0911ff58, 0x0916a8d2, 0x06fa3a4d, 0x1f17d879, 0x1e6983a8, 0x0fa183f0, 0xa3d87}}}, - /* 5*16^55*G: */ - {{{0x0744bfa1, 0x0cad6552, 0x04d90f5b, 0x0da4f9c1, 0x1e387cc2, 0x13896c79, 0x1bd9ef08, 0x07096a2c, 0xf8ec14}}, - {{0x12b65f6d, 0x14927319, 0x04001831, 0x06f58b87, 0x00f610a6, 0x07d934eb, 0x0698c8da, 0x164227f7, 0x761134}}}, - /* 7*16^55*G: */ - {{{0x1227a4bb, 0x1161df49, 0x03667cbd, 0x0d63e01f, 0x0f2e64be, 0x075690ea, 0x0b9e539d, 0x0f1b6f7f, 0x320cff}}, - {{0x10f3d2d4, 0x00e64835, 0x18be5c16, 0x0e46e813, 0x16299604, 0x0b512a7f, 0x1a4aadde, 0x1a80e550, 0xaf9fe8}}}, - /* 9*16^55*G: */ - {{{0x1c2ca683, 0x1adad2f2, 0x0569cdce, 0x19e6bc15, 0x1426a206, 0x0ee65aa1, 0x16145fb7, 0x0f8d4f5d, 0xc08de}}, - {{0x1db5f259, 0x12036dab, 0x1a9a31a4, 0x11af6fc1, 0x00e79c3c, 0x14ce6fe7, 0x1866df20, 0x10abd42d, 0xddb76d}}}, - /* 11*16^55*G: */ - {{{0x052ae5cd, 0x033d67c1, 0x1f75e187, 0x0ca5f5e9, 0x0390995b, 0x1bd22672, 0x10f4639b, 0x0d5a188f, 0xd1f8c7}}, - {{0x1e6d2dda, 0x15cbde1f, 0x027d3f1f, 0x15d02ad3, 0x1203239b, 0x0bd80fb0, 0x000ab1e6, 0x18cc241d, 0x74d45d}}}, - /* 13*16^55*G: */ - {{{0x0bdc603f, 0x1c803355, 0x17ff96ad, 0x1acb9acf, 0x020d8c96, 0x1f63133b, 0x03024f8c, 0x0d27e712, 0xa6cb83}}, - {{0x096befcc, 0x16701f06, 0x1985cd72, 0x1d82d498, 0x10b72fb1, 0x0ded2628, 0x0bf23cb6, 0x1c8c3e79, 0xd823c8}}}, - /* 15*16^55*G: */ - {{{0x02c374b0, 0x0f1d3097, 0x1c36d28a, 0x166b316a, 0x04ef0bf5, 0x04b8a921, 0x0c84dafb, 0x123d4d86, 0x8a6c9c}}, - {{0x178c08bd, 0x1fbe7c6d, 0x03d3560e, 0x0a69e868, 0x132a0461, 0x042ee480, 0x1ebde69e, 0x09ecb9bf, 0xe4bc7f}}} - }, - { - /* 1*16^56*G: */ - {{{0x0895df07, 0x1381f887, 0x01daf61a, 0x0be7f403, 0x08ffefd7, 0x03738670, 0x1fbbad6c, 0x0a84f07b, 0x68f6b8}}, - {{0x18712655, 0x063b7c53, 0x042fdfe4, 0x0527a5e6, 0x05028cf5, 0x0226fed2, 0x139bef20, 0x17525c81, 0xcbe1fe}}}, - /* 3*16^56*G: */ - {{{0x1aa89692, 0x00c7d119, 0x1308c239, 0x1611adf2, 0x0a776713, 0x1320920c, 0x1d37a65b, 0x0e302cd1, 0x3bdfca}}, - {{0x1a510308, 0x1ededa18, 0x18bbc4e4, 0x1818c68b, 0x05333c7d, 0x10a8d76d, 0x1ee12509, 0x0d0aca2c, 0xa721f}}}, - /* 5*16^56*G: */ - {{{0x037ea1d7, 0x1cd91a16, 0x06ab9341, 0x126cb1f1, 0x19e4fb23, 0x02a928c6, 0x0158d4ca, 0x12b6ea42, 0xaca8ac}}, - {{0x1ba973a2, 0x0f7d8824, 0x0e4d7a77, 0x1b7fb882, 0x12189e1e, 0x0625c943, 0x108250c1, 0x0cfbaeb9, 0x7f12c5}}}, - /* 7*16^56*G: */ - {{{0x13245b7f, 0x0d93c0e6, 0x165fefd7, 0x1acd2d20, 0x05311a37, 0x10d7cc6c, 0x103881b0, 0x009b6ccf, 0xfa9047}}, - {{0x0ddf6bef, 0x1c19ef8a, 0x13c751fb, 0x1dd9a4c4, 0x1c189cb9, 0x11f6a078, 0x1a90b5be, 0x06ce9506, 0x1a1c8c}}}, - /* 9*16^56*G: */ - {{{0x17f0953a, 0x10fbc7eb, 0x0550e6ad, 0x122907fe, 0x092a8184, 0x1c70e97d, 0x163359ca, 0x15723eaf, 0x1d431a}}, - {{0x1d68f260, 0x1e2cebb4, 0x1c1f9f05, 0x1c535210, 0x1fae0f48, 0x0641e70a, 0x087af14c, 0x1877e322, 0x8d667}}}, - /* 11*16^56*G: */ - {{{0x05227c70, 0x1188b89b, 0x08fa9c16, 0x17d56667, 0x1c60ff32, 0x19ad9718, 0x04df7692, 0x01ab47c2, 0x6deeea}}, - {{0x0369b9b7, 0x0b6d1c08, 0x0420f6eb, 0x15d83cad, 0x0cc84287, 0x05d7f7b5, 0x19000053, 0x01f8e887, 0xcbb93f}}}, - /* 13*16^56*G: */ - {{{0x0421b54d, 0x1afeaf44, 0x159293fe, 0x1657074a, 0x09dca579, 0x0e95d8fd, 0x036352b2, 0x020c6aaf, 0x28135c}}, - {{0x0ee5d868, 0x0e6784dc, 0x18c4362b, 0x09299923, 0x18c15ef0, 0x0eba083f, 0x18541bea, 0x17c70a37, 0x9ed84a}}}, - /* 15*16^56*G: */ - {{{0x08e4ac10, 0x0bf2ac8f, 0x1892a6a4, 0x0d502559, 0x1b568799, 0x062d04ff, 0x1def5b0f, 0x0ec41620, 0x339a05}}, - {{0x0d1312a0, 0x1b6d4322, 0x07319bbd, 0x13cf11e8, 0x1553e503, 0x06fbc567, 0x11fd0e15, 0x17dbad52, 0xca985f}}} - }, - { - /* 1*16^57*G: */ - {{{0x07ea1f34, 0x1a6d58bb, 0x1ce78374, 0x17a6a808, 0x153d6646, 0x0e8bc9d9, 0x0d9b0ed0, 0x1447a8e9, 0x7f9460}}, - {{0x0d9063ec, 0x05f61656, 0x18d3ff16, 0x1f02a249, 0x16661c6f, 0x195fc783, 0x061da7c7, 0x0ef1f60c, 0xd0d516}}}, - /* 3*16^57*G: */ - {{{0x1dfc0a9d, 0x02dba64d, 0x1ddea837, 0x0846b629, 0x0a2a2de4, 0x11b23570, 0x1808a983, 0x1f098653, 0xdb43e7}}, - {{0x1e9ad713, 0x058849d4, 0x14bc153c, 0x1208e6ad, 0x19fa4883, 0x1640a677, 0x1646e295, 0x1457c6d6, 0xb0168d}}}, - /* 5*16^57*G: */ - {{{0x0283808d, 0x05e58bba, 0x190ea24c, 0x1e0f9c6a, 0x078980f8, 0x0f4890fd, 0x06bae145, 0x103dc1a4, 0xe9af30}}, - {{0x19b39d33, 0x13617c71, 0x04db4665, 0x1724a22a, 0x14971976, 0x132a87f7, 0x098216bc, 0x091388e2, 0xa976c8}}}, - /* 7*16^57*G: */ - {{{0x0d8426df, 0x1497a165, 0x1be28289, 0x0272b49c, 0x083590f4, 0x049c1dfc, 0x0601c0eb, 0x0c65900d, 0x6eb733}}, - {{0x000b4267, 0x1fbacf71, 0x1f86e0cf, 0x05d2f907, 0x08e8d925, 0x05967660, 0x0a680c39, 0x1822e60f, 0x96c56e}}}, - /* 9*16^57*G: */ - {{{0x1a16453d, 0x1e8b6be0, 0x040cf6fd, 0x1d0f7cec, 0x0d0e68b7, 0x0dc8fc5a, 0x1d1785d0, 0x0bc0f3ab, 0xd3979d}}, - {{0x07b6d737, 0x1e5dc18b, 0x1a58693c, 0x1becc514, 0x0456917d, 0x092ba9b9, 0x16e69342, 0x06baf335, 0xc55f93}}}, - /* 11*16^57*G: */ - {{{0x0d326504, 0x150ccd2f, 0x0d480b33, 0x15368c4f, 0x0fc12f65, 0x1dc460d7, 0x08d0b0e0, 0x139cb718, 0x54c392}}, - {{0x1ec9e107, 0x1f808fd3, 0x0299c9a2, 0x0a7b3cc1, 0x0ab4447a, 0x1514248a, 0x1b431226, 0x04ac1d42, 0x469630}}}, - /* 13*16^57*G: */ - {{{0x1b5ecce7, 0x0227abb5, 0x03484d4c, 0x102b1618, 0x059c8732, 0x0741e0cb, 0x1b16e13a, 0x1650ccda, 0x3744e9}}, - {{0x0a247721, 0x00990a0b, 0x09be0e48, 0x116be0a5, 0x1ec3c28e, 0x14ab7594, 0x1ea83839, 0x1f1b3208, 0x9546e0}}}, - /* 15*16^57*G: */ - {{{0x05fef996, 0x064946f2, 0x1094d454, 0x0d1ec728, 0x1f2de140, 0x08520f79, 0x154cc933, 0x02fc6cad, 0x11343e}}, - {{0x1792aded, 0x00a8573a, 0x01bc6390, 0x1c9acb41, 0x13765d0c, 0x0fc98313, 0x1bbac137, 0x101bd751, 0x4a9e84}}} - }, - { - /* 1*16^58*G: */ - {{{0x0e6d8483, 0x164da6bc, 0x059fc373, 0x05af508d, 0x0e94582f, 0x1a4f8db7, 0x18f4a563, 0x0c1467aa, 0x9c39cb}}, - {{0x0b2c50fb, 0x0599ab7b, 0x0f90da25, 0x1bca5e7b, 0x16546bba, 0x0b5bde50, 0x14400f46, 0x03dc927c, 0xf097bf}}}, - /* 3*16^58*G: */ - {{{0x07a14dda, 0x0ae18fc2, 0x12d37cfd, 0x1a0852ce, 0x13083606, 0x147b9200, 0x0b5d10dd, 0x19921d5b, 0x18f37a}}, - {{0x05ac8364, 0x117e6e19, 0x014db2f8, 0x11ef8f15, 0x1cd0b77d, 0x1ff6770d, 0x109b5eef, 0x17554125, 0x2f944b}}}, - /* 5*16^58*G: */ - {{{0x0c7d59be, 0x13a74746, 0x024cbed5, 0x1430b11c, 0x0736b98e, 0x1ff723b9, 0x07693b17, 0x118503cf, 0x541335}}, - {{0x04f80590, 0x0bf50fb7, 0x002cd9cb, 0x04b62b92, 0x0515a53e, 0x07e900b2, 0x00939f12, 0x1bd2d396, 0x680fd4}}}, - /* 7*16^58*G: */ - {{{0x076051a8, 0x15c064fc, 0x115fa963, 0x0ee72c74, 0x05280bed, 0x00d1e0dc, 0x13c1773f, 0x04d23632, 0x4e2fd1}}, - {{0x09cc9005, 0x17f63a7f, 0x113f8b9a, 0x11754b25, 0x031bcebb, 0x1ad0a845, 0x0ec8dc6c, 0x1b7ebe9f, 0x122abb}}}, - /* 9*16^58*G: */ - {{{0x16a80e09, 0x13e547d2, 0x097d7f8d, 0x0be1eecc, 0x08fa0a27, 0x1ab409e0, 0x0d648013, 0x1a97dfe3, 0x2de758}}, - {{0x036a1cd3, 0x0b176faa, 0x16b5b267, 0x15b8cd2b, 0x064a07a1, 0x1958132f, 0x199f5f00, 0x062efb1d, 0xdd9acf}}}, - /* 11*16^58*G: */ - {{{0x1a3628ac, 0x1281ad97, 0x16d593b0, 0x177459be, 0x012a4568, 0x10b9e377, 0x095ca316, 0x159b83a9, 0xf597a0}}, - {{0x0cd3550f, 0x1501886b, 0x04841b9f, 0x1d9f23a8, 0x02cc0772, 0x1db944b1, 0x1155eec6, 0x11c6657a, 0xdb916}}}, - /* 13*16^58*G: */ - {{{0x0b75d6c3, 0x06b41ea5, 0x0e8a159e, 0x14a8afaa, 0x040f3c42, 0x038c10df, 0x1ee42284, 0x10dade89, 0xaa222a}}, - {{0x044cb028, 0x1932d273, 0x0a323d84, 0x03f9296b, 0x0df42607, 0x0512d771, 0x19db3912, 0x12600351, 0x563787}}}, - /* 15*16^58*G: */ - {{{0x035790c9, 0x1d42b9c9, 0x1cf140df, 0x03722ee7, 0x15e2e9e0, 0x0321c979, 0x16dd5bc3, 0x0d79b2e2, 0x8568b2}}, - {{0x06b1f5ac, 0x09faa9c1, 0x0151e7f7, 0x0bcbf1f7, 0x03ce8014, 0x0705721b, 0x0ab7a41e, 0x034b09ba, 0xd3f226}}} - }, - { - /* 1*16^59*G: */ - {{{0x1c38d4e4, 0x0ed4be2a, 0x0c5cdd1f, 0x1acbe363, 0x01e25e2f, 0x173a180c, 0x04e25d59, 0x04c22453, 0x3d9285}}, - {{0x00ccf0d3, 0x1d577806, 0x1eaf1fdb, 0x15627032, 0x069eacc0, 0x0b81ae14, 0x0ad4ffc1, 0x14ba8d1d, 0xd32ca0}}}, - /* 3*16^59*G: */ - {{{0x0dd7718a, 0x039192c0, 0x0f9393b4, 0x1036ca33, 0x0dff891c, 0x0cd12f3b, 0x1f0fdf05, 0x06e57205, 0x3b180e}}, - {{0x1afd82db, 0x1331314c, 0x0b45341c, 0x1222ace0, 0x1211e584, 0x1e4e9482, 0x02abea92, 0x02fe6d6b, 0xf2b6b1}}}, - /* 5*16^59*G: */ - {{{0x13d3653d, 0x140d288c, 0x1919f57e, 0x1d8964e9, 0x03eb2134, 0x07a04c54, 0x127d17bd, 0x00723ad3, 0xf352ff}}, - {{0x0a44f28e, 0x0f333c64, 0x1160b41e, 0x132bf2e5, 0x0d5055c1, 0x0b9efed3, 0x1af4082f, 0x0d996d8b, 0x447262}}}, - /* 7*16^59*G: */ - {{{0x0d4478da, 0x130ef8d7, 0x03805535, 0x19ed8448, 0x13ca1f15, 0x02e6dfbc, 0x108c2bed, 0x0e2069b1, 0x670ee4}}, - {{0x14f563f0, 0x147ff27f, 0x1c91dc18, 0x07702c1f, 0x150e81cc, 0x102d89c3, 0x0b289519, 0x084b7404, 0x5ca0c7}}}, - /* 9*16^59*G: */ - {{{0x03dbd581, 0x02714822, 0x15acd6eb, 0x1d671051, 0x06fa93cf, 0x1d185676, 0x0f6fbeef, 0x0a8693b3, 0x96f2e3}}, - {{0x08f59952, 0x0cd27ff7, 0x13d75153, 0x031e3aa0, 0x1baf435a, 0x0c71cb06, 0x1b3d3f97, 0x0110baa4, 0x9fcd8}}}, - /* 11*16^59*G: */ - {{{0x04e9c2fc, 0x159a1925, 0x0f5c1a87, 0x19e19e5f, 0x09a35e72, 0x01058a30, 0x06b20106, 0x0a2fd073, 0xc4946e}}, - {{0x06398ce8, 0x01a3b1bb, 0x1188c48d, 0x17e71da2, 0x18237e48, 0x07b47a3d, 0x0933a668, 0x041630b1, 0x748901}}}, - /* 13*16^59*G: */ - {{{0x04960b03, 0x05c8b9f4, 0x0023a3d7, 0x18756191, 0x14d8fb6a, 0x0462bc04, 0x0f6fe923, 0x09b537c6, 0x1653b6}}, - {{0x10f73c69, 0x00352a75, 0x0d5939fe, 0x11c1c943, 0x1a8948b3, 0x15ec1f4a, 0x15827d2c, 0x102d3cba, 0xa58370}}}, - /* 15*16^59*G: */ - {{{0x1b63640e, 0x0abbf18d, 0x11cb7cb1, 0x176fe521, 0x1cbf4979, 0x13ce5342, 0x14fd4031, 0x1afda5e2, 0x51076d}}, - {{0x02e4476c, 0x1b4b943c, 0x083bc087, 0x1d49d3ce, 0x0fda6c8b, 0x1280b970, 0x1ddabaf9, 0x0945adbb, 0xb39727}}} - }, - { - /* 1*16^60*G: */ - {{{0x044e8de3, 0x0318258d, 0x130781d8, 0x112cd45d, 0x117915c0, 0x1ee7845e, 0x02dce969, 0x16e8d102, 0xf50b99}}, - {{0x1b7f3588, 0x11f9dd36, 0x1c87a152, 0x0be31a42, 0x1cebbe97, 0x0b9d16f6, 0x1c321e26, 0x03cabe31, 0xe2b506}}}, - /* 3*16^60*G: */ - {{{0x02accf8b, 0x0ee35b5c, 0x005be9f7, 0x05332305, 0x1430481d, 0x1871289c, 0x1dc1917c, 0x0c34aa0a, 0x598d7f}}, - {{0x0f6cb808, 0x1c2339e0, 0x0d502e46, 0x11351e6a, 0x1ebcad22, 0x08b15939, 0x182551b1, 0x1ee9f1e4, 0x9f3121}}}, - /* 5*16^60*G: */ - {{{0x04aa7b3e, 0x1d9cd2a3, 0x1b273aa7, 0x09de360a, 0x0581013c, 0x1048aa0e, 0x113593f4, 0x025e93e9, 0x715a20}}, - {{0x1c7d081d, 0x0d19ca25, 0x02d1f436, 0x178b1151, 0x13b62421, 0x1447c548, 0x10287de4, 0x16354c0d, 0x5922b3}}}, - /* 7*16^60*G: */ - {{{0x020db220, 0x0dedb4bb, 0x01eb3934, 0x1996202d, 0x07876c71, 0x0744bfdc, 0x04971027, 0x0bcd5536, 0x49ec8c}}, - {{0x077338c2, 0x0dc56503, 0x0ee733a6, 0x1860e7ca, 0x15429842, 0x061a432f, 0x0a6cf6a7, 0x09fcbd4c, 0x99a97d}}}, - /* 9*16^60*G: */ - {{{0x1e771268, 0x0f5e518a, 0x02995a14, 0x1e294fb2, 0x07b7a2f4, 0x0c8702f0, 0x1120f9bc, 0x01a90a16, 0x1f8fb7}}, - {{0x0909c8dd, 0x17e98086, 0x04aceac6, 0x1a786239, 0x192a14e1, 0x16ba3930, 0x0afc4b0b, 0x1b68c374, 0xf53e7a}}}, - /* 11*16^60*G: */ - {{{0x08d9819e, 0x0f607959, 0x0b6ac695, 0x0cf25ee8, 0x0732cd60, 0x0a15d33c, 0x187f7574, 0x034c92fe, 0xb8d5c7}}, - {{0x09138ac4, 0x03c5f475, 0x15170f37, 0x093e26c3, 0x1dc79e2f, 0x121acdb1, 0x1e08edbb, 0x1e26426f, 0x1cd14e}}}, - /* 13*16^60*G: */ - {{{0x00bca3f3, 0x149edf33, 0x1801241a, 0x0686a28a, 0x0d8c4ecb, 0x15b0e440, 0x18f7758f, 0x158cb755, 0x2265b5}}, - {{0x117409ff, 0x0c14e362, 0x0e4f5689, 0x014c25a4, 0x164983c8, 0x09d1d884, 0x183d868c, 0x17eb959f, 0x97a198}}}, - /* 15*16^60*G: */ - {{{0x05bac36e, 0x19691ffa, 0x1d77340d, 0x11328b32, 0x1abcb599, 0x054fafe4, 0x049487f6, 0x1a206b09, 0xaf381c}}, - {{0x11b119a9, 0x19ec43d5, 0x1352a43f, 0x1705e3de, 0x02648589, 0x1f914a8d, 0x1ef72515, 0x0ff6fbe1, 0x681a08}}} - }, - { - /* 1*16^61*G: */ - {{{0x0037cfb4, 0x10cca02b, 0x136aa167, 0x01e48d87, 0x0b0e0740, 0x1a4406d0, 0x142c35df, 0x1047febd, 0x42531}}, - {{0x18775d23, 0x05b992f6, 0x1b177500, 0x07c9ea69, 0x01faceea, 0x12686433, 0x1df98a32, 0x199f5c01, 0xc90e8b}}}, - /* 3*16^61*G: */ - {{{0x06c34577, 0x027b39aa, 0x094abdde, 0x013d91cd, 0x0e4bde64, 0x11847460, 0x0922c7d7, 0x141c6179, 0x27557a}}, - {{0x0416193c, 0x0ff5cdc0, 0x110e02eb, 0x0594e6e9, 0x134f318a, 0x0bad24fe, 0x0ceddf23, 0x0b08c20b, 0x8399c7}}}, - /* 5*16^61*G: */ - {{{0x0401f4d3, 0x12c7edb5, 0x056cc07b, 0x185ca1d5, 0x1d7decf6, 0x1c1dfab0, 0x0d923941, 0x02fa4b0e, 0x8e6878}}, - {{0x0294d86b, 0x0140f4a2, 0x08644a24, 0x172de25d, 0x13cae900, 0x04d02836, 0x0fe98be0, 0x110dc593, 0x989cab}}}, - /* 7*16^61*G: */ - {{{0x0d2aa8e6, 0x0cb1ef13, 0x1bff8b71, 0x06b3f881, 0x1dbee205, 0x1401e533, 0x13db440d, 0x08c4a7cb, 0x98a417}}, - {{0x006cf75b, 0x0ba05f6b, 0x1fb4865a, 0x042ff556, 0x1cec9e30, 0x017ad17a, 0x0f5ac455, 0x128fc68c, 0x579ac6}}}, - /* 9*16^61*G: */ - {{{0x152c2d31, 0x0516647b, 0x187bb35f, 0x01576118, 0x1a946180, 0x17221f10, 0x03f64885, 0x084460a8, 0xe16854}}, - {{0x04a50fec, 0x05c41b41, 0x0660e507, 0x0c3257f1, 0x1c9343e7, 0x13216815, 0x0850becb, 0x0b9251ce, 0x70085}}}, - /* 11*16^61*G: */ - {{{0x13a7cdad, 0x119dd71b, 0x02f3ebd2, 0x1b07a5ca, 0x151a53ca, 0x117299c4, 0x0fa8728a, 0x09613aa2, 0xbfa631}}, - {{0x095cb953, 0x0fc44981, 0x1011e871, 0x0321f190, 0x0d1a7261, 0x02ddd8f7, 0x11e0a97e, 0x03299005, 0xb452e8}}}, - /* 13*16^61*G: */ - {{{0x0ade0fb7, 0x0de64280, 0x1946363b, 0x1b8e9bd4, 0x18e200c6, 0x0baf36ec, 0x134fb3c2, 0x05a152c3, 0xe68708}}, - {{0x1d4d6ece, 0x0bcf0798, 0x03089664, 0x03d0bdf1, 0x1a72117c, 0x072990e8, 0x1555797c, 0x090d0992, 0x2135a4}}}, - /* 15*16^61*G: */ - {{{0x0e432daf, 0x01e5af86, 0x009eb272, 0x1db41155, 0x14975f3b, 0x146bca83, 0x07a52ff0, 0x1f0c5535, 0x7ab16e}}, - {{0x071bdc48, 0x08bac455, 0x13f6c04c, 0x139c75ce, 0x1a7c5c7e, 0x0c1f146d, 0x02c68d64, 0x0152f865, 0x584e0e}}} - }, - { - /* 1*16^62*G: */ - {{{0x085fbd44, 0x03a3894c, 0x09899eb0, 0x0595473e, 0x1222c89c, 0x18e70b6a, 0x04178151, 0x1b5b356b, 0x9bbf06}}, - {{0x1a1d3e88, 0x1a23efd3, 0x00dbb4a8, 0x097bb82a, 0x147e8c0d, 0x0d798537, 0x028d9d57, 0x1509bc24, 0x1bcc7f}}}, - /* 3*16^62*G: */ - {{{0x14a7b506, 0x1bd73c95, 0x0182f822, 0x0b1775cf, 0x00ee9227, 0x1d9573a8, 0x0f4d0a73, 0x1ecb676b, 0x646ff7}}, - {{0x0b36f946, 0x0bce0929, 0x039a6572, 0x1bf89f81, 0x08fe8492, 0x1198c025, 0x02956987, 0x13a0c943, 0xbc112a}}}, - /* 5*16^62*G: */ - {{{0x0103b553, 0x0a5b8e4e, 0x0e16a005, 0x01d44f06, 0x0507ebe6, 0x0800593f, 0x0e6a7430, 0x0f54c2fa, 0x7cc054}}, - {{0x0d45a526, 0x1cce5d1e, 0x08a2df55, 0x10b41558, 0x094c4001, 0x14659cfe, 0x116af75c, 0x17a46500, 0x7b329e}}}, - /* 7*16^62*G: */ - {{{0x19e717a4, 0x0177a2a0, 0x1c06e06b, 0x1457b559, 0x0e15468d, 0x16a9b6d7, 0x0d38158f, 0x1321783b, 0x946851}}, - {{0x1526dea3, 0x1af87e8d, 0x02b36729, 0x132b21ee, 0x07dc0579, 0x08735933, 0x06a2cee3, 0x0841b8b2, 0xca5c78}}}, - /* 9*16^62*G: */ - {{{0x08362735, 0x1c161b78, 0x0acc9ef7, 0x1166fde2, 0x0d1f5dff, 0x07c75229, 0x03eac496, 0x037cfc1d, 0xe1b98f}}, - {{0x0ecb11b7, 0x0b09c64e, 0x1d0242be, 0x13dc67be, 0x12ba27e1, 0x1a4d41dd, 0x082df816, 0x15b352ed, 0xca83e9}}}, - /* 11*16^62*G: */ - {{{0x19046346, 0x1a05dec1, 0x0510020e, 0x0b1bce60, 0x1962d56a, 0x1035ecb3, 0x1fbdb422, 0x0b91fac0, 0x3536f2}}, - {{0x0c14fea6, 0x0008315e, 0x166cf8a5, 0x187a3d45, 0x1e1c39e6, 0x0b50d294, 0x0279cee8, 0x1c2fbc6a, 0x1e271f}}}, - /* 13*16^62*G: */ - {{{0x0847f6f8, 0x1ffc1f6b, 0x103bd4c3, 0x136a3f7a, 0x18c3c102, 0x08f9a5bf, 0x1379a405, 0x08d7c47a, 0xdf502}}, - {{0x1b1633a6, 0x06654535, 0x17cd126d, 0x1c2ccd13, 0x174ab4c6, 0x1627de10, 0x0728ac8c, 0x0fe53b5e, 0x210704}}}, - /* 15*16^62*G: */ - {{{0x1d4f1b81, 0x02e7576f, 0x1d2ec546, 0x134f4919, 0x09330ad6, 0x11d99b29, 0x0e63da77, 0x1a899ea6, 0xca9dd5}}, - {{0x02b7c8bd, 0x06316572, 0x0b6843e3, 0x12ec17f5, 0x07b3e66c, 0x18fda223, 0x11590091, 0x10ca37c5, 0x6e4b98}}} - }, - { - /* 1*16^63*G: */ - {{{0x044c0448, 0x1569919a, 0x00c678c7, 0x0aed0d82, 0x093e7963, 0x1e659dbc, 0x1e95250f, 0x1ea5287b, 0xb12fad}}, - {{0x1369de57, 0x12baf3b5, 0x1f137ca5, 0x0bce0665, 0x0a6a71d0, 0x07b33bd9, 0x12b3a5be, 0x12b3361e, 0x2e245}}}, - /* 3*16^63*G: */ - {{{0x04e9151f, 0x09b622a3, 0x0361063d, 0x14673390, 0x0fb3e67e, 0x0eed48ec, 0x15a10c95, 0x069e38a0, 0x48388e}}, - {{0x0d7a9434, 0x1f724f6e, 0x17a0c406, 0x028222a7, 0x02bcc99b, 0x19c98aa4, 0x1a79a894, 0x157e9c89, 0xb0ec63}}}, - /* 5*16^63*G: */ - {{{0x0e5b833d, 0x1efda52c, 0x02c90675, 0x1400e794, 0x109c9593, 0x0fc08280, 0x0f697997, 0x08f5c28a, 0xde8e64}}, - {{0x014c5cc7, 0x07e60cd5, 0x0071b27c, 0x1c062652, 0x1e265987, 0x14465eb6, 0x0f638cc8, 0x0782a122, 0x5e146}}}, - /* 7*16^63*G: */ - {{{0x01f7df48, 0x112c9f56, 0x1c4c5ecf, 0x0e8e7d70, 0x0f385b26, 0x0da7272c, 0x1a7a3955, 0x1a149d8f, 0xb18b12}}, - {{0x0846b546, 0x0d9eac87, 0x14795664, 0x07efc907, 0x0c33b3c8, 0x0135e2d6, 0x0d1173b1, 0x04546b3f, 0xff5319}}}, - /* 9*16^63*G: */ - {{{0x19c9fd24, 0x129d6e34, 0x0847837c, 0x1bb1308a, 0x0694402c, 0x05526394, 0x10cf1f07, 0x0e391b92, 0x5f51ad}}, - {{0x0d2ffd3a, 0x01dd7443, 0x092a65a7, 0x03ec488c, 0x04d03872, 0x02fde617, 0x0528334c, 0x023befce, 0x2bbbef}}}, - /* 11*16^63*G: */ - {{{0x17cec42e, 0x1e2031fe, 0x18ef6df8, 0x1b9267dd, 0x0d8556f3, 0x117721a3, 0x1aefe960, 0x1b26e603, 0xfdf340}}, - {{0x0db6908b, 0x07b1a5be, 0x178c320e, 0x1cd57ea1, 0x0d2c4456, 0x0ff39c65, 0x1b875c30, 0x0c72d198, 0xa3e59a}}}, - /* 13*16^63*G: */ - {{{0x01dc4fe8, 0x00c4a2a7, 0x01c9057f, 0x1142752c, 0x1c983f9e, 0x0948bdbe, 0x15e7b191, 0x19173d4b, 0xe3caeb}}, - {{0x1307b403, 0x15b05b90, 0x13e1a845, 0x0006cb42, 0x1f976513, 0x1ae5c580, 0x04a34880, 0x1a4f7e0b, 0x97f093}}}, - /* 15*16^63*G: */ - {{{0x1c119eff, 0x00a6b2e9, 0x07e6e119, 0x005c1815, 0x1a003399, 0x0d2e72c7, 0x16e26bd0, 0x1728550c, 0x3312d}}, - {{0x18b1b950, 0x14ad1d4f, 0x1455617f, 0x18b3b6be, 0x1e86f0ae, 0x1518bc04, 0x137c413b, 0x0c8d66e4, 0x6e3eda}}} - }, diff --git a/trezor-crypto/crypto/pbkdf2.c b/trezor-crypto/crypto/pbkdf2.c deleted file mode 100644 index 117d14e618b..00000000000 --- a/trezor-crypto/crypto/pbkdf2.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - * 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 -#include -#include -#include -#include - -void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, - int passlen, const uint8_t *salt, int saltlen, - uint32_t blocknr) { - SHA256_CTX ctx = {0}; -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(blocknr, blocknr); -#endif - - hmac_sha256_prepare(pass, passlen, pctx->odig, pctx->idig); - memzero(pctx->g, sizeof(pctx->g)); - pctx->g[8] = 0x80000000; - pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - - memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); - ctx.bitcount = SHA256_BLOCK_LENGTH * 8; - sha256_Update(&ctx, salt, saltlen); - sha256_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr)); - sha256_Final(&ctx, (uint8_t *)pctx->g); -#if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { - REVERSE32(pctx->g[k], pctx->g[k]); - } -#endif - sha256_Transform(pctx->odig, pctx->g, pctx->g); - memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH); - pctx->first = 1; -} - -void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, - uint32_t iterations) { - for (uint32_t i = pctx->first; i < iterations; i++) { - sha256_Transform(pctx->idig, pctx->g, pctx->g); - sha256_Transform(pctx->odig, pctx->g, pctx->g); - for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) { - pctx->f[j] ^= pctx->g[j]; - } - } - pctx->first = 0; -} - -void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key) { -#if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) { - REVERSE32(pctx->f[k], pctx->f[k]); - } -#endif - memcpy(key, pctx->f, SHA256_DIGEST_LENGTH); - memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); -} - -void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen) { - uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH; - uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH; - if (last_block_size) { - blocks_count++; - } else { - last_block_size = SHA256_DIGEST_LENGTH; - } - for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { - PBKDF2_HMAC_SHA256_CTX pctx = {0}; - pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen, blocknr); - pbkdf2_hmac_sha256_Update(&pctx, iterations); - uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; - pbkdf2_hmac_sha256_Final(&pctx, digest); - uint32_t key_offset = (blocknr - 1) * SHA256_DIGEST_LENGTH; - if (blocknr < blocks_count) { - memcpy(key + key_offset, digest, SHA256_DIGEST_LENGTH); - } else { - memcpy(key + key_offset, digest, last_block_size); - } - } -} - -void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, - int passlen, const uint8_t *salt, int saltlen, - uint32_t blocknr) { - SHA512_CTX ctx = {0}; -#if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(blocknr, blocknr); -#endif - - hmac_sha512_prepare(pass, passlen, pctx->odig, pctx->idig); - memzero(pctx->g, sizeof(pctx->g)); - pctx->g[8] = 0x8000000000000000; - pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8; - - memcpy(ctx.state, pctx->idig, sizeof(pctx->idig)); - ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8; - ctx.bitcount[1] = 0; - sha512_Update(&ctx, salt, saltlen); - sha512_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr)); - sha512_Final(&ctx, (uint8_t *)pctx->g); -#if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { - REVERSE64(pctx->g[k], pctx->g[k]); - } -#endif - sha512_Transform(pctx->odig, pctx->g, pctx->g); - memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH); - pctx->first = 1; -} - -void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, - uint32_t iterations) { - for (uint32_t i = pctx->first; i < iterations; i++) { - sha512_Transform(pctx->idig, pctx->g, pctx->g); - sha512_Transform(pctx->odig, pctx->g, pctx->g); - for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH / sizeof(uint64_t); j++) { - pctx->f[j] ^= pctx->g[j]; - } - } - pctx->first = 0; -} - -void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key) { -#if BYTE_ORDER == LITTLE_ENDIAN - for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) { - REVERSE64(pctx->f[k], pctx->f[k]); - } -#endif - memcpy(key, pctx->f, SHA512_DIGEST_LENGTH); - memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX)); -} - -void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen) { - uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH; - uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH; - if (last_block_size) { - blocks_count++; - } else { - last_block_size = SHA512_DIGEST_LENGTH; - } - for (uint32_t blocknr = 1; blocknr <= blocks_count; blocknr++) { - PBKDF2_HMAC_SHA512_CTX pctx = {0}; - pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen, blocknr); - pbkdf2_hmac_sha512_Update(&pctx, iterations); - uint8_t digest[SHA512_DIGEST_LENGTH] = {0}; - pbkdf2_hmac_sha512_Final(&pctx, digest); - uint32_t key_offset = (blocknr - 1) * SHA512_DIGEST_LENGTH; - if (blocknr < blocks_count) { - memcpy(key + key_offset, digest, SHA512_DIGEST_LENGTH); - } else { - memcpy(key + key_offset, digest, last_block_size); - } - } -} diff --git a/trezor-crypto/crypto/rc4.c b/trezor-crypto/crypto/rc4.c deleted file mode 100644 index e940d277061..00000000000 --- a/trezor-crypto/crypto/rc4.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * 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 - -static inline void rc4_swap(RC4_CTX *ctx, uint8_t i, uint8_t j) { - uint8_t temp = ctx->S[i]; - ctx->S[i] = ctx->S[j]; - ctx->S[j] = temp; -} - -void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length) { - ctx->i = 0; - ctx->j = 0; - - for (size_t i = 0; i < 256; i++) { - ctx->S[i] = i; - } - - uint8_t j = 0; - for (size_t i = 0; i < 256; i++) { - j += ctx->S[i] + key[i % length]; - rc4_swap(ctx, i, j); - } -} - -void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length) { - for (size_t idx = 0; idx < length; idx++) { - ctx->i++; - ctx->j += ctx->S[ctx->i]; - - rc4_swap(ctx, ctx->i, ctx->j); - - uint8_t K = ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256]; - buffer[idx] ^= K; - } -} diff --git a/trezor-crypto/crypto/rfc6979.c b/trezor-crypto/crypto/rfc6979.c deleted file mode 100644 index c781e47b926..00000000000 --- a/trezor-crypto/crypto/rfc6979.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * Copyright (c) 2015 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 - -#include -#include -#include - -void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, - const ecdsa_curve *curve, rfc6979_state *state) { - if (curve) { - bignum256 hash_bn = {0}; - bn_read_be(hash, &hash_bn); - - // Make sure hash is partly reduced modulo order - assert(bn_bitcount(&curve->order) >= 256); - bn_mod(&hash_bn, &curve->order); - - uint8_t hash_reduced[32] = {0}; - bn_write_be(&hash_bn, hash_reduced); - memzero(&hash_bn, sizeof(hash_bn)); - hmac_drbg_init(state, priv_key, 32, hash_reduced, 32); - memzero(hash_reduced, sizeof(hash_reduced)); - } else { - hmac_drbg_init(state, priv_key, 32, hash, 32); - } -} - -// generate next number from deterministic random number generator -void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) { - hmac_drbg_generate(state, rnd, 32); -} - -// generate K in a deterministic way, according to RFC6979 -// http://tools.ietf.org/html/rfc6979 -void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) { - uint8_t buf[32] = {0}; - generate_rfc6979(buf, state); - bn_read_be(buf, k); - memzero(buf, sizeof(buf)); -} diff --git a/trezor-crypto/crypto/ripemd160.c b/trezor-crypto/crypto/ripemd160.c deleted file mode 100644 index f90e4340b9d..00000000000 --- a/trezor-crypto/crypto/ripemd160.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * RIPE MD-160 implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * The RIPEMD-160 algorithm was designed by RIPE in 1996 - * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html - * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 - */ - -#include - -#include -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (uint8_t) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (uint8_t) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (uint8_t) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (uint8_t) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -/* - * RIPEMD-160 context setup - */ -void ripemd160_Init(RIPEMD160_CTX *ctx) -{ - memzero(ctx, sizeof(RIPEMD160_CTX)); - ctx->total[0] = 0; - ctx->total[1] = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) -/* - * Process one block - */ -void ripemd160_process( RIPEMD160_CTX *ctx, const uint8_t data[RIPEMD160_BLOCK_LENGTH] ) -{ - uint32_t A = 0, B = 0, C = 0, D = 0, E = 0, Ap = 0, Bp = 0, Cp = 0, Dp = 0, Ep = 0, X[16] = {0}; - - GET_UINT32_LE( X[ 0], data, 0 ); - GET_UINT32_LE( X[ 1], data, 4 ); - GET_UINT32_LE( X[ 2], data, 8 ); - GET_UINT32_LE( X[ 3], data, 12 ); - GET_UINT32_LE( X[ 4], data, 16 ); - GET_UINT32_LE( X[ 5], data, 20 ); - GET_UINT32_LE( X[ 6], data, 24 ); - GET_UINT32_LE( X[ 7], data, 28 ); - GET_UINT32_LE( X[ 8], data, 32 ); - GET_UINT32_LE( X[ 9], data, 36 ); - GET_UINT32_LE( X[10], data, 40 ); - GET_UINT32_LE( X[11], data, 44 ); - GET_UINT32_LE( X[12], data, 48 ); - GET_UINT32_LE( X[13], data, 52 ); - GET_UINT32_LE( X[14], data, 56 ); - GET_UINT32_LE( X[15], data, 60 ); - - A = Ap = ctx->state[0]; - B = Bp = ctx->state[1]; - C = Cp = ctx->state[2]; - D = Dp = ctx->state[3]; - E = Ep = ctx->state[4]; - -#define F1( x, y, z ) ( x ^ y ^ z ) -#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) -#define F3( x, y, z ) ( ( x | ~y ) ^ z ) -#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) -#define F5( x, y, z ) ( x ^ ( y | ~z ) ) - -#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) - -#define P( a, b, c, d, e, r, s, f, k ) \ - a += f( b, c, d ) + X[r] + k; \ - a = S( a, s ) + e; \ - c = S( c, 10 ); - -#define P2( a, b, c, d, e, r, s, rp, sp ) \ - P( a, b, c, d, e, r, s, F, K ); \ - P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); - -#define F F1 -#define K 0x00000000 -#define Fp F5 -#define Kp 0x50A28BE6 - P2( A, B, C, D, E, 0, 11, 5, 8 ); - P2( E, A, B, C, D, 1, 14, 14, 9 ); - P2( D, E, A, B, C, 2, 15, 7, 9 ); - P2( C, D, E, A, B, 3, 12, 0, 11 ); - P2( B, C, D, E, A, 4, 5, 9, 13 ); - P2( A, B, C, D, E, 5, 8, 2, 15 ); - P2( E, A, B, C, D, 6, 7, 11, 15 ); - P2( D, E, A, B, C, 7, 9, 4, 5 ); - P2( C, D, E, A, B, 8, 11, 13, 7 ); - P2( B, C, D, E, A, 9, 13, 6, 7 ); - P2( A, B, C, D, E, 10, 14, 15, 8 ); - P2( E, A, B, C, D, 11, 15, 8, 11 ); - P2( D, E, A, B, C, 12, 6, 1, 14 ); - P2( C, D, E, A, B, 13, 7, 10, 14 ); - P2( B, C, D, E, A, 14, 9, 3, 12 ); - P2( A, B, C, D, E, 15, 8, 12, 6 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F2 -#define K 0x5A827999 -#define Fp F4 -#define Kp 0x5C4DD124 - P2( E, A, B, C, D, 7, 7, 6, 9 ); - P2( D, E, A, B, C, 4, 6, 11, 13 ); - P2( C, D, E, A, B, 13, 8, 3, 15 ); - P2( B, C, D, E, A, 1, 13, 7, 7 ); - P2( A, B, C, D, E, 10, 11, 0, 12 ); - P2( E, A, B, C, D, 6, 9, 13, 8 ); - P2( D, E, A, B, C, 15, 7, 5, 9 ); - P2( C, D, E, A, B, 3, 15, 10, 11 ); - P2( B, C, D, E, A, 12, 7, 14, 7 ); - P2( A, B, C, D, E, 0, 12, 15, 7 ); - P2( E, A, B, C, D, 9, 15, 8, 12 ); - P2( D, E, A, B, C, 5, 9, 12, 7 ); - P2( C, D, E, A, B, 2, 11, 4, 6 ); - P2( B, C, D, E, A, 14, 7, 9, 15 ); - P2( A, B, C, D, E, 11, 13, 1, 13 ); - P2( E, A, B, C, D, 8, 12, 2, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F3 -#define K 0x6ED9EBA1 -#define Fp F3 -#define Kp 0x6D703EF3 - P2( D, E, A, B, C, 3, 11, 15, 9 ); - P2( C, D, E, A, B, 10, 13, 5, 7 ); - P2( B, C, D, E, A, 14, 6, 1, 15 ); - P2( A, B, C, D, E, 4, 7, 3, 11 ); - P2( E, A, B, C, D, 9, 14, 7, 8 ); - P2( D, E, A, B, C, 15, 9, 14, 6 ); - P2( C, D, E, A, B, 8, 13, 6, 6 ); - P2( B, C, D, E, A, 1, 15, 9, 14 ); - P2( A, B, C, D, E, 2, 14, 11, 12 ); - P2( E, A, B, C, D, 7, 8, 8, 13 ); - P2( D, E, A, B, C, 0, 13, 12, 5 ); - P2( C, D, E, A, B, 6, 6, 2, 14 ); - P2( B, C, D, E, A, 13, 5, 10, 13 ); - P2( A, B, C, D, E, 11, 12, 0, 13 ); - P2( E, A, B, C, D, 5, 7, 4, 7 ); - P2( D, E, A, B, C, 12, 5, 13, 5 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F4 -#define K 0x8F1BBCDC -#define Fp F2 -#define Kp 0x7A6D76E9 - P2( C, D, E, A, B, 1, 11, 8, 15 ); - P2( B, C, D, E, A, 9, 12, 6, 5 ); - P2( A, B, C, D, E, 11, 14, 4, 8 ); - P2( E, A, B, C, D, 10, 15, 1, 11 ); - P2( D, E, A, B, C, 0, 14, 3, 14 ); - P2( C, D, E, A, B, 8, 15, 11, 14 ); - P2( B, C, D, E, A, 12, 9, 15, 6 ); - P2( A, B, C, D, E, 4, 8, 0, 14 ); - P2( E, A, B, C, D, 13, 9, 5, 6 ); - P2( D, E, A, B, C, 3, 14, 12, 9 ); - P2( C, D, E, A, B, 7, 5, 2, 12 ); - P2( B, C, D, E, A, 15, 6, 13, 9 ); - P2( A, B, C, D, E, 14, 8, 9, 12 ); - P2( E, A, B, C, D, 5, 6, 7, 5 ); - P2( D, E, A, B, C, 6, 5, 10, 15 ); - P2( C, D, E, A, B, 2, 12, 14, 8 ); -#undef F -#undef K -#undef Fp -#undef Kp - -#define F F5 -#define K 0xA953FD4E -#define Fp F1 -#define Kp 0x00000000 - P2( B, C, D, E, A, 4, 9, 12, 8 ); - P2( A, B, C, D, E, 0, 15, 15, 5 ); - P2( E, A, B, C, D, 5, 5, 10, 12 ); - P2( D, E, A, B, C, 9, 11, 4, 9 ); - P2( C, D, E, A, B, 7, 6, 1, 12 ); - P2( B, C, D, E, A, 12, 8, 5, 5 ); - P2( A, B, C, D, E, 2, 13, 8, 14 ); - P2( E, A, B, C, D, 10, 12, 7, 6 ); - P2( D, E, A, B, C, 14, 5, 6, 8 ); - P2( C, D, E, A, B, 1, 12, 2, 13 ); - P2( B, C, D, E, A, 3, 13, 13, 6 ); - P2( A, B, C, D, E, 8, 14, 14, 5 ); - P2( E, A, B, C, D, 11, 11, 0, 15 ); - P2( D, E, A, B, C, 6, 8, 3, 13 ); - P2( C, D, E, A, B, 15, 5, 9, 11 ); - P2( B, C, D, E, A, 13, 6, 11, 11 ); -#undef F -#undef K -#undef Fp -#undef Kp - - C = ctx->state[1] + C + Dp; - ctx->state[1] = ctx->state[2] + D + Ep; - ctx->state[2] = ctx->state[3] + E + Ap; - ctx->state[3] = ctx->state[4] + A + Bp; - ctx->state[4] = ctx->state[0] + B + Cp; - ctx->state[0] = C; -} -#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ - -/* - * RIPEMD-160 process buffer - */ -void ripemd160_Update( RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen ) -{ - uint32_t fill = 0; - uint32_t left = 0; - - if( ilen == 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = RIPEMD160_BLOCK_LENGTH - left; - - ctx->total[0] += (uint32_t) ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (uint32_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), input, fill ); - ripemd160_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= RIPEMD160_BLOCK_LENGTH ) - { - ripemd160_process( ctx, input ); - input += RIPEMD160_BLOCK_LENGTH; - ilen -= RIPEMD160_BLOCK_LENGTH; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), input, ilen ); - } -} - -const uint8_t ripemd160_padding[RIPEMD160_BLOCK_LENGTH] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * RIPEMD-160 final digest - */ -void ripemd160_Final( RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH] ) -{ - uint32_t last = 0; uint32_t padn = 0; - uint32_t high = 0; uint32_t low = 0; - uint8_t msglen[8] = {0}; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - ripemd160_Update( ctx, ripemd160_padding, padn ); - ripemd160_Update( ctx, msglen, 8 ); - - PUT_UINT32_LE( ctx->state[0], output, 0 ); - PUT_UINT32_LE( ctx->state[1], output, 4 ); - PUT_UINT32_LE( ctx->state[2], output, 8 ); - PUT_UINT32_LE( ctx->state[3], output, 12 ); - PUT_UINT32_LE( ctx->state[4], output, 16 ); - - memzero(ctx, sizeof(RIPEMD160_CTX)); -} - -/* - * output = RIPEMD-160( input buffer ) - */ -void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]) -{ - RIPEMD160_CTX ctx = {0}; - ripemd160_Init( &ctx ); - ripemd160_Update( &ctx, msg, msg_len ); - ripemd160_Final( &ctx, hash ); -} diff --git a/trezor-crypto/crypto/script.c b/trezor-crypto/crypto/script.c deleted file mode 100644 index 4d181cea6b3..00000000000 --- a/trezor-crypto/crypto/script.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 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 -#include -#include - -int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, - int addrsize) { - uint8_t raw[35] = {0}; - - // P2PKH - if (scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 && - script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xAC) { - raw[0] = 0x00; - memcpy(raw + 1, script + 3, 20); - return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); - } - - // P2SH - if (scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 && - script[22] == 0x87) { - raw[0] = 0x05; - memcpy(raw + 1, script + 2, 20); - return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize); - } - - // P2WPKH - if (scriptlen == 22 && script[0] == 0x00 && script[1] == 0x14) { - raw[0] = 0x06; - raw[1] = 0x00; - raw[2] = 0x00; - memcpy(raw + 3, script + 2, 20); - return base58_encode_check(raw, 3 + 20, HASHER_SHA2D, addr, addrsize); - } - - // P2WSH - if (scriptlen == 34 && script[0] == 0x00 && script[1] == 0x20) { - raw[0] = 0x0A; - raw[1] = 0x00; - raw[2] = 0x00; - memcpy(raw + 3, script + 2, 32); - return base58_encode_check(raw, 3 + 32, HASHER_SHA2D, addr, addrsize); - } - - return 0; -} diff --git a/trezor-crypto/crypto/scrypt.c b/trezor-crypto/crypto/scrypt.c deleted file mode 100644 index 4e94beab0e8..00000000000 --- a/trezor-crypto/crypto/scrypt.c +++ /dev/null @@ -1,340 +0,0 @@ -/*- - * Copyright 2009 Colin Percival - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * This file was originally written by Colin Percival as part of the Tarsnap - * online backup system. - */ - -#include - -#include -#include -#include - -#include -#ifndef _WIN32 -#include -#endif -#include -#include -#include -#include - -static void blkcpy(uint32_t *, const uint32_t *, size_t); -static void blkxor(void *, void *, size_t); -static void salsa20_8(uint32_t[16]); -static void blockmix_salsa8(uint32_t *, uint32_t *, uint32_t *, size_t); -static uint64_t integerify(void *, size_t); -static void smix(uint8_t *, size_t, uint64_t, uint32_t *, uint32_t *); - -static void -blkcpy(uint32_t * dest, const uint32_t * src, size_t len) -{ - size_t L = len / sizeof(uint32_t); - - for (size_t i = 0; i < L; i++) - dest[i] = src[i]; -} - -static void -blkxor(void * dest, void * src, size_t len) -{ - size_t * D = dest; - size_t * S = src; - size_t L = len / sizeof(size_t); - size_t i; - - for (i = 0; i < L; i++) - D[i] ^= S[i]; -} - -/** - * salsa20_8(B): - * Apply the salsa20/8 core to the provided block. - */ -static void -salsa20_8(uint32_t B[16]) -{ - uint32_t x[16]; - size_t i; - - blkcpy(x, B, 64); - for (i = 0; i < 8; i += 2) { -#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) - /* Operate on columns. */ - x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); - x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); - - x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); - x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); - - x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); - x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); - - x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); - x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); - - /* Operate on rows. */ - x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); - x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); - - x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); - x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); - - x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); - x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); - - x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); - x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); -#undef R - } - for (i = 0; i < 16; i++) - B[i] += x[i]; -} - -/** - * blockmix_salsa8(Bin, Bout, X, r): - * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r - * bytes in length; the output Bout must also be the same size. The - * temporary space X must be 64 bytes. - */ -static void -blockmix_salsa8(uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) -{ - size_t i; - - /* 1: X <-- B_{2r - 1} */ - blkcpy(X, &Bin[(2 * r - 1) * 16], 64); - - /* 2: for i = 0 to 2r - 1 do */ - for (i = 0; i < 2 * r; i += 2) { - /* 3: X <-- H(X \xor B_i) */ - blkxor(X, &Bin[i * 16], 64); - salsa20_8(X); - - /* 4: Y_i <-- X */ - /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy(&Bout[i * 8], X, 64); - - /* 3: X <-- H(X \xor B_i) */ - blkxor(X, &Bin[i * 16 + 16], 64); - salsa20_8(X); - - /* 4: Y_i <-- X */ - /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy(&Bout[i * 8 + r * 16], X, 64); - } -} - -/** - * integerify(B, r): - * Return the result of parsing B_{2r-1} as a little-endian integer. - */ -static uint64_t -integerify(void * B, size_t r) -{ - uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64); - - return (((uint64_t)(X[1]) << 32) + X[0]); -} - -/** - * smix(B, r, N, V, XY): - * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; - * the temporary storage V must be 128rN bytes in length; the temporary - * storage XY must be 256r + 64 bytes in length. The value N must be a - * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a - * multiple of 64 bytes. - */ -static void -smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY) -{ - uint32_t * X = XY; - uint32_t * Y = &XY[32 * r]; - uint32_t * Z = &XY[64 * r]; - uint64_t i; - uint64_t j; - size_t k; - - /* 1: X <-- B */ - for (k = 0; k < 32 * r; k++) - X[k] = le32dec(&B[4 * k]); - - /* 2: for i = 0 to N - 1 do */ - for (i = 0; i < N; i += 2) { - /* 3: V_i <-- X */ - blkcpy(&V[i * (32 * r)], X, 128 * r); - - /* 4: X <-- H(X) */ - blockmix_salsa8(X, Y, Z, r); - - /* 3: V_i <-- X */ - blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r); - - /* 4: X <-- H(X) */ - blockmix_salsa8(Y, X, Z, r); - } - - /* 6: for i = 0 to N - 1 do */ - for (i = 0; i < N; i += 2) { - /* 7: j <-- Integerify(X) mod N */ - j = integerify(X, r) & (N - 1); - - /* 8: X <-- H(X \xor V_j) */ - blkxor(X, &V[j * (32 * r)], 128 * r); - blockmix_salsa8(X, Y, Z, r); - - /* 7: j <-- Integerify(X) mod N */ - j = integerify(Y, r) & (N - 1); - - /* 8: X <-- H(X \xor V_j) */ - blkxor(Y, &V[j * (32 * r)], 128 * r); - blockmix_salsa8(Y, X, Z, r); - } - - /* 10: B' <-- X */ - for (k = 0; k < 32 * r; k++) - le32enc(&B[4 * k], X[k]); -} - -/** - * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): - * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, - * p, buflen) and write the result into buf. The parameters r, p, and buflen - * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N - * must be a power of 2 greater than 1. - * - * Return 0 on success; or -1 on error - */ -int -scrypt(const uint8_t * passwd, size_t passwdlen, - const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, - uint8_t * buf, size_t buflen) -{ - void * B0, * V0, * XY0; - uint8_t * B; - uint32_t * V; - uint32_t * XY; - uint32_t i; - - /* Sanity-check parameters. */ -#if SIZE_MAX > UINT32_MAX - if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { - errno = EFBIG; - goto err0; - } -#endif - if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { - errno = EFBIG; - goto err0; - } - if (r == 0 || p == 0) { - errno = EINVAL; - goto err0; - } - if (((N & (N - 1)) != 0) || (N < 2)) { - errno = EINVAL; - goto err0; - } - if ((r > SIZE_MAX / 128 / p) || -#if SIZE_MAX / 256 <= UINT32_MAX - (r > SIZE_MAX / 256) || -#endif - (N > SIZE_MAX / 128 / r)) { - errno = ENOMEM; - goto err0; - } - - /* Allocate memory. */ -#ifdef HAVE_POSIX_MEMALIGN - if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) - goto err0; - B = (uint8_t *)(B0); - if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) - goto err1; - XY = (uint32_t *)(XY0); -#ifndef MAP_ANON - if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) - goto err2; - V = (uint32_t *)(V0); -#endif -#else - if ((B0 = malloc(128 * r * p + 63)) == NULL) - goto err0; - B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); - if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) - goto err1; - XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); -#ifndef MAP_ANON - if ((V0 = malloc(128 * r * N + 63)) == NULL) - goto err2; - V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); -#endif -#endif -#ifdef MAP_ANON - if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, -#ifdef MAP_NOCORE - MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -#else - MAP_ANON | MAP_PRIVATE, -#endif - -1, 0)) == MAP_FAILED) - goto err2; - V = (uint32_t *)(V0); -#endif - - /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ - pbkdf2_hmac_sha256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); - - /* 2: for i = 0 to p - 1 do */ - for (i = 0; i < p; i++) { - /* 3: B_i <-- MF(B_i, N) */ - smix(&B[i * 128 * r], r, N, V, XY); - } - - /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ - pbkdf2_hmac_sha256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); - - /* Free memory. */ -#ifdef MAP_ANON - if (munmap(V0, 128 * r * N)) - goto err2; -#else - free(V0); -#endif - free(XY0); - free(B0); - - /* Success! */ - return (0); - -err2: - free(XY0); -err1: - free(B0); -err0: - /* Failure! */ - return (-1); -} diff --git a/trezor-crypto/crypto/secp256k1.c b/trezor-crypto/crypto/secp256k1.c deleted file mode 100644 index 9b1f0d82e48..00000000000 --- a/trezor-crypto/crypto/secp256k1.c +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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 - -const ecdsa_curve secp256k1 = { - /* .prime */ {/*.val =*/{0x1ffffc2f, 0x1ffffff7, 0x1fffffff, 0x1fffffff, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, - 0xffffff}}, - - /* G */ - {/*.x =*/{/*.val =*/{0x16f81798, 0x0f940ad8, 0x138a3656, 0x17f9b65b, - 0x10b07029, 0x114ae743, 0x0eb15681, 0x0fdf3b97, - 0x79be66}}, - /*.y =*/{/*.val =*/{0x1b10d4b8, 0x023e847f, 0x01550667, 0x0f68914d, - 0x108a8fd1, 0x1dfe0708, 0x11957693, 0x0ee4d478, - 0x483ada}}}, - - /* order */ - {/*.val =*/{0x10364141, 0x1e92f466, 0x12280eef, 0x1db9cd5e, 0x1fffebaa, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0xffffff}}, - - /* order_half */ - {/*.val =*/{0x081b20a0, 0x1f497a33, 0x09140777, 0x0edce6af, 0x1ffff5d5, - 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x7fffff}}, - - /* a */ 0, - - /* b */ {/*.val =*/{7}} - -#if USE_PRECOMPUTED_CP - , - /* cp */ - { -#include "secp256k1.table" - } -#endif -}; - -const curve_info secp256k1_info = { - .bip32_name = "Bitcoin seed", - .params = &secp256k1, - .hasher_base58 = HASHER_SHA2D, - .hasher_sign = HASHER_SHA2D, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; - -const curve_info secp256k1_decred_info = { - .bip32_name = "Bitcoin seed", - .params = &secp256k1, - .hasher_base58 = HASHER_BLAKED, - .hasher_sign = HASHER_BLAKE, - .hasher_pubkey = HASHER_BLAKE_RIPEMD, - .hasher_script = HASHER_BLAKE, -}; - -const curve_info secp256k1_groestl_info = { - .bip32_name = "Bitcoin seed", - .params = &secp256k1, - .hasher_base58 = HASHER_GROESTLD_TRUNC, - .hasher_sign = HASHER_SHA2, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; - -const curve_info secp256k1_smart_info = { - .bip32_name = "Bitcoin seed", - .params = &secp256k1, - .hasher_base58 = HASHER_SHA3K, - .hasher_sign = HASHER_SHA2, - .hasher_pubkey = HASHER_SHA2_RIPEMD, - .hasher_script = HASHER_SHA2, -}; diff --git a/trezor-crypto/crypto/secp256k1.table b/trezor-crypto/crypto/secp256k1.table deleted file mode 100644 index 0fa87a8b16c..00000000000 --- a/trezor-crypto/crypto/secp256k1.table +++ /dev/null @@ -1,1664 +0,0 @@ - { - /* 1*16^0*G: */ - {{{0x16f81798, 0x0f940ad8, 0x138a3656, 0x17f9b65b, 0x10b07029, 0x114ae743, 0x0eb15681, 0x0fdf3b97, 0x79be66}}, - {{0x1b10d4b8, 0x023e847f, 0x01550667, 0x0f68914d, 0x108a8fd1, 0x1dfe0708, 0x11957693, 0x0ee4d478, 0x483ada}}}, - /* 3*16^0*G: */ - {{{0x1ce036f9, 0x100f889d, 0x1be66c21, 0x03908b06, 0x15229b53, 0x07c2fc4e, 0x0c4124d1, 0x00324b18, 0xf9308a}}, - {{0x04b8e672, 0x05cfebac, 0x1088c6db, 0x01533269, 0x1f356650, 0x1bf3151b, 0x00503f8c, 0x01ec65bd, 0x388f7b}}}, - /* 5*16^0*G: */ - {{{0x1240efe4, 0x1d46ab4d, 0x1866adf2, 0x17097bb8, 0x05128e88, 0x1392852e, 0x024d56d2, 0x09a340e4, 0x2f8bde}}, - {{0x06ac62d6, 0x0543e9d5, 0x035a1037, 0x104e3756, 0x1c426f78, 0x14eed364, 0x0f5b536e, 0x04c6dcbc, 0xd8ac22}}}, - /* 7*16^0*G: */ - {{{0x0ac4f9bc, 0x095eef6e, 0x0c38e73a, 0x0336fc06, 0x07a0e3d4, 0x19b2f975, 0x13aa8e63, 0x0c8dcbb6, 0x5cbdf0}}, - {{0x087264da, 0x08413140, 0x1f79ed69, 0x07a17027, 0x054dba81, 0x06b6c30d, 0x05828c5e, 0x081744ab, 0x6aebca}}}, - /* 9*16^0*G: */ - {{{0x1c27ccbe, 0x1af8886f, 0x15f9c530, 0x0f2d2e98, 0x19abde09, 0x0bc54faa, 0x194c26b4, 0x1c5e18fe, 0xacd484}}, - {{0x064f9c37, 0x0e613156, 0x17e383c1, 0x1111486e, 0x161e9add, 0x04b8bb1d, 0x07f590e0, 0x043614fb, 0xcc3389}}}, - /* 11*16^0*G: */ - {{{0x1da008cb, 0x1f60bc4a, 0x105e246e, 0x133017cb, 0x05aac564, 0x1235b863, 0x04797bd0, 0x1f0b1528, 0x774ae7}}, - {{0x0953c61b, 0x00eba64e, 0x1e75aa0c, 0x1b63c5bf, 0x1b365372, 0x0eab6bdb, 0x1864090f, 0x065d6d6b, 0xd984a0}}}, - /* 13*16^0*G: */ - {{{0x19405aa8, 0x176efc78, 0x03963377, 0x0bf78cc2, 0x08651b07, 0x0902e1ba, 0x022f1f47, 0x185b2ea5, 0xf28773}}, - {{0x1b03ed81, 0x0dae5a96, 0x07ea47ca, 0x140db4a4, 0x1af473a1, 0x0975b2e6, 0x0a25d608, 0x05d1b101, 0xab090}}}, - /* 15*16^0*G: */ - {{{0x027e080e, 0x056de7c7, 0x017de791, 0x0b28de79, 0x1f41131e, 0x0d7184af, 0x0a596919, 0x09efa87d, 0xd7924d}}, - {{0x16a26b58, 0x0826e4ff, 0x05b4e971, 0x015e57b1, 0x06defea4, 0x17611466, 0x0a9a0e10, 0x0e550d8e, 0x581e28}}} - }, - { - /* 1*16^1*G: */ - {{{0x0a6dec0a, 0x027744f1, 0x1e96ba71, 0x0626d370, 0x03e97b2a, 0x155e10e1, 0x1b14c046, 0x1276b3d3, 0xe60fce}}, - {{0x09616821, 0x0f996673, 0x148fc2f8, 0x0d123c89, 0x13710129, 0x0f9a7abc, 0x164a76e6, 0x0e733cb2, 0xf7e350}}}, - /* 3*16^1*G: */ - {{{0x1118e5c3, 0x1ec38550, 0x0afaf066, 0x0f364e8a, 0x05b4bfc5, 0x12b77a73, 0x01f6d105, 0x0bb2c8a6, 0x6eca33}}, - {{0x05a08668, 0x0c517bc0, 0x1e3b0d12, 0x12d47477, 0x075a03a4, 0x0bc83a5c, 0x1c4164bd, 0x16af4f40, 0xd50123}}}, - /* 5*16^1*G: */ - {{{0x0f87f62e, 0x16698f0a, 0x1c5849c3, 0x0dcc70c6, 0x059f010e, 0x1a2769a3, 0x03b035f1, 0x17de37f2, 0xe9623b}}, - {{0x044ee737, 0x1809f57d, 0x1a211394, 0x008793ba, 0x0a929fe6, 0x0a9d476d, 0x07a783fa, 0x07697853, 0x38a974}}}, - /* 7*16^1*G: */ - {{{0x0a8d733c, 0x18556fc1, 0x1f2a3e7a, 0x04e97ec5, 0x0d682ffc, 0x11b79040, 0x16e82212, 0x0e7ca2c3, 0xbc82dd}}, - {{0x147797f0, 0x13c30827, 0x0e25cc07, 0x074175ce, 0x102dfae9, 0x1a5fb8cf, 0x12b152a6, 0x07408963, 0xe5f28c}}}, - /* 9*16^1*G: */ - {{{0x1fbc7671, 0x1f7f118a, 0x01638cb5, 0x1e3790a5, 0x0f490743, 0x08e70bcc, 0x0847480a, 0x0918ecae, 0x8e3d12}}, - {{0x18717dec, 0x178ee320, 0x0f85129f, 0x0a57554c, 0x1e90eb93, 0x0070c9c9, 0x0e07d912, 0x1c21d9f9, 0x99a48}}}, - /* 11*16^1*G: */ - {{{0x1eb31db2, 0x1943a195, 0x1d41a83c, 0x15d04f11, 0x0a2b68fc, 0x0c9f6844, 0x126225a8, 0x15444694, 0x78a891}}, - {{0x19fa4343, 0x034eb11d, 0x002e0b4c, 0x0f379bb0, 0x02df6543, 0x192a9398, 0x172ff3d7, 0x0b7d6a06, 0x6912a3}}}, - /* 13*16^1*G: */ - {{{0x0db0e595, 0x09a47bbc, 0x0820aed9, 0x0c7973f7, 0x076eba71, 0x1bb2c0b0, 0x0c5f5f38, 0x030abb63, 0x7d8678}}, - {{0x1c733de8, 0x0ca8f1d5, 0x09754ca6, 0x0f089c1c, 0x18838293, 0x1715f6a7, 0x01dcb958, 0x1bfd90df, 0xe2b99a}}}, - /* 15*16^1*G: */ - {{{0x16060dfc, 0x047f7c28, 0x179a8a80, 0x08bf0840, 0x0b086765, 0x05cee20d, 0x0b212125, 0x01e00b05, 0xddc531}}, - {{0x07820ca8, 0x1afc55b7, 0x1411cc3e, 0x175f8d57, 0x10e9041d, 0x15b6e647, 0x1a480646, 0x075e41b2, 0xba0d2f}}} - }, - { - /* 1*16^2*G: */ - {{{0x15f51508, 0x123711fe, 0x0b072841, 0x073957ab, 0x1e238d8c, 0x171f0b96, 0x0767a8a9, 0x064258c1, 0x828226}}, - {{0x16e26caf, 0x18db757f, 0x1ec5efb4, 0x0c27585e, 0x00ace62d, 0x0b74185b, 0x1f917a09, 0x0130aafb, 0x11f8a8}}}, - /* 3*16^2*G: */ - {{{0x057e8dfa, 0x07e065cf, 0x11f8613f, 0x01232347, 0x18ca0098, 0x187c5654, 0x11303668, 0x05fe0f33, 0x8262cf}}, - {{0x1bac376a, 0x0e7fc6c7, 0x05311e0d, 0x0dda6656, 0x14f3457b, 0x111762d9, 0x19399bfb, 0x1c412213, 0x83fd95}}}, - /* 5*16^2*G: */ - {{{0x026bdb6f, 0x02972458, 0x1cd2e524, 0x0837a8f6, 0x19c877ca, 0x02d92674, 0x17545a04, 0x1163b41b, 0x19825c}}, - {{0x049cfc9b, 0x0efb8426, 0x1db4e9ad, 0x13dd9919, 0x19f6cebe, 0x10e64a7a, 0x1e3cc809, 0x01e1a990, 0x629431}}}, - /* 7*16^2*G: */ - {{{0x1d82824c, 0x07684a91, 0x054d3994, 0x0b1c68bc, 0x0999edfa, 0x1ab76361, 0x04510f17, 0x0d822c03, 0x6f12d8}}, - {{0x06eb34d0, 0x0bce1a40, 0x152f16e1, 0x19248210, 0x03769391, 0x0a79feb1, 0x1e821d66, 0x1e895677, 0x5c4ff7}}}, - /* 9*16^2*G: */ - {{{0x1b453629, 0x1b6ee016, 0x167980c1, 0x1fb9b81e, 0x0bef645c, 0x138b511d, 0x09745098, 0x0df34155, 0x203a8c}}, - {{0x1ff89f84, 0x0b8e3c29, 0x0a17b516, 0x1bd64b8a, 0x10612686, 0x1b68afa0, 0x06e4db31, 0x0a7bcbbb, 0x3b0f0b}}}, - /* 11*16^2*G: */ - {{{0x046c7ecb, 0x018986ef, 0x0ed33a5e, 0x15da7fcb, 0x0e1ec9d3, 0x1b99a433, 0x0607207b, 0x1d67a068, 0x6e2aca}}, - {{0x0ebc8720, 0x024900f7, 0x19d44b21, 0x0e0d7236, 0x1643afac, 0x026d787d, 0x18527603, 0x0cf2fdfd, 0x9e61a4}}}, - /* 13*16^2*G: */ - {{{0x10a4147e, 0x1b80c79f, 0x1d7c807a, 0x0fbb17ee, 0x10a58274, 0x18bf4524, 0x15aebd85, 0x125d3d22, 0xd5a704}}, - {{0x13fb65ff, 0x1259e5c1, 0x19fd5fe3, 0x09b308f2, 0x00532f4c, 0x04c83b2f, 0x071bf124, 0x1ebb7571, 0x9db526}}}, - /* 15*16^2*G: */ - {{{0x18edcec6, 0x16eda35e, 0x18d3d153, 0x0c3985a6, 0x0dac6a10, 0x17e31816, 0x0ea0148f, 0x13557c31, 0x38c511}}, - {{0x1933db08, 0x0b705fd8, 0x154c2991, 0x02d90456, 0x1282f28a, 0x196d13af, 0x0ca99a32, 0x0450bb2e, 0xe649dd}}} - }, - { - /* 1*16^3*G: */ - {{{0x11e5b739, 0x1fe72daa, 0x0888bb5c, 0x127067fa, 0x0846de0b, 0x0e63637e, 0x1969cbe6, 0x13ee5170, 0x175e15}}, - {{0x09fed695, 0x17d37ff7, 0x090d171b, 0x0b2ab5ba, 0x11f5eacb, 0x0bd28ffb, 0x07ae93be, 0x01b3c78f, 0xd3506e}}}, - /* 3*16^3*G: */ - {{{0x05041216, 0x0dbfc78e, 0x0ae0da99, 0x066bed08, 0x1ed523f7, 0x0cf7ee17, 0x13d04a2d, 0x0f643ef5, 0xda7531}}, - {{0x0e708572, 0x176994c3, 0x1eb3b6b6, 0x1580f5ce, 0x17fc6e9a, 0x110d9a16, 0x17c37c67, 0x08d7ee5a, 0x73f8a0}}}, - /* 5*16^3*G: */ - {{{0x0465a930, 0x00a1f38f, 0x04d4bf6c, 0x0fe382d6, 0x0eb1e258, 0x02c62541, 0x075c15cf, 0x1691d2e9, 0x1c71c5}}, - {{0x034638b5, 0x0c39fb66, 0x05d351c7, 0x08bc7f6e, 0x1b68c793, 0x18f94125, 0x08309c4f, 0x069d1ebf, 0x4a91c3}}}, - /* 7*16^3*G: */ - {{{0x1adb6ee7, 0x18c6d72d, 0x11281df8, 0x01ba864e, 0x14c9c785, 0x01bd484d, 0x159a4dba, 0x1f83e634, 0xd84e4a}}, - {{0x142ebed2, 0x16aab736, 0x08f99260, 0x11592e95, 0x1de4dfdd, 0x06ac7ab2, 0x07384a8e, 0x134f8f6f, 0xe52580}}}, - /* 9*16^3*G: */ - {{{0x049e6d10, 0x0a74f67d, 0x0b26748e, 0x15bfe75d, 0x16ed3f60, 0x15c942ff, 0x053506c8, 0x097bccd0, 0xf3d444}}, - {{0x1347da3f, 0x101c6602, 0x075b18c2, 0x15b4a19d, 0x04b5bfc1, 0x0ad60cc5, 0x18f52eae, 0x1bf4de02, 0xa4324}}}, - /* 11*16^3*G: */ - {{{0x09d33a07, 0x0659a037, 0x0e6f2ad2, 0x05dc1154, 0x1f4044e7, 0x0a9066de, 0x1627e421, 0x0593b383, 0xae3065}}, - {{0x00a0b2a6, 0x0438607b, 0x15fa571d, 0x186febbf, 0x0d5cf1c9, 0x13e99edc, 0x195fbf33, 0x1871ac7f, 0x6cb9d9}}}, - /* 13*16^3*G: */ - {{{0x0c28caca, 0x0cb2a5c8, 0x00a0769d, 0x138f7799, 0x08c9a186, 0x1f3ac19c, 0x07205785, 0x054b7abc, 0xd8dc1b}}, - {{0x03b3ec7a, 0x0db3b751, 0x004a3db3, 0x02ba59d9, 0x07d947d3, 0x06d21012, 0x1f5631b6, 0x1b24f9d8, 0x8cec0a}}}, - /* 15*16^3*G: */ - {{{0x1bc4416f, 0x090fdb31, 0x02c100a2, 0x1dfa47e6, 0x0f31da7a, 0x12d46819, 0x1b335650, 0x1258bf09, 0x2749e2}}, - {{0x1c6bbd8e, 0x14c5ef17, 0x1a58415f, 0x1d3f6cbd, 0x0db3ef59, 0x0a4c87e5, 0x0f1100f6, 0x09c6ece5, 0x50cc2d}}} - }, - { - /* 1*16^4*G: */ - {{{0x03ff4640, 0x135d6c7c, 0x154bff94, 0x0838fcaa, 0x02ee0534, 0x1602db13, 0x1272673a, 0x1a88f601, 0x363d90}}, - {{0x1bee9de9, 0x1001e3f9, 0x0667b2d8, 0x13512010, 0x1363145b, 0x0229cbf9, 0x088654ed, 0x15bf8e64, 0x4e273}}}, - /* 3*16^4*G: */ - {{{0x16e55dc8, 0x1c4890b7, 0x12810e52, 0x12b56dd5, 0x094426ff, 0x12206028, 0x1ecaea12, 0x08f218bf, 0x443140}}, - {{0x1be323b3, 0x0eca2576, 0x0a8b940c, 0x14536f3d, 0x0fed7a66, 0x01bfab21, 0x1be3fa66, 0x085cca6c, 0x96b0c1}}}, - /* 5*16^4*G: */ - {{{0x101b23a8, 0x1f4a42eb, 0x01fb82b7, 0x16fa8e15, 0x1089dab7, 0x01eadc90, 0x01f04989, 0x11b0cd95, 0x9e22fe}}, - {{0x0884edae, 0x1d209e28, 0x14473b3d, 0x0f9293f6, 0x01533c0f, 0x1f8104ce, 0x14405dfc, 0x1d394245, 0xfd2ff0}}}, - /* 7*16^4*G: */ - {{{0x071a70e4, 0x0ba045f8, 0x173d1d77, 0x1dca3ebe, 0x1306dcd5, 0x14f32382, 0x0a34bb75, 0x1aa079c5, 0x508df6}}, - {{0x09950984, 0x1972dfb9, 0x02ab7fb7, 0x006451dd, 0x049c54ec, 0x0255399f, 0x10b5ddcc, 0x13726778, 0x154c43}}}, - /* 9*16^4*G: */ - {{{0x0e1abe11, 0x157ed3b6, 0x12c883db, 0x124384b3, 0x125b2dab, 0x1ac0c980, 0x1d8cce37, 0x108aa212, 0xe3dbff}}, - {{0x1fa8de63, 0x1a4d6aa4, 0x1ad71052, 0x12fb2078, 0x08ef3d3c, 0x1d3aedc5, 0x108590e3, 0x01334682, 0x6f2f9}}}, - /* 11*16^4*G: */ - {{{0x03593449, 0x078d91b0, 0x0a91bff7, 0x16f825c8, 0x1014af61, 0x0e09d03e, 0x10361e36, 0x0c98fbd2, 0x19ace0}}, - {{0x0df83631, 0x120a5c9d, 0x0101a28e, 0x02173e81, 0x02c46ac7, 0x0b9ceca0, 0x0cceffaf, 0x006a4d14, 0xe37992}}}, - /* 13*16^4*G: */ - {{{0x0cba6b63, 0x11f4c496, 0x02ceed7b, 0x1fcce9fa, 0x08e310a0, 0x19914754, 0x16a84230, 0x1d841f0f, 0xd8740c}}, - {{0x0934c5f3, 0x1751b603, 0x005a52af, 0x009eb987, 0x0c37d401, 0x1774c81d, 0x0afcde29, 0x0678d726, 0x6472c1}}}, - /* 15*16^4*G: */ - {{{0x1b3ec038, 0x0ca7f960, 0x031ac9d8, 0x1aa2d5cc, 0x10a50d9f, 0x1f3b1794, 0x020d9220, 0x07236a0c, 0x58ac33}}, - {{0x10246279, 0x17551f88, 0x13eef285, 0x12087816, 0x1fe97021, 0x0924f4c8, 0x0b65e1de, 0x00daab92, 0x9163d7}}} - }, - { - /* 1*16^5*G: */ - {{{0x1ffdf80c, 0x0fbcd2ae, 0x16f346da, 0x094f0342, 0x1638843e, 0x025adba2, 0x0afa3189, 0x02cbbe78, 0x8b4b5f}}, - {{0x1fd4fd36, 0x1f7f8632, 0x18bb95ac, 0x066ca8c2, 0x0da04f9e, 0x0bc09d58, 0x02d2cfef, 0x0ded1a61, 0x4aad0a}}}, - /* 3*16^5*G: */ - {{{0x155812dd, 0x05152c17, 0x0b4c38a8, 0x08ce46aa, 0x0f78e3d4, 0x1f6b602c, 0x14bc2daa, 0x0f525fe6, 0x7029bd}}, - {{0x1a2d2927, 0x10e63358, 0x0cb1cf1c, 0x15d08487, 0x083ac47d, 0x0a257183, 0x0f49f759, 0x1b5fbd16, 0xb0eefa}}}, - /* 5*16^5*G: */ - {{{0x1d486ed1, 0x0e72b41d, 0x1596da92, 0x0b7d7492, 0x17560574, 0x0084ec67, 0x12640275, 0x195d5ccb, 0x9ccfed}}, - {{0x15e95d8d, 0x1b6acf6b, 0x164aa893, 0x02ceb2d2, 0x13411242, 0x12409005, 0x0b3ed848, 0x0e27ad46, 0x7c2f4d}}}, - /* 7*16^5*G: */ - {{{0x1bd0eaca, 0x10358d3a, 0x0b52ade8, 0x0e8aed74, 0x0df19d0c, 0x1ef19e52, 0x050cd6a3, 0x10ec6828, 0xcd9a4b}}, - {{0x0bff4acc, 0x137d7dad, 0x1bd8d3db, 0x0f671dda, 0x0a08b012, 0x0457499f, 0x08fa0552, 0x0f343d1e, 0xf04558}}}, - /* 9*16^5*G: */ - {{{0x07bc57c6, 0x104a9d1e, 0x0c9db2fc, 0x07af447d, 0x03094490, 0x169749eb, 0x0faa213c, 0x05f11db3, 0xad0988}}, - {{0x0e4a0ab8, 0x1196076d, 0x0438b4f2, 0x023a6e6b, 0x0be5f7b3, 0x036394ed, 0x14ae8a06, 0x11885f74, 0x7243c0}}}, - /* 11*16^5*G: */ - {{{0x0ba56302, 0x14186395, 0x03c618ba, 0x0d526f5e, 0x0d2e0f50, 0x116954fd, 0x107c7ab6, 0x015d6794, 0xd9d129}}, - {{0x08291c29, 0x156ed7d4, 0x09d3caba, 0x135d9b3f, 0x186e4173, 0x0ae33931, 0x1bb40a5c, 0x027d85a7, 0x7eb531}}}, - /* 13*16^5*G: */ - {{{0x14d1243a, 0x1669b827, 0x15297f6e, 0x024c047e, 0x1558402b, 0x10d6031f, 0x13be4734, 0x1bca73ad, 0xbc5079}}, - {{0x055db68a, 0x0e4a8b44, 0x1d1c5a7d, 0x1dc9eb63, 0x1c8d75f7, 0x195ca6ff, 0x12ee3bb1, 0x07674e0b, 0x65062a}}}, - /* 15*16^5*G: */ - {{{0x174a3f9f, 0x06922735, 0x02605a42, 0x0f4ccbb8, 0x0625ac28, 0x15573ed9, 0x1fa244f7, 0x0fca0bf8, 0x4d31a7}}, - {{0x101e0ba7, 0x1e581209, 0x18029d53, 0x0df6a36d, 0x02753cbf, 0x079c63c0, 0x1d6c1ac6, 0x192c130a, 0x22241e}}} - }, - { - /* 1*16^6*G: */ - {{{0x1232fcda, 0x1b08ac92, 0x1039def2, 0x01b7ff4d, 0x148c7b70, 0x18e005ea, 0x05b5afdd, 0x14dcbb73, 0x723cba}}, - {{0x1eb39f5f, 0x0ee034ec, 0x1e525200, 0x0140ca6e, 0x04d6e266, 0x09ba4441, 0x1262a484, 0x16ab2b98, 0x96e867}}}, - /* 3*16^6*G: */ - {{{0x00633cb1, 0x0b3f04f4, 0x140844c9, 0x144496d3, 0x01fcb575, 0x1399090c, 0x0b500318, 0x1e62f559, 0x6dde9c}}, - {{0x07ce6b34, 0x1eea4d53, 0x0167bcd5, 0x04ffb59f, 0x066a880b, 0x17c350dd, 0x10757267, 0x1cf4e0fc, 0x9188fb}}}, - /* 5*16^6*G: */ - {{{0x0933f3c5, 0x0cd28c69, 0x1c494890, 0x141ee22b, 0x1b850085, 0x1dbfc723, 0x17a04f12, 0x059ab6b9, 0x486fa7}}, - {{0x0afb0f53, 0x16a538d6, 0x03c8ede6, 0x136f079e, 0x0f19f62d, 0x045d7664, 0x150f9231, 0x033ead7b, 0x62e123}}}, - /* 7*16^6*G: */ - {{{0x1e99f728, 0x1eaca112, 0x1c48813a, 0x06ebf7cd, 0x05303677, 0x1f93dbb5, 0x1d3ed993, 0x0e951295, 0x247969}}, - {{0x0baaebff, 0x1d0028b7, 0x1d68b60d, 0x17e7812a, 0x1664a5ad, 0x143f3ec6, 0x0007b14b, 0x088d11e6, 0xe3d78d}}}, - /* 9*16^6*G: */ - {{{0x0fb0079a, 0x0f0636a1, 0x04981272, 0x1f3dee47, 0x18324916, 0x0cf73b59, 0x1fc18c69, 0x1b547aab, 0x2f39cb}}, - {{0x0c5690ba, 0x1114b981, 0x0a808c3f, 0x167f7910, 0x1a58b9bf, 0x1b6813c6, 0x060d36a4, 0x1bc270c7, 0xabeadb}}}, - /* 11*16^6*G: */ - {{{0x04f7ab73, 0x09980597, 0x1110e9de, 0x07a9d53a, 0x0aed262e, 0x0f43629a, 0x06e95a8e, 0x0d864fac, 0xe5a31d}}, - {{0x10561f42, 0x089d1fe3, 0x032e884e, 0x18889350, 0x0ce5dbf8, 0x054bbd27, 0x15e83046, 0x07b1a3d3, 0x37788c}}}, - /* 13*16^6*G: */ - {{{0x014dcd86, 0x07c94d1e, 0x0fdc6d62, 0x0ba8412d, 0x1dcf11fc, 0x0ecc1028, 0x111f7d43, 0x0941a2a6, 0xcc389d}}, - {{0x08f0a873, 0x075b6ece, 0x1f9e1d1a, 0x0afc31fc, 0x110ca05c, 0x05eddf54, 0x0fb66d5a, 0x1acc1ed7, 0x93ae4f}}}, - /* 15*16^6*G: */ - {{{0x18819311, 0x07ce375b, 0x01dc51c9, 0x1c3dc421, 0x1ed1f0b3, 0x10bf067a, 0x0408dd42, 0x1913ae3d, 0x7f9291}}, - {{0x0c2eb125, 0x14fcdabd, 0x01a85d2a, 0x15548139, 0x015b6120, 0x0f462292, 0x1bc3d743, 0x020c7d87, 0x9da00d}}} - }, - { - /* 1*16^7*G: */ - {{{0x0e7dd7fa, 0x1299f650, 0x0a4660e6, 0x0f2c246f, 0x0d3b5094, 0x17640961, 0x1e62e97f, 0x1a9277d7, 0xeebfa4}}, - {{0x01de8999, 0x0fea7ed7, 0x047dc4b7, 0x099b874e, 0x0089d9ae, 0x1f6d78bc, 0x03c9a7b9, 0x1472e1de, 0x5d9a8c}}}, - /* 3*16^7*G: */ - {{{0x1b7ceceb, 0x1fb3c7fd, 0x05febc3c, 0x0b3f2711, 0x0681473a, 0x1c0937b7, 0x1140dbfe, 0x04084eda, 0x437a86}}, - {{0x16c181e1, 0x1b1de61a, 0x03e5e09c, 0x041f9fb9, 0x097ff872, 0x1f5b4ce9, 0x0cbda6e3, 0x1427dd58, 0xb916b}}}, - /* 5*16^7*G: */ - {{{0x097f96f2, 0x0c6b94f0, 0x121cd735, 0x046a53a5, 0x0c273358, 0x1f1dcd1e, 0x06f20f2d, 0x027c5491, 0xa9ef9f}}, - {{0x16c04be4, 0x01eaad82, 0x06d1c0b0, 0x1f135eb5, 0x1613db74, 0x170b075d, 0x15f3655b, 0x1cb28ab3, 0xe814cc}}}, - /* 7*16^7*G: */ - {{{0x150cf77e, 0x0055ad09, 0x0a2ac36f, 0x17eae8a9, 0x0064207d, 0x13eb4fd5, 0x16f954e0, 0x083dc3a6, 0x66d805}}, - {{0x00eaa3a6, 0x12fcbd7d, 0x0c6ddb4a, 0x0968756f, 0x013f6944, 0x0a1029ab, 0x0d0b0fc7, 0x1ce65fff, 0x51cfdf}}}, - /* 9*16^7*G: */ - {{{0x07213a5a, 0x1aa43144, 0x17e98ae4, 0x064094f0, 0x0c3c80b7, 0x0450e326, 0x1e8afcd4, 0x1c26ca07, 0x62ac05}}, - {{0x146a9e45, 0x08690e07, 0x1e653bf0, 0x12120302, 0x12579e55, 0x13cf03d4, 0x1b934e57, 0x1e741a34, 0x236fbd}}}, - /* 11*16^7*G: */ - {{{0x07bad12b, 0x187ea4c3, 0x1d9b87b0, 0x0bd401d5, 0x12db385d, 0x09d7ae37, 0x1d6d6fd8, 0x092e4891, 0xca13c4}}, - {{0x1723b0f2, 0x0b4cfa34, 0x095d59a2, 0x0156e223, 0x1a3d6637, 0x1d327556, 0x1f22b057, 0x106c3850, 0x83aa09}}}, - /* 13*16^7*G: */ - {{{0x1c80414e, 0x0d772fca, 0x19b3dff7, 0x1f150c5a, 0x09e4914e, 0x0e27a230, 0x0ba16b04, 0x0034e0a5, 0x1cecb1}}, - {{0x12169a3b, 0x0574a496, 0x1c8c7437, 0x0aafca88, 0x1ad16907, 0x11941af6, 0x13ed396a, 0x0cd2c12f, 0xf34360}}}, - /* 15*16^7*G: */ - {{{0x0ed810a9, 0x07ade462, 0x1c005571, 0x113a7e78, 0x123924f8, 0x0d7af8ef, 0x1e732543, 0x0ea09af1, 0x2a6990}}, - {{0x1a9b4728, 0x1c359c47, 0x105171f3, 0x1a8fd2fd, 0x104fc667, 0x0c34aa7d, 0x1f6b0fb1, 0x136d87bf, 0x54f903}}} - }, - { - /* 1*16^8*G: */ - {{{0x19a48db0, 0x1ebc1ad9, 0x0f00effb, 0x042b4536, 0x1de459f1, 0x08504dbd, 0x059c9e47, 0x1b4d2dce, 0x100f44}}, - {{0x0bc65a09, 0x1deae6b1, 0x14656b03, 0x1e9431fe, 0x10666b7f, 0x19980604, 0x0ddcbb23, 0x06325401, 0xcdd9e1}}}, - /* 3*16^8*G: */ - {{{0x15bc15b4, 0x05cd09a4, 0x168bb9a7, 0x0a051c8c, 0x1ca8d927, 0x0774e76b, 0x1727b616, 0x05ca3dd5, 0x10e90e}}, - {{0x18aa258d, 0x075f304a, 0x0edaa20d, 0x0b12c605, 0x11f754ca, 0x14630b56, 0x0109355e, 0x00701abc, 0xc68a37}}}, - /* 5*16^8*G: */ - {{{0x1fe75269, 0x0e9fe181, 0x0f4cc60b, 0x0f47980a, 0x17dcda37, 0x1c85b8a5, 0x18e115d6, 0x085b4a82, 0xf7422f}}, - {{0x17e49bd5, 0x04c07438, 0x08e63806, 0x07446fe9, 0x035977fb, 0x13ee5cfb, 0x04ff4633, 0x03466261, 0x406c2f}}}, - /* 7*16^8*G: */ - {{{0x15a7175f, 0x09db34b7, 0x073d0a99, 0x11cee3a6, 0x1debbedb, 0x0d2ac16a, 0x13fdca1e, 0x0082fa87, 0x2d8cad}}, - {{0x1b9d592a, 0x19bddc8d, 0x0d797833, 0x08d7fb39, 0x09d377a8, 0x197d3096, 0x0529eec8, 0x10663195, 0xc73f3b}}}, - /* 9*16^8*G: */ - {{{0x14b51045, 0x1a64de1c, 0x07096cf8, 0x0d912de6, 0x0cf73bbc, 0x1ea758f4, 0x1a962b9c, 0x03b7314d, 0x1ecbfd}}, - {{0x02c70026, 0x1d338808, 0x0d908b54, 0x000c8d68, 0x09b38b19, 0x05d8c24d, 0x0e9911f4, 0x06117338, 0x1cf6e2}}}, - /* 11*16^8*G: */ - {{{0x09358533, 0x1d66bb37, 0x1ed2e77d, 0x1267f3a9, 0x12a8c10a, 0x0ad148e9, 0x14a20fa5, 0x18bfcaee, 0x9a0894}}, - {{0x0360ba08, 0x19f0e2ee, 0x00376b7e, 0x0dcb7b77, 0x1c32165a, 0x1eafcaa7, 0x1f0c7e45, 0x18840371, 0xa79883}}}, - /* 13*16^8*G: */ - {{{0x198ef7f6, 0x0a202eb0, 0x01e3e7da, 0x07e7eef4, 0x0aea6592, 0x042939dc, 0x0b8d6f67, 0x093b69fa, 0x664dd8}}, - {{0x1d1eac94, 0x1a4b7f9a, 0x039bb3b9, 0x1a756637, 0x058cffc3, 0x0672ee82, 0x04ca8512, 0x02e2fe4f, 0xad5120}}}, - /* 15*16^8*G: */ - {{{0x03c934b3, 0x060535be, 0x02b8b138, 0x03eb00b6, 0x1a7022b3, 0x0cb34c08, 0x018e08c7, 0x126efa17, 0x82113a}}, - {{0x042c6a0f, 0x1f2f3156, 0x111a00dd, 0x1ef84d34, 0x0c628aa1, 0x16795ad0, 0x19982119, 0x1b5935c6, 0x8da1b8}}} - }, - { - /* 1*16^9*G: */ - {{{0x0534fd2d, 0x04566f37, 0x1cece14b, 0x1f1a88c9, 0x0c017a77, 0x113d2502, 0x146c7724, 0x1c4c58fd, 0xe1031b}}, - {{0x1456a00d, 0x0278c794, 0x073b5e69, 0x05ba833c, 0x1535af29, 0x120bb2cb, 0x0179aeda, 0x12512808, 0x9d7061}}}, - /* 3*16^9*G: */ - {{{0x0f028d83, 0x1cb11d77, 0x1d0e5855, 0x0b24db74, 0x069db619, 0x1f2d0aef, 0x17b1a96a, 0x189c78f0, 0xa7ebf7}}, - {{0x19d0bed1, 0x1201c95c, 0x014e4665, 0x07124e96, 0x0804b47a, 0x039bb822, 0x0b573f67, 0x05f7fc6c, 0x620515}}}, - /* 5*16^9*G: */ - {{{0x07dd5cfa, 0x17072011, 0x02752d6e, 0x138a26fe, 0x146336a8, 0x1529a131, 0x1d307371, 0x11b96049, 0x5b5ca0}}, - {{0x1e48e98c, 0x132537cc, 0x0c9a74f9, 0x00cf995e, 0x09094bfd, 0x18675443, 0x0097a647, 0x1ee1542b, 0x3eccb6}}}, - /* 7*16^9*G: */ - {{{0x03531f82, 0x1ca94719, 0x030b27ca, 0x0264d762, 0x02c29ff5, 0x1f3a44e1, 0x0ed733bc, 0x15982229, 0x46f26}}, - {{0x0bceda07, 0x082fe458, 0x0d571fe9, 0x0b28b9b5, 0x12579d02, 0x185617e1, 0x0bab388d, 0x062c6b70, 0x6b804b}}}, - /* 9*16^9*G: */ - {{{0x10432711, 0x058aa1b8, 0x045ae418, 0x08165fbb, 0x1645acf1, 0x1787844c, 0x1ed4d7e5, 0x1b263c1d, 0xc11926}}, - {{0x0fe2610c, 0x04930f17, 0x1cd01579, 0x17245941, 0x0c6cf83a, 0x05f8c366, 0x1a246125, 0x198fa4b6, 0x8be1f8}}}, - /* 11*16^9*G: */ - {{{0x01257963, 0x0bcc3a7d, 0x12aa1870, 0x031aa586, 0x179c45b0, 0x1aa5a9c4, 0x1cb9b36e, 0x1d3d6d11, 0x690846}}, - {{0x066f9835, 0x12bb2cca, 0x124ac94e, 0x18795043, 0x1bb7f6cb, 0x18127c97, 0x0f16d005, 0x196fe7fd, 0xe2485f}}}, - /* 13*16^9*G: */ - {{{0x1ee23ace, 0x0889ca5e, 0x1374bf4b, 0x10f8cb6a, 0x12915dec, 0x0a96fa51, 0x02eaee9d, 0x1f719244, 0xfb3df7}}, - {{0x1722e8de, 0x04ef7a64, 0x149fd7b8, 0x04e285fd, 0x0b58a9e7, 0x08aa06dd, 0x11594a89, 0x178238e7, 0x510e29}}}, - /* 15*16^9*G: */ - {{{0x10272351, 0x103e7f7a, 0x07fc4261, 0x06967bf3, 0x1cd41707, 0x11f59d58, 0x062cfae2, 0x1849eb8a, 0x6dd85e}}, - {{0x1fc7664b, 0x183fd15b, 0x18205f26, 0x18dfef87, 0x041b7877, 0x03fcd7ae, 0x09f82750, 0x1e8243e8, 0x16ea67}}} - }, - { - /* 1*16^10*G: */ - {{{0x1094696d, 0x0af3446c, 0x075abd4b, 0x1164cd48, 0x1d7ec5cf, 0x01cf8a1d, 0x0d4c2b0a, 0x15c8daab, 0xfeea6c}}, - {{0x18090088, 0x0aaef5f8, 0x10510b4c, 0x1912af98, 0x0cd5c981, 0x07095f9f, 0x06eac1b9, 0x0d92fb9c, 0xe57c6b}}}, - /* 3*16^10*G: */ - {{{0x08dfd587, 0x1c9b0dda, 0x0c099581, 0x09747193, 0x1a12d5ec, 0x1d55167a, 0x022cd219, 0x03759e8a, 0x5084b4}}, - {{0x11470e89, 0x13cf4bfc, 0x047d581b, 0x0deac0d1, 0x127475db, 0x13642a94, 0x14c5866a, 0x0343b301, 0x34a963}}}, - /* 5*16^10*G: */ - {{{0x1ab34cc6, 0x0411930b, 0x1cc284b4, 0x1852ecf9, 0x17128c80, 0x1f8fe8c6, 0x17a94fec, 0x07c0c85a, 0x4f14c0}}, - {{0x187e681f, 0x0f61297c, 0x00774089, 0x1c799d1d, 0x02540b9d, 0x1387a1d3, 0x0253194e, 0x1519549d, 0x7b53d0}}}, - /* 7*16^10*G: */ - {{{0x1241d90d, 0x013b8808, 0x09113e0d, 0x19e283b6, 0x1d363e81, 0x1b04af6e, 0x1b475050, 0x0fc938f3, 0xa74db8}}, - {{0x1f7adad4, 0x1928c5c1, 0x0828c4fc, 0x1ca12689, 0x171c8a9e, 0x08452c40, 0x1bcc9ff7, 0x19b5e47d, 0xf78691}}}, - /* 9*16^10*G: */ - {{{0x11c1ae1f, 0x0f665111, 0x13502ca9, 0x1cb18d15, 0x15658456, 0x06a275d1, 0x0b3e6b37, 0x0ae89754, 0x6901fa}}, - {{0x122838b0, 0x1c19832e, 0x11dea4c3, 0x1e774bcb, 0x0900dd79, 0x09c0614e, 0x0849186d, 0x11044e78, 0x35de5c}}}, - /* 11*16^10*G: */ - {{{0x127a4bdb, 0x1818840d, 0x12532b12, 0x14da086a, 0x1a35d046, 0x1b21f8dd, 0x049e8912, 0x05a3a870, 0x8d3cd8}}, - {{0x069a8a2c, 0x1e9a63e7, 0x02b4a5b0, 0x0700fa6e, 0x0236ed4e, 0x1fce803b, 0x07d1c33e, 0x0c301dc8, 0x9bd425}}}, - /* 13*16^10*G: */ - {{{0x14ec1d2d, 0x00669e35, 0x1f63d151, 0x133eb8dc, 0x1691fd90, 0x0b394b3d, 0x1ce6bfa7, 0x0c7ac0c8, 0xeaf983}}, - {{0x0c838452, 0x07f3ab02, 0x1a12d4ff, 0x0a5aa8af, 0x199aaa9f, 0x14507358, 0x1489dd48, 0x074ffcf1, 0xe51818}}}, - /* 15*16^10*G: */ - {{{0x045ae767, 0x059adfb8, 0x025dc72f, 0x0753973d, 0x0e5d8c27, 0x07029603, 0x18d19bd0, 0x02c75db6, 0xfb95bd}}, - {{0x1bbf0e11, 0x029f5057, 0x167c4d06, 0x0de8e314, 0x0275bb81, 0x06ce9b41, 0x16f14801, 0x1b02351b, 0x664c14}}} - }, - { - /* 1*16^11*G: */ - {{{0x01ec6cb1, 0x1fd4bc5e, 0x0160f78c, 0x1acafb01, 0x1ca3cfee, 0x1f25f37f, 0x1372cd9e, 0x03b22093, 0xda67a9}}, - {{0x1a68be1d, 0x14f54713, 0x1dd0285f, 0x0f5b8a11, 0x180e5dec, 0x11fbf64b, 0x0af107d1, 0x06a902c8, 0x9bacaa}}}, - /* 3*16^11*G: */ - {{{0x15bc8a44, 0x17ee8328, 0x18546867, 0x0202ef97, 0x05fc7684, 0x12d25d2d, 0x168f4e15, 0x0b079f9d, 0x4d0180}}, - {{0x1adbc09e, 0x18fca648, 0x00b68d8b, 0x08408d0b, 0x03813969, 0x1d4003eb, 0x174d9fa6, 0x1831969e, 0x3a33c6}}}, - /* 5*16^11*G: */ - {{{0x05daeb00, 0x00d5a943, 0x1917ddaf, 0x07d6499c, 0x0e9d1592, 0x1b5139db, 0x055c20b2, 0x00fbeb9f, 0x2f6615}}, - {{0x033992c0, 0x113b3c4c, 0x174c2304, 0x1bdc4e32, 0x0add06ec, 0x09bd4100, 0x0cfdbbe5, 0x026dea56, 0xfd5c12}}}, - /* 7*16^11*G: */ - {{{0x116aa6d9, 0x01548504, 0x1c0b73c6, 0x05916c8e, 0x15a38366, 0x0ba6d0c1, 0x1f48953c, 0x0fa0bfc8, 0xf59411}}, - {{0x1f2e50cf, 0x1e834b75, 0x1ad6e1b1, 0x04ef107c, 0x0bceb7a9, 0x0ded584a, 0x0c4b3d97, 0x14add2e3, 0xcaa761}}}, - /* 9*16^11*G: */ - {{{0x1ac6f4c0, 0x15701cab, 0x12f71332, 0x1d1bd198, 0x0711dda4, 0x01c5f34b, 0x137b1387, 0x0fe3e9b3, 0xf2d4d}}, - {{0x12339b58, 0x1f3ddd6b, 0x090995b9, 0x14214f20, 0x1e71e8f6, 0x13fef9c0, 0x19345fec, 0x10afd27b, 0x3ec89f}}}, - /* 11*16^11*G: */ - {{{0x1f428cb2, 0x02a829fe, 0x088ad576, 0x1045facd, 0x0d0f1233, 0x10c0acac, 0x0ef47ade, 0x185c5429, 0x1d5dce}}, - {{0x095b189b, 0x12f68804, 0x18112947, 0x1d225f0e, 0x10b88bd3, 0x03c12437, 0x0314341e, 0x10762859, 0x6e5c40}}}, - /* 13*16^11*G: */ - {{{0x08381273, 0x1875447d, 0x04f6b97e, 0x06ed2c0d, 0x126ced84, 0x14d96620, 0x1d0e7f7a, 0x1fa6012c, 0x89d9a2}}, - {{0x1309773d, 0x01f59f76, 0x049cc928, 0x03ad015a, 0x162f58f6, 0x17903b67, 0x1d40ddea, 0x168a3acd, 0xdfca25}}}, - /* 15*16^11*G: */ - {{{0x15c71d91, 0x06195965, 0x0253f487, 0x08bc5c55, 0x0fece239, 0x0e0988ad, 0x0b8714a8, 0x10f074a1, 0x83191b}}, - {{0x02148a61, 0x05cf6047, 0x01117b9c, 0x023ea2ea, 0x0ae8a17a, 0x0f09e8be, 0x0dc2781b, 0x02ae7003, 0xe0ac7f}}} - }, - { - /* 1*16^12*G: */ - {{{0x1a37b7c0, 0x1aa2e660, 0x0441a7d5, 0x11a1ef76, 0x02151ec0, 0x0049af79, 0x13769b80, 0x15416669, 0x53904f}}, - {{0x022771c8, 0x0e584b58, 0x110d1a67, 0x133303c2, 0x13c1c139, 0x16656106, 0x01b62327, 0x1a179002, 0x5bc087}}}, - /* 3*16^12*G: */ - {{{0x08a2050e, 0x0d6217f2, 0x17e299dc, 0x1deaaec2, 0x19b89742, 0x14e63723, 0x0c625add, 0x1fa4978e, 0x673724}}, - {{0x061d3d70, 0x0864d248, 0x0d2730ae, 0x1759fa86, 0x06b6dbe6, 0x01604d44, 0x088080d2, 0x0af12d49, 0xe4cf82}}}, - /* 5*16^12*G: */ - {{{0x02de63bf, 0x1fb7241c, 0x098719b2, 0x15ea650e, 0x166a8e03, 0x05318fb0, 0x10c27966, 0x148e5be9, 0x4366ef}}, - {{0x017924cd, 0x16352047, 0x0a9b5ac0, 0x1618a4b5, 0x068eaf33, 0x09bf0981, 0x1f38bb89, 0x0137dc5a, 0x2e7dd9}}}, - /* 7*16^12*G: */ - {{{0x06f96190, 0x08293ff8, 0x125497bc, 0x005bd20f, 0x0a75fd1f, 0x0ab4b33d, 0x0c7e5ef9, 0x0c4f3235, 0x7bd753}}, - {{0x0bda00f6, 0x1e8b9025, 0x03a9a568, 0x1f98b83c, 0x027d6ce0, 0x123a4a1c, 0x0c2757b5, 0x167b774c, 0x8336f2}}}, - /* 9*16^12*G: */ - {{{0x16ad41ed, 0x1d8a98aa, 0x1c0d490c, 0x11586be9, 0x0dc92030, 0x00cf448c, 0x1706be8d, 0x0f7bb55a, 0x4f7e92}}, - {{0x1e642d57, 0x1a1abc33, 0x0bddd6f7, 0x0628e29d, 0x0f6a62e7, 0x006fa9d4, 0x0c4154a6, 0x0a2ad511, 0xdfe774}}}, - /* 11*16^12*G: */ - {{{0x07748690, 0x1d302893, 0x18c2c073, 0x0f209bb0, 0x13d007d5, 0x0958f6e9, 0x133252d1, 0x10cfa523, 0x2355cb}}, - {{0x0c89582b, 0x1e23a98a, 0x0724e451, 0x10d0b19a, 0x07c58582, 0x02f60ad5, 0x07e3d56e, 0x114b4e3c, 0x21c2f1}}}, - /* 13*16^12*G: */ - {{{0x0ade7f16, 0x0d7510b0, 0x0f80a31b, 0x1975d279, 0x15d24ae9, 0x0955b613, 0x15b004d6, 0x0b7367b4, 0xb6682}}, - {{0x08c56217, 0x0a221342, 0x19f34af6, 0x08781be7, 0x1a97fb72, 0x1b5d45ab, 0x0cffbce9, 0x17031c13, 0xa1fba0}}}, - /* 15*16^12*G: */ - {{{0x19060d5b, 0x08358114, 0x0e8e9f0a, 0x0c276238, 0x151cb904, 0x0d97ecfc, 0x08b2d842, 0x079e17a0, 0xf60204}}, - {{0x1af88f13, 0x17b7a858, 0x17468fdd, 0x14ada56f, 0x17bea37a, 0x07b25627, 0x1c66206a, 0x00d83e19, 0xf036b7}}} - }, - { - /* 1*16^13*G: */ - {{{0x1ad86047, 0x1fcacfa1, 0x06e2f2bb, 0x0a740875, 0x0906779b, 0x053bb265, 0x0e9dc673, 0x017a6b30, 0x8e7bcd}}, - {{0x0460372a, 0x108023f4, 0x1f5a2cfa, 0x111c5c8f, 0x1514579e, 0x08210654, 0x12ce500c, 0x016547b4, 0x10b777}}}, - /* 3*16^13*G: */ - {{{0x041ead4b, 0x1f443cd0, 0x06c0f07f, 0x0bdbf6d2, 0x076be3a7, 0x19a77d7f, 0x0dfb1c51, 0x019191e6, 0xbfc90c}}, - {{0x06fedaed, 0x02963784, 0x182b8f9d, 0x0d1dfe65, 0x02d36fb4, 0x18c6ea82, 0x1b4936e9, 0x163c139b, 0x7a9481}}}, - /* 5*16^13*G: */ - {{{0x15bb3b3e, 0x173de83b, 0x07dcf2c9, 0x0a6c2fdf, 0x13f5b507, 0x0c9f4616, 0x0a937296, 0x0397c7f5, 0x732df1}}, - {{0x17366693, 0x02bbf0f6, 0x11610db3, 0x1b5adac9, 0x13916e69, 0x12ac2012, 0x05df2df8, 0x07dbd1f3, 0x7f4190}}}, - /* 7*16^13*G: */ - {{{0x088dc3b9, 0x0fad9e0c, 0x1dd32671, 0x0cd249d2, 0x1ef6019a, 0x0420664b, 0x1ed0a36a, 0x172c0728, 0x4ce094}}, - {{0x05c0de52, 0x00a7bdb7, 0x1a81940b, 0x00b64193, 0x0aca2162, 0x06c0653b, 0x0cfb55ed, 0x1757e353, 0x5390f}}}, - /* 9*16^13*G: */ - {{{0x0aaafe5a, 0x01baf058, 0x026bb753, 0x08e1674a, 0x03fd0e25, 0x1354ad81, 0x1f7a5b62, 0x16edf8cc, 0x9a968e}}, - {{0x0ed975c0, 0x135fea12, 0x19c33033, 0x0b1014cb, 0x01d0ee7b, 0x13681ec3, 0x08a553f1, 0x00f4da77, 0xabf6fb}}}, - /* 11*16^13*G: */ - {{{0x134c6397, 0x1a8e5fcf, 0x1d33424d, 0x1a7b6a00, 0x0b22107d, 0x17c0129b, 0x06553c2b, 0x1da02e2c, 0xd3c6fb}}, - {{0x08cb3f9c, 0x0fe4682b, 0x1783802c, 0x18ee1120, 0x0b6468a0, 0x1ca6c975, 0x0bc65160, 0x18abcbc5, 0x4a0dd2}}}, - /* 13*16^13*G: */ - {{{0x0ac3137e, 0x0dc12c98, 0x0bd91186, 0x04b6c54b, 0x13953fe9, 0x0353b555, 0x0ee380bc, 0x13025248, 0x4cbde3}}, - {{0x0ec02fe6, 0x00478ae7, 0x03ab5830, 0x074f5cb1, 0x0c370d19, 0x1509a5ca, 0x05654024, 0x0c11e26c, 0x6ce554}}}, - /* 15*16^13*G: */ - {{{0x00fbf84b, 0x1d118367, 0x0fc2e291, 0x091f9778, 0x0cebb03c, 0x0e39860a, 0x091ee2f6, 0x0790562c, 0x4b9d33}}, - {{0x036c3c48, 0x1cf725a5, 0x1d6d7988, 0x0daa87c5, 0x1b7eb676, 0x1ecc133c, 0x054954c4, 0x1f7c4998, 0xfd7fc7}}} - }, - { - /* 1*16^14*G: */ - {{{0x19c43862, 0x1420f0ac, 0x05f99a42, 0x0fe9e307, 0x01bde71a, 0x00c344dc, 0x1c879b42, 0x069839bf, 0x385eed}}, - {{0x142e5453, 0x022c7f2a, 0x01b72330, 0x009dd841, 0x1f4576b3, 0x0f0cf4f5, 0x0fd59c07, 0x187d1d44, 0x283beb}}}, - /* 3*16^14*G: */ - {{{0x16e2d9b3, 0x05e98355, 0x0e358d45, 0x17250636, 0x1845641d, 0x15309ce7, 0x179d784b, 0x1e72f8e0, 0x19a314}}, - {{0x0baaaf33, 0x0a97712e, 0x012f95b5, 0x043a3a48, 0x128b3a50, 0x12fc43fa, 0x03748d25, 0x1ebb58e5, 0x6cacd8}}}, - /* 5*16^14*G: */ - {{{0x12f00480, 0x0c2c3f58, 0x00373b9f, 0x0b100942, 0x07219203, 0x0c31b27b, 0x0a8d5772, 0x0972b51b, 0x5840ed}}, - {{0x1e22cf9e, 0x0c96af15, 0x0b8e1c85, 0x0a44a8a5, 0x1d8daba7, 0x06f550ae, 0x05041e5a, 0x0d64417e, 0x670cda}}}, - /* 7*16^14*G: */ - {{{0x03f54c42, 0x0426f741, 0x068f7239, 0x1834784d, 0x0532545d, 0x060fa767, 0x03ec7716, 0x14a68d23, 0x9f5701}}, - {{0x0feb6a21, 0x1070e249, 0x067949e1, 0x1cf09564, 0x1bfdd89e, 0x0db5ab94, 0x195efee5, 0x171003b3, 0xce7b8f}}}, - /* 9*16^14*G: */ - {{{0x1522461a, 0x14a09994, 0x11c60c9f, 0x06144cb7, 0x0f9a0bcb, 0x0380833f, 0x13f006ee, 0x0d246b51, 0x27f611}}, - {{0x07301a2d, 0x152657ce, 0x018e511a, 0x103641b5, 0x08ee8e49, 0x02b093a1, 0x0b4ba923, 0x1532014d, 0xe512f1}}}, - /* 11*16^14*G: */ - {{{0x114f36b9, 0x07164d96, 0x0e7ce433, 0x119576c7, 0x0a981259, 0x197a1afa, 0x0504986f, 0x10ad9ddf, 0x640779}}, - {{0x04b4b50a, 0x0a58f74f, 0x073baca2, 0x1410e093, 0x07b6c8cd, 0x0bafec2d, 0x1bebbe43, 0x11e89cad, 0xda6192}}}, - /* 13*16^14*G: */ - {{{0x14d6b76f, 0x17b1efcc, 0x120576f3, 0x0b53f769, 0x1feae7fe, 0x1845e04e, 0x1a7d14bd, 0x1c6390ac, 0xa23750}}, - {{0x0dcca8da, 0x0ec96664, 0x0e123450, 0x00f823fb, 0x11113e77, 0x1d1f26a0, 0x19b6b0cb, 0x0294dcfb, 0xf7339b}}}, - /* 15*16^14*G: */ - {{{0x1ceee475, 0x1774e327, 0x1b5e0ac4, 0x15905081, 0x0ff41ab6, 0x0010f9e5, 0x1e357b4f, 0x00f47e46, 0xbbf1ac}}, - {{0x07fe5067, 0x03115004, 0x02d075a1, 0x173b1287, 0x15fe324e, 0x1e641b58, 0x03984220, 0x1bdd5a8c, 0xb4bfb8}}} - }, - { - /* 1*16^15*G: */ - {{{0x03fac3a7, 0x10376c36, 0x11fef271, 0x1bf094b2, 0x1fa180fd, 0x19d2209e, 0x06458df1, 0x17007d9e, 0x6f9d9}}, - {{0x1a842160, 0x03448301, 0x0a0400b6, 0x09ba5eb8, 0x1c4d47ea, 0x11518722, 0x06e9a6e3, 0x11cc060b, 0x7c80c6}}}, - /* 3*16^15*G: */ - {{{0x121ce204, 0x076baf46, 0x19d8f549, 0x0e4b1c84, 0x0f72fb2a, 0x06c2ce53, 0x193ee0dd, 0x1a2c5678, 0x43ca41}}, - {{0x134a8f6b, 0x09282274, 0x09291a39, 0x0d8f667d, 0x1a31f9ab, 0x07c90c6d, 0x0fe87194, 0x105c6e04, 0xdcea5a}}}, - /* 5*16^15*G: */ - {{{0x0be6efda, 0x07e74967, 0x1ca01659, 0x1a9fe7f0, 0x0506d922, 0x1b91bc2d, 0x0fd6d99b, 0x1de45125, 0x9c3e06}}, - {{0x07aefc7d, 0x18a07995, 0x0dbf7df7, 0x1790d0f6, 0x06fd5d43, 0x196a2671, 0x08f62bc2, 0x1cbcec52, 0xa7b709}}}, - /* 7*16^15*G: */ - {{{0x06c88be2, 0x0893d5ae, 0x1bb9789e, 0x18f041a0, 0x0775bea2, 0x13acec18, 0x1c0ceedc, 0x14627c41, 0x5d6f8a}}, - {{0x0d7ad75d, 0x0972a9f8, 0x0fe4b0a2, 0x16df1d4d, 0x0bc20eda, 0x1799d584, 0x13a31c6a, 0x11b1aada, 0xadc4b1}}}, - /* 9*16^15*G: */ - {{{0x12d1b844, 0x1449a8dc, 0x1cf9213c, 0x18070582, 0x08bc5c69, 0x0ae1e09c, 0x157f21ac, 0x186094c1, 0xf57d35}}, - {{0x01266837, 0x125d5deb, 0x04571a91, 0x0d2e4061, 0x0634c700, 0x09fad4f2, 0x1365e413, 0x13d531de, 0x707f3d}}}, - /* 11*16^15*G: */ - {{{0x1cc7cb09, 0x1a6803f9, 0x146d0d48, 0x0fd6d143, 0x071463bc, 0x10ff71ec, 0x1297d65b, 0x0f474cb2, 0x13e760}}, - {{0x08079160, 0x1f3ad450, 0x0d5d9046, 0x15c576cd, 0x0299d65e, 0x1eec2d9a, 0x02c78c97, 0x11bd1f77, 0x284dc8}}}, - /* 13*16^15*G: */ - {{{0x18cdee05, 0x03067092, 0x0bb0ee40, 0x0c3f642e, 0x0901da87, 0x12858d83, 0x0b989000, 0x044ad030, 0x29bea3}}, - {{0x062651c8, 0x12501acd, 0x11a638e7, 0x18636d91, 0x05ec7f9f, 0x0d9fdc38, 0x083aa402, 0x144d21d3, 0x7c40d9}}}, - /* 15*16^15*G: */ - {{{0x12f18ada, 0x0db63ab0, 0x16f6f304, 0x017b2777, 0x14a59d46, 0x17d7f99e, 0x039f670d, 0x0da47051, 0xf52178}}, - {{0x03953516, 0x0eb457e9, 0x16fc2607, 0x1de946d8, 0x1d1d6aa5, 0x10815e68, 0x0d5fb309, 0x17ec071b, 0xe0686f}}} - }, - { - /* 1*16^16*G: */ - {{{0x02d0e6bd, 0x1dbf073a, 0x03d794c4, 0x09a2c7b6, 0x16ecbf77, 0x0a3e0826, 0x18960a88, 0x00248789, 0x3322d4}}, - {{0x0c28b2a0, 0x079d174b, 0x01cebd89, 0x0bec7d45, 0x0f9b7280, 0x0cde26ed, 0x1bd6fec0, 0x12fd2cc9, 0x56e707}}}, - /* 3*16^16*G: */ - {{{0x059ab499, 0x1ece9f90, 0x1cf0cc2a, 0x065338dc, 0x101bc0b1, 0x0b59e33f, 0x16e97486, 0x1e602b80, 0x78baaf}}, - {{0x1ee097fd, 0x00e918c7, 0x0494665a, 0x065ddd1a, 0x0082e916, 0x027076c1, 0x02bebf2a, 0x1b7b60d8, 0xad4bdc}}}, - /* 5*16^16*G: */ - {{{0x1d06ace6, 0x049f0b67, 0x0e883291, 0x01366df0, 0x1ab1a237, 0x024c2494, 0x0f53082e, 0x0234295c, 0x6f70f2}}, - {{0x1602d5de, 0x045f69a5, 0x16b17b81, 0x052acd7c, 0x19f50753, 0x0c79a3dc, 0x0dcdbe57, 0x0612804f, 0x791e8a}}}, - /* 7*16^16*G: */ - {{{0x00ee1b40, 0x04771f73, 0x1a5891f7, 0x1a90b6e3, 0x1ccd48ce, 0x04f8c881, 0x1057e025, 0x1653ad54, 0xe1599d}}, - {{0x178f93a6, 0x0eb132f6, 0x0ca66778, 0x0c74e978, 0x1c7cfa63, 0x04a55517, 0x1283bebe, 0x0465503a, 0x793362}}}, - /* 9*16^16*G: */ - {{{0x09c00c3e, 0x00efd142, 0x048238be, 0x1d1e0792, 0x11859f00, 0x11699ea2, 0x05590d95, 0x12e0880d, 0xbb0b04}}, - {{0x11955a35, 0x0cd4c168, 0x1772429e, 0x0e089d20, 0x1b052fe6, 0x17d0bd58, 0x1d8d9574, 0x0b0a75f3, 0x4067e4}}}, - /* 11*16^16*G: */ - {{{0x05dd32e6, 0x073adce0, 0x0f97b9f8, 0x076aa36a, 0x05fbfc66, 0x0edf03ad, 0x027a6d92, 0x0aa832af, 0xdc5a41}}, - {{0x154a99b9, 0x073edbd3, 0x1926f3e0, 0x05dd20ed, 0x159442ff, 0x12f100df, 0x1e9db73a, 0x14c7f3ec, 0x4af3a8}}}, - /* 13*16^16*G: */ - {{{0x0544e7cb, 0x16a2dd62, 0x0a580d67, 0x0c844b6a, 0x14e99a10, 0x0a52b880, 0x0e76f8cd, 0x0e0730e7, 0x156e19}}, - {{0x0d250a37, 0x0a9c9605, 0x0d0e735b, 0x0dab1abd, 0x14be8949, 0x0b9531c1, 0x01f6a4e5, 0x13f1e632, 0x6bc08d}}}, - /* 15*16^16*G: */ - {{{0x059853ca, 0x1fde14e6, 0x066fd536, 0x12c4d73e, 0x1161348e, 0x1b511473, 0x0e09af29, 0x19d96d08, 0x4269bc}}, - {{0x15b8d367, 0x14ac77a9, 0x196a28f6, 0x12814bf3, 0x1a409fd3, 0x0654e218, 0x1adc8f21, 0x03505802, 0xed2b1c}}} - }, - { - /* 1*16^17*G: */ - {{{0x0134ab83, 0x10eba694, 0x190ce5dc, 0x167f35ee, 0x05868741, 0x1b86c4b3, 0x1f68af45, 0x0fa5bc16, 0x85672c}}, - {{0x190313a6, 0x07184a7b, 0x0a63d132, 0x1e2ff98a, 0x0c2e5e77, 0x024dfd31, 0x0bad8dd0, 0x136b6876, 0x7c481b}}}, - /* 3*16^17*G: */ - {{{0x03ba9000, 0x0f8391d4, 0x097a2dbf, 0x0e5f38d0, 0x0143dc48, 0x1b03ac20, 0x0305a121, 0x1f3ffe3b, 0xac3874}}, - {{0x0f10cf0a, 0x0d1e3ecb, 0x19ba7e93, 0x1c6a1afe, 0x17f93085, 0x0ef44a08, 0x01a6e18b, 0x04611438, 0xaa65e9}}}, - /* 5*16^17*G: */ - {{{0x0d06dbd4, 0x13037b37, 0x08834206, 0x1c7f0af1, 0x1e729ec0, 0x003af4d1, 0x004e6b45, 0x1cf54d0e, 0x570d5c}}, - {{0x1d1ed495, 0x132df675, 0x1182fb56, 0x0746db8c, 0x01bbbb68, 0x173388e8, 0x0bd816d9, 0x092841c0, 0xa6ae53}}}, - /* 7*16^17*G: */ - {{{0x092d230e, 0x1a60fc90, 0x04ce4a10, 0x1c6541a5, 0x06ef5dae, 0x114f701b, 0x0edbe1f0, 0x0e0504d1, 0x75b5f8}}, - {{0x151570b8, 0x1be5efde, 0x047e3ec0, 0x0f49600a, 0x1fa8e026, 0x03a2aa6e, 0x148d8f5e, 0x043c74f0, 0x527cce}}}, - /* 9*16^17*G: */ - {{{0x034fcc0e, 0x1db5fb56, 0x18e21311, 0x1e214857, 0x059c8927, 0x1c0713e9, 0x1b0ac296, 0x1f5c3dbb, 0x44fc8e}}, - {{0x119c420a, 0x07f818f3, 0x14122767, 0x1d294979, 0x1d3d7720, 0x13f3c419, 0x0d9f9249, 0x12975362, 0xd2c7de}}}, - /* 11*16^17*G: */ - {{{0x0bb69991, 0x0d240fe4, 0x0c1c5d75, 0x167f4586, 0x0f535fff, 0x0b310701, 0x0f1a19a8, 0x08f759cf, 0xdea2ba}}, - {{0x116fe2df, 0x033a154f, 0x07b66f1c, 0x1b9b66c4, 0x1b9e7229, 0x1ff6427b, 0x0392b172, 0x1adb2185, 0xae28bf}}}, - /* 13*16^17*G: */ - {{{0x114fc9cc, 0x01206812, 0x09185963, 0x00157853, 0x0a83626d, 0x07b6625c, 0x035bbf07, 0x1314dc2d, 0x3968fc}}, - {{0x1fad37dd, 0x0c9ca44a, 0x023ccd00, 0x08caedff, 0x132c91a1, 0x0c168d56, 0x04a048de, 0x1a1b696b, 0x789cbb}}}, - /* 15*16^17*G: */ - {{{0x0e0c85f1, 0x17610c8d, 0x0e8e8942, 0x0a5ca6c0, 0x145d5a6a, 0x0ef84abc, 0x08a49ac9, 0x00d31c0d, 0x689691}}, - {{0x0dc1de21, 0x03a41199, 0x1540e48b, 0x01833b41, 0x1d72d1f4, 0x02e0ec22, 0x1e495bcc, 0x16967192, 0xaefd3f}}} - }, - { - /* 1*16^18*G: */ - {{{0x00c82a0a, 0x1ecacd7b, 0x19a20cbf, 0x044d8c1e, 0x013b10f9, 0x04f8c8ca, 0x0291ac1b, 0x10136331, 0x948bf}}, - {{0x18c8e589, 0x065bfc46, 0x1f34afb5, 0x1bfe1192, 0x1418c6d4, 0x1a62e8e1, 0x191b71ad, 0x10adb96c, 0x53a562}}}, - /* 3*16^18*G: */ - {{{0x18c8ac7f, 0x1417f2fd, 0x18aa949c, 0x0485dccb, 0x0f849641, 0x1cb6902b, 0x0ef2d70c, 0x1f7c7045, 0x9945b2}}, - {{0x09aea3b0, 0x16ca1d0b, 0x16b37ea5, 0x1ef447dd, 0x0eff5282, 0x1a27fd94, 0x00b581f6, 0x104961e5, 0x3eefed}}}, - /* 5*16^18*G: */ - {{{0x169e353a, 0x08ebcf1c, 0x0ef87dbb, 0x008810a5, 0x1d5fe10a, 0x01113883, 0x03988d7e, 0x0d640b0e, 0x2a314c}}, - {{0x05746067, 0x12c9370f, 0x09962ff0, 0x14a955b6, 0x01ba0138, 0x1f23b5d5, 0x1eb06918, 0x017e6b44, 0x15a4ac}}}, - /* 7*16^18*G: */ - {{{0x09b84966, 0x0f17a4f7, 0x1fcffe62, 0x1e820dba, 0x16c911b4, 0x17d79d35, 0x10b5262d, 0x0016e07f, 0x5959a5}}, - {{0x07473a6a, 0x0533190c, 0x1f890990, 0x01b98119, 0x02a70910, 0x094106e4, 0x025fe50c, 0x0e83eb95, 0x370e6}}}, - /* 9*16^18*G: */ - {{{0x0bc6b173, 0x1864dc91, 0x1b4fface, 0x10c478fd, 0x15f9d7dd, 0x0623182d, 0x1fa38458, 0x0726e445, 0x9eeb31}}, - {{0x1723a71d, 0x09cb106c, 0x19c312e5, 0x0e357da1, 0x01ae30ea, 0x15fedddd, 0x163654aa, 0x1c0221da, 0xe121f1}}}, - /* 11*16^18*G: */ - {{{0x1ec805f3, 0x1b9221fb, 0x16656455, 0x081eea13, 0x097887de, 0x191c4037, 0x03d45bae, 0x1c98fee3, 0x39cc4f}}, - {{0x1a3c48d3, 0x0c8d0609, 0x1244b934, 0x12ae6e7f, 0x0de7dbbb, 0x1349e7a1, 0x03cc5479, 0x058b48df, 0xecb147}}}, - /* 13*16^18*G: */ - {{{0x0e22580e, 0x1eb17dae, 0x15be21e4, 0x06512da5, 0x1d4d2c71, 0x1fef326d, 0x11a5a24b, 0x0e8cdd9b, 0xf94c80}}, - {{0x1127db82, 0x0f291fb3, 0x0dc753a0, 0x0fd88a64, 0x081f6988, 0x1ffb55ad, 0x096a4652, 0x1b8cf0a4, 0x5e9c7f}}}, - /* 15*16^18*G: */ - {{{0x10c4f21f, 0x1f205d68, 0x00f69e9a, 0x0952b29a, 0x199d2502, 0x10346d8c, 0x058bf300, 0x0d8d5aba, 0x8cccb8}}, - {{0x129dfea0, 0x1f893753, 0x192f8a3d, 0x05b95904, 0x158a54b9, 0x17aa4e43, 0x110da66f, 0x0b0c4ea3, 0x57f896}}} - }, - { - /* 1*16^19*G: */ - {{{0x138fd8e8, 0x0766c0cf, 0x1a5d4ab3, 0x01c89bf8, 0x073a8f1b, 0x1e707814, 0x070d3c19, 0x0fe8c300, 0x6260ce}}, - {{0x12b4ae17, 0x0d4274ad, 0x14706630, 0x05244700, 0x01ef7ecd, 0x0824bbb5, 0x15c69fc2, 0x056df4b6, 0xbc2da8}}}, - /* 3*16^19*G: */ - {{{0x01136602, 0x185d232a, 0x078e96ee, 0x08de901b, 0x13b3d38c, 0x049bf919, 0x1f0cf416, 0x0500905b, 0x87d127}}, - {{0x18af6aac, 0x1b41e20e, 0x14efdf13, 0x1108e8df, 0x1745387a, 0x13b67fb3, 0x0f7a49a8, 0x10e14b40, 0x71ce24}}}, - /* 5*16^19*G: */ - {{{0x08c5a916, 0x1902eb9a, 0x15843c96, 0x18881aa6, 0x14aa13f5, 0x0631ed5a, 0x05d1ac2b, 0x07fc4c3d, 0xfd5d7d}}, - {{0x1adb8bda, 0x0a59bd83, 0x13dbeaac, 0x0e70297b, 0x1b52fe5d, 0x1e533ce3, 0x0c1f4ad0, 0x1a1dd6ab, 0xdd83e}}}, - /* 7*16^19*G: */ - {{{0x15f7529c, 0x0ecc84b1, 0x0f547751, 0x0cb7316b, 0x04381387, 0x09e1969a, 0x1848ae91, 0x02130384, 0xde0dd4}}, - {{0x04cd88fe, 0x1e106017, 0x06ddd018, 0x12498d11, 0x03570178, 0x04c116bd, 0x117e6c84, 0x13a21442, 0xd70a6e}}}, - /* 9*16^19*G: */ - {{{0x18f76d11, 0x0417a469, 0x014555cf, 0x02001f7f, 0x092a2151, 0x1f7e1ce1, 0x1139a716, 0x115b499e, 0xb26c20}}, - {{0x03b7356b, 0x00e0058f, 0x009892f7, 0x0060cb3b, 0x16433050, 0x143ec866, 0x0cf3c313, 0x1041293a, 0x1f1cf8}}}, - /* 11*16^19*G: */ - {{{0x069e22db, 0x0a71d833, 0x07224cfe, 0x127feb3f, 0x0294eac9, 0x1e9480c6, 0x148e9f8e, 0x171f8ffe, 0xfceb14}}, - {{0x1c2260a1, 0x1ab96d92, 0x13af932f, 0x0a1cf274, 0x10924ad5, 0x12d3a92f, 0x0347f362, 0x07481ad7, 0x64aa6b}}}, - /* 13*16^19*G: */ - {{{0x038a2755, 0x18420bcd, 0x1271541b, 0x0434e2ca, 0x07faa537, 0x1abba5a8, 0x12b15705, 0x0c4799ab, 0x4e909a}}, - {{0x03cca3de, 0x1bd24fb1, 0x0a60032b, 0x1aa729a4, 0x159dbb6c, 0x036ea83a, 0x16bb3bc9, 0x10f199c6, 0xae56da}}}, - /* 15*16^19*G: */ - {{{0x183ba64d, 0x012c4acc, 0x116568ea, 0x0c1eef11, 0x040e2bde, 0x10a2f5c7, 0x100efec2, 0x0b845c09, 0xc36745}}, - {{0x0a2181fd, 0x0a6647cb, 0x1de3c518, 0x04d55942, 0x164c7426, 0x0737426c, 0x00cc2038, 0x1a0d396c, 0x3a520a}}} - }, - { - /* 1*16^20*G: */ - {{{0x0037fa2d, 0x0a9e6469, 0x0ff710ca, 0x1d91eaeb, 0x14103043, 0x0420a5df, 0x0350f60d, 0x1c15f83b, 0xe5037d}}, - {{0x1d755bda, 0x072ee420, 0x1207c438, 0x1eb607d8, 0x10bddbd5, 0x0684fdcc, 0x0ed7e7e6, 0x0975529a, 0x457153}}}, - /* 3*16^20*G: */ - {{{0x177e7775, 0x04545370, 0x1b657d8e, 0x02ab2711, 0x091aeb5e, 0x01dd67a9, 0x0f3b9615, 0x075ff2c6, 0x9d896a}}, - {{0x1a056691, 0x1e7b69d5, 0x06494efb, 0x139afdc5, 0x0927de89, 0x1276b928, 0x1c2e53a5, 0x1c87e937, 0xdd91a9}}}, - /* 5*16^20*G: */ - {{{0x1c2a3293, 0x1ef026f1, 0x00d1db17, 0x1170ddd2, 0x0f4cd568, 0x052b9941, 0x1e4b43ac, 0x1dce22c6, 0x8327b8}}, - {{0x0e0df9bd, 0x1e42a70c, 0x0c9a905a, 0x1fb569dc, 0x1708496a, 0x1f53313c, 0x063862ec, 0x04cddc15, 0x4997e}}}, - /* 7*16^20*G: */ - {{{0x0562c042, 0x010d9362, 0x037ec689, 0x1a464697, 0x08ed6092, 0x130ec7cd, 0x05a25f59, 0x15454db6, 0x5ae42a}}, - {{0x0f79269c, 0x082e66fc, 0x1f3636fe, 0x01b72a20, 0x09d4a94e, 0x0eee301c, 0x147aad70, 0x0f80bfe0, 0x99d93a}}}, - /* 9*16^20*G: */ - {{{0x1e85af61, 0x1a440942, 0x12b9d9ac, 0x1dae45ba, 0x01b0f4e8, 0x1b47fb61, 0x03ad66ba, 0x1c84d439, 0x92c23a}}, - {{0x036a2b09, 0x1391b34e, 0x0a1bfb53, 0x075b056c, 0x0d5792d2, 0x0beae39c, 0x0ed027c8, 0x11e02aa3, 0x414cf8}}}, - /* 11*16^20*G: */ - {{{0x07b5eba8, 0x11578d96, 0x063a8db3, 0x17db8ff2, 0x0df422da, 0x1a0bb57c, 0x1c422343, 0x118ed5fb, 0xfee560}}, - {{0x0d0b9b5c, 0x1a8ae9b4, 0x04151e4f, 0x01fe857f, 0x1c14ee38, 0x017cc943, 0x02bec450, 0x12269fcb, 0x380759}}}, - /* 13*16^20*G: */ - {{{0x1c63caf4, 0x0f1dd259, 0x1d4f54a0, 0x1fe75651, 0x06afca28, 0x09da6315, 0x1f988284, 0x1d725ccc, 0x42e544}}, - {{0x169c29c8, 0x03d7604c, 0x1bf17c46, 0x0a1cf6d7, 0x15e7873a, 0x11060ba0, 0x19c7dc7c, 0x1c1f2398, 0x9ff854}}}, - /* 15*16^20*G: */ - {{{0x1e0f09a1, 0x0515ecc2, 0x100ca0e0, 0x0213e372, 0x00efef0a, 0x17695238, 0x138e0e65, 0x16ccaa65, 0x7aed83}}, - {{0x05857d73, 0x02ec66f4, 0x0fd29501, 0x165e601e, 0x12d8ed88, 0x1e855881, 0x1df1f76b, 0x0bf3463d, 0xf5b854}}} - }, - { - /* 1*16^21*G: */ - {{{0x04fce725, 0x0c335057, 0x09b16dc9, 0x11b7a38d, 0x171b4e7e, 0x082f478b, 0x1eb7d7aa, 0x161e9440, 0xe06372}}, - {{0x0eee31dd, 0x1381a7ca, 0x04121c2c, 0x1094ef0e, 0x0488cd74, 0x1dd956ad, 0x13f84a89, 0x0e979c31, 0x7a9089}}}, - /* 3*16^21*G: */ - {{{0x1a328d6a, 0x1d540c46, 0x0b7062f6, 0x1aee752b, 0x08fa7b24, 0x04c8c2d8, 0x18028d1a, 0x0b74c469, 0xc663c0}}, - {{0x1ec9b8c0, 0x1d85db55, 0x0afe7308, 0x0aa3d4a2, 0x11317dd8, 0x1ee793ab, 0x10e34e6b, 0x11abee43, 0x3331e9}}}, - /* 5*16^21*G: */ - {{{0x1996de2f, 0x048e4241, 0x0c94452f, 0x1dbe5dc1, 0x1e4e977c, 0x186f7507, 0x091673ac, 0x105bf70d, 0xd3fc26}}, - {{0x14526f8c, 0x0249120e, 0x1eafc5a3, 0x136931be, 0x181da4e5, 0x03aa6a7b, 0x0863da2d, 0x13348be1, 0xc4f0df}}}, - /* 7*16^21*G: */ - {{{0x03e697ea, 0x03624688, 0x17e0fa17, 0x0cf1f730, 0x1abd19ce, 0x0ff64d1f, 0x008df728, 0x087fd658, 0xc17a4b}}, - {{0x1edc6c87, 0x171dc3ee, 0x07c0aac3, 0x03436aff, 0x01fae96e, 0x1c7b8cb0, 0x05532b85, 0x05aab56b, 0x39355c}}}, - /* 9*16^21*G: */ - {{{0x1163da1b, 0x16961811, 0x04e8c460, 0x1dbdcc1f, 0x11fde9a0, 0x1a4ebfe0, 0x02d1a324, 0x0f944cf2, 0x8f618b}}, - {{0x03bdd76e, 0x1f989088, 0x126db9f1, 0x018cd464, 0x05a42645, 0x0d3a6bd6, 0x0dbad7ef, 0x04be117d, 0x78233f}}}, - /* 11*16^21*G: */ - {{{0x0ec8ae90, 0x142c87f0, 0x0ef177bb, 0x04d725d1, 0x1f1b8cfb, 0x0dc6d641, 0x19bae1b5, 0x1e2b6f43, 0x9798c0}}, - {{0x052844d3, 0x14d61757, 0x0c62389e, 0x092cb7a0, 0x073bee2e, 0x04a4a7ce, 0x1b4f74bb, 0x154eb485, 0xba40e2}}}, - /* 13*16^21*G: */ - {{{0x11d66b7f, 0x0d0cbc78, 0x01f72041, 0x0d24a0a3, 0x084757aa, 0x0dc85c49, 0x159d1f3c, 0x1c7f6b45, 0xfdfa6e}}, - {{0x18e5178b, 0x1547c033, 0x15e37a76, 0x0df3ba27, 0x018c4d84, 0x00e4d1ed, 0x036e4f03, 0x03c44933, 0x4d9cf3}}}, - /* 15*16^21*G: */ - {{{0x1265bcf0, 0x003abc24, 0x071f4c2e, 0x1c56f082, 0x1220e69c, 0x14d230e7, 0x190eb77a, 0x071bc453, 0xfd58ce}}, - {{0x0b996292, 0x19f3d4e7, 0x1c73477c, 0x0c37fc51, 0x1e4fb872, 0x155cd242, 0x056f54e0, 0x1ca6ec64, 0xffe0a5}}} - }, - { - /* 1*16^22*G: */ - {{{0x10559754, 0x056b4846, 0x08fd6150, 0x0217bbc5, 0x0e02204b, 0x1dfcee06, 0x114d6342, 0x0e2b9aba, 0x213c7a}}, - {{0x14b458f2, 0x1f9613a9, 0x1a9fbb77, 0x10a1ebe6, 0x1a190bb4, 0x1683122d, 0x0941c04e, 0x016b5c8c, 0x4b6dad}}}, - /* 3*16^22*G: */ - {{{0x1e05dccc, 0x196c008c, 0x066a4f94, 0x1f47da98, 0x1d172ae3, 0x104b5ca9, 0x00c2551b, 0x1c2ea7b4, 0xb8cef6}}, - {{0x0c6d5750, 0x00a5067e, 0x1ada04cc, 0x0aff86d4, 0x0bd99df7, 0x053a7269, 0x0efda935, 0x0c14d993, 0x302b8a}}}, - /* 5*16^22*G: */ - {{{0x173bb31a, 0x0deff709, 0x16e5ed21, 0x1ef6d6bf, 0x15f49701, 0x05ef175d, 0x0e1780a8, 0x1cef368e, 0x3fb33}}, - {{0x1d215c9e, 0x1a65f34b, 0x1d903538, 0x14f8ed88, 0x1572bc65, 0x0b0d55dd, 0x18a07830, 0x0a4a91df, 0xf36ad9}}}, - /* 7*16^22*G: */ - {{{0x1d9a4ab4, 0x0da8af5e, 0x16edf029, 0x186d830a, 0x17a36717, 0x17bda687, 0x184587c5, 0x1a213d87, 0x4b177c}}, - {{0x035ab6f7, 0x156eff23, 0x1d07d562, 0x0fc4abe2, 0x06b486e3, 0x1b3949b1, 0x0997f6a3, 0x1d34bc5f, 0x3ec966}}}, - /* 9*16^22*G: */ - {{{0x101c23a4, 0x1a37d94d, 0x09273d5b, 0x1482b08f, 0x1cd75c22, 0x1c14dcdc, 0x081b0a80, 0x0a40d44f, 0x5e8703}}, - {{0x10d986f9, 0x10bccb58, 0x1333f684, 0x0e3b0e94, 0x06e2da21, 0x0ae8d716, 0x08879c5d, 0x09df7392, 0x5b9664}}}, - /* 11*16^22*G: */ - {{{0x007b0c66, 0x19f9ae90, 0x1b21bec7, 0x0ffdc8ca, 0x0eb7434a, 0x1227b056, 0x002911c8, 0x003261ad, 0xe545c3}}, - {{0x11f2d470, 0x03fabe93, 0x1688e776, 0x0b051c36, 0x1bcbf97e, 0x17ed1cac, 0x1579f971, 0x01d18c52, 0xe06a34}}}, - /* 13*16^22*G: */ - {{{0x03648bba, 0x12c0c85c, 0x10f1d112, 0x01e160d3, 0x1b39882a, 0x17112f80, 0x160284cf, 0x02af4a9e, 0xb2a442}}, - {{0x00fb6452, 0x037d5a50, 0x0705eec9, 0x10aa2a39, 0x17e31c0d, 0x1e4bc7de, 0x19867a7e, 0x1856d26c, 0xfe4f5f}}}, - /* 15*16^22*G: */ - {{{0x0bab27d0, 0x1b6e9177, 0x11440ff3, 0x1683f458, 0x17007f70, 0x180c8c6c, 0x01946ea5, 0x01e7a8a7, 0x1b908e}}, - {{0x00d3d110, 0x0f433af2, 0x1f946d5c, 0x179526b0, 0x04b9ab5b, 0x1e48c0be, 0x0d79bcd5, 0x0bdd88cd, 0x9b6d62}}} - }, - { - /* 1*16^23*G: */ - {{{0x08fbd53c, 0x0661d1d8, 0x118b377c, 0x0718e15b, 0x19a87e28, 0x09a952a0, 0x0d3a36ee, 0x054f5e96, 0x4e7c27}}, - {{0x17dcaae6, 0x059ca0c0, 0x1df74cf8, 0x172c297f, 0x1681b530, 0x084fb6f7, 0x0c6385bf, 0x0ecd93a1, 0x17749c}}}, - /* 3*16^23*G: */ - {{{0x0521b3ff, 0x114c2327, 0x0a9d433b, 0x180e2fd3, 0x024a5233, 0x0695f4d7, 0x1571d791, 0x06021928, 0x2484e}}, - {{0x0269da7e, 0x00d725c8, 0x0eb22ef3, 0x000dbd24, 0x10eebad7, 0x159e1596, 0x0c341fb0, 0x1415447c, 0x9619d0}}}, - /* 5*16^23*G: */ - {{{0x004ba7b9, 0x0b5bcfd4, 0x1d05d47e, 0x0d48e060, 0x0954e20d, 0x1b86b396, 0x195fbde6, 0x04d9f6d9, 0x16c1c5}}, - {{0x1c5bd741, 0x1adf1d28, 0x126a7311, 0x0ab8037b, 0x094deec7, 0x13a2ce45, 0x10e41898, 0x0f868062, 0xdb157f}}}, - /* 7*16^23*G: */ - {{{0x036683fa, 0x01b243d5, 0x1b02097a, 0x0436a701, 0x07b66958, 0x0e73ba29, 0x06be1ea2, 0x1aea7f26, 0x3973c}}, - {{0x1f4a577f, 0x1afd95bb, 0x1a6077b7, 0x1109c31f, 0x1a26cd77, 0x095b195a, 0x0e8d90f8, 0x05986194, 0x38cf5a}}}, - /* 9*16^23*G: */ - {{{0x00bf6f06, 0x0059ccce, 0x010ed5c6, 0x1826644a, 0x05765713, 0x027a5810, 0x054470b0, 0x174e5d9e, 0xba6a9b}}, - {{0x181db551, 0x195f7b83, 0x1a5eabf8, 0x1a29ef58, 0x0bd8e9e5, 0x05f972ac, 0x06c0c808, 0x07166942, 0x13771e}}}, - /* 11*16^23*G: */ - {{{0x11231a43, 0x08f7cf83, 0x0b50ee7f, 0x0a29accb, 0x0442f44d, 0x0ca8326f, 0x174b62bb, 0x1984f989, 0x35c5bc}}, - {{0x1620c8f6, 0x0db97228, 0x0f3c2b9f, 0x0f49980c, 0x0589d4cf, 0x0c105b7d, 0x1b39cd39, 0x0e4772e8, 0xe3675}}}, - /* 13*16^23*G: */ - {{{0x1dd40609, 0x1a05e2b7, 0x00735daf, 0x0321301b, 0x0356ac74, 0x1897e2c4, 0x1af2848b, 0x048b8ab0, 0xfd479c}}, - {{0x0a64ca53, 0x0f1789b3, 0x07291ce7, 0x075dae4c, 0x041fd911, 0x0bd21e4c, 0x1fbfcb2b, 0x16a4d295, 0x3069cf}}}, - /* 15*16^23*G: */ - {{{0x0b799a7f, 0x0db817a9, 0x0e3a1093, 0x116d9aa7, 0x07d544f1, 0x075cd796, 0x0192f7b6, 0x0547599b, 0x6c4000}}, - {{0x13c81e32, 0x1ae64166, 0x0120fda2, 0x157a9904, 0x1dcbdc07, 0x01b5070e, 0x16f9a42e, 0x02a616c6, 0x95c2dc}}} - }, - { - /* 1*16^24*G: */ - {{{0x00fb27b6, 0x1213f142, 0x10c15d8c, 0x1c7b657c, 0x06aa5c76, 0x1c56b0b4, 0x0c6c43c8, 0x07b7cef1, 0xfea74e}}, - {{0x123cb96f, 0x00e9edbf, 0x0fdedddc, 0x16b2d72e, 0x0af93126, 0x1a6f665b, 0x0ca5f3d9, 0x1b736162, 0x6e0568}}}, - /* 3*16^24*G: */ - {{{0x1e889756, 0x0ec0d74d, 0x0012ec97, 0x16c932f6, 0x099f3f27, 0x0cbd938c, 0x1aa089b3, 0x1866423f, 0x762e8b}}, - {{0x1ca6b774, 0x0f12cf03, 0x013e9789, 0x05b66291, 0x0e347197, 0x0278a4c1, 0x05f0f1f3, 0x04c15e7d, 0xc02894}}}, - /* 5*16^24*G: */ - {{{0x0975d2ea, 0x17baf4b8, 0x053a3a89, 0x0559f420, 0x0f4a91e5, 0x1edd9184, 0x14d23866, 0x08fbec12, 0xdf077d}}, - {{0x11936f95, 0x11e16cf1, 0x0f749dea, 0x1d8b709f, 0x0527c8a1, 0x012e4c51, 0x1d109321, 0x11001def, 0xf8617a}}}, - /* 7*16^24*G: */ - {{{0x1c4c92d7, 0x1c248fdd, 0x10e46d16, 0x169addca, 0x1142935d, 0x0f5419a5, 0x080cb85f, 0x0eb17a7b, 0x9f3e7d}}, - {{0x114906dd, 0x05ddfe7d, 0x0538461b, 0x144607ad, 0x11502452, 0x1590e5d5, 0x19ad6218, 0x03d4efa8, 0xecd284}}}, - /* 9*16^24*G: */ - {{{0x12a8c483, 0x1706b995, 0x0102b0d6, 0x1619118a, 0x15281174, 0x01e9177c, 0x1e7b70e3, 0x0baf6b99, 0xa0cc79}}, - {{0x12cc6ba9, 0x04b3a2ac, 0x1a4d8154, 0x091e37be, 0x1df786b3, 0x07e4b918, 0x1cfb88dd, 0x045f1670, 0xabc301}}}, - /* 11*16^24*G: */ - {{{0x05dd3aee, 0x1878db5e, 0x05b4bc85, 0x0a75151f, 0x176ca131, 0x154d6354, 0x1f338388, 0x14a2aa78, 0x6d1c50}}, - {{0x1df597f7, 0x171aa727, 0x1b54eb7f, 0x1c621551, 0x1d474851, 0x19001143, 0x1f725dc9, 0x11c0d57b, 0xafff14}}}, - /* 13*16^24*G: */ - {{{0x04a6d0bb, 0x1c654dbf, 0x086bf719, 0x1a6245eb, 0x0418f659, 0x136c5453, 0x07cfcc46, 0x0c3172ff, 0x5e5f1d}}, - {{0x1033eaf9, 0x141c23c8, 0x1bd94e85, 0x0abe5ca0, 0x121da725, 0x15e68273, 0x1bdcd63d, 0x0560d4fc, 0xd7b150}}}, - /* 15*16^24*G: */ - {{{0x0f005e3f, 0x0d4daf22, 0x10e6f4b7, 0x0d1c637d, 0x1a1495af, 0x05cd6700, 0x09ffff4f, 0x0d6782c8, 0xf8138a}}, - {{0x0f357eb7, 0x16bf0101, 0x12f884d0, 0x18837aaa, 0x1cb51f4e, 0x0af2bd52, 0x0f67e740, 0x077df69d, 0xca758f}}} - }, - { - /* 1*16^25*G: */ - {{{0x17bdde39, 0x16015220, 0x1810ca54, 0x09c2f36e, 0x168d3154, 0x0b86accc, 0x1c384289, 0x027ecef9, 0x76e641}}, - {{0x1901ac01, 0x058ba968, 0x1b480cad, 0x1467a56a, 0x1f0d35e2, 0x136b8340, 0x173d5dc1, 0x11bdc9d2, 0xc90ddf}}}, - /* 3*16^25*G: */ - {{{0x0078ee8d, 0x182848e6, 0x1a46510b, 0x1e419ca0, 0x14ff64eb, 0x1931d54d, 0x06f897fd, 0x15b0b3b5, 0xd08e57}}, - {{0x0da63e86, 0x0cbfa6e1, 0x08bb677a, 0x1def9f28, 0x06df4123, 0x19773abf, 0x035cb585, 0x13095691, 0x852e97}}}, - /* 5*16^25*G: */ - {{{0x029129ec, 0x0c8a3382, 0x12095205, 0x1c759e3c, 0x11d080ca, 0x1f407669, 0x149d7d62, 0x10bc9a89, 0x7da6c0}}, - {{0x0cd9ff0e, 0x1a857715, 0x12961aba, 0x11810ca9, 0x027bf044, 0x0103a48b, 0x015d4474, 0x0d773e83, 0xf49814}}}, - /* 7*16^25*G: */ - {{{0x11654f22, 0x1c1ea4aa, 0x06abba53, 0x0fe72846, 0x1d94fb2f, 0x0800df34, 0x19b886fa, 0x19feb837, 0x90d090}}, - {{0x001a43e1, 0x1aef02bb, 0x08fe1d03, 0x0c6aca7b, 0x170336dd, 0x010f035f, 0x186a54fc, 0x03a5759e, 0xcd569a}}}, - /* 9*16^25*G: */ - {{{0x076b19fa, 0x1b77b28e, 0x020675c6, 0x0dc0da0d, 0x1292ed9d, 0x16188410, 0x07b31cc8, 0x0b0f9e3a, 0xda4798}}, - {{0x126f5af7, 0x15137759, 0x14ff081a, 0x17a27d2a, 0x0569ea67, 0x1483bf0b, 0x1c0745cd, 0x0f137995, 0xebb1d7}}}, - /* 11*16^25*G: */ - {{{0x19135dbd, 0x0c97db2d, 0x1618c7b3, 0x010f5e73, 0x1897cf0c, 0x157ac174, 0x19ab605e, 0x00951bbd, 0xe3e475}}, - {{0x0748045d, 0x083579f2, 0x12576a5a, 0x0405febd, 0x03ffea5a, 0x040ca95c, 0x1b102e63, 0x1f013978, 0x930a5b}}}, - /* 13*16^25*G: */ - {{{0x0dee455f, 0x1f85cf2e, 0x13901d72, 0x0fffcdd1, 0x1db4aff6, 0x099c7c05, 0x06c291d1, 0x0dfd0e15, 0x7e8c65}}, - {{0x171b9cba, 0x19ef4cc0, 0x1d1989c5, 0x05a2ce8d, 0x1a53b4aa, 0x1b07a401, 0x103ca8fd, 0x0659460e, 0xbdddc6}}}, - /* 15*16^25*G: */ - {{{0x0698b59e, 0x1bcb5cdb, 0x0d11e90d, 0x06b24b12, 0x1c7260a3, 0x01ad59f1, 0x1ac56fac, 0x1f12352b, 0x3df841}}, - {{0x0b92baf5, 0x07c733cb, 0x12527e2f, 0x190cf642, 0x0f3867bf, 0x1d74788e, 0x0307680a, 0x1bf31612, 0xb38fe6}}} - }, - { - /* 1*16^26*G: */ - {{{0x0bcbb891, 0x158a8121, 0x09b2fb8e, 0x198c87be, 0x18f9a8f7, 0x0dd53a1f, 0x0f87a0a0, 0x0d607655, 0xc738c5}}, - {{0x099a84c3, 0x1f39aecb, 0x0033fa45, 0x029ddef1, 0x1bbbb823, 0x0797565f, 0x094dfdc6, 0x0f12a35a, 0x893fb5}}}, - /* 3*16^26*G: */ - {{{0x0761d58d, 0x05d5799c, 0x15838bcd, 0x1937c811, 0x0df7aca4, 0x0051ab90, 0x05184289, 0x04f047ec, 0xb8c461}}, - {{0x1d1051a4, 0x1c7505d4, 0x041f16d8, 0x0a08f0bc, 0x1c5053f7, 0x0c7b4bf9, 0x0df45291, 0x0d8a2e1c, 0x8f9ed9}}}, - /* 5*16^26*G: */ - {{{0x050b0040, 0x0d859820, 0x04d2b70b, 0x08fb73e0, 0x03671f3f, 0x04c9ff4d, 0x07de8d43, 0x13ee204e, 0x8d56e}}, - {{0x1b3fd0a1, 0x0c7133d2, 0x05e0afad, 0x0f88e41c, 0x1b285f6d, 0x0a8546bc, 0x0a887ff4, 0x15d7a153, 0xa12185}}}, - /* 7*16^26*G: */ - {{{0x13573b7f, 0x0b2b1ef8, 0x02d89c3d, 0x1438bda6, 0x05a37889, 0x07cbbdf3, 0x198d0788, 0x065a85f9, 0xdc13f2}}, - {{0x0c1f2ba6, 0x15669142, 0x1012c710, 0x0aa8e02e, 0x10a76704, 0x086d4254, 0x1030f1d0, 0x100853c6, 0xc909ba}}}, - /* 9*16^26*G: */ - {{{0x07ae9ceb, 0x017ac85c, 0x1bcb452c, 0x1843d4e1, 0x119a8226, 0x0ab2ed90, 0x1c1cebc6, 0x1cc03bef, 0x25c02d}}, - {{0x0bc6e275, 0x1848689a, 0x1961c991, 0x0c83be14, 0x111d537c, 0x0706e7d6, 0x00f03221, 0x1a590247, 0x8a9fea}}}, - /* 11*16^26*G: */ - {{{0x0c5a3c34, 0x1c04c7b7, 0x16527f87, 0x1d058052, 0x03e58aec, 0x0fa653d7, 0x1273a2ae, 0x03659f1c, 0xfedd9d}}, - {{0x013d7714, 0x15aa5fa7, 0x0fe0a5d8, 0x1d6a8d33, 0x14b00ada, 0x02989647, 0x0382c2fa, 0x18630a77, 0xa52e24}}}, - /* 13*16^26*G: */ - {{{0x0ab6a396, 0x1a72a68d, 0x04d81da6, 0x04372342, 0x088b3730, 0x16bfaf42, 0x1230b7b8, 0x10d78dd4, 0x3e0e32}}, - {{0x1980e27e, 0x1598f246, 0x11a3da8b, 0x002083e6, 0x13fc66ab, 0x1f0ef5a2, 0x1e593cc7, 0x0e5f4766, 0xca4481}}}, - /* 15*16^26*G: */ - {{{0x141023ec, 0x179ac311, 0x1b3d5c2a, 0x0bb1eedf, 0x0b9af564, 0x101004c1, 0x14a1260b, 0x06101865, 0x344ab9}}, - {{0x1e1eeb87, 0x07c4c148, 0x0e6575c1, 0x1d2ed5f8, 0x14c5ffc4, 0x1968f528, 0x18a9cfe3, 0x00856488, 0x6e1c2b}}} - }, - { - /* 1*16^27*G: */ - {{{0x08f6c14b, 0x1974fb2c, 0x0494050d, 0x0e5cbe75, 0x12877d1d, 0x03b1be4b, 0x0e078993, 0x0ca916cb, 0xd89562}}, - {{0x1d7d991f, 0x09b1f6ba, 0x0c19f85e, 0x051ac657, 0x140eb034, 0x03040c61, 0x1ab9ca3b, 0x071e578f, 0xfebfaa}}}, - /* 3*16^27*G: */ - {{{0x0127b756, 0x05d43ffb, 0x0825c120, 0x0517c957, 0x0b416034, 0x116d2830, 0x0499cb4d, 0x05ee2dbe, 0x6d8c78}}, - {{0x1f172571, 0x0a8fba55, 0x1f373299, 0x154db45a, 0x14daf4e3, 0x14169b69, 0x04445166, 0x0112dfb7, 0x99aedf}}}, - /* 5*16^27*G: */ - {{{0x158cf17a, 0x0f70d39b, 0x0208d493, 0x10bb974b, 0x097f8f1f, 0x0d778da0, 0x0b2a3416, 0x1bb2b7ef, 0xebcabe}}, - {{0x1caa0ccd, 0x0366e2fa, 0x0b3a5711, 0x15a425a1, 0x12e6b10f, 0x050db3e1, 0x072c0b00, 0x01f1e457, 0x47d3ce}}}, - /* 7*16^27*G: */ - {{{0x0c855c5b, 0x077728ad, 0x1f22beef, 0x0ac43402, 0x1fc28118, 0x0d1b4f0b, 0x189114cc, 0x05c97a99, 0xe8df4d}}, - {{0x0e465650, 0x0eaf3961, 0x07935f56, 0x076abe3c, 0x132c5966, 0x0da7acf7, 0x0c991113, 0x0e188ff3, 0x6c57fd}}}, - /* 9*16^27*G: */ - {{{0x12e7e454, 0x047aded2, 0x03985434, 0x05dfde1e, 0x01662fe3, 0x03011d4c, 0x00ca4492, 0x1ae31d95, 0x4068d3}}, - {{0x18ef191e, 0x1cd66f2e, 0x10dccc9d, 0x1a43da27, 0x138d1988, 0x0a2cbece, 0x1eaae7b0, 0x16e4a948, 0x8cd853}}}, - /* 11*16^27*G: */ - {{{0x06c5d939, 0x02bd6fc2, 0x0a4cf782, 0x0b450ef7, 0x0027ea47, 0x19973065, 0x1782d56f, 0x19b63b04, 0x12550e}}, - {{0x19e757c9, 0x153a7e2a, 0x16350c64, 0x16e83fd9, 0x04a72838, 0x121e0bb9, 0x1e9d5123, 0x069f0e5a, 0x7b8f83}}}, - /* 13*16^27*G: */ - {{{0x16c8a56f, 0x06855632, 0x1cdd084e, 0x1278a869, 0x0d08f850, 0x1bda9d7d, 0x17531a6e, 0x035876b0, 0x944d67}}, - {{0x1a7be289, 0x0fa6e32e, 0x01945fae, 0x0982e9ba, 0x0c61967d, 0x1c9b099d, 0x1ffd3050, 0x12ef6a03, 0xa71065}}}, - /* 15*16^27*G: */ - {{{0x0e08f15a, 0x175c50c5, 0x04a402eb, 0x13cadb90, 0x1c305fd6, 0x01b2ad69, 0x0833f9ac, 0x1239a133, 0x86a54e}}, - {{0x01388308, 0x09268f3e, 0x0d49534d, 0x053a24b6, 0x16867771, 0x146836ba, 0x1180e9ca, 0x0906f4f0, 0xcfee61}}} - }, - { - /* 1*16^28*G: */ - {{{0x0f676e03, 0x08a852b2, 0x1a13b752, 0x1f8e6d27, 0x08761cef, 0x1219ab8f, 0x1463ac3d, 0x006552ae, 0xb8da94}}, - {{0x0efdf6e7, 0x0447273a, 0x1fced445, 0x18b09b2b, 0x008b092c, 0x0e64bb14, 0x07935f26, 0x148900b4, 0x2804df}}}, - /* 3*16^28*G: */ - {{{0x06e1346b, 0x10cc24ee, 0x16bc717a, 0x1cf62070, 0x152c05ab, 0x1b0f8a68, 0x042f9531, 0x1fe1305a, 0x69068}}, - {{0x17226c13, 0x1dac52a6, 0x11809b9e, 0x0d127329, 0x0442aa4f, 0x0d95e843, 0x189b6a17, 0x1c1217fb, 0xb863e3}}}, - /* 5*16^28*G: */ - {{{0x1ca1f6a1, 0x07348fe6, 0x033fc68c, 0x197a2869, 0x06ce1068, 0x0e2e58f4, 0x1d854a1b, 0x127964b2, 0x898c34}}, - {{0x164f647c, 0x056e1078, 0x0af5e729, 0x0f9f2f3e, 0x06e93b2a, 0x0a122956, 0x15527611, 0x10d56ad4, 0x75f759}}}, - /* 7*16^28*G: */ - {{{0x1d1e3998, 0x134f01e1, 0x0810ca2a, 0x0d91722f, 0x0274e5e5, 0x0ceb8115, 0x0fc0694a, 0x1fda5231, 0xb213e2}}, - {{0x125fb81e, 0x0165ee31, 0x17b45d7b, 0x082cb7d7, 0x03bc3d53, 0x0f5fc1d2, 0x104b0f58, 0x1841e5a7, 0x229f8e}}}, - /* 9*16^28*G: */ - {{{0x025be234, 0x05f0ff65, 0x17cd41c0, 0x07c7ce1b, 0x06e060e8, 0x05d348b0, 0x04f97474, 0x1b02d8ff, 0x4b3b3a}}, - {{0x120e8362, 0x11dbf01c, 0x0846e101, 0x0ffb259e, 0x0c04c41e, 0x14b6fec6, 0x1271e1d7, 0x0770bb57, 0x5eec02}}}, - /* 11*16^28*G: */ - {{{0x0289f55e, 0x0b31a53f, 0x11d9c1ee, 0x0d61e1c5, 0x165be297, 0x08d813c4, 0x1e580809, 0x16dbb609, 0x9f7b88}}, - {{0x1e1e4bde, 0x1e69db2f, 0x0428ac6c, 0x0a6dc1d6, 0x1c71fc0e, 0x035a14c7, 0x03def8c5, 0x1098e082, 0x32f9f7}}}, - /* 13*16^28*G: */ - {{{0x1dfe1d2b, 0x12a4e460, 0x1a1e3945, 0x07ea13ca, 0x173a4c49, 0x056fe9fd, 0x038f9db3, 0x1d396e89, 0xd58a43}}, - {{0x0cd50922, 0x0793cadc, 0x0f5befff, 0x137442b9, 0x0276b54d, 0x14899414, 0x0f3c429c, 0x0d740b10, 0xfc1786}}}, - /* 15*16^28*G: */ - {{{0x049c795e, 0x120a8df1, 0x13a01784, 0x080d5533, 0x1ea4eed4, 0x0b4e1e13, 0x0c4335b6, 0x072e2230, 0x21d271}}, - {{0x19208ece, 0x0009761c, 0x17edd86c, 0x03289495, 0x1b4c3d67, 0x0dc2a915, 0x13a85dcd, 0x16960eb5, 0x94c5f9}}} - }, - { - /* 1*16^29*G: */ - {{{0x03c0df5d, 0x0d08bbc7, 0x15a9e4bc, 0x13dff6a2, 0x17fab201, 0x0d5ca3ae, 0x0ce9f62b, 0x028883f6, 0xe80fea}}, - {{0x0ac9ec78, 0x05a148db, 0x0c8baa7f, 0x0abd015e, 0x094472d1, 0x1b4651e5, 0x01dc7a25, 0x0fec71c0, 0xeed1de}}}, - /* 3*16^29*G: */ - {{{0x17592d55, 0x001acf66, 0x18d4064b, 0x0b728e81, 0x0e3b106d, 0x17b4b19e, 0x149822bf, 0x1b789420, 0x5d2ec6}}, - {{0x0f5183a7, 0x1372e875, 0x04545d09, 0x14f79b5a, 0x0d6950e2, 0x087d1346, 0x17ad63dc, 0x1f138dc8, 0xa92cd}}}, - /* 5*16^29*G: */ - {{{0x1e8f9f5c, 0x08fa5a4f, 0x02029466, 0x03e3c2b3, 0x1404d736, 0x171a10af, 0x1d0bf8b2, 0x1876237e, 0xac371d}}, - {{0x125a503c, 0x1d41ff99, 0x1d478745, 0x0a68b1dc, 0x0e735229, 0x00f3992a, 0x11dffc84, 0x1830e134, 0xc51616}}}, - /* 7*16^29*G: */ - {{{0x19e33446, 0x050e46a8, 0x0bce177d, 0x127788a5, 0x0a17a408, 0x005e8111, 0x10324d23, 0x07429e30, 0x894200}}, - {{0x06387689, 0x069c5007, 0x19d3e610, 0x1aee6cf3, 0x1e4e06bf, 0x16b6877e, 0x1de9362c, 0x12b2b4a0, 0xa9fd03}}}, - /* 9*16^29*G: */ - {{{0x1913cb26, 0x0b9464ad, 0x0ef5b40f, 0x16833802, 0x05c9899e, 0x1227faa8, 0x0aa28b36, 0x0d661468, 0x277026}}, - {{0x1348a7a2, 0x1f38b99f, 0x0056faef, 0x01923799, 0x0b324e94, 0x092683f9, 0x0c69554b, 0x0bcf361b, 0xf649bc}}}, - /* 11*16^29*G: */ - {{{0x195e8247, 0x0555010a, 0x01b346bc, 0x1fb88aad, 0x0ba9097b, 0x13700e7c, 0x1485e397, 0x1a70797d, 0x75e4d0}}, - {{0x19982d22, 0x111fecea, 0x06b624f2, 0x156b6dd5, 0x126d47dd, 0x0b8763db, 0x0641d07e, 0x142ea821, 0x1fce42}}}, - /* 13*16^29*G: */ - {{{0x06333323, 0x03cfa26d, 0x1d2afd1d, 0x177838d1, 0x0da849cb, 0x06b02cc2, 0x0fc0fc08, 0x07066c37, 0x3ed1b6}}, - {{0x15d61ba3, 0x189fe245, 0x1e3dca52, 0x0e514216, 0x1929ea9b, 0x04c4b447, 0x1b9d765f, 0x14916b69, 0xd84f2d}}}, - /* 15*16^29*G: */ - {{{0x133980bf, 0x1282bea5, 0x17402ebc, 0x06e05ca1, 0x0dd4368a, 0x1ebb91a4, 0x0606e11b, 0x1e0d4eb0, 0x70fdd2}}, - {{0x00b75785, 0x17754675, 0x15d29584, 0x006b070b, 0x0596b0a1, 0x008688f7, 0x1a5a55e9, 0x181a1ab0, 0x5edfca}}} - }, - { - /* 1*16^30*G: */ - {{{0x04e16070, 0x0e03dde6, 0x1f5a4577, 0x0304063d, 0x07543f2a, 0x04728eab, 0x010c4ee9, 0x0f7bf9ae, 0xa30169}}, - {{0x1e177ea1, 0x0068d020, 0x084684c3, 0x0bb7ef81, 0x00f9b173, 0x04fd12ea, 0x13d42060, 0x039f6cfc, 0x7370f9}}}, - /* 3*16^30*G: */ - {{{0x138011fc, 0x18093800, 0x1ca15899, 0x12d4cf5a, 0x00a4d835, 0x09984110, 0x0c4455ac, 0x146102bd, 0x6e8313}}, - {{0x1f15ab7d, 0x165b4fd1, 0x1147e69a, 0x1f22b5d3, 0x0c30426a, 0x16d900ed, 0x08130684, 0x117b849e, 0xc14781}}}, - /* 5*16^30*G: */ - {{{0x100e6ba7, 0x1d3a4dc6, 0x045bdfd4, 0x0dd8b689, 0x1e1b43d3, 0x101c526c, 0x147caf47, 0x0132f090, 0xf952a9}}, - {{0x0175e4c1, 0x0dd77728, 0x18a8ae63, 0x0e2cf698, 0x1a0f6555, 0x1b51713f, 0x1afe184d, 0x0b611579, 0xd8a93a}}}, - /* 7*16^30*G: */ - {{{0x03aa0e93, 0x08032d14, 0x1ec7d89a, 0x1c72875d, 0x0893a8f2, 0x18d0cecf, 0x1b9d4100, 0x0bc63a7f, 0x94016d}}, - {{0x07addac2, 0x07769344, 0x15ec1e8e, 0x086e7754, 0x06fd7f48, 0x0e9aa777, 0x165900d5, 0x1dcb88a9, 0x675032}}}, - /* 9*16^30*G: */ - {{{0x0266b17b, 0x07a43170, 0x18aeccac, 0x0ad14404, 0x109c2023, 0x1c42354f, 0x0a246ee5, 0x0e9ab3f6, 0xef22d1}}, - {{0x19dac83e, 0x1537021b, 0x10d06dcc, 0x0e4edee3, 0x0a1073ee, 0x0661d71a, 0x11d5a3e7, 0x192f5649, 0xbc5784}}}, - /* 11*16^30*G: */ - {{{0x12d382a0, 0x18980ad4, 0x1b366b88, 0x1b9779c5, 0x1f927f28, 0x063c0596, 0x04b4e72b, 0x19c99d71, 0xb5f7ef}}, - {{0x05b4b532, 0x117855dd, 0x0b3e316e, 0x1612da53, 0x1ddd371f, 0x0be37065, 0x08d4f025, 0x0b6a387e, 0x684354}}}, - /* 13*16^30*G: */ - {{{0x012cffa5, 0x13492322, 0x0331711f, 0x1a8410cd, 0x0624389e, 0x0a6c7dea, 0x01d9021d, 0x1a565ce2, 0x1cddc3}}, - {{0x1521954e, 0x0f36c4e6, 0x0dad4a2b, 0x193084d6, 0x0b08ac41, 0x0935fca1, 0x0298ff6c, 0x01965e3f, 0x1e476a}}}, - /* 15*16^30*G: */ - {{{0x14a9f22f, 0x1aff21c9, 0x1ea38ab4, 0x10338a42, 0x035b0cc0, 0x05c5ca44, 0x04e7c87e, 0x0b3e4b9d, 0x2accb3}}, - {{0x175c4927, 0x1baee59d, 0x0e9542de, 0x17af7d8b, 0x0edf1154, 0x1d1bf6f8, 0x0b946484, 0x1d2b115a, 0xd518a4}}} - }, - { - /* 1*16^31*G: */ - {{{0x1fb04ed4, 0x1bd631f1, 0x0c1fffea, 0x18661622, 0x18de208c, 0x0e828933, 0x04d918fe, 0x16713ad7, 0x90ad85}}, - {{0x0b6ef150, 0x08ea6a46, 0x00a25366, 0x1df57c2b, 0x022b839a, 0x05eca139, 0x0986bff7, 0x06c41470, 0xe507a}}}, - /* 3*16^31*G: */ - {{{0x10b7b678, 0x13aed99d, 0x1d8e0598, 0x18862379, 0x16c76f13, 0x15e52135, 0x0c6e8661, 0x0e669c84, 0x186e49}}, - {{0x18d91fc1, 0x1d03b797, 0x054d7729, 0x0ee44a89, 0x1e67e110, 0x0412e05b, 0x1612a9ff, 0x1c9300f7, 0xc0d460}}}, - /* 5*16^31*G: */ - {{{0x13421fb8, 0x18372e5d, 0x16957433, 0x12e3e5de, 0x12412984, 0x159a61db, 0x1d8b9f81, 0x1069edb7, 0x61c8d}}, - {{0x0e3ccd80, 0x0af7b342, 0x1bf374a6, 0x0e269674, 0x1eb5c806, 0x092c8702, 0x12deea4e, 0x1b320076, 0x6dfc6a}}}, - /* 7*16^31*G: */ - {{{0x0f6b35a4, 0x0925f0c5, 0x09fed21c, 0x1e6f4d56, 0x068ad889, 0x1920399d, 0x144edcd8, 0x074411dc, 0xf6a6b6}}, - {{0x01f422a6, 0x175b7f64, 0x1b8618b2, 0x0aeadceb, 0x0186f19d, 0x1b827ab0, 0x0e2c72b4, 0x150005a2, 0x3df7c8}}}, - /* 9*16^31*G: */ - {{{0x06954c11, 0x0b411f45, 0x1834062e, 0x1148782a, 0x178ff7fa, 0x0d878a83, 0x0dd88834, 0x051850d8, 0x87a2fc}}, - {{0x072a8b45, 0x0b719971, 0x1e0492dd, 0x11267e54, 0x07532cc4, 0x0a46d069, 0x13be5ec6, 0x1168b55d, 0x33ad51}}}, - /* 11*16^31*G: */ - {{{0x02706ab6, 0x123a3957, 0x194f036b, 0x16683ba5, 0x04cfe3c0, 0x177e5e1c, 0x069a1155, 0x008dcf10, 0xe1472e}}, - {{0x1d58de05, 0x174350b4, 0x0f349d4d, 0x113aaa8a, 0x021f8aa5, 0x08cbc643, 0x1f1a0fda, 0x1548f8b1, 0x82cd92}}}, - /* 13*16^31*G: */ - {{{0x07a84fb6, 0x1fd72a10, 0x0854087a, 0x06d0ea1f, 0x0b9ebc42, 0x06b00f24, 0x1bd77a2d, 0x19009f15, 0x1caf92}}, - {{0x07149109, 0x158c0c81, 0x0b399d85, 0x1982d2d4, 0x01622ec1, 0x127c7f88, 0x14e92069, 0x0b592edc, 0xbc24b8}}}, - /* 15*16^31*G: */ - {{{0x0a955911, 0x1b467f0a, 0x17b54b6d, 0x1c2d44c1, 0x18397107, 0x17f4d9eb, 0x14349627, 0x0d35e12c, 0x705bfd}}, - {{0x1fd200e4, 0x1dbe349f, 0x10b9cb62, 0x1e76a454, 0x051fa297, 0x1ec0faa0, 0x06429f98, 0x02616e7f, 0xe14aa4}}} - }, - { - /* 1*16^32*G: */ - {{{0x1ec4c0da, 0x1bda2264, 0x0fa8cd46, 0x18acf0e4, 0x1162ee88, 0x00d6cc0f, 0x1cce48e7, 0x1a5ec76b, 0x8f68b9}}, - {{0x101fff82, 0x11e5fbca, 0x1442ff7c, 0x1459fd2a, 0x0215dbbe, 0x08615b5f, 0x061b7876, 0x05b740c7, 0x662a9f}}}, - /* 3*16^32*G: */ - {{{0x123809fa, 0x0715c76e, 0x16552f86, 0x08b966a3, 0x11f08fd8, 0x19b1f922, 0x1c8a2ea4, 0x17c5ca13, 0x38381d}}, - {{0x131fed52, 0x0b83a8c1, 0x163c936f, 0x03f99665, 0x0b1cc368, 0x02d2a907, 0x1f72c250, 0x0141f722, 0xe4a32d}}}, - /* 5*16^32*G: */ - {{{0x17c2a310, 0x15213244, 0x04898c0f, 0x0d5d4a80, 0x099a1f18, 0x0dc15523, 0x0b9bda48, 0x049c86e5, 0x492627}}, - {{0x1e27ded0, 0x020db40a, 0x17fe3383, 0x0c6c254e, 0x0303b6d1, 0x1d2b4b8a, 0x0fe568b3, 0x0e7794f5, 0x1337e7}}}, - /* 7*16^32*G: */ - {{{0x0ebd2d31, 0x1c2583ce, 0x01b6e344, 0x1834adfe, 0x1e2f84dc, 0x09d9f23b, 0x12435789, 0x11834481, 0xe30656}}, - {{0x12546e44, 0x095a041c, 0x0dce099a, 0x1900857c, 0x10db6ffb, 0x15883fbe, 0x0982223c, 0x1c6f1268, 0xeac6f}}}, - /* 9*16^32*G: */ - {{{0x163136b0, 0x09861cf1, 0x0d077671, 0x17f1b355, 0x1d63374e, 0x073b11fd, 0x1bf09c6c, 0x01c48519, 0x3b9e10}}, - {{0x0cdbbc8a, 0x09f60b7b, 0x14c7e065, 0x1c514675, 0x15b26a2a, 0x19f5c7a3, 0x0dc77c54, 0x02a5a2d7, 0xfafb98}}}, - /* 11*16^32*G: */ - {{{0x0f485d3f, 0x10478239, 0x01efbba5, 0x140ed102, 0x0def717c, 0x05407aef, 0x06a4addb, 0x092e2559, 0xbb0aad}}, - {{0x1ca2f975, 0x1c9c9281, 0x19c2fff9, 0x14b5f462, 0x1da34895, 0x100fb94b, 0x11e63b34, 0x0a78b06a, 0xea699c}}}, - /* 13*16^32*G: */ - {{{0x16718dc9, 0x177699d1, 0x0448f792, 0x0b169b60, 0x00113e1e, 0x158cbd7f, 0x130353a3, 0x191c9ddf, 0x79090a}}, - {{0x1cfae7c5, 0x11991588, 0x0a4022e5, 0x0d5f6e17, 0x0aa56dd3, 0x0b65e6cd, 0x0e3c4f60, 0x0572320b, 0xeaab72}}}, - /* 15*16^32*G: */ - {{{0x1f60c7d1, 0x134b4a63, 0x1dd6b4a8, 0x0e3bcf9a, 0x1ba668dd, 0x0dde72a4, 0x0d54700f, 0x15bd3f2f, 0xe77c81}}, - {{0x02d72449, 0x162c0f94, 0x0a61b4d3, 0x08e1ee38, 0x01543631, 0x1d991f54, 0x0c8717f0, 0x0f1ddf02, 0x3acf14}}} - }, - { - /* 1*16^33*G: */ - {{{0x13231e11, 0x1437ea82, 0x1a078f99, 0x11d0ca06, 0x036091f4, 0x0ffc8cc6, 0x17597fe6, 0x002ed5f0, 0xe4f3fb}}, - {{0x0feb73bc, 0x1161c2bb, 0x14747260, 0x0fce9d92, 0x0b7286cc, 0x13687501, 0x1c705986, 0x075a1de9, 0x1e6363}}}, - /* 3*16^33*G: */ - {{{0x0bf05bd6, 0x1ccf8273, 0x0aa65194, 0x0adc0642, 0x10deca2f, 0x1a8ff5a3, 0x1fa420cb, 0x0837dc89, 0x900c32}}, - {{0x100d358b, 0x129569df, 0x13bec577, 0x10a6b078, 0x12439d69, 0x19022b85, 0x03d7e571, 0x1d1d163e, 0x6c31f9}}}, - /* 5*16^33*G: */ - {{{0x1f105c50, 0x13e14664, 0x04e1495e, 0x01bddef6, 0x033cd82e, 0x061a01e1, 0x02ab58a3, 0x0c5560b2, 0x5a8d03}}, - {{0x18a4cde9, 0x04d900c1, 0x1404f0d7, 0x0bed14cd, 0x1ff74a60, 0x15b920a1, 0x14da4da9, 0x16227a9c, 0xc059ea}}}, - /* 7*16^33*G: */ - {{{0x12d64feb, 0x03f0c5cd, 0x048a4b19, 0x05f14b25, 0x1a4e8377, 0x1d2bbb65, 0x182923bc, 0x0062465e, 0xd93f4d}}, - {{0x14698359, 0x187deac9, 0x124368de, 0x008617dd, 0x08c4d93e, 0x188e2a6e, 0x1cce88dc, 0x0ba8b964, 0x792555}}}, - /* 9*16^33*G: */ - {{{0x039fbc84, 0x1110266a, 0x15e8059c, 0x00c522c0, 0x0c65b7e7, 0x115e3315, 0x01106c53, 0x18dc6de5, 0x2f0769}}, - {{0x1c201bec, 0x1dc816f0, 0x137575cf, 0x0f36d498, 0x02149cca, 0x1803cc87, 0x1777e977, 0x0e49ae77, 0xb434f3}}}, - /* 11*16^33*G: */ - {{{0x06a758ea, 0x09bf5664, 0x1fc67135, 0x11063124, 0x16e39911, 0x04ad0aa0, 0x0c26561a, 0x100ab3c0, 0xfe7e67}}, - {{0x1b7ab649, 0x07916cae, 0x0c483479, 0x002e0e88, 0x1251f3b8, 0x070b4c24, 0x12e62302, 0x0cf4503b, 0x38aa69}}}, - /* 13*16^33*G: */ - {{{0x0cfffefa, 0x138ab134, 0x1946beb7, 0x10089ee0, 0x1af85101, 0x17c8a861, 0x049f5b7d, 0x194ea706, 0x91baf5}}, - {{0x1f7f6faf, 0x1e9b79a6, 0x1f4c0f71, 0x1de621cd, 0x13d92f4b, 0x14f893ee, 0x13af9765, 0x023268f7, 0x4e5cf}}}, - /* 15*16^33*G: */ - {{{0x0d33c546, 0x1e048bf4, 0x17b6bccb, 0x0ebf6650, 0x1ddd7825, 0x09b9f07a, 0x029f2cb1, 0x043967ef, 0x445841}}, - {{0x000b4fd4, 0x05368c38, 0x0b29cd98, 0x1e1479f6, 0x0da20852, 0x0f571c8d, 0x14e9dc89, 0x0efe7f0e, 0x308d93}}} - }, - { - /* 1*16^34*G: */ - {{{0x00eae29e, 0x17db7571, 0x138741c5, 0x069e5e1a, 0x04266c70, 0x0a9bd22d, 0x0cc7ae58, 0x13631d7e, 0x8c00fa}}, - {{0x0702414b, 0x1e952633, 0x18db1539, 0x15b5f503, 0x0c974c2f, 0x1a1d1b9b, 0x0686a770, 0x0cffd4a4, 0xefa472}}}, - /* 3*16^34*G: */ - {{{0x0bfd913d, 0x1fcab01f, 0x15327ab0, 0x0d01cddc, 0x08d2050a, 0x1d042615, 0x17e1d341, 0x14fd20fb, 0x36362a}}, - {{0x052e243d, 0x027cd756, 0x0cbeabf1, 0x017621ad, 0x02a82d83, 0x1221b86d, 0x1f54d058, 0x0ced9715, 0x48f278}}}, - /* 5*16^34*G: */ - {{{0x0d132896, 0x055d5fcd, 0x0f1b259f, 0x03c7756f, 0x1200dfcb, 0x16cb16ec, 0x180bca56, 0x0dbe6543, 0x448797}}, - {{0x0f685248, 0x0600d895, 0x1daa9e92, 0x081ab4c4, 0x01a3306b, 0x1483ba2b, 0x1f87bf26, 0x0c1a22b5, 0x27bd58}}}, - /* 7*16^34*G: */ - {{{0x1fa2670c, 0x040ab7b5, 0x189cf9b8, 0x01f05740, 0x10324740, 0x0e55419a, 0x0de22daa, 0x18517970, 0x4a4d3a}}, - {{0x16c1764d, 0x045cffee, 0x0a6fbb60, 0x00b2997e, 0x02b9d493, 0x188eef78, 0x093c5f9d, 0x0380308b, 0x70abb9}}}, - /* 9*16^34*G: */ - {{{0x0cb24aa7, 0x0cb57f12, 0x0d1714c3, 0x02118c72, 0x0fe18903, 0x17ec4ffc, 0x000b0eb9, 0x03215d23, 0x5f7b2d}}, - {{0x0a693d7d, 0x0bc03a1a, 0x1207431b, 0x1bd6e127, 0x07c47ce8, 0x1c051e73, 0x0accc28f, 0x00189fbe, 0x77036}}}, - /* 11*16^34*G: */ - {{{0x0f7fb8bd, 0x0c8de2f9, 0x19024290, 0x08c942bf, 0x086d87bc, 0x12736ca4, 0x0340abb0, 0x0a2673b2, 0x513974}}, - {{0x03908c0f, 0x04a5616c, 0x1e6356a0, 0x1865a7c7, 0x15c47faf, 0x1f7ed740, 0x0fcd2e23, 0x07c8ec87, 0xfcd714}}}, - /* 13*16^34*G: */ - {{{0x0e36ca73, 0x15ba48af, 0x0efcfb78, 0x10c9a6d7, 0x14887eac, 0x08895f80, 0x1ee2a90a, 0x1ac57f7b, 0xcf8316}}, - {{0x0ec25534, 0x1a490ca1, 0x035c43d6, 0x0c2b31b1, 0x0ca681c9, 0x0284486e, 0x15cf8e11, 0x11bd6bb3, 0x9feb5}}}, - /* 15*16^34*G: */ - {{{0x1752f97d, 0x0449beb5, 0x0d1d984f, 0x1df78ebe, 0x1a6165a2, 0x09433467, 0x127794e7, 0x13498976, 0x8610de}}, - {{0x1f1b1af2, 0x02bee6a0, 0x1550f820, 0x169b3ea8, 0x1f99e57a, 0x0ccd9299, 0x0ef24df3, 0x14056c61, 0xd31997}}} - }, - { - /* 1*16^35*G: */ - {{{0x00cb3e41, 0x0bfeefe3, 0x02e4b026, 0x1a109e61, 0x18ed3143, 0x076054f4, 0x0a7cf843, 0x1cd3ba90, 0xe7a26c}}, - {{0x0f2cfd51, 0x1454a10e, 0x03a0f883, 0x0d658084, 0x1bb18d0a, 0x00350d57, 0x012d1c6c, 0x0601f4f3, 0x2a758e}}}, - /* 3*16^35*G: */ - {{{0x1aee42db, 0x07cfe95f, 0x0c1c529c, 0x1778b68e, 0x0bfc1d9b, 0x176dc8f6, 0x0543f1ed, 0x1cfb36b2, 0xcc3427}}, - {{0x15d87bdb, 0x1114e008, 0x1c908b71, 0x0b975b1c, 0x1520010e, 0x1fe9fd90, 0x1a862178, 0x0834a438, 0xea2498}}}, - /* 5*16^35*G: */ - {{{0x1ed4a086, 0x1a1b3633, 0x071043bf, 0x0eb82b1d, 0x15cf4b1d, 0x02c2fde5, 0x1177b20f, 0x1759b308, 0x948f05}}, - {{0x1e2bca4b, 0x150c007c, 0x0fe8b468, 0x06514e38, 0x139411c2, 0x08533008, 0x08ce0bd1, 0x13ff6b45, 0x864ca8}}}, - /* 7*16^35*G: */ - {{{0x17542c21, 0x065f5365, 0x09930570, 0x13e9a51d, 0x16d43ae1, 0x1e22a28e, 0x0b24195b, 0x0c525233, 0x258419}}, - {{0x072bfabf, 0x1f5f18cb, 0x10ab5ece, 0x07430dc9, 0x113d5f3e, 0x0d52663a, 0x11200797, 0x03e39b64, 0xfcb35b}}}, - /* 9*16^35*G: */ - {{{0x0c1ecbf8, 0x1e230fa0, 0x1bb5f290, 0x13e1bd35, 0x0421f648, 0x1aa660f4, 0x14948aa5, 0x18826e78, 0x7e12cd}}, - {{0x10bed615, 0x0a2dc66d, 0x18767d67, 0x13ec3b1f, 0x11259c96, 0x0a6d5f26, 0x00dc50fe, 0x111111b9, 0x71284f}}}, - /* 11*16^35*G: */ - {{{0x14557d86, 0x1f3328e0, 0x199ffd05, 0x1dd88f1c, 0x1a6cf1cf, 0x08e53d02, 0x0a99dcae, 0x1fe546e8, 0x4b8ec2}}, - {{0x15167eb9, 0x0ecd8c8d, 0x10fda4af, 0x0be5de1f, 0x1ac5f28d, 0x0396f293, 0x1eac5290, 0x1fe0982a, 0xfde6c3}}}, - /* 13*16^35*G: */ - {{{0x0780763c, 0x15c169da, 0x195a4754, 0x14dabd24, 0x0c07e5f8, 0x1b6e34bd, 0x09094c90, 0x00e672c7, 0xfcd5c1}}, - {{0x18e851cb, 0x0a73a101, 0x1918e92d, 0x13645ce2, 0x0e38cb11, 0x06d9afb9, 0x1118edc8, 0x1c5caa45, 0x18ddab}}}, - /* 15*16^35*G: */ - {{{0x1d8ef686, 0x071df182, 0x09cb99af, 0x1c91e804, 0x06e53f68, 0x12ed7c13, 0x0f9488e2, 0x1dcb0879, 0x900f2c}}, - {{0x0121a8cf, 0x19d24b3f, 0x0455b541, 0x19bfe879, 0x1d110596, 0x0a8d89a4, 0x096b5871, 0x0abd8c08, 0x732ac1}}} - }, - { - /* 1*16^36*G: */ - {{{0x1e6b80ef, 0x0794f59e, 0x1e5093cf, 0x17972cfa, 0x0bdc571c, 0x006111de, 0x1b2348d5, 0x01dc6cc5, 0xb6459e}}, - {{0x1a71ba45, 0x185f85b0, 0x18d6cbfc, 0x075cda91, 0x01db3c4b, 0x0f8b72b3, 0x01b7876b, 0x0da0de7c, 0x67c87}}}, - /* 3*16^36*G: */ - {{{0x119888e9, 0x1ce793c9, 0x1122a2d0, 0x0574d7e4, 0x081673d1, 0x069814b3, 0x1b8b7798, 0x0ee75874, 0x1f90ea}}, - {{0x0f113b79, 0x17efe4bf, 0x0548b995, 0x0ea3fdcb, 0x196a8213, 0x09e938f5, 0x043a5605, 0x0f82bb54, 0x89be36}}}, - /* 5*16^36*G: */ - {{{0x1562222c, 0x02f7db79, 0x19bcb182, 0x0688f323, 0x152bade0, 0x15d699a5, 0x02b5b9c0, 0x09bdbffc, 0x13a4e5}}, - {{0x08200145, 0x058b3465, 0x12413023, 0x138aef5b, 0x09a52d4f, 0x017c0eb0, 0x004ecb2b, 0x09cb02dd, 0xc9d67d}}}, - /* 7*16^36*G: */ - {{{0x143b46bb, 0x1bf26e07, 0x12494950, 0x1a74c7f5, 0x15dbd12e, 0x1e02ec22, 0x0b747501, 0x17e46795, 0x61991e}}, - {{0x0c20a848, 0x047ac80e, 0x0bb363bd, 0x10e5394a, 0x1adf11ca, 0x1c38b37d, 0x124a54bc, 0x011e7fbc, 0x1c5e3}}}, - /* 9*16^36*G: */ - {{{0x121add3b, 0x12df1eee, 0x1c9f63df, 0x15289e8a, 0x026118b9, 0x0e6d868b, 0x0e1d240e, 0x1496f0fa, 0xea27ae}}, - {{0x168ce7dd, 0x1af148ed, 0x1386f9c6, 0x0425ad1c, 0x02f6278b, 0x0759192e, 0x1f795c8f, 0x1cdc8542, 0xc70ff1}}}, - /* 11*16^36*G: */ - {{{0x011ff757, 0x1457c5db, 0x13089b9b, 0x19d2e838, 0x0b6da9b4, 0x087c5b71, 0x1552ea40, 0x06ad6fff, 0x594651}}, - {{0x094d031a, 0x05337654, 0x0fff8eca, 0x1778f6ff, 0x006f9961, 0x1c680ae2, 0x1d401080, 0x019cbbe4, 0x361136}}}, - /* 13*16^36*G: */ - {{{0x036160b5, 0x1b12c51b, 0x19faf019, 0x0a7e48e1, 0x11ec0ccc, 0x17bcb804, 0x0a43a10e, 0x0722bee6, 0x16b26e}}, - {{0x18a1dc0e, 0x0312fdfa, 0x0e8fbe05, 0x0c7558e1, 0x054d4e13, 0x01a9231b, 0x1e2ed8d9, 0x0b4c605d, 0x60f56}}}, - /* 15*16^36*G: */ - {{{0x17b32db8, 0x0b269449, 0x11de47ce, 0x1dae93ec, 0x0ea85c91, 0x0a1e4216, 0x1e4c6fa8, 0x12b88ab3, 0x24b52}}, - {{0x0a64f760, 0x0a2a7d55, 0x16e06a56, 0x16d02240, 0x05be862a, 0x1410e62f, 0x0271edb8, 0x11eb7fe6, 0x609fef}}} - }, - { - /* 1*16^37*G: */ - {{{0x096943e8, 0x16d07ada, 0x1cf16977, 0x1e3f8cfc, 0x106231d6, 0x1a5508c7, 0x0101e4c8, 0x19050177, 0xd68a80}}, - {{0x0b133120, 0x0a642133, 0x114a568a, 0x1cf71ef0, 0x0e28b5b0, 0x0fc8bbd8, 0x1b40312c, 0x1ffe96b0, 0xdb8ba9}}}, - /* 3*16^37*G: */ - {{{0x0ca1c4f9, 0x0da1550c, 0x0df8a08d, 0x1dfc6995, 0x116f44f4, 0x1c1ed30f, 0x0a313102, 0x11e457ae, 0x7815f7}}, - {{0x1778bc15, 0x158f51b5, 0x1df47866, 0x085bcc2a, 0x0c35d5cb, 0x1e798a2c, 0x1da9f764, 0x1d19a735, 0xc1c601}}}, - /* 5*16^37*G: */ - {{{0x0e8c8530, 0x09370e1f, 0x03d3639b, 0x1bed03df, 0x06c6d512, 0x1e3200b5, 0x005db8dd, 0x19b41d88, 0xc39273}}, - {{0x198446c7, 0x0018787b, 0x1bb5c571, 0x1bf97b45, 0x1199850e, 0x09ca20e1, 0x123a7407, 0x084ae867, 0x8c41be}}}, - /* 7*16^37*G: */ - {{{0x037a26c1, 0x0f9205d9, 0x16fda94c, 0x18dcb181, 0x03b25166, 0x1218e0e8, 0x06c09d48, 0x08feb082, 0xda3174}}, - {{0x0cf74d6f, 0x08c1b767, 0x0a05497d, 0x106d8baf, 0x1d8b7d36, 0x00b3e12c, 0x11a748e1, 0x170febb1, 0x753b97}}}, - /* 9*16^37*G: */ - {{{0x1739dc49, 0x15b14549, 0x1d5580f4, 0x0725b4cd, 0x1231a239, 0x162845ff, 0x19b04192, 0x196055e1, 0x6a4be6}}, - {{0x12edd5cf, 0x13515cef, 0x1292934f, 0x1c569962, 0x08058ab7, 0x1371b07d, 0x1d65f705, 0x15455120, 0xf15d8f}}}, - /* 11*16^37*G: */ - {{{0x06987fac, 0x05f45062, 0x0a1bd9e6, 0x121f0c81, 0x18a3c8bc, 0x01301f64, 0x1c4d13a6, 0x13e275cf, 0x1f7c6}}, - {{0x19174c68, 0x1c8f39c0, 0x1daf098f, 0x1ebbc433, 0x0b6f9cb7, 0x01b7194d, 0x08b796c4, 0x07e6dfb4, 0x9d4ecc}}}, - /* 13*16^37*G: */ - {{{0x16daba4d, 0x099d0deb, 0x0c658987, 0x0bf61c40, 0x02bcb9c6, 0x1176ec7d, 0x0e072dc1, 0x002ec3fa, 0x557e94}}, - {{0x17a52316, 0x09ba50dd, 0x10d64294, 0x1371ebf4, 0x0bc86c5e, 0x0e7d0ae6, 0x1f811b4d, 0x074c03f4, 0x7a7e8f}}}, - /* 15*16^37*G: */ - {{{0x09f5341a, 0x1c7a97f9, 0x058dae00, 0x0f4658cd, 0x101419cc, 0x0a0753d8, 0x16a4eca7, 0x10433310, 0x3adada}}, - {{0x0586c6cc, 0x08ac049b, 0x17a3ef2d, 0x0da5cb68, 0x11017e9d, 0x1adf9b55, 0x1a7d54b8, 0x04513326, 0xbfea1e}}} - }, - { - /* 1*16^38*G: */ - {{{0x028d3d5d, 0x04acc07e, 0x11273a90, 0x055d72e6, 0x030b0961, 0x0138483d, 0x01094b70, 0x0fbecb90, 0x324aed}}, - {{0x16ab7c84, 0x1391257c, 0x0cca10e5, 0x027618fc, 0x01f4f192, 0x0061ad76, 0x1cbfc4c3, 0x0aee96c3, 0x648a36}}}, - /* 3*16^38*G: */ - {{{0x0fd53ed3, 0x0e48bac1, 0x095b33bd, 0x1ee9f73b, 0x17c49163, 0x105c98ef, 0x0ab56e3d, 0x1ab32cee, 0x20840b}}, - {{0x1a7a7132, 0x18a1ff28, 0x19c22661, 0x0f88e729, 0x0fac2548, 0x0a3b535d, 0x090d21ef, 0x12f9d830, 0xf29934}}}, - /* 5*16^38*G: */ - {{{0x08a35b35, 0x1e965dac, 0x028487b6, 0x0bb114b8, 0x0ebfd1ab, 0x0814f2c4, 0x06eef44f, 0x1ec1d667, 0xe6b6bf}}, - {{0x1c1007bd, 0x0b949edc, 0x1a6671f1, 0x16d93a77, 0x161ddfe3, 0x01f1c1ac, 0x0bcc99bd, 0x17a6601a, 0x1a5ff2}}}, - /* 7*16^38*G: */ - {{{0x00360dd3, 0x0a77c696, 0x14388243, 0x11506db0, 0x0e3bb47a, 0x1c043706, 0x06ca22c2, 0x0e8b7c93, 0xe05317}}, - {{0x1c24f87b, 0x15766c89, 0x040f70ac, 0x130fbd30, 0x0a01461b, 0x0ac15adb, 0x1ce73602, 0x0e34bb25, 0xdc1c3b}}}, - /* 9*16^38*G: */ - {{{0x1098dfea, 0x00a33316, 0x099e1e5f, 0x1967925d, 0x05e57fad, 0x12e9541d, 0x11678063, 0x074ef10d, 0xa8153b}}, - {{0x0e6d892f, 0x124d4efb, 0x16bd0562, 0x0bc1ee85, 0x13e03b1b, 0x0dce2bc2, 0x03f14f63, 0x0c8c3a0c, 0x2a4739}}}, - /* 11*16^38*G: */ - {{{0x0bcecfa5, 0x13f3bd24, 0x05aec082, 0x1ac5b436, 0x0da3b2a0, 0x14ae31c7, 0x176b7ad1, 0x1661fd95, 0x4f05c3}}, - {{0x15d37b53, 0x16681254, 0x06d2334b, 0x1dc863e0, 0x134b9447, 0x191b0aca, 0x09beb758, 0x1d4c07a8, 0x53a499}}}, - /* 13*16^38*G: */ - {{{0x084b96aa, 0x10f3b2c8, 0x0aaf3391, 0x130c6aa4, 0x1980ed02, 0x02f0d51d, 0x046f8990, 0x1733ecf5, 0xd9309a}}, - {{0x02b28a86, 0x136279be, 0x13fa5e3c, 0x0d93f75f, 0x0cb5fd3b, 0x0783313a, 0x155f5f84, 0x055369d8, 0x6ef99b}}}, - /* 15*16^38*G: */ - {{{0x1f8fcf0e, 0x1bdc682c, 0x1129beb3, 0x16dffbcf, 0x03411d65, 0x1a236f55, 0x14d6ea70, 0x14270ac5, 0x7d587c}}, - {{0x18bc9459, 0x00e0d04e, 0x08de0294, 0x072015a6, 0x16ad0c46, 0x0005b67e, 0x11849c8d, 0x00710609, 0xa7295c}}} - }, - { - /* 1*16^39*G: */ - {{{0x1d054c96, 0x145e9b9f, 0x1472a223, 0x08287751, 0x0e5dceec, 0x0fedf2ff, 0x187db547, 0x092339bc, 0x4df9c1}}, - {{0x0ad10d5d, 0x175d6036, 0x02124064, 0x0a0d9b85, 0x185d4b5d, 0x1a611d0e, 0x1ca01425, 0x0a2125b0, 0x35ec}}}, - /* 3*16^39*G: */ - {{{0x1def001d, 0x07912ed2, 0x06e89fbd, 0x1377ad31, 0x1b64b21f, 0x1e8e04f1, 0x12bc8382, 0x05b64fc5, 0xa549a3}}, - {{0x10624783, 0x0aed8d3f, 0x125c16b7, 0x083c54c5, 0x19456eb1, 0x01876c52, 0x1b2f7d33, 0x0f20db2c, 0x799b7a}}}, - /* 5*16^39*G: */ - {{{0x052ed4cb, 0x0d778f2e, 0x027b1681, 0x09bdf678, 0x12e6ec95, 0x05ecc1a9, 0x13448fc2, 0x061b40fd, 0x7e798f}}, - {{0x14bb9462, 0x0b8b303c, 0x07cde849, 0x06ae37ff, 0x0f057b17, 0x0aa4ef79, 0x120c106a, 0x189449b5, 0xd23dcc}}}, - /* 7*16^39*G: */ - {{{0x13630834, 0x0f9d07de, 0x16b019ff, 0x07e250c7, 0x08108846, 0x0f4b5d46, 0x1e0eb56e, 0x00062a28, 0x224fa2}}, - {{0x047a2272, 0x09e239be, 0x0943dd73, 0x05249d81, 0x109f53d6, 0x187d1c8e, 0x0970f12d, 0x065767db, 0xbbe54e}}}, - /* 9*16^39*G: */ - {{{0x183c19d7, 0x13b24e8a, 0x0b3d5eed, 0x16bc8b58, 0x08ef2bbb, 0x12e67211, 0x07904a68, 0x198c0147, 0xc2d4a0}}, - {{0x0507928d, 0x17945c16, 0x0d1725dc, 0x0095062e, 0x1260d268, 0x1dafbfa0, 0x0a535060, 0x1f38100c, 0x65ada0}}}, - /* 11*16^39*G: */ - {{{0x1c940c9a, 0x064056a5, 0x1d08cc21, 0x1e79c275, 0x1dc2113c, 0x02f13a26, 0x0c643956, 0x0fd860be, 0x2ec22a}}, - {{0x051e7a4d, 0x08ca7ecc, 0x08d6f6b3, 0x00a307b3, 0x07feb124, 0x127a814e, 0x05a130b8, 0x0d1bc66f, 0x8b1da4}}}, - /* 13*16^39*G: */ - {{{0x1d683eeb, 0x138772fe, 0x034c4cea, 0x0dd67141, 0x0b8f33e3, 0x1b292842, 0x13b2ac6b, 0x0e71f351, 0xafc669}}, - {{0x10cd4509, 0x0f14e559, 0x1b77f724, 0x1756aa4b, 0x19c16570, 0x0e3fe511, 0x1d4af0d6, 0x12edba44, 0x2c21}}}, - /* 15*16^39*G: */ - {{{0x176f4293, 0x1100fc3d, 0x0f144e7a, 0x12f16aca, 0x1282e10e, 0x04679b85, 0x0c24486f, 0x0b53e686, 0xd2557b}}, - {{0x1282740a, 0x0d8c3d12, 0x101697c7, 0x16d071bc, 0x0d21fe34, 0x178375a5, 0x1fc049a0, 0x086abc84, 0xa787b3}}} - }, - { - /* 1*16^40*G: */ - {{{0x0c1f98cd, 0x1fe4ce45, 0x1fc0c232, 0x09120a9a, 0x06021523, 0x054e0e63, 0x01c3ebb6, 0x150948e9, 0x9c3919}}, - {{0x14fc599d, 0x13f2f01e, 0x193239af, 0x064deed8, 0x0e641905, 0x0225f930, 0x155d613c, 0x01e949bb, 0xddb84f}}}, - /* 3*16^40*G: */ - {{{0x0fb64db3, 0x1dcc6a9c, 0x1754e105, 0x1bc99473, 0x1b8d6a7e, 0x1c1fdf29, 0x12dd02ee, 0x124537b9, 0xc11423}}, - {{0x1c0259be, 0x118674ff, 0x1159f478, 0x0b01209a, 0x18bd1a87, 0x06f27f4b, 0x1f0a973b, 0x1b8b690d, 0x1237f6}}}, - /* 5*16^40*G: */ - {{{0x03081e46, 0x16f6c1a0, 0x11567a87, 0x044318aa, 0x034713a5, 0x0e160c93, 0x089020b6, 0x1f0634ee, 0x6c5b4b}}, - {{0x0bfbcd70, 0x08fce5c0, 0x108a98bb, 0x019f04d5, 0x1e47841d, 0x1c31e715, 0x10bec8d1, 0x0e2924da, 0xcb0513}}}, - /* 7*16^40*G: */ - {{{0x064dcd4b, 0x0572d762, 0x04704937, 0x018fab32, 0x10a450c3, 0x0332e558, 0x1792d59c, 0x0acce195, 0xe1e9a8}}, - {{0x1b041f2c, 0x085b12f5, 0x085aca4b, 0x09a33559, 0x177927f4, 0x01accd92, 0x14c6deb1, 0x12a88ab8, 0x562b0a}}}, - /* 9*16^40*G: */ - {{{0x0badd73c, 0x02c3b7f1, 0x0992df40, 0x139bb205, 0x014208fd, 0x1a72176e, 0x0265de29, 0x0af5a236, 0x51b21a}}, - {{0x0b36d8d1, 0x1bea570f, 0x11cd2e9b, 0x00261e51, 0x01cfa6c2, 0x03f80e96, 0x0f975528, 0x020003fa, 0x7930}}}, - /* 11*16^40*G: */ - {{{0x1b09f34b, 0x0bae85b9, 0x1319b39b, 0x10e7cc11, 0x19d61e58, 0x114b79f9, 0x1e6186ad, 0x14c76396, 0x9701f3}}, - {{0x00df5793, 0x06e42866, 0x1731e52b, 0x097872ff, 0x08337710, 0x18da98ab, 0x1b4575c0, 0x177195e1, 0x3dd44b}}}, - /* 13*16^40*G: */ - {{{0x1f1e2f46, 0x0e73111d, 0x09de0c05, 0x01ee3d0e, 0x03c57527, 0x0970206b, 0x1b311156, 0x03a593cc, 0xa036b4}}, - {{0x1effb349, 0x198f134a, 0x1c2c7d3d, 0x01c5059f, 0x0b08d068, 0x1b5523cf, 0x0cf5f7c7, 0x14007d2d, 0xc3bf91}}}, - /* 15*16^40*G: */ - {{{0x0c4cea08, 0x06c5c81c, 0x03a8876f, 0x16b1741c, 0x04652654, 0x108a9a00, 0x1141bd29, 0x1b7549d1, 0x6a85fa}}, - {{0x1862f4f3, 0x0cef672c, 0x15c86da8, 0x0e349687, 0x06230b42, 0x19e0a47f, 0x16754c64, 0x00975c8c, 0xb646}}} - }, - { - /* 1*16^41*G: */ - {{{0x00a959e5, 0x1109c109, 0x04753316, 0x02927517, 0x006bb91e, 0x0f940ec7, 0x1f7e3781, 0x0163ba25, 0x605717}}, - {{0x0385a2a8, 0x04cdf499, 0x1893197a, 0x02a5787d, 0x1f262465, 0x116d7b8e, 0x001eb766, 0x164d4d49, 0x9a1af0}}}, - /* 3*16^41*G: */ - {{{0x171c032b, 0x0a6d0b14, 0x0bf72603, 0x16cd142f, 0x166c5ff6, 0x0dafefe3, 0x0980f744, 0x1f9adc00, 0x71eba8}}, - {{0x1668359f, 0x1d5ad470, 0x12d1d579, 0x0635a2ee, 0x0bb7f719, 0x028b7aa6, 0x0e77bd98, 0x0c496c3a, 0xd2ff12}}}, - /* 5*16^41*G: */ - {{{0x0a03a61c, 0x03723a29, 0x01c15d34, 0x10d1e8d2, 0x09dd0507, 0x1a215d55, 0x148cb285, 0x00b66493, 0x855ec3}}, - {{0x065dfc07, 0x0fe37556, 0x1f912597, 0x05ee9d42, 0x0fb4ed33, 0x05ffcda1, 0x105fd50f, 0x05d8be03, 0xdd85d}}}, - /* 7*16^41*G: */ - {{{0x1f32d706, 0x00605240, 0x1a819e2c, 0x119948e8, 0x1bfa2061, 0x094d184a, 0x0fc7c543, 0x0d57567f, 0x3ce448}}, - {{0x1c7fd9e4, 0x05b9b1bf, 0x187a27d0, 0x02ac879a, 0x14906edd, 0x08235884, 0x014a23bf, 0x11b55c6f, 0xe77540}}}, - /* 9*16^41*G: */ - {{{0x191cd3fb, 0x0da065db, 0x0a6f9a1b, 0x1467fb2e, 0x044eb4a2, 0x0190c7c4, 0x1febc0b8, 0x0287e9c6, 0x11ccc5}}, - {{0x15160d86, 0x09b8b5d2, 0x174d1caa, 0x163dfa59, 0x0c239fa0, 0x112249c6, 0x077ad4a3, 0x05520562, 0x4aa56b}}}, - /* 11*16^41*G: */ - {{{0x018f7552, 0x03dc88cb, 0x0153eb0e, 0x02271730, 0x182ddbd4, 0x1bba7c11, 0x11bd0ee5, 0x02fca293, 0x250bb}}, - {{0x1510b14d, 0x18424b11, 0x0f5bc78f, 0x00de7866, 0x1d817da0, 0x1efbaff4, 0x0208d0b5, 0x1f9377d0, 0x731930}}}, - /* 13*16^41*G: */ - {{{0x1f725d12, 0x0e89f49c, 0x0d7d1d41, 0x0c8577b9, 0x02fbfd94, 0x1ce70501, 0x1f4ead28, 0x111668cf, 0x1a749c}}, - {{0x03ac56e4, 0x09b28a69, 0x0436a9c0, 0x0410d313, 0x13d8f607, 0x1f3ae157, 0x18b3d162, 0x12ae7d81, 0x7e91d1}}}, - /* 15*16^41*G: */ - {{{0x09fae458, 0x10824729, 0x1bb25ff5, 0x14b884ec, 0x17b328b0, 0x0ab52efd, 0x06304274, 0x0b7c1f04, 0xc75068}}, - {{0x1757b598, 0x00b420ca, 0x165468ac, 0x1b94a066, 0x0c7b40a5, 0x1a0a6339, 0x1817ed4b, 0x1f19f243, 0xead795}}} - }, - { - /* 1*16^42*G: */ - {{{0x0cb94266, 0x0d34b9f7, 0x1537c4ac, 0x1de1f74f, 0x1a31880c, 0x1cd228c6, 0x10450850, 0x11c47410, 0xa576df}}, - {{0x01b28ec8, 0x145f08d7, 0x05367cfb, 0x1c214fea, 0x0d82c432, 0x0bd7f2c6, 0x02cb24ae, 0x041cecc8, 0x40a6bf}}}, - /* 3*16^42*G: */ - {{{0x0d9ed6c1, 0x14575ac6, 0x1564f5ad, 0x1ce8b787, 0x0dd0ec24, 0x00c3b82f, 0x14fa02ff, 0x0db96e9e, 0x32833}}, - {{0x18fafeee, 0x16375f37, 0x12d252b7, 0x17e9be4b, 0x17c8c265, 0x0ca1d106, 0x1ca311b5, 0x07025fb3, 0x71a898}}}, - /* 5*16^42*G: */ - {{{0x1235983a, 0x0cd4d469, 0x0ef3aca4, 0x14206e02, 0x01531e38, 0x0936b87f, 0x1153718e, 0x15d17223, 0xce4f4e}}, - {{0x0d3cdecf, 0x07eb58c8, 0x0fdd02bb, 0x18ca451d, 0x07543526, 0x10124f38, 0x0eecfab7, 0x0e78721f, 0xf3c9f9}}}, - /* 7*16^42*G: */ - {{{0x15b0e6c9, 0x16d55b32, 0x1b932269, 0x1ff39ef0, 0x0bcbddb5, 0x07d9b6fc, 0x0889e38a, 0x14a9730c, 0x4dbebf}}, - {{0x1eb2cc25, 0x0a53c2aa, 0x1413beba, 0x06236578, 0x029f3589, 0x11373711, 0x0bb7d169, 0x16079227, 0x10fee7}}}, - /* 9*16^42*G: */ - {{{0x05857295, 0x0700d08d, 0x10cfc059, 0x11c8fe06, 0x0a12069c, 0x08c7e50e, 0x10862cb8, 0x017fde8b, 0xa42a24}}, - {{0x0a7eb9c1, 0x159bbff6, 0x1464e555, 0x038459a2, 0x1a4c427a, 0x1915926e, 0x15159e9a, 0x1e4c200b, 0x3aa0b3}}}, - /* 11*16^42*G: */ - {{{0x0fcdc098, 0x1107faab, 0x191a00c8, 0x15c01ed5, 0x099c1550, 0x0fc36062, 0x0899e9fc, 0x05f2df64, 0x34e12b}}, - {{0x0a7474e2, 0x0658d6f3, 0x0620fd99, 0x1ea261e3, 0x172db04d, 0x05e420bc, 0x0c8b65d3, 0x1bbaf6ba, 0xa64ac2}}}, - /* 13*16^42*G: */ - {{{0x0f173b92, 0x06b75af4, 0x07edd847, 0x1ce5e82d, 0x165683b7, 0x0d10c7a6, 0x07ca6f8c, 0x081b3772, 0x10f4d2}}, - {{0x033146c2, 0x0810036b, 0x01ab6df2, 0x16ed3a29, 0x108ba90b, 0x12d2d19c, 0x0eb4846c, 0x12a122ea, 0x850e2d}}}, - /* 15*16^42*G: */ - {{{0x08d84958, 0x137e8ecd, 0x0b3172bb, 0x03bd62d9, 0x0cc866a1, 0x0dcbb6a0, 0x1f9d27c6, 0x016d36ce, 0xe846e8}}, - {{0x1882cf9f, 0x062323db, 0x18306990, 0x03466ce3, 0x0b76fad5, 0x0c8823cc, 0x1895076f, 0x1f91298f, 0xa29cb8}}} - }, - { - /* 1*16^43*G: */ - {{{0x1e58ad71, 0x1bb1c44d, 0x068e8823, 0x01a3eb9f, 0x08c38bb3, 0x1f4b14ef, 0x0f8c2817, 0x11851bd8, 0x7778a7}}, - {{0x1d9f43ac, 0x1a89fe0f, 0x092b158e, 0x070823fe, 0x1580087b, 0x0709797f, 0x08bfdc26, 0x1356b4b6, 0x34626d}}}, - /* 3*16^43*G: */ - {{{0x1319c869, 0x1be37571, 0x07ac9c0b, 0x13f2baec, 0x0acdc18a, 0x1c8117e6, 0x1f234060, 0x0bb302e7, 0x301804}}, - {{0x12b856f0, 0x0063b64e, 0x0f669eff, 0x15099494, 0x02e3bca2, 0x121906b1, 0x1edbe198, 0x0f04a076, 0xac5fc5}}}, - /* 5*16^43*G: */ - {{{0x05ed29b5, 0x0334c37d, 0x0ab746d3, 0x0616c0e2, 0x1c885f58, 0x13edcd31, 0x1bcd0ead, 0x16c3dcaf, 0x322881}}, - {{0x1cd15ad2, 0x1a789373, 0x1b9d813b, 0x075d5729, 0x131e1ca8, 0x18cefa0a, 0x113ac442, 0x1082f406, 0x167702}}}, - /* 7*16^43*G: */ - {{{0x06c96100, 0x1fd4203c, 0x1a72398e, 0x0602354d, 0x1dbcca16, 0x0ecd96f9, 0x0e7fed0f, 0x07581f63, 0x3f3847}}, - {{0x12624707, 0x0f1560df, 0x1d7c6f3c, 0x0e38f816, 0x19ce5665, 0x02231783, 0x0e5494d3, 0x0abeba80, 0x70c69c}}}, - /* 9*16^43*G: */ - {{{0x1d22d2ac, 0x1a637637, 0x12ab3808, 0x1bfc24db, 0x1df2f10d, 0x00704bc2, 0x1db72d0f, 0x18bfa4f4, 0x288113}}, - {{0x0f42a268, 0x00f5aafc, 0x12323f42, 0x07a8942a, 0x16137ddc, 0x1b93064b, 0x1723c81d, 0x002b1f78, 0xa1a7eb}}}, - /* 11*16^43*G: */ - {{{0x045f8ea8, 0x05d406e9, 0x134a4035, 0x0491c72c, 0x19fe5d17, 0x06caeb88, 0x08a954fd, 0x001908c7, 0xf963a2}}, - {{0x19bc99eb, 0x1e2afd82, 0x02d82092, 0x11e46b3b, 0x027208bb, 0x11180ffa, 0x0f028edc, 0x04d18ff0, 0x9c8594}}}, - /* 13*16^43*G: */ - {{{0x0606a315, 0x10d44189, 0x1a58eb67, 0x04c0e5e4, 0x0097e407, 0x05952c87, 0x069fe636, 0x099fee1b, 0xa5d922}}, - {{0x1e3b68d1, 0x1ab099ac, 0x0469f274, 0x1a1a68fa, 0x00de9ed4, 0x0355ebcc, 0x096cd0cc, 0x0007641b, 0x87328b}}}, - /* 15*16^43*G: */ - {{{0x06231493, 0x06dbdaa0, 0x131351a7, 0x02350619, 0x1e6a4964, 0x120e8072, 0x0d813ad3, 0x05c36e78, 0xf1fe98}}, - {{0x158848c1, 0x0b54cd33, 0x17fc3406, 0x07f668dc, 0x199d3f17, 0x1e102fbe, 0x177085b4, 0x1d5db349, 0x2e2019}}} - }, - { - /* 1*16^44*G: */ - {{{0x06d903ac, 0x04f6d4e0, 0x0b5f972c, 0x12c4e9cb, 0x0fd2ed5f, 0x0fe9873d, 0x01118dca, 0x0bdcc6f5, 0x92895}}, - {{0x1bcd091f, 0x08c0749a, 0x0a360ff1, 0x1a4ddf51, 0x095eeac3, 0x0509849d, 0x0aa09ede, 0x0007a7e8, 0xc25621}}}, - /* 3*16^44*G: */ - {{{0x1874b839, 0x088943ab, 0x0f4ad060, 0x022b672a, 0x0b6aebe4, 0x186fd918, 0x16a014f7, 0x03f81c3c, 0x3e03b8}}, - {{0x1c0594ba, 0x060e72b3, 0x0ad6e368, 0x0b8be1fb, 0x18f667de, 0x1303ab8c, 0x1d0b113d, 0x0c7bfe0f, 0xd13ae1}}}, - /* 5*16^44*G: */ - {{{0x0357a513, 0x11fbc734, 0x0cc08fce, 0x037a268b, 0x122c5f15, 0x1141d514, 0x04b358be, 0x16f45e89, 0xe662c0}}, - {{0x0017d07e, 0x095100e5, 0x14e36246, 0x06b9ac4a, 0x1a419d80, 0x11045090, 0x148c176b, 0x079cc248, 0xab0b19}}}, - /* 7*16^44*G: */ - {{{0x1f37d242, 0x0cafbf7e, 0x07052c12, 0x1fd94c0f, 0x1587dc29, 0x1163e5f1, 0x1b2e10e1, 0x1639299e, 0x40bf80}}, - {{0x06405088, 0x08ec13cd, 0x0f4d560f, 0x043d7485, 0x0fe12743, 0x1f4d8d93, 0x0bc13d4f, 0x06bb0ad5, 0xb579dd}}}, - /* 9*16^44*G: */ - {{{0x195a3558, 0x17959b22, 0x0d29fcae, 0x0e3f0bc4, 0x159f6ac0, 0x0bc09c6d, 0x09c201be, 0x12ec03b9, 0x3d14fe}}, - {{0x0443df4c, 0x156d9d63, 0x1075c9f1, 0x0145c28f, 0x16e1482e, 0x1498edfa, 0x07be3ca6, 0x1add08d0, 0x16c6bd}}}, - /* 11*16^44*G: */ - {{{0x02b1fc24, 0x0f4fad6c, 0x0fdd5c3b, 0x11b038fc, 0x04865252, 0x16269649, 0x14947306, 0x081d05cc, 0xdd6fa5}}, - {{0x0e9b74ca, 0x1218e230, 0x1cc88c12, 0x01bcd7da, 0x17e77ec1, 0x18f5f8b2, 0x01bf8d9b, 0x0fd63a63, 0x67e62b}}}, - /* 13*16^44*G: */ - {{{0x1dd08e02, 0x0f548ac9, 0x0b7c0a20, 0x0a8f6ffb, 0x11e80108, 0x0a4cd51e, 0x15e03e1a, 0x1505bcab, 0x13fa2d}}, - {{0x1cb03410, 0x12aa0ee1, 0x090ae5f6, 0x095f7633, 0x032c7e64, 0x0b1035da, 0x09c8c4cd, 0x1608aabb, 0x136338}}}, - /* 15*16^44*G: */ - {{{0x144ee41a, 0x0119d5cc, 0x1f5a69ab, 0x16adba76, 0x08282879, 0x085b3963, 0x0910fdf0, 0x0a3a78e1, 0xd06c48}}, - {{0x0b295e6f, 0x18fc274c, 0x18bb894b, 0x170868c2, 0x030919b7, 0x166a7a7b, 0x02b6eec2, 0x0980b09a, 0x5815fd}}} - }, - { - /* 1*16^45*G: */ - {{{0x03d82751, 0x1d573a8b, 0x0b4d5149, 0x0b69520f, 0x1b285564, 0x1279d071, 0x0424e641, 0x1e7d8db6, 0x85d0fe}}, - {{0x0eb1f962, 0x1611bd12, 0x1dccc560, 0x0ea3d2d0, 0x0f5663e8, 0x04b72c16, 0x102f8a75, 0x10827471, 0x1f0364}}}, - /* 3*16^45*G: */ - {{{0x0cde4cf3, 0x0caa830f, 0x02819aae, 0x01ca6a8f, 0x19ae7934, 0x169368ae, 0x0b0ef9f0, 0x09582284, 0x384dab}}, - {{0x052d0566, 0x1e3cb591, 0x146e9ced, 0x0614672e, 0x0c6f01f4, 0x16b6d15a, 0x090efed3, 0x179a3739, 0xd6e3c5}}}, - /* 5*16^45*G: */ - {{{0x1e5238c2, 0x0579f490, 0x03b2e2e6, 0x0abeb870, 0x0ed48403, 0x1085a741, 0x16a906c5, 0x01d6fa82, 0x14f0ec}}, - {{0x12f07922, 0x14351a3c, 0x0124e75b, 0x1801b006, 0x0747fd25, 0x039f1c21, 0x1602487f, 0x07ba906b, 0xab12d5}}}, - /* 7*16^45*G: */ - {{{0x1543e94d, 0x1b1a977e, 0x1e638623, 0x06054ead, 0x00ddadd1, 0x1a33c52d, 0x01fb1070, 0x176f0585, 0xeb42f3}}, - {{0x05924d89, 0x02acef22, 0x035b5090, 0x108d1bcc, 0x1fb774cd, 0x0eab97e6, 0x04b72683, 0x00e9e4bb, 0x234a6d}}}, - /* 9*16^45*G: */ - {{{0x1e19aaed, 0x19272dab, 0x199cc9c0, 0x1759bd18, 0x0a920459, 0x0017b703, 0x0366a7bb, 0x194a2d04, 0x1cf138}}, - {{0x092f400e, 0x09b752eb, 0x11dffef0, 0x1ddf1fdf, 0x1de17479, 0x195335b6, 0x0e197d0d, 0x1e62e38c, 0xd6ffda}}}, - /* 11*16^45*G: */ - {{{0x16a8aa39, 0x1b6074fd, 0x1e3eb157, 0x0cc6f694, 0x190d937a, 0x104b424c, 0x104b21d6, 0x17cbe81a, 0xb58686}}, - {{0x0b493c1f, 0x1e3c9ae9, 0x16cd1ee3, 0x1b5f31cd, 0x0a91dabb, 0x1c6a2a60, 0x10b05251, 0x086498f1, 0x5632d5}}}, - /* 13*16^45*G: */ - {{{0x103b4cc5, 0x148f5f1d, 0x071df0bb, 0x106374b4, 0x1a802572, 0x1e27f3f9, 0x10ad9ed6, 0x160d7179, 0x5fc19d}}, - {{0x05b57c28, 0x1d9cfdc3, 0x021fb128, 0x0dea0798, 0x05ef4927, 0x09c7cd1d, 0x1f19bb88, 0x181d9318, 0xec8e84}}}, - /* 15*16^45*G: */ - {{{0x0cb38cb5, 0x1a5c2bea, 0x0e22522e, 0x16ffbe9a, 0x0ea1be10, 0x05207e9f, 0x0a277aea, 0x01a85dbc, 0xb88fb7}}, - {{0x1965f3d7, 0x1dfd3ab2, 0x0be31c65, 0x1e7c244f, 0x1a8e24d4, 0x1dcca59a, 0x0a0180d2, 0x15a8dd46, 0xd6c736}}} - }, - { - /* 1*16^46*G: */ - {{{0x0526087e, 0x1aa02412, 0x16880c23, 0x16db1105, 0x0b85dfdf, 0x1b020bcc, 0x1a5f0726, 0x19d2fdd9, 0xff2b0d}}, - {{0x10c29907, 0x04a8f00f, 0x038b3acb, 0x0fdadf72, 0x07936c7b, 0x026e2a68, 0x08622bd3, 0x1fdea497, 0x493d13}}}, - /* 3*16^46*G: */ - {{{0x19d681f9, 0x0c82a7f3, 0x03fae7f1, 0x1c1ddf59, 0x094b066c, 0x1f92f016, 0x0c2222df, 0x1e4eebe4, 0xc745fd}}, - {{0x1bbb1247, 0x018b9a1b, 0x1f5171d8, 0x17a66b8c, 0x018678cd, 0x1ca63874, 0x179e29c4, 0x1e5ed73c, 0x590222}}}, - /* 5*16^46*G: */ - {{{0x15cd0ea3, 0x10267769, 0x12b12057, 0x08f1d041, 0x0e7f2b34, 0x0f2f5b39, 0x142c9e96, 0x1e752ea0, 0xabb279}}, - {{0x1c307bce, 0x1849899b, 0x00bced91, 0x0ed20b3c, 0x18ed47c9, 0x1f060183, 0x1c367ed2, 0x0777e2f2, 0x5dee10}}}, - /* 7*16^46*G: */ - {{{0x1bc9ee3e, 0x017179f8, 0x19ce0b17, 0x1f4352c7, 0x1ed11ea9, 0x1553a133, 0x00a09feb, 0x016b3f8d, 0x3f8115}}, - {{0x199aae06, 0x0756d862, 0x16a0580f, 0x0765b9f9, 0x15662762, 0x1f59e23c, 0x00b519c6, 0x0d1fb7f5, 0x19c88a}}}, - /* 9*16^46*G: */ - {{{0x18e4a007, 0x0b8df7d7, 0x0ecd62d8, 0x19dd9e11, 0x0c7ec15e, 0x1d19d52b, 0x179a5652, 0x05ba0105, 0x5cf813}}, - {{0x1068b883, 0x131f8484, 0x071ffa33, 0x08df2d8f, 0x03df6c89, 0x00ac4246, 0x0837d2b5, 0x0b81ac3f, 0xb45aee}}}, - /* 11*16^46*G: */ - {{{0x06c2d4a7, 0x0ab7f3d9, 0x13ffec42, 0x06df2677, 0x04ed21bc, 0x19cb9e20, 0x125194f8, 0x09a1a974, 0xb6d5fe}}, - {{0x1ae86371, 0x0c6e73f1, 0x178f3204, 0x16fc9cde, 0x1fd8e745, 0x1c904eff, 0x1b0537f3, 0x1427577a, 0x47f373}}}, - /* 13*16^46*G: */ - {{{0x1c66dd33, 0x0499b117, 0x171db714, 0x1f791fe3, 0x1b022ea8, 0x0d8a8014, 0x021c1aec, 0x180cd9eb, 0x61c8bb}}, - {{0x16f10bfa, 0x1ddd4f9d, 0x00832328, 0x020dd585, 0x1d3fb6a5, 0x0cca5cc2, 0x1c0d119a, 0x0473ca9e, 0x93599e}}}, - /* 15*16^46*G: */ - {{{0x1d6b2ff8, 0x002dbe66, 0x01b23ea6, 0x066d82e5, 0x1bdf1876, 0x1a9b9f61, 0x01461f27, 0x14ae84cf, 0x94e32b}}, - {{0x0ce1af3e, 0x0ea42aa9, 0x1aff84eb, 0x15e084a4, 0x19e8cb33, 0x12443316, 0x13864bc7, 0x11687b40, 0xd1b44}}} - }, - { - /* 1*16^47*G: */ - {{{0x1856e241, 0x0072f167, 0x15b74a1e, 0x03dc2919, 0x1212b57f, 0x1973180d, 0x03aa7b4a, 0x1c963d10, 0x827fbb}}, - {{0x0ec293ec, 0x102db45d, 0x040c59b5, 0x0f4c630d, 0x112687ff, 0x19633e8e, 0x0c2dc6fb, 0x12478e4f, 0xc60f9c}}}, - /* 3*16^47*G: */ - {{{0x1bb80fa7, 0x1a242e59, 0x0104e218, 0x0fb4d76e, 0x0819f3aa, 0x1035e990, 0x0bef0346, 0x03ec6118, 0x857e3}}, - {{0x09366b2d, 0x0cc108f8, 0x15c05aaf, 0x1c6e0879, 0x17147172, 0x064e8ee5, 0x1c824b5f, 0x08475c02, 0xf64393}}}, - /* 5*16^47*G: */ - {{{0x09c70e63, 0x0e8161d0, 0x14f525bd, 0x1716f1ce, 0x0672e9cb, 0x032abb25, 0x0010d517, 0x1d4ad7ac, 0x28aacc}}, - {{0x1057da4e, 0x0f81c417, 0x13687a2e, 0x18b39c88, 0x0ebb7f5f, 0x0b33e3b4, 0x18559ea2, 0x05df0341, 0x2b6932}}}, - /* 7*16^47*G: */ - {{{0x13e674b5, 0x00ee297b, 0x0182ab18, 0x11ed39ce, 0x18a4f92d, 0x1964de75, 0x19851776, 0x04b40ab4, 0xa2f3b6}}, - {{0x0e937941, 0x049c6470, 0x0cfe94ec, 0x05f462f8, 0x07c4b922, 0x05487995, 0x02ba0011, 0x0b2c298d, 0x620ea1}}}, - /* 9*16^47*G: */ - {{{0x191eb056, 0x1b00b18e, 0x13f4e1b1, 0x05dfb71d, 0x115f5a00, 0x1ae351fa, 0x048c7662, 0x193d55cb, 0x3c4f83}}, - {{0x005cecab, 0x012c49ed, 0x13dae1dd, 0x056a8903, 0x07880198, 0x12b9e1d9, 0x0da8ceb5, 0x00ea2951, 0x944790}}}, - /* 11*16^47*G: */ - {{{0x1d86dfa9, 0x0830fedd, 0x0e64e9c6, 0x11694813, 0x03baadc3, 0x0f01f408, 0x1f538a70, 0x0511532c, 0xaff8e1}}, - {{0x01d12681, 0x1881e1b6, 0x067e71c1, 0x02db5288, 0x153f4f91, 0x15d50fe7, 0x10ff4f4f, 0x166426ef, 0x8d8b4b}}}, - /* 13*16^47*G: */ - {{{0x189ba9c1, 0x07939b5c, 0x074ce38a, 0x1ef94b41, 0x0e579e40, 0x01315767, 0x02cfa116, 0x08a51b80, 0xd3fb78}}, - {{0x0b51b267, 0x10dc46ff, 0x046b7801, 0x19dbab80, 0x10fe6341, 0x102bac5b, 0x139f29f2, 0x069df4d6, 0xf894d4}}}, - /* 15*16^47*G: */ - {{{0x0f2bb909, 0x0d4b60e8, 0x16636667, 0x0204f8a6, 0x07d7f639, 0x14c41c8c, 0x0a23fd1c, 0x01c15935, 0x4ec930}}, - {{0x04cf4071, 0x0451c1fd, 0x0b0e09ee, 0x1c2d041b, 0x049bad52, 0x0e228c26, 0x13717203, 0x00d7c360, 0x782ba1}}} - }, - { - /* 1*16^48*G: */ - {{{0x0120e2b3, 0x19dac7d1, 0x11fe6a9f, 0x11fb9cfe, 0x0e5217a5, 0x0571a673, 0x16eb9ef9, 0x1e43ea37, 0xeaa649}}, - {{0x1a5ad93d, 0x03d2982d, 0x0fdf9675, 0x0d72cbe2, 0x1aa5a01a, 0x007c4c3c, 0x00eb1a6a, 0x1dab7776, 0xbe3279}}}, - /* 3*16^48*G: */ - {{{0x1f2e070d, 0x0c1fe9d1, 0x0a9aa63d, 0x156e398a, 0x047e229a, 0x18e1dc28, 0x0affd21c, 0x1d2085e9, 0x4b72a5}}, - {{0x096dd780, 0x025d4177, 0x05230f79, 0x08cbbba5, 0x13c10b0b, 0x1dd9b687, 0x073d809d, 0x09c3ad5c, 0x599e1d}}}, - /* 5*16^48*G: */ - {{{0x0a02591c, 0x0e73fec2, 0x1449687a, 0x0a932cb0, 0x1fd613ef, 0x1fdf5af0, 0x038a169a, 0x1f8ca739, 0xa9fc93}}, - {{0x09bec2dc, 0x0856ef7b, 0x13dc94de, 0x111882bf, 0x165e5ca8, 0x00bd0d48, 0x1c5cfa13, 0x073b8a70, 0x9c2ce7}}}, - /* 7*16^48*G: */ - {{{0x0d968b59, 0x08037071, 0x12ef0b84, 0x05175c27, 0x1027709a, 0x1d60904d, 0x1c29a9f5, 0x0f834df3, 0xc94001}}, - {{0x0de572fb, 0x17ebb204, 0x0432723f, 0x08596c87, 0x1742ce28, 0x10dfd2da, 0x18804ee2, 0x0a019370, 0x39d922}}}, - /* 9*16^48*G: */ - {{{0x126b3332, 0x143999ab, 0x1b9779a8, 0x0711a0e7, 0x1f8e0310, 0x09d2fb85, 0x0093b19e, 0x13afdda0, 0x1f84bb}}, - {{0x14e8d52e, 0x0a214518, 0x1b70e895, 0x199c5a86, 0x1edf0c2b, 0x013fbadc, 0x1b30951f, 0x00e57953, 0xee726d}}}, - /* 11*16^48*G: */ - {{{0x0defa98e, 0x06d52a56, 0x0b09e657, 0x1088d023, 0x1e9c7724, 0x0abd9cc8, 0x1341b2a0, 0x112128bf, 0xf13e0}}, - {{0x1e286767, 0x0453bb4d, 0x13ab3370, 0x1ce0bc2d, 0x162db287, 0x1c5853d9, 0x1140d78f, 0x1e2ec9cf, 0xadd521}}}, - /* 13*16^48*G: */ - {{{0x09f59b6b, 0x0f0e01df, 0x02238be9, 0x0718c783, 0x026d3e9b, 0x050e96ac, 0x11f6cdca, 0x14aa3bbd, 0xdde191}}, - {{0x06cb1410, 0x156cb149, 0x0553fb3d, 0x0e7177ce, 0x0e14e8b5, 0x0beb0e29, 0x172f829d, 0x0f00504e, 0x5b2bfb}}}, - /* 15*16^48*G: */ - {{{0x09c6b699, 0x1462afee, 0x191a1c6d, 0x1eae6ad7, 0x01682a86, 0x0bdfcbda, 0x1de9685b, 0x05ddb06d, 0x5fab01}}, - {{0x01c6c3aa, 0x0b990a96, 0x020d466c, 0x1622ffd5, 0x02f7b90a, 0x1a08986b, 0x0513a7ae, 0x0e14787a, 0x2d9bfa}}} - }, - { - /* 1*16^49*G: */ - {{{0x1a34d24f, 0x111b196e, 0x084dd007, 0x0db1e193, 0x02ee541b, 0x0fb6f67a, 0x1a764e47, 0x0878b9e2, 0xe4a42d}}, - {{0x1eba9414, 0x13fb898e, 0x16393c4e, 0x0dddbf51, 0x0d34ce88, 0x0ce67dc5, 0x1cd49bf2, 0x1ce2da38, 0x4d9f92}}}, - /* 3*16^49*G: */ - {{{0x1bea0c68, 0x04208579, 0x1ece4ad7, 0x060246ce, 0x16faf094, 0x1e47469c, 0x0e892526, 0x069c2ad4, 0x3e4196}}, - {{0x1a45edb6, 0x05db7fb8, 0x0f3686af, 0x02328c60, 0x093062fa, 0x05ff1b83, 0x07dfcdcf, 0x13b24964, 0x123c5}}}, - /* 5*16^49*G: */ - {{{0x139824d7, 0x1bae91e4, 0x072625eb, 0x0f6c986a, 0x10b576eb, 0x11f317bf, 0x1423bb52, 0x1ea8abae, 0x8d9438}}, - {{0x1366489f, 0x10027a44, 0x1ac18f62, 0x13c57064, 0x0ef6f8fb, 0x05e98d5b, 0x10a8b298, 0x0e69fdcd, 0x3261e0}}}, - /* 7*16^49*G: */ - {{{0x18d713de, 0x124038d4, 0x0a398823, 0x0185f6e8, 0x14543936, 0x089517f2, 0x1108352a, 0x18ab1dca, 0xb72524}}, - {{0x1b8350e9, 0x17ff292c, 0x1297f2dd, 0x05a4dfc8, 0x09415048, 0x08c174eb, 0x1914410b, 0x13514507, 0x4c51b3}}}, - /* 9*16^49*G: */ - {{{0x1e3b2cb4, 0x0636149f, 0x1c84100b, 0x13e6b7e6, 0x1149e304, 0x1b71c090, 0x09466b71, 0x0b442da2, 0x3de45f}}, - {{0x107eb02f, 0x10f19d61, 0x01c1133d, 0x1c51ccb5, 0x09106823, 0x055254be, 0x17714382, 0x13080bd5, 0xba2a85}}}, - /* 11*16^49*G: */ - {{{0x0ce4e5bf, 0x11a3b37b, 0x04016c5c, 0x0f950d41, 0x106ae9b6, 0x1e71ba44, 0x1a1f078f, 0x18d12b37, 0x8511f1}}, - {{0x01789c08, 0x1e494a26, 0x14d9498b, 0x10f11378, 0x000232da, 0x0fbf6355, 0x121d3077, 0x19f2379a, 0xecdff5}}}, - /* 13*16^49*G: */ - {{{0x1d3258ab, 0x0dab3451, 0x0f05370c, 0x04850315, 0x0ab5957d, 0x0e39770a, 0x0088b3e8, 0x05d039ec, 0x8c5a05}}, - {{0x022d0f8f, 0x0bf04298, 0x16512b79, 0x15d1f381, 0x008c246d, 0x0063c826, 0x16841e6a, 0x09768877, 0x6811db}}}, - /* 15*16^49*G: */ - {{{0x1f91bcee, 0x0c615055, 0x03036105, 0x1e3b1e3c, 0x1f137f5c, 0x1e762ab5, 0x1582f718, 0x02dbd7a6, 0xcef7f8}}, - {{0x01966b33, 0x1da6d4fc, 0x1cbdab1a, 0x1c960542, 0x1245fa63, 0x199ce00e, 0x1c04918e, 0x106c6e90, 0x67e74c}}} - }, - { - /* 1*16^50*G: */ - {{{0x0300bf19, 0x18b9dcea, 0x03fa9251, 0x0a6aed51, 0x12b6b92b, 0x07d6d59a, 0x17655058, 0x1de6c197, 0x1ec80f}}, - {{0x0107cefd, 0x18e6e0e6, 0x05681ed9, 0x0dcefec5, 0x1bf5e014, 0x04ac53d5, 0x1034bce9, 0x06ead6a6, 0xaeefe9}}}, - /* 3*16^50*G: */ - {{{0x12fea1f9, 0x18be5de2, 0x0114ae52, 0x1e16a118, 0x06531c4f, 0x0ed5b388, 0x0ba0ef3f, 0x014aba3e, 0xa6dc88}}, - {{0x1bc345e9, 0x18e0a723, 0x1a3df98e, 0x1713b6fc, 0x0bc50057, 0x01d08b56, 0x1f0c0e1a, 0x0a8fb86c, 0x7ef1a8}}}, - /* 5*16^50*G: */ - {{{0x06d6c9b3, 0x06a061f8, 0x01958df2, 0x1899d0e9, 0x081ba8c6, 0x114e3c52, 0x1664af70, 0x07fd4848, 0xfe6ba9}}, - {{0x0948bdfb, 0x0163c47d, 0x10ba6c03, 0x01e37e0b, 0x13b56d98, 0x00d9a2a0, 0x01cadaed, 0x1ae80a73, 0x7ee918}}}, - /* 7*16^50*G: */ - {{{0x0cf95151, 0x11788398, 0x0b12d910, 0x0900dc88, 0x0ded1b96, 0x04616e04, 0x02fec083, 0x1e28df93, 0x15d5e2}}, - {{0x0ff8ecf2, 0x01503e61, 0x16303e52, 0x009f72fb, 0x023f9bb2, 0x1084bc48, 0x13b1fe43, 0x06322bfa, 0xa5b72e}}}, - /* 9*16^50*G: */ - {{{0x096a5658, 0x0bc085c9, 0x1bd9590f, 0x0964a483, 0x029be381, 0x100493d7, 0x11eb631f, 0x0e4ad108, 0x84c0e8}}, - {{0x181b80d1, 0x0cb394de, 0x13c7f48b, 0x0c35303e, 0x1725ed3a, 0x118c8329, 0x0b12821f, 0x10182c04, 0x265983}}}, - /* 11*16^50*G: */ - {{{0x14dc6a0f, 0x1addae44, 0x1f855d4d, 0x06832285, 0x077c2744, 0x1273d160, 0x0c755949, 0x18e3526e, 0xfed6b1}}, - {{0x176fc7e0, 0x05c6b96c, 0x0ff10273, 0x09ab2614, 0x1ae23137, 0x0c0d7269, 0x1c2a11e4, 0x1cd61fff, 0x8de2ab}}}, - /* 13*16^50*G: */ - {{{0x18e29355, 0x19c42f88, 0x1c8361b6, 0x191d2672, 0x1b9d82f1, 0x1c302011, 0x0f1c3f3b, 0x1b325a79, 0x2a6a4d}}, - {{0x15cc2872, 0x029f007d, 0x1131db00, 0x00b474c9, 0x0f90dfe9, 0x0e40f134, 0x1831d83f, 0x174f894f, 0x8677df}}}, - /* 15*16^50*G: */ - {{{0x0148dabf, 0x1cfd447f, 0x075e3ac7, 0x1ba57269, 0x0e735c1a, 0x07611afd, 0x151b65d9, 0x004d924e, 0xe42d93}}, - {{0x011e1361, 0x1b963ab4, 0x19dfae75, 0x04eae033, 0x18530327, 0x0675fef9, 0x12c362ce, 0x058dc5b0, 0x641386}}} - }, - { - /* 1*16^51*G: */ - {{{0x166642be, 0x0edac941, 0x162ea227, 0x0920e2fa, 0x1fa8bce3, 0x057a3406, 0x10be46c0, 0x11808ce1, 0x146a77}}, - {{0x1d83efd0, 0x0594ba41, 0x1f97b474, 0x152e3a5e, 0x0b2870aa, 0x0c13fcea, 0x0a2b759a, 0x1d866a80, 0xb318e0}}}, - /* 3*16^51*G: */ - {{{0x07315443, 0x0c9c39c1, 0x1a19ca67, 0x1377aa95, 0x142a13d7, 0x04cc1050, 0x0d7fd0b2, 0x0080cc12, 0xfc696c}}, - {{0x17d28960, 0x0486b05a, 0x06f46c5d, 0x1fe90c21, 0x077b5487, 0x10e6eb4b, 0x024aefc3, 0x1d7f076b, 0xe0ce27}}}, - /* 5*16^51*G: */ - {{{0x16fdb4eb, 0x0dd97ae0, 0x0b9a9e74, 0x07baf38c, 0x0b0928fa, 0x151ab15f, 0x0ab46b95, 0x043fe9fe, 0x974af2}}, - {{0x09f6f484, 0x004e1efd, 0x1ff08d21, 0x18ae5477, 0x090ed111, 0x121e8160, 0x0f299347, 0x0faa6a00, 0x555238}}}, - /* 7*16^51*G: */ - {{{0x1d5aeee3, 0x1c8256da, 0x163204dc, 0x109786cc, 0x070c5e82, 0x0d9d3349, 0x062c2448, 0x13693bc7, 0x5baab5}}, - {{0x10f69717, 0x1694d7db, 0x14c7bb60, 0x1bb93b57, 0x1daf7215, 0x004330ff, 0x1a15b968, 0x0c2f81ef, 0x8a577f}}}, - /* 9*16^51*G: */ - {{{0x15726890, 0x08d8f227, 0x00df4561, 0x004bfd59, 0x10a0ee59, 0x17e75fc8, 0x10f4040c, 0x14fd6938, 0xfb685f}}, - {{0x1835783a, 0x0375479d, 0x039e6c98, 0x0d9625d2, 0x0ba094fa, 0x10b6cc32, 0x18ba1a72, 0x045931cb, 0xd750df}}}, - /* 11*16^51*G: */ - {{{0x08bca48a, 0x0325f89d, 0x0f7d8bd5, 0x09abe9d0, 0x1f71d78b, 0x1dc8e143, 0x05682ac9, 0x1ecb3c53, 0x5de58f}}, - {{0x12fd41cd, 0x03ca7406, 0x03e2aa56, 0x0b7b389c, 0x13c843fe, 0x111e1296, 0x0d54c269, 0x07b006b3, 0x685a3b}}}, - /* 13*16^51*G: */ - {{{0x05ef63b6, 0x0f1c1a27, 0x06c60baf, 0x09a02ce6, 0x1c1c85ab, 0x1fed1da7, 0x02febc6d, 0x19bd5ac3, 0x6f1825}}, - {{0x05c655f3, 0x1642367a, 0x1fe51504, 0x12b4c804, 0x134553c8, 0x1026bc19, 0x046e63d0, 0x0fbab232, 0xff097e}}}, - /* 15*16^51*G: */ - {{{0x14a63f3b, 0x1a823f6f, 0x1e3e5c9e, 0x00760332, 0x0c765832, 0x08afaf3b, 0x0ddad61c, 0x12beec54, 0xc5ecb8}}, - {{0x05005024, 0x09f9ba34, 0x0c2fb96d, 0x16cbdcbc, 0x033ec8be, 0x002c7fc9, 0x07cdd3a9, 0x03032f10, 0x222525}}} - }, - { - /* 1*16^52*G: */ - {{{0x1180eef9, 0x0bb543c9, 0x0a2e5ddb, 0x00244134, 0x07b128d0, 0x075d8d50, 0x17c1f8eb, 0x1ec3a45c, 0xfa50c0}}, - {{0x1f4f2811, 0x066c6be9, 0x1e884ece, 0x1065274a, 0x1a68a5e6, 0x09439140, 0x0ea6dcb3, 0x124472fd, 0x6b84c6}}}, - /* 3*16^52*G: */ - {{{0x11da5e12, 0x0f70719c, 0x12b2ca5c, 0x0c14802b, 0x0a2b6a9c, 0x14fc9d0e, 0x0c6f368c, 0x07886f3c, 0xf7502e}}, - {{0x0385f4eb, 0x125ce2f4, 0x0973af1e, 0x0da65dee, 0x072047b8, 0x04a2e1eb, 0x0bf5665c, 0x1dbacf9f, 0x3c57f5}}}, - /* 5*16^52*G: */ - {{{0x10b7d105, 0x03a49988, 0x195f27c8, 0x14b89729, 0x055b3f4c, 0x1b31271a, 0x018a8e93, 0x1f3075cb, 0x12fe78}}, - {{0x1f794a60, 0x0c5637dc, 0x1ba42e11, 0x19c4cbad, 0x1cb771de, 0x0d50ccd3, 0x13dde1ad, 0x14671ad7, 0x2062f1}}}, - /* 7*16^52*G: */ - {{{0x1e0c5d05, 0x110ec19c, 0x15cb6bfd, 0x1cd8a154, 0x04b1a480, 0x1d881404, 0x1cf56312, 0x0268fbe8, 0x76aac3}}, - {{0x11ece63e, 0x0b30cdba, 0x179bb8d5, 0x044b9e02, 0x0625f4b1, 0x19641901, 0x03beafbc, 0x1de1ab8e, 0xef5576}}}, - /* 9*16^52*G: */ - {{{0x1c53c086, 0x1137a42f, 0x0686bb27, 0x0ab86939, 0x08104c6b, 0x0618a2f4, 0x13321f98, 0x0b77cb8b, 0xa663fe}}, - {{0x05016201, 0x14e28195, 0x0653f039, 0x1d994ae7, 0x03dc3991, 0x081644c1, 0x1efd746c, 0x0fed6423, 0xb54199}}}, - /* 11*16^52*G: */ - {{{0x0b758574, 0x16c00f6a, 0x13e71ba6, 0x04cd1286, 0x0bdf3d83, 0x10813d71, 0x16096df2, 0x0f4040d9, 0xde9552}}, - {{0x1b67232a, 0x1bef8fe7, 0x168b7ad2, 0x0d420a2a, 0x09ed7bae, 0x0e423f8b, 0x05393887, 0x0ad5927a, 0x4cd3e0}}}, - /* 13*16^52*G: */ - {{{0x1d85474f, 0x1bcdc55f, 0x18d19a35, 0x18945712, 0x05aea894, 0x065f223c, 0x0b76ffb7, 0x1c0cda65, 0x8da6bc}}, - {{0x1d7b4ef7, 0x1efce3e9, 0x16f75e97, 0x198b260b, 0x1fff10b1, 0x0fae838e, 0x13fe13f7, 0x0d5e63da, 0x13fc6c}}}, - /* 15*16^52*G: */ - {{{0x1dd042ea, 0x1aea12b3, 0x03abf41a, 0x144d4c8b, 0x093beebf, 0x1324f19e, 0x08e6c6f5, 0x18f9f677, 0x7329ac}}, - {{0x0f5c94a1, 0x0d467f61, 0x1ead3c2b, 0x112ee63b, 0x168ee184, 0x073ca7d5, 0x1c5224a1, 0x06a836ed, 0x927249}}} - }, - { - /* 1*16^53*G: */ - {{{0x1f067ec2, 0x129e995a, 0x0ee94883, 0x11156bab, 0x0e8421a2, 0x1fb5bec4, 0x0846c696, 0x1a194e43, 0xda1d61}}, - {{0x1ad836f1, 0x0afdd078, 0x1e6d2299, 0x0e7133a4, 0x11e2966a, 0x1b30b0e4, 0x01b1e701, 0x0b4f9326, 0x8157f5}}}, - /* 3*16^53*G: */ - {{{0x1a95a8db, 0x0ec3b997, 0x074dbd85, 0x1d81888f, 0x11723b83, 0x13234c8d, 0x141067a5, 0x148c607b, 0xe3e90d}}, - {{0x1b0d1cf9, 0x00b67bf8, 0x06134f44, 0x03df2f99, 0x0e76afbb, 0x15486381, 0x1e2ec03e, 0x1800ad82, 0xfbe53b}}}, - /* 5*16^53*G: */ - {{{0x112ee214, 0x1d57eb20, 0x04c55005, 0x149d2f2b, 0x0c01c782, 0x086feae0, 0x1dd6a2d9, 0x18e65c7a, 0x9f4ffe}}, - {{0x1085f37a, 0x17a21112, 0x12200a0f, 0x136d2617, 0x1c69d971, 0x13417eba, 0x1cb983a5, 0x1c2631c5, 0x639ce2}}}, - /* 7*16^53*G: */ - {{{0x1f61a0a5, 0x05b40a28, 0x10538fbe, 0x04a7c367, 0x00b2c4b1, 0x10520fa2, 0x0b06c5c6, 0x05a82269, 0x431f62}}, - {{0x18cef899, 0x15bdbff3, 0x1595dc91, 0x1554086a, 0x1aa7241b, 0x1328cb91, 0x0e3db5b7, 0x0ffcf548, 0xa29832}}}, - /* 9*16^53*G: */ - {{{0x07748503, 0x16133eab, 0x04ca39f2, 0x1c1c8ee6, 0x012ac0e6, 0x1779cfc5, 0x1ee1b2d8, 0x1bbd9cf1, 0x993dba}}, - {{0x1eb0cee2, 0x1d39b09b, 0x02b6a926, 0x10f7ed37, 0x1f51a17f, 0x1c23c3d0, 0x1bade17d, 0x1dd0ad3d, 0xa521a9}}}, - /* 11*16^53*G: */ - {{{0x06d23d80, 0x0f5113ad, 0x11d351e3, 0x17a23e4c, 0x162c0e10, 0x018e5c84, 0x1a968ce5, 0x1740d5ab, 0x75f17a}}, - {{0x080dd57e, 0x03542d81, 0x13a96426, 0x1ff7db76, 0x16292372, 0x1e85f8cd, 0x0a031ff1, 0x1fc2ac73, 0xa07a62}}}, - /* 13*16^53*G: */ - {{{0x01ad3413, 0x115cdb6b, 0x09f5a12b, 0x13800806, 0x07b7a8db, 0x0fa42e5c, 0x12829ba5, 0x0bc23b3e, 0x667855}}, - {{0x1ebca672, 0x12408103, 0x17199804, 0x1c5a2a75, 0x1df9ea6c, 0x136c93e5, 0x191a4949, 0x07bc4f1e, 0x510dda}}}, - /* 15*16^53*G: */ - {{{0x06cc8563, 0x00057ad8, 0x18407aab, 0x09beb7ff, 0x03688922, 0x015ec0cb, 0x1d22b6b2, 0x06c59b4e, 0xebdc4a}}, - {{0x0394ccfa, 0x0d8bde75, 0x0813e492, 0x080f2492, 0x14f07bec, 0x11af366e, 0x0d7e6c7b, 0x089d0ada, 0x659a31}}} - }, - { - /* 1*16^54*G: */ - {{{0x0d064e13, 0x139d8308, 0x1bc7818a, 0x023bc088, 0x14166153, 0x1fcc747e, 0x1a41c857, 0x1fe192e0, 0xa8e282}}, - {{0x11f4cc0c, 0x17be3988, 0x175af5b3, 0x0f347ca1, 0x115888b6, 0x1f9e2d92, 0x1026afed, 0x0b71b703, 0x7f9735}}}, - /* 3*16^54*G: */ - {{{0x1a3979b5, 0x150ccd85, 0x1fa0a788, 0x111f1bcc, 0x00e50ba2, 0x1f858f72, 0x098c9fcd, 0x18b9b5bc, 0xae2207}}, - {{0x0450fa6f, 0x079e6b34, 0x153e225a, 0x10f6fa6f, 0x17060fca, 0x092291d6, 0x1dc6b532, 0x0a2180f3, 0xea91fe}}}, - /* 5*16^54*G: */ - {{{0x0efca824, 0x0080c880, 0x08593eb9, 0x1c189fd4, 0x05461e0b, 0x0a08032c, 0x139673b1, 0x0195ae55, 0xcb8ded}}, - {{0x0f227361, 0x0a05e82c, 0x04c5d0bc, 0x1a3fbf8f, 0x0cbc496a, 0x16243d16, 0x03216cc5, 0x11ee81b1, 0x33a500}}}, - /* 7*16^54*G: */ - {{{0x1bcbd327, 0x008da6d1, 0x192abba5, 0x1c10a443, 0x16ed6b04, 0x04806bf3, 0x0d9c23a5, 0x05315e30, 0xb0c53b}}, - {{0x0d7be436, 0x10b5e251, 0x18da83c5, 0x144418e8, 0x0b2afd82, 0x15300db3, 0x1a858e3d, 0x0803f7af, 0xee2a97}}}, - /* 9*16^54*G: */ - {{{0x17b836a1, 0x1377db1c, 0x19e7bdf7, 0x0c80bfee, 0x1f526c80, 0x0317673b, 0x04835362, 0x07e653b7, 0x6f6ba7}}, - {{0x06832b84, 0x0def97d8, 0x187fe4d3, 0x1218a511, 0x0e9c0d89, 0x1c5202df, 0x0638f6c2, 0x02ffebf8, 0xdc778a}}}, - /* 11*16^54*G: */ - {{{0x1eb39ede, 0x1771a104, 0x0184b50a, 0x110065ae, 0x04360310, 0x1a33f081, 0x0bd2ef3f, 0x0fb8e845, 0x7d471a}}, - {{0x0bf6607e, 0x04de6ca5, 0x08aa3f43, 0x0b9efa38, 0x086fa779, 0x1118f7fe, 0x15941ee0, 0x033e74d0, 0x4a7b}}}, - /* 13*16^54*G: */ - {{{0x165eb1c1, 0x0b6a4f12, 0x0b9716a9, 0x1aeacf9b, 0x0f0967fc, 0x1e618cc1, 0x1eb1c1c3, 0x0c7f36e7, 0xf00251}}, - {{0x0dde2ae0, 0x0d3eb823, 0x1344795f, 0x0dfeb9ad, 0x0afed857, 0x1a52ed13, 0x037d319a, 0x1d1107a4, 0x54ea9}}}, - /* 15*16^54*G: */ - {{{0x1ac32c64, 0x079a849e, 0x0b92fe13, 0x0dfc07d9, 0x1715e0e3, 0x074a87a3, 0x0ea83dc1, 0x00003da4, 0xac1214}}, - {{0x1eb1a867, 0x00956dd6, 0x14fc2262, 0x14ba74b4, 0x099a3ed5, 0x1b4ab982, 0x0ebc61c2, 0x19758671, 0xce8ebc}}} - }, - { - /* 1*16^55*G: */ - {{{0x0319497c, 0x179c16f4, 0x09423008, 0x1363f4a2, 0x1cab15d5, 0x12b73489, 0x161cb4e7, 0x17393450, 0x174a53}}, - {{0x079afa73, 0x1ed09d60, 0x0e6150e0, 0x16743b19, 0x1f9e6646, 0x0aaf9623, 0x10595ed0, 0x06f57f93, 0xccc9dc}}}, - /* 3*16^55*G: */ - {{{0x154b8367, 0x0a4039eb, 0x1541affa, 0x0b6efacf, 0x16a5db77, 0x12ea2c21, 0x09b9032a, 0x095c88ca, 0x5e5a09}}, - {{0x11ce85ca, 0x0994d4ec, 0x197fe911, 0x1553de7b, 0x04b7a796, 0x00f8ab95, 0x18170b24, 0x19348f2b, 0xae8af8}}}, - /* 5*16^55*G: */ - {{{0x17b10d9d, 0x0cc2bc9c, 0x07e3f2bc, 0x0a5e313a, 0x0b82de6a, 0x05c19886, 0x1a1677b3, 0x15b72e05, 0xd4e0}}, - {{0x1140dced, 0x01080243, 0x18b648fa, 0x113192f1, 0x087f70b5, 0x1c232191, 0x10251f4b, 0x130306ec, 0x87b801}}}, - /* 7*16^55*G: */ - {{{0x1c9caee8, 0x0408d304, 0x089c2ec8, 0x1c408b63, 0x0a667632, 0x10cd7762, 0x1303dbde, 0x026d1dee, 0x36652}}, - {{0x1772b711, 0x14f6351d, 0x056e9fc2, 0x17531265, 0x0944501c, 0x1e340dd3, 0x1b666527, 0x0565527b, 0x1f18c3}}}, - /* 9*16^55*G: */ - {{{0x1446c85c, 0x1ffcba8c, 0x007018d4, 0x0fbc11cc, 0x0c6eade3, 0x1b6229fb, 0x1c7ea819, 0x00adfb71, 0xe5891}}, - {{0x0148972e, 0x1b63bf39, 0x1376b757, 0x00469d01, 0x01898f49, 0x00c5d7a4, 0x0f683b1d, 0x0be23f4f, 0xe39a48}}}, - /* 11*16^55*G: */ - {{{0x022e1259, 0x18c56f9e, 0x004d8abf, 0x0e73480d, 0x17771931, 0x1afd5003, 0x18fcadb3, 0x0da4de28, 0xa74012}}, - {{0x134a5f43, 0x1bb8b921, 0x075b6b57, 0x0cbcea76, 0x07ee5178, 0x18ba533e, 0x07fc6c17, 0x175e329e, 0x5a9ff}}}, - /* 13*16^55*G: */ - {{{0x0b08f1fe, 0x0450bd1e, 0x0821eff6, 0x1cfdce17, 0x0d177d7c, 0x02bb2ec1, 0x13929950, 0x042db28e, 0x87e4b8}}, - {{0x0ed5e2ec, 0x0fba564d, 0x1e1b675d, 0x1e47b7ac, 0x0c2cc6e2, 0x1fc7517c, 0x033b35f5, 0x180ecc69, 0xf74e3a}}}, - /* 15*16^55*G: */ - {{{0x01c4d15c, 0x14380735, 0x1039d2e6, 0x1d4f7e0f, 0x14a44105, 0x11606092, 0x0696a4b0, 0x08c7fd4f, 0x35ea1b}}, - {{0x1f3fe1ea, 0x049cdd7b, 0x194257b7, 0x06754060, 0x13b185d6, 0x1d2feba6, 0x0b35e223, 0x0ca373da, 0xad2191}}} - }, - { - /* 1*16^56*G: */ - {{{0x1475b7ba, 0x027eff84, 0x0462cf62, 0x13ce61c9, 0x18cdbe03, 0x0bf6fa80, 0x0170f4f9, 0x1303286f, 0x959396}}, - {{0x1524f2fd, 0x0dc55fc3, 0x1c24e17a, 0x0a7ec990, 0x0d6849c6, 0x1c3525ce, 0x07762e80, 0x05111866, 0x2e7e55}}}, - /* 3*16^56*G: */ - {{{0x0fd69985, 0x04e2eec8, 0x17dcaba8, 0x013996db, 0x0cf149f3, 0x1486fde6, 0x1df9e23d, 0x0eb9d6e5, 0xae976}}, - {{0x1409a003, 0x0e475a08, 0x1b86bfe2, 0x133a82f5, 0x054c5d0b, 0x0ff7028d, 0x1453a6e3, 0x0e7edc91, 0x912199}}}, - /* 5*16^56*G: */ - {{{0x19262b90, 0x0e0c9efe, 0x0f30a6a7, 0x078983fc, 0x05d1fb72, 0x0f8bbc01, 0x04bb26d9, 0x054b582c, 0x2b1586}}, - {{0x083d7557, 0x08ccb732, 0x05226926, 0x0692e1f3, 0x149066f5, 0x06a96d43, 0x0fea9e8c, 0x07b54146, 0x2eb005}}}, - /* 7*16^56*G: */ - {{{0x08e7be40, 0x1fcb8a65, 0x0103b964, 0x05912922, 0x0769af2d, 0x0e0b0b72, 0x199dfba5, 0x1da352dd, 0x6af9ea}}, - {{0x0e387e1c, 0x120b7013, 0x1d655a7e, 0x07eccd41, 0x1dc8145e, 0x152141a3, 0x19259c27, 0x022d200c, 0xb3812a}}}, - /* 9*16^56*G: */ - {{{0x1482801e, 0x135b7d07, 0x0f505574, 0x129f178b, 0x0d6f9407, 0x15a1265c, 0x113bacea, 0x1dc08882, 0x596668}}, - {{0x04870c37, 0x03b8a478, 0x14d4d6b5, 0x0d8396c7, 0x1304e8db, 0x1cb043b8, 0x1d7c7b23, 0x150b775d, 0x949aa0}}}, - /* 11*16^56*G: */ - {{{0x032c19fd, 0x064d973e, 0x000a30f9, 0x1571d20b, 0x10b5b4ac, 0x068bd5ab, 0x01d8bf7d, 0x11036a0a, 0xbe84d1}}, - {{0x12f1281f, 0x1b4a529b, 0x14370dd9, 0x0b4feabc, 0x03994795, 0x12fa4184, 0x02513479, 0x19665b8a, 0xeff960}}}, - /* 13*16^56*G: */ - {{{0x16c69482, 0x08dbafea, 0x0be859ef, 0x156a8026, 0x0bc88cbe, 0x193a6579, 0x1b9507d5, 0x062981af, 0x9867a0}}, - {{0x0f792cd7, 0x178308a3, 0x158a2a45, 0x048b9ea2, 0x099639e6, 0x16aad8dd, 0x0d3e71e4, 0x0b476210, 0xd02e61}}}, - /* 15*16^56*G: */ - {{{0x1d557aa1, 0x0511cec8, 0x007f0a5e, 0x1b25fd9a, 0x1d6abdf1, 0x1975004c, 0x0569649f, 0x08a81b10, 0xa866f2}}, - {{0x01430634, 0x0c0ddda6, 0x184692de, 0x16d38cf8, 0x0e13961e, 0x0c7d2ed8, 0x0d135e4f, 0x1ed50045, 0xb58739}}} - }, - { - /* 1*16^57*G: */ - {{{0x1d82b151, 0x1a89a064, 0x07ee8b6e, 0x01487aac, 0x09a8fcca, 0x108a9d88, 0x195b5916, 0x0a15c803, 0xd2a63a}}, - {{0x1cf89405, 0x00a10ba6, 0x013294b5, 0x1eea15e9, 0x08220a70, 0x172c594a, 0x12dd596b, 0x1f6c887f, 0xe82d86}}}, - /* 3*16^57*G: */ - {{{0x0e4b3ba0, 0x02cfb1af, 0x02fc7c5e, 0x157debe3, 0x1245f5c2, 0x0b8798df, 0x0dcefbf8, 0x00a443ff, 0x410811}}, - {{0x17525595, 0x034b0ee0, 0x08191552, 0x0c930acb, 0x18498133, 0x12d70eb5, 0x19a3cb29, 0x0d2edfea, 0xdc37f3}}}, - /* 5*16^57*G: */ - {{{0x13d98ded, 0x114e4dc4, 0x02808611, 0x1e450677, 0x1d65edbd, 0x114c8298, 0x0323233c, 0x02142d98, 0x63a2a2}}, - {{0x00d1cfc2, 0x0c8cbea7, 0x11e1ce94, 0x17ed4013, 0x194461fa, 0x01992a76, 0x1dbf4194, 0x1c5cffd8, 0x882b42}}}, - /* 7*16^57*G: */ - {{{0x18045445, 0x1430d285, 0x07a35fba, 0x1ee6e320, 0x1bef080f, 0x17172eab, 0x1f28f7c4, 0x0ba893ac, 0xc1581}}, - {{0x0054a206, 0x0a7c3eaa, 0x1633a8c8, 0x00a9c86c, 0x1cd28ba3, 0x1e1db331, 0x045742a4, 0x01475d28, 0x2f30d6}}}, - /* 9*16^57*G: */ - {{{0x03857faf, 0x14891ce6, 0x05865c07, 0x1f95bc3d, 0x0ef7f882, 0x1d47a414, 0x0a70355e, 0x0d7135d1, 0xc757eb}}, - {{0x00584ca4, 0x0eced865, 0x06253040, 0x1a621a20, 0x0c61b627, 0x14f9045f, 0x1cd895cd, 0x19f9a47f, 0xf03a59}}}, - /* 11*16^57*G: */ - {{{0x1459225d, 0x1268c27a, 0x02163443, 0x15eefc5b, 0x002a244f, 0x0a04c8ce, 0x0343e057, 0x15d5b5f4, 0xfa8063}}, - {{0x1ece1507, 0x115bf1db, 0x01f1670e, 0x16d86da0, 0x0425c0a2, 0x11104126, 0x01a45837, 0x120af818, 0xba71f}}}, - /* 13*16^57*G: */ - {{{0x16f0d044, 0x13cff4a0, 0x079869e5, 0x153fa921, 0x0e0a5aab, 0x14e7c317, 0x1ea278bd, 0x18b3a04a, 0x658ca3}}, - {{0x17cb872d, 0x0e8f9977, 0x0633a26b, 0x02cec788, 0x1d37655a, 0x0eb1389d, 0x15183c59, 0x06ef5d44, 0xae5cc1}}}, - /* 15*16^57*G: */ - {{{0x1696756d, 0x1ad64ab9, 0x158505ea, 0x15e2c0ac, 0x1305c676, 0x0cc1ae9f, 0x0aeb3930, 0x0955f23e, 0x31c94b}}, - {{0x1e08ae78, 0x1e22f46e, 0x0b441c2a, 0x1dbf95cd, 0x0160683a, 0x05acd57a, 0x0ea6fd2e, 0x096aadd0, 0xf80f88}}} - }, - { - /* 1*16^58*G: */ - {{{0x1617e073, 0x01b7cda2, 0x0e4c5ecd, 0x197b7a70, 0x1dc866ba, 0x1c4b6be7, 0x1ae243b9, 0x0466a8e3, 0x64587e}}, - {{0x1faf6589, 0x014cf2f4, 0x0ebaacd6, 0x12147226, 0x099a185b, 0x0eb223e1, 0x0b8aba5b, 0x1ab7ed20, 0xd99fcd}}}, - /* 3*16^58*G: */ - {{{0x0e103dd6, 0x0fb8a390, 0x0012166b, 0x0c0980f8, 0x0a17ac34, 0x09e7e2c9, 0x0fe0da88, 0x1aab4840, 0xbc477b}}, - {{0x16f7c343, 0x1c8416c6, 0x0ed12b18, 0x126ae58c, 0x0a6395d2, 0x02a9636f, 0x1549b2eb, 0x0485351b, 0xe31e1e}}}, - /* 5*16^58*G: */ - {{{0x144eab31, 0x086e1d86, 0x198d241f, 0x0b5e2809, 0x1f8e80ac, 0x1a11933d, 0x00e00c0e, 0x1fcb4d77, 0x589db4}}, - {{0x11361f6a, 0x00d75f3a, 0x123e36e5, 0x021caa42, 0x190f31f6, 0x0310125e, 0x0a93d81c, 0x0b821154, 0x625544}}}, - /* 7*16^58*G: */ - {{{0x1a0c2c41, 0x1fcb0b94, 0x00cdb19e, 0x063838ac, 0x0db7c428, 0x0c3056b7, 0x1e8baa28, 0x06fa2dc5, 0x1339b3}}, - {{0x09f1bc2b, 0x02f82a5d, 0x1a48e906, 0x044ff0fb, 0x1a3406b1, 0x1207e889, 0x196e9e8c, 0x0c6c58f5, 0x9f9b29}}}, - /* 9*16^58*G: */ - {{{0x18fc47af, 0x18258fc2, 0x10337b0d, 0x1bfd9065, 0x1b568a8d, 0x194da800, 0x1c5f3140, 0x14226c79, 0x7ff3bb}}, - {{0x19ba43a7, 0x1c30b267, 0x02eb0a5f, 0x0a7635a3, 0x1446b17a, 0x048dba39, 0x18a682f2, 0x15d00314, 0x1f6ba7}}}, - /* 11*16^58*G: */ - {{{0x15213775, 0x0c26b004, 0x150aa640, 0x08527647, 0x07f6100b, 0x149caff6, 0x02ed8507, 0x08c79d6c, 0x8ec670}}, - {{0x1841ffff, 0x100879f3, 0x13d47a43, 0x15314179, 0x1ee0e71d, 0x01a0ae76, 0x0f8c1b99, 0x0df41b4b, 0x8f58a6}}}, - /* 13*16^58*G: */ - {{{0x1452abbb, 0x059ffc69, 0x0e570b8f, 0x154e5fc5, 0x1d495ae6, 0x161ff6ca, 0x06ee276e, 0x16883ce0, 0x83de61}}, - {{0x054eb66e, 0x1028bb58, 0x1390a462, 0x18be6d77, 0x01563d79, 0x1b57c627, 0x027e9afe, 0x0694698c, 0x32f0e3}}}, - /* 15*16^58*G: */ - {{{0x159276f1, 0x0b446137, 0x085ec57a, 0x1c4b6525, 0x0d86833a, 0x1ae007be, 0x076c6a2e, 0x1131ea18, 0x3d7663}}, - {{0x059cbcb3, 0x0f2532dc, 0x0c65e180, 0x03304033, 0x0333ef32, 0x171a6d6c, 0x176d825d, 0x0e6f430f, 0xd37669}}} - }, - { - /* 1*16^59*G: */ - {{{0x1d45e458, 0x0c6b6436, 0x1439ff4d, 0x154d9d44, 0x1de042f0, 0x0369f2a4, 0x0216ce95, 0x1c1c9c9b, 0x8481bd}}, - {{0x1779057e, 0x0b258dac, 0x098b955b, 0x14f38856, 0x0b2ca900, 0x0df9ce76, 0x13761289, 0x11974a80, 0x38ee7b}}}, - /* 3*16^59*G: */ - {{{0x152da17d, 0x10507d20, 0x14191ac5, 0x1827b611, 0x00bc811d, 0x13582ff0, 0x117c2253, 0x03c1ea31, 0x3beaed}}, - {{0x0cc768d2, 0x13824c2f, 0x1fb105b3, 0x1bcef71b, 0x0e1b554c, 0x145f5f40, 0x0b37fbd2, 0x1eab5fef, 0xc3b0d7}}}, - /* 5*16^59*G: */ - {{{0x1a4edcc5, 0x1a7d0bed, 0x00c46dc8, 0x1c644284, 0x15997e74, 0x0fe01c93, 0x15861d4b, 0x14197b93, 0x6e73db}}, - {{0x159da0e4, 0x198fbe6e, 0x019e40de, 0x14efb4e0, 0x08693278, 0x0a844441, 0x1122fa91, 0x1f893dd9, 0xee0ac1}}}, - /* 7*16^59*G: */ - {{{0x0a80b979, 0x04e26212, 0x06aecc50, 0x01ebf465, 0x1c310049, 0x0cbf5523, 0x1649d89f, 0x1126fcb6, 0x7706dd}}, - {{0x0126cfde, 0x067a4082, 0x1fbf8c85, 0x141469fa, 0x09c7117f, 0x0ebcc8f5, 0x1c51dde3, 0x104fab76, 0x8a02a9}}}, - /* 9*16^59*G: */ - {{{0x126fe285, 0x06dce25b, 0x0fbc49f7, 0x17585282, 0x1e06aa45, 0x1e3d20fc, 0x03e034bc, 0x18b25378, 0x16d422}}, - {{0x0155b441, 0x1f07ff36, 0x0d93508c, 0x1e18226e, 0x131b1e93, 0x1f34d31a, 0x1906a2ad, 0x1f4a3c44, 0xdf888}}}, - /* 11*16^59*G: */ - {{{0x1acfa513, 0x11885e55, 0x1838ebab, 0x080f3f34, 0x16a9c4e2, 0x1a23a87a, 0x158ea968, 0x08fdd8ed, 0x1fcc0e}}, - {{0x107afc9c, 0x083add20, 0x060e461d, 0x1bdba2c9, 0x1f9b44be, 0x1c3aa19c, 0x11e2d238, 0x14083c6a, 0x165dc1}}}, - /* 13*16^59*G: */ - {{{0x1edc69b2, 0x0d1383e7, 0x1addc5c8, 0x14c11364, 0x0a386a50, 0x01821ae5, 0x0285cc19, 0x0e75ad97, 0xc12b90}}, - {{0x00dd41dd, 0x19574d81, 0x09eca800, 0x1c3b7c7a, 0x14976b8e, 0x16e44fc4, 0x17c765dc, 0x07fca699, 0x3173c4}}}, - /* 15*16^59*G: */ - {{{0x1961fe4d, 0x1b7ac2ef, 0x041c65ea, 0x0910df16, 0x0a73e8a1, 0x14989896, 0x0a3e8fcf, 0x10bb864f, 0xd059bf}}, - {{0x0ae823c2, 0x0c9ad833, 0x16ad932e, 0x111743e9, 0x155b4fd3, 0x1b2ee424, 0x0978ff81, 0x0c18116a, 0x45107a}}} - }, - { - /* 1*16^60*G: */ - {{{0x0caf666b, 0x06b181fb, 0x0c738c2f, 0x19fda789, 0x1f4637ff, 0x0bcd740b, 0x0aa98ada, 0x0af4f020, 0x13464a}}, - {{0x1f6ecc27, 0x1a4ad483, 0x0250b84f, 0x0601503a, 0x0b0ca48f, 0x019a29e6, 0x1603bdf9, 0x12008c28, 0x69be15}}}, - /* 3*16^60*G: */ - {{{0x0eca5f51, 0x10b5904c, 0x1f26bafc, 0x142e3729, 0x1b5cfdde, 0x0b595f82, 0x1a58b1bb, 0x029bb3dc, 0xdde9d5}}, - {{0x10c638f7, 0x16b4d39e, 0x0255c7e6, 0x1dd7d1bd, 0x18f0950f, 0x19a5853f, 0x04476247, 0x02679c50, 0xb84e69}}}, - /* 5*16^60*G: */ - {{{0x199c88e4, 0x1c83582c, 0x0b51bb0b, 0x1aa27c41, 0x04b179ae, 0x00375890, 0x0dcdba7d, 0x02046d32, 0xfd1a62}}, - {{0x195bc8df, 0x0e4648b2, 0x13003ca6, 0x16e3a92b, 0x17782dc6, 0x0034aa4b, 0x082fec4f, 0x0a973918, 0x1ac97b}}}, - /* 7*16^60*G: */ - {{{0x1f8018ce, 0x0a8adada, 0x024b5a2f, 0x1b4ae71b, 0x06dc7cf2, 0x1e727964, 0x1ae7c4ff, 0x063b1852, 0x4ee485}}, - {{0x1e48381f, 0x01ad30d8, 0x1a01804f, 0x0e92e369, 0x1c5e6710, 0x02046863, 0x02d7f1ed, 0x1a90217f, 0xb68f9e}}}, - /* 9*16^60*G: */ - {{{0x11473678, 0x1429748f, 0x10e4bdc0, 0x00af2a12, 0x0c070cba, 0x18a62adc, 0x036ffd78, 0x13869880, 0xfd76cc}}, - {{0x0d144f4f, 0x10b27754, 0x007210df, 0x051ddc28, 0x12cd6606, 0x10539e81, 0x0f6b83fb, 0x086f0e28, 0xf20465}}}, - /* 11*16^60*G: */ - {{{0x0d7a2193, 0x1805b8a4, 0x05d51bb7, 0x123c89e3, 0x0ea212c6, 0x07413a5a, 0x1008679b, 0x14662476, 0x85a2ab}}, - {{0x10cdcf3a, 0x18641ea5, 0x0ec4909f, 0x0db5bf38, 0x0029fe1c, 0x104168e6, 0x145b60b1, 0x0afd6560, 0x9c1298}}}, - /* 13*16^60*G: */ - {{{0x177568b0, 0x0d8182d9, 0x180ec14d, 0x1d1ba033, 0x1650f35a, 0x16b62bc1, 0x19d1102d, 0x1f8e79ff, 0xd25ddb}}, - {{0x1f39929c, 0x0509c936, 0x0f0fc018, 0x04e7103c, 0x1d92b832, 0x17ba66f3, 0x024e2fab, 0x0eb27f09, 0x7a3aff}}}, - /* 15*16^60*G: */ - {{{0x071d7c13, 0x0ff288c5, 0x03fe8e15, 0x156beff4, 0x0c805641, 0x1f4d4bd5, 0x09c957c1, 0x06287d29, 0x458135}}, - {{0x1aff63cf, 0x11c5e2a9, 0x0f65ae65, 0x000caa85, 0x169c9702, 0x0878bbee, 0x0b62d5fd, 0x1d8292f3, 0x9f5858}}} - }, - { - /* 1*16^61*G: */ - {{{0x0d83f366, 0x16d1d069, 0x1ca16232, 0x1399dbc5, 0x1c97a0cd, 0x0185e60e, 0x18ba6bbd, 0x1eb6e27f, 0xbc4a9d}}, - {{0x181f33c1, 0x1ac6b332, 0x151ec5b5, 0x1153f7f4, 0x198caa6e, 0x1bd6fa5b, 0x1018e0e4, 0x194dcf0b, 0xd3a81}}}, - /* 3*16^61*G: */ - {{{0x1712be3c, 0x03517197, 0x051a99ac, 0x0be31db4, 0x01534729, 0x12edd580, 0x0de34f1c, 0x13b26636, 0x39d734}}, - {{0x1c6ff65c, 0x0180cfa0, 0x09059133, 0x1def4bd9, 0x012e8ef5, 0x1aaa6334, 0x0fdfec49, 0x09eadde7, 0x8f929b}}}, - /* 5*16^61*G: */ - {{{0x1f77f22b, 0x15727de6, 0x1e0b80d6, 0x12e47329, 0x1af26c69, 0x06b614ca, 0x17427947, 0x02fefb83, 0xf0cba6}}, - {{0x1909a03c, 0x1e47163a, 0x08255987, 0x0318fd21, 0x0d04004f, 0x1361b28b, 0x1e627bcc, 0x08627f3b, 0x1a25ab}}}, - /* 7*16^61*G: */ - {{{0x06509c12, 0x0566e6a6, 0x147d1d96, 0x17fc46b7, 0x068ed8d6, 0x18746c39, 0x134c8745, 0x173b642a, 0x381d7a}}, - {{0x0eb46102, 0x03215471, 0x19babdd5, 0x1050b0d9, 0x181e7205, 0x122b9d32, 0x16a7ad74, 0x0b6ffb47, 0xa47aab}}}, - /* 9*16^61*G: */ - {{{0x184fe955, 0x0d9da6b1, 0x18ef3923, 0x12ad4b40, 0x08a53f69, 0x1b9f34a6, 0x1f991e4e, 0x0a8cf570, 0xa703f0}}, - {{0x161344bd, 0x135977de, 0x05c9dfe8, 0x1c2c538b, 0x1199b539, 0x1c96b58c, 0x1eb703a9, 0x06b45608, 0xd500f9}}}, - /* 11*16^61*G: */ - {{{0x06eace58, 0x04cb2b60, 0x1cc8474d, 0x1c8ac745, 0x1a03f1b7, 0x1686b829, 0x035d1b1a, 0x18b55aaa, 0x73c6b3}}, - {{0x0af8654e, 0x0b8548b9, 0x0e34a45c, 0x150f1b77, 0x191c6aa6, 0x04c89b36, 0x1dd06ea4, 0x148e6749, 0x3a2fb4}}}, - /* 13*16^61*G: */ - {{{0x00181d5e, 0x059c45f8, 0x16abc815, 0x03675372, 0x0ddb8de7, 0x069d0e07, 0x1ff68740, 0x1cea0da8, 0xc627f3}}, - {{0x169f886d, 0x13c80531, 0x12f8b0e4, 0x0d600a93, 0x1f7d68ef, 0x0b009c50, 0x098ecb5a, 0x1ae3c885, 0xd78f9d}}}, - /* 15*16^61*G: */ - {{{0x17828b16, 0x07146cfd, 0x09211fcd, 0x0f2b1e51, 0x0de53a04, 0x1a053783, 0x08cfe897, 0x17c1dbfa, 0xbb88fa}}, - {{0x0aea5df7, 0x08a39d10, 0x087a5a71, 0x1502e9c7, 0x19163ec4, 0x02cb008a, 0x0374d177, 0x16609ebd, 0xb73676}}} - }, - { - /* 1*16^62*G: */ - {{{0x05324caa, 0x0a55987f, 0x051ca8e5, 0x16cbc615, 0x0a32e694, 0x063a4a29, 0x0f0348f6, 0x0f7f0531, 0x8c28a9}}, - {{0x0bef9482, 0x138ee39e, 0x072e5167, 0x0f09e08a, 0x0c0eb7ae, 0x16f98fbe, 0x064cde3f, 0x0c74660a, 0x40a304}}}, - /* 3*16^62*G: */ - {{{0x0754dd40, 0x11f438aa, 0x0d19b3e1, 0x044c63f8, 0x0f6e9a24, 0x020fe6b9, 0x1f3d16d2, 0x0e06581b, 0x972924}}, - {{0x0aa36143, 0x025a4979, 0x0b2bd24e, 0x15d0a4ab, 0x0df3690d, 0x03aee5ea, 0x08773457, 0x0884cbfd, 0x91d1a2}}}, - /* 5*16^62*G: */ - {{{0x0c2ca7ff, 0x016c175c, 0x17c0868f, 0x06c8bb2b, 0x127af180, 0x08d6ad17, 0x05b8141e, 0x12eb014f, 0x89637f}}, - {{0x10493e68, 0x16a0af0b, 0x10baadef, 0x178d471c, 0x17489f87, 0x0e78aa1a, 0x109355ee, 0x04919110, 0x2d1fe1}}}, - /* 7*16^62*G: */ - {{{0x0ca8dd7f, 0x0c36b1d0, 0x084e0698, 0x0e5006ad, 0x157421bc, 0x0ed01ea9, 0x1824bf72, 0x1ce37c4b, 0x308138}}, - {{0x0a92c7f2, 0x00af923c, 0x12b64579, 0x0cac8c86, 0x08e18c81, 0x1622e8a0, 0x124978e7, 0x1a51051f, 0x28d1e2}}}, - /* 9*16^62*G: */ - {{{0x066a3fb1, 0x06e62b44, 0x04b881b0, 0x00125033, 0x0862f6ec, 0x1a8642db, 0x0d974795, 0x1d054dbd, 0x575fc4}}, - {{0x102655ad, 0x0dc74854, 0x08ebcbc2, 0x076ae78d, 0x087daed3, 0x0de14bc7, 0x128b59c7, 0x120854df, 0x6f6edb}}}, - /* 11*16^62*G: */ - {{{0x190117df, 0x0db54523, 0x08040a48, 0x0a77779c, 0x02a8fda2, 0x137c0f75, 0x0de889fc, 0x06d6c9d5, 0xa5ec90}}, - {{0x186462fe, 0x0094099f, 0x0528d8f6, 0x08c3e0ac, 0x1a0f71c8, 0x1cc1d68f, 0x01003165, 0x0c4bd828, 0xb79dc6}}}, - /* 13*16^62*G: */ - {{{0x172ad712, 0x187cbae0, 0x0411ca42, 0x131961bc, 0x149b95a3, 0x1cbb0a31, 0x0c252779, 0x1d226621, 0xa153df}}, - {{0x0d48fdd2, 0x052fb29c, 0x1c2cca72, 0x0a7e50b5, 0x1b89abd0, 0x0c6af8f8, 0x0cbf120c, 0x0827f60b, 0xfd94d8}}}, - /* 15*16^62*G: */ - {{{0x11cf5b3a, 0x1861b808, 0x0d69e040, 0x0675077b, 0x1c824c44, 0x1a684476, 0x18564d70, 0x18d5ef28, 0x9a541a}}, - {{0x16a44ae4, 0x1faabaf9, 0x07a94b58, 0x11fdc4a4, 0x1475f554, 0x0d79b447, 0x0adf2bf8, 0x1839620d, 0xb66148}}} - }, - { - /* 1*16^63*G: */ - {{{0x1faccae0, 0x0625d088, 0x12eccdd2, 0x166a18b4, 0x11fd23c8, 0x0a672783, 0x1ea30776, 0x0cc272a4, 0x8ea96}}, - {{0x0e62b945, 0x0d79a518, 0x1c3e3a55, 0x0f077d39, 0x1c5d735b, 0x1e067dca, 0x1e0b8939, 0x17791dc4, 0x620efa}}}, - /* 3*16^63*G: */ - {{{0x06a06f5e, 0x0d205acb, 0x0820dc08, 0x0324a2dd, 0x1b716a34, 0x06a10931, 0x14eb0dec, 0x1f7d4284, 0x383b24}}, - {{0x13c6e772, 0x04fa3c36, 0x030ac102, 0x0d5ce977, 0x05a19e8f, 0x0b36aa75, 0x0881133d, 0x0d589db7, 0x54cf70}}}, - /* 5*16^63*G: */ - {{{0x0638a136, 0x1cbae0ea, 0x00e06571, 0x1a39c66d, 0x1790c2b0, 0x0ce35b06, 0x15b5e279, 0x1a07c05d, 0xe68432}}, - {{0x0c6c2584, 0x17e8c084, 0x0d5ccdaa, 0x13c7d7b6, 0x1e6472e0, 0x13981d00, 0x0998934a, 0x02731c6b, 0xca5be4}}}, - /* 7*16^63*G: */ - {{{0x16e8c10c, 0x0743e220, 0x06f5a01f, 0x0530be72, 0x06e7fb47, 0x1ef67398, 0x10a83bbe, 0x0b3c5fcb, 0x395dd5}}, - {{0x05fe638e, 0x01eb6c98, 0x19a48b2f, 0x013809b8, 0x04e274c9, 0x1f43d7fd, 0x0b174104, 0x1a968b25, 0xfd62dc}}}, - /* 9*16^63*G: */ - {{{0x0d6c14ef, 0x0b326d90, 0x1e4f23d4, 0x11f8ea0d, 0x06480085, 0x16adf771, 0x172e7dbb, 0x1b86aa4b, 0x7a514a}}, - {{0x0b3fbd13, 0x169f0c38, 0x09b893de, 0x1d5dee55, 0x15c3729b, 0x185ca647, 0x1363a25f, 0x1fda2a5c, 0x56edd1}}}, - /* 11*16^63*G: */ - {{{0x0f6d65eb, 0x14a31e82, 0x10085492, 0x1220eea8, 0x08f235a9, 0x179dfa48, 0x04363aa3, 0x0b0864bb, 0x1ee1fd}}, - {{0x1d22941c, 0x101b5c92, 0x0d60ac47, 0x05e9d30c, 0x0fcfaca3, 0x1cfe27a1, 0x1cf073ea, 0x1237bad8, 0xbb6928}}}, - /* 13*16^63*G: */ - {{{0x0e36cb44, 0x18ca8778, 0x12880647, 0x1d16d91b, 0x1357d617, 0x07e86c41, 0x0aa2f016, 0x069a71f5, 0x155156}}, - {{0x1f495a68, 0x14d7a328, 0x0830794c, 0x06e2ebe0, 0x1205da8c, 0x11f85a31, 0x08578dc3, 0x18eaaaea, 0xab4fff}}}, - /* 15*16^63*G: */ - {{{0x1427bacc, 0x0fca3083, 0x0b58b854, 0x0662c9ba, 0x1c4aa9e7, 0x07584ac6, 0x0804d8d6, 0x0c88d7ea, 0x3bc6bc}}, - {{0x0ad6fda6, 0x0619feaf, 0x02fad1c5, 0x16eb4a45, 0x0c02bd71, 0x1771136b, 0x0c1736d8, 0x180e2ed8, 0x8e305c}}} - }, diff --git a/trezor-crypto/crypto/setup.py b/trezor-crypto/crypto/setup.py deleted file mode 100755 index aee3dd4a928..00000000000 --- a/trezor-crypto/crypto/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -from distutils.core import setup -from distutils.extension import Extension - -from Cython.Build import cythonize -from Cython.Distutils import build_ext - -srcs = [ - "nist256p1", - "base58", - "bignum", - "bip32", - "ecdsa", - "curve25519", - "hmac", - "rand", - "ripemd160", - "secp256k1", - "sha2", -] - -extensions = [ - Extension( - "TrezorCrypto", - sources=["TrezorCrypto.pyx", "c.pxd"] + [x + ".c" for x in srcs], - extra_compile_args=[], - ) -] - -setup( - name="TrezorCrypto", - version="0.0.0", - description="Cython wrapper around trezor-crypto library", - author="Pavol Rusnak", - author_email="stick@satoshilabs.com", - url="https://github.com/trezor/trezor-crypto", - cmdclass={"build_ext": build_ext}, - ext_modules=cythonize(extensions), -) diff --git a/trezor-crypto/crypto/sha2.c b/trezor-crypto/crypto/sha2.c deleted file mode 100644 index 47d7eebbcdb..00000000000 --- a/trezor-crypto/crypto/sha2.c +++ /dev/null @@ -1,1317 +0,0 @@ -/** - * Copyright (c) 2000-2001 Aaron D. Gifford - * Copyright (c) 2013-2014 Pavol Rusnak - * 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 contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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. - */ - -#include -#include -#include -#include - -/* - * ASSERT NOTE: - * Some sanity checking code is included using assert(). On my FreeBSD - * system, this additional code can be removed by compiling with NDEBUG - * defined. Check your own systems manpage on assert() to see how to - * compile WITHOUT the sanity checking code on your system. - * - * UNROLLED TRANSFORM LOOP NOTE: - * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform - * loop version for the hash transform rounds (defined using macros - * later in this file). Either define on the command line, for example: - * - * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c - * - * or define below: - * - * #define SHA2_UNROLL_TRANSFORM - * - */ - - -/*** SHA-256/384/512 Machine Architecture Definitions *****************/ -/* - * BYTE_ORDER NOTE: - * - * Please make sure that your system defines BYTE_ORDER. If your - * architecture is little-endian, make sure it also defines - * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are - * equivilent. - * - * If your system does not define the above, then you can do so by - * hand like this: - * - * #define LITTLE_ENDIAN 1234 - * #define BIG_ENDIAN 4321 - * - * And for little-endian machines, add: - * - * #define BYTE_ORDER LITTLE_ENDIAN - * - * Or for big-endian machines: - * - * #define BYTE_ORDER BIG_ENDIAN - * - * The FreeBSD machine this was written on defines BYTE_ORDER - * appropriately by including (which in turn includes - * where the appropriate definitions are actually - * made). - */ - -#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) -#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN -#endif - -typedef uint8_t sha2_byte; /* Exactly 1 byte */ -typedef uint32_t sha2_word32; /* Exactly 4 bytes */ -typedef uint64_t sha2_word64; /* Exactly 8 bytes */ - -/*** SHA-256/384/512 Various Length Definitions ***********************/ -/* NOTE: Most of these are in sha2.h */ -#define SHA1_SHORT_BLOCK_LENGTH (SHA1_BLOCK_LENGTH - 8) -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) - -/* - * Macro for incrementally adding the unsigned 64-bit integer n to the - * unsigned 128-bit integer (represented using a two-element array of - * 64-bit words): - */ -#define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ -} - -#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) - -/*** THE SIX LOGICAL FUNCTIONS ****************************************/ -/* - * Bit shifting and rotation (used by the six SHA-XYZ logical functions: - * - * NOTE: In the original SHA-256/384/512 document, the shift-right - * function was named R and the rotate-right function was called S. - * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the - * web.) - * - * The newer NIST FIPS 180-2 document uses a much clearer naming - * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for - * rotate-left. (See: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - * on the web.) - * - * WARNING: These macros must be used cautiously, since they reference - * supplied parameters sometimes more than once, and thus could have - * unexpected side-effects if used without taking this into account. - */ - -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define SHR(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ -#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) -/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) -/* 32-bit Rotate-left (used in SHA-1): */ -#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) - -/* Two of six logical functions used in SHA-1, SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -/* Function used in SHA-1: */ -#define Parity(x,y,z) ((x) ^ (y) ^ (z)) - -/* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) -#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) -#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR(3 , (x))) -#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR(10, (x))) - -/* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) -#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) -#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) -#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) - -/*** INTERNAL FUNCTION PROTOTYPES *************************************/ -/* NOTE: These should not be accessed directly from outside this - * library -- they are intended for private internal visibility/use - * only. - */ -static void sha512_Last(SHA512_CTX*); - - -/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ - -/* Hash constant words K for SHA-1: */ -#define K1_0_TO_19 0x5a827999UL -#define K1_20_TO_39 0x6ed9eba1UL -#define K1_40_TO_59 0x8f1bbcdcUL -#define K1_60_TO_79 0xca62c1d6UL - -/* Initial hash value H for SHA-1: */ -const sha2_word32 sha1_initial_hash_value[SHA1_DIGEST_LENGTH / sizeof(sha2_word32)] = { - 0x67452301UL, - 0xefcdab89UL, - 0x98badcfeUL, - 0x10325476UL, - 0xc3d2e1f0UL -}; - -/* Hash constant words K for SHA-256: */ -const sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Initial hash value H for SHA-256: */ -const sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL -}; - -/* Hash constant words K for SHA-384 and SHA-512: */ -const sha2_word64 K512[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, - 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, - 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, - 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, - 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, - 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, - 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, - 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, - 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, - 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, - 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, - 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, - 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, - 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -/* Initial hash value H for SHA-512 */ -const sha2_word64 sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL -}; - -// [wallet-core] -const sha2_word64 sha512_256_initial_hash_value[8] = { - 0x22312194fc2bf72cULL, - 0x9f555fa3c84c64c2ULL, - 0x2393b86b6f53b151ULL, - 0x963877195940eabdULL, - 0x96283ee2a88effe3ULL, - 0xbe5e1e2553863992ULL, - 0x2b0199fc2c85b8aaULL, - 0x0eb72ddc81c52ca2ULL, -}; - -/* - * Constant used by SHA256/384/512_End() functions for converting the - * digest to a readable hexadecimal character string: - */ -const char *sha2_hex_digits = "0123456789abcdef"; - - -/*** SHA-1: ***********************************************************/ -void sha1_Init(SHA1_CTX* context) { - MEMCPY_BCOPY(context->state, sha1_initial_hash_value, SHA1_DIGEST_LENGTH); - memzero(context->buffer, SHA1_BLOCK_LENGTH); - context->bitcount = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-1 round macros: */ - -#define ROUND1_0_TO_15(a,b,c,d,e) \ - (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ - K1_0_TO_19 + ( W1[j] = *data++ ); \ - (b) = ROTL32(30, (b)); \ - j++; - -#define ROUND1_16_TO_19(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_20_TO_39(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_40_TO_59(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -#define ROUND1_60_TO_79(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; - -void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; - sha2_word32 T1 = 0; - sha2_word32 W1[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - - j = 0; - - /* Rounds 0 to 15 unrolled: */ - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - - /* Rounds 16 to 19 unrolled: */ - ROUND1_16_TO_19(e,a,b,c,d); - ROUND1_16_TO_19(d,e,a,b,c); - ROUND1_16_TO_19(c,d,e,a,b); - ROUND1_16_TO_19(b,c,d,e,a); - - /* Rounds 20 to 39 unrolled: */ - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - - /* Rounds 40 to 59 unrolled: */ - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - - /* Rounds 60 to 79 unrolled: */ - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - - /* Clean up */ - a = b = c = d = e = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void sha1_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0; - sha2_word32 T1 = 0; - sha2_word32 W1[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - j = 0; - do { - T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 16); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 20); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 40); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 60); - - do { - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; - T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1)); - e = d; - d = c; - c = ROTL32(30, b); - b = a; - a = T1; - j++; - } while (j < 80); - - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - - /* Clean up */ - a = b = c = d = e = T1 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void sha1_Update(SHA1_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA1_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - sha1_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA1_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA1_BLOCK_LENGTH); -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - sha1_Transform(context->state, context->buffer, context->state); - context->bitcount += SHA1_BLOCK_LENGTH << 3; - len -= SHA1_BLOCK_LENGTH; - data += SHA1_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; -} - -void sha1_Final(SHA1_CTX* context, sha2_byte digest[SHA1_DIGEST_LENGTH]) { - unsigned int usedspace = 0; - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA1_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; - - if (usedspace > SHA1_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA1_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - /* Do second-to-last transform: */ - sha1_Transform(context->state, context->buffer, context->state); - - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA1_SHORT_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - /* Set the bit count: */ - context->buffer[14] = context->bitcount >> 32; - context->buffer[15] = context->bitcount & 0xffffffff; - - /* Final transform: */ - sha1_Transform(context->state, context->buffer, context->state); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 5; j++) { - REVERSE32(context->state[j],context->state[j]); - } -#endif - MEMCPY_BCOPY(digest, context->state, SHA1_DIGEST_LENGTH); - } - - /* Clean up state data: */ - memzero(context, sizeof(SHA1_CTX)); - usedspace = 0; -} - -char *sha1_End(SHA1_CTX* context, char buffer[SHA1_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA1_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha1_Final(context, digest); - - for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA1_CTX)); - } - memzero(digest, SHA1_DIGEST_LENGTH); - return buffer; -} - -void sha1_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA1_DIGEST_LENGTH]) { - SHA1_CTX context = {0}; - sha1_Init(&context); - sha1_Update(&context, data, len); - sha1_Final(&context, digest); -} - -char* sha1_Data(const sha2_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { - SHA1_CTX context = {0}; - - sha1_Init(&context); - sha1_Update(&context, data, len); - return sha1_End(&context, digest); -} - -/*** SHA-256: *********************************************************/ -void sha256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - memzero(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-256 round macros: */ - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word32 T1 = 0; - sha2_word32 W256[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void sha256_Transform(const sha2_word32* state_in, const sha2_word32* data, sha2_word32* state_out) { - sha2_word32 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word32 T1 = 0, T2 = 0 , W256[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Apply the SHA-256 compression function to update a..h with copy */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W256[(j+1)&0x0f]; - s0 = sigma0_256(s0); - s1 = W256[(j+14)&0x0f]; - s1 = sigma1_256(s1); - - /* Apply the SHA-256 compression function to update a..h */ - T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 64); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - sha256_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA256_BLOCK_LENGTH); -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - sha256_Transform(context->state, context->buffer, context->state); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; -} - -void sha256_Final(SHA256_CTX* context, sha2_byte digest[SHA256_DIGEST_LENGTH]) { - unsigned int usedspace = 0; - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; - - if (usedspace > SHA256_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA256_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - /* Do second-to-last transform: */ - sha256_Transform(context->state, context->buffer, context->state); - - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA256_SHORT_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE32(context->buffer[j],context->buffer[j]); - } -#endif - /* Set the bit count: */ - context->buffer[14] = context->bitcount >> 32; - context->buffer[15] = context->bitcount & 0xffffffff; - - /* Final transform: */ - sha256_Transform(context->state, context->buffer, context->state); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - } -#endif - MEMCPY_BCOPY(digest, context->state, SHA256_DIGEST_LENGTH); - } - - /* Clean up state data: */ - memzero(context, sizeof(SHA256_CTX)); - usedspace = 0; -} - -char *sha256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA256_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha256_Final(context, digest); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA256_CTX)); - } - memzero(digest, SHA256_DIGEST_LENGTH); - return buffer; -} - -void sha256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) { - SHA256_CTX context = {0}; - sha256_Init(&context); - sha256_Update(&context, data, len); - sha256_Final(&context, digest); -} - -char* sha256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context = {0}; - - sha256_Init(&context); - sha256_Update(&context, data, len); - return sha256_End(&context, digest); -} - - -/*** SHA-512: *********************************************************/ -void sha512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - memzero(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -// [wallet-core] -void sha512_256_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha512_256_initial_hash_value, SHA512_DIGEST_LENGTH); - memzero(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-512 round macros: */ -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -#define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word64 T1 = 0, W512[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void sha512_Transform(const sha2_word64* state_in, const sha2_word64* data, sha2_word64* state_out) { - sha2_word64 a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, s0 = 0, s1 = 0; - sha2_word64 T1 = 0, T2 = 0, W512[16] = {0}; - int j = 0; - - /* Initialize registers with the prev. intermediate value */ - a = state_in[0]; - b = state_in[1]; - c = state_in[2]; - d = state_in[3]; - e = state_in[4]; - f = state_in[5]; - g = state_in[6]; - h = state_in[7]; - - j = 0; - do { - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - state_out[0] = state_in[0] + a; - state_out[1] = state_in[1] + b; - state_out[2] = state_in[2] + c; - state_out[3] = state_in[3] + d; - state_out[4] = state_in[4] + e; - state_out[5] = state_in[5] + f; - state_out[6] = state_in[6] + g; - state_out[7] = state_in[7] + h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace = 0, usedspace = 0; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } -#endif - sha512_Transform(context->state, context->buffer, context->state); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(((uint8_t*)context->buffer) + usedspace, data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - MEMCPY_BCOPY(context->buffer, data, SHA512_BLOCK_LENGTH); -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } -#endif - sha512_Transform(context->state, context->buffer, context->state); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; -} - -static void sha512_Last(SHA512_CTX* context) { - unsigned int usedspace = 0; - - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; - /* Begin padding with a 1 bit: */ - ((uint8_t*)context->buffer)[usedspace++] = 0x80; - - if (usedspace > SHA512_SHORT_BLOCK_LENGTH) { - memzero(((uint8_t*)context->buffer) + usedspace, SHA512_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 16; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } -#endif - /* Do second-to-last transform: */ - sha512_Transform(context->state, context->buffer, context->state); - - /* And prepare the last transform: */ - usedspace = 0; - } - /* Set-up for the last transform: */ - memzero(((uint8_t*)context->buffer) + usedspace, SHA512_SHORT_BLOCK_LENGTH - usedspace); - -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert TO host byte order */ - for (int j = 0; j < 14; j++) { - REVERSE64(context->buffer[j],context->buffer[j]); - } -#endif - /* Store the length of input data (in bits): */ - context->buffer[14] = context->bitcount[1]; - context->buffer[15] = context->bitcount[0]; - - /* Final transform: */ - sha512_Transform(context->state, context->buffer, context->state); -} - -void sha512_Final(SHA512_CTX* context, sha2_byte digest[SHA512_DIGEST_LENGTH]) { - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - sha512_Last(context); - - /* Save the hash data for output: */ -#if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - for (int j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - } -#endif - MEMCPY_BCOPY(digest, context->state, SHA512_DIGEST_LENGTH); - } - - /* Zero out state data */ - memzero(context, sizeof(SHA512_CTX)); -} - -char *sha512_End(SHA512_CTX* context, char buffer[SHA512_DIGEST_STRING_LENGTH]) { - sha2_byte digest[SHA512_DIGEST_LENGTH] = {0}, *d = digest; - int i = 0; - - if (buffer != (char*)0) { - sha512_Final(context, digest); - - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memzero(context, sizeof(SHA512_CTX)); - } - memzero(digest, SHA512_DIGEST_LENGTH); - return buffer; -} - -void sha512_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA512_DIGEST_LENGTH]) { - SHA512_CTX context = {0}; - sha512_Init(&context); - sha512_Update(&context, data, len); - sha512_Final(&context, digest); -} - -// [wallet-core] -void sha512_256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) { - SHA512_CTX context = {0}; - uint8_t result[SHA512_DIGEST_LENGTH]; - sha512_256_Init(&context); - sha512_Update(&context, data, len); - sha512_Final(&context, result); - - memcpy(digest, result, SHA256_DIGEST_LENGTH); - memzero(result, SHA512_DIGEST_LENGTH); -} - -char* sha512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context = {0}; - - sha512_Init(&context); - sha512_Update(&context, data, len); - return sha512_End(&context, digest); -} diff --git a/trezor-crypto/crypto/sha3.c b/trezor-crypto/crypto/sha3.c deleted file mode 100644 index 0b01bfe3a14..00000000000 --- a/trezor-crypto/crypto/sha3.c +++ /dev/null @@ -1,397 +0,0 @@ -/* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak). - * based on the - * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 - * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche - * - * Copyright: 2013 Aleksey Kravchenko - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! - */ - -#include -#include - -#include -#include - -#define I64(x) x##LL -#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) -#define le2me_64(x) (x) -#define IS_ALIGNED_64(p) (0 == (7 & ((long)(p)))) // [wallet-core] pointer/numerical type, for MacOS SDK 12.3 -# define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) - -/* constants */ -#define NumberOfRounds 24 - -/* SHA3 (Keccak) constants for 24 rounds */ -uint64_t keccak_round_constants[NumberOfRounds] = { - I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000), - I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009), - I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A), - I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003), - I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A), - I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008) -}; - -/* Initializing a sha3 context for given number of output bits */ -static void keccak_Init(SHA3_CTX *ctx, unsigned bits) -{ - /* NB: The Keccak capacity parameter = bits * 2 */ - unsigned rate = 1600 - bits * 2; - - memzero(ctx, sizeof(SHA3_CTX)); - ctx->block_size = rate / 8; - assert(rate <= 1600 && (rate % 64) == 0); -} - -/** - * Initialize context before calculating hash. - * - * @param ctx context to initialize - */ -void sha3_224_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 224); -} - -/** - * Initialize context before calculating hash. - * - * @param ctx context to initialize - */ -void sha3_256_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 256); -} - -/** - * Initialize context before calculating hash. - * - * @param ctx context to initialize - */ -void sha3_384_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 384); -} - -/** - * Initialize context before calculating hash. - * - * @param ctx context to initialize - */ -void sha3_512_Init(SHA3_CTX *ctx) -{ - keccak_Init(ctx, 512); -} - -/* Keccak theta() transformation */ -static void keccak_theta(uint64_t *A) -{ - unsigned int x = 0; - uint64_t C[5] = {0}, D[5] = {0}; - - for (x = 0; x < 5; x++) { - C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; - } - D[0] = ROTL64(C[1], 1) ^ C[4]; - D[1] = ROTL64(C[2], 1) ^ C[0]; - D[2] = ROTL64(C[3], 1) ^ C[1]; - D[3] = ROTL64(C[4], 1) ^ C[2]; - D[4] = ROTL64(C[0], 1) ^ C[3]; - - for (x = 0; x < 5; x++) { - A[x] ^= D[x]; - A[x + 5] ^= D[x]; - A[x + 10] ^= D[x]; - A[x + 15] ^= D[x]; - A[x + 20] ^= D[x]; - } -} - -/* Keccak pi() transformation */ -static void keccak_pi(uint64_t *A) -{ - uint64_t A1 = 0; - A1 = A[1]; - A[ 1] = A[ 6]; - A[ 6] = A[ 9]; - A[ 9] = A[22]; - A[22] = A[14]; - A[14] = A[20]; - A[20] = A[ 2]; - A[ 2] = A[12]; - A[12] = A[13]; - A[13] = A[19]; - A[19] = A[23]; - A[23] = A[15]; - A[15] = A[ 4]; - A[ 4] = A[24]; - A[24] = A[21]; - A[21] = A[ 8]; - A[ 8] = A[16]; - A[16] = A[ 5]; - A[ 5] = A[ 3]; - A[ 3] = A[18]; - A[18] = A[17]; - A[17] = A[11]; - A[11] = A[ 7]; - A[ 7] = A[10]; - A[10] = A1; - /* note: A[ 0] is left as is */ -} - -/* Keccak chi() transformation */ -static void keccak_chi(uint64_t *A) -{ - int i = 0; - for (i = 0; i < 25; i += 5) { - uint64_t A0 = A[0 + i], A1 = A[1 + i]; - A[0 + i] ^= ~A1 & A[2 + i]; - A[1 + i] ^= ~A[2 + i] & A[3 + i]; - A[2 + i] ^= ~A[3 + i] & A[4 + i]; - A[3 + i] ^= ~A[4 + i] & A0; - A[4 + i] ^= ~A0 & A1; - } -} - -static void sha3_permutation(uint64_t *state) -{ - int round = 0; - for (round = 0; round < NumberOfRounds; round++) - { - keccak_theta(state); - - /* apply Keccak rho() transformation */ - state[ 1] = ROTL64(state[ 1], 1); - state[ 2] = ROTL64(state[ 2], 62); - state[ 3] = ROTL64(state[ 3], 28); - state[ 4] = ROTL64(state[ 4], 27); - state[ 5] = ROTL64(state[ 5], 36); - state[ 6] = ROTL64(state[ 6], 44); - state[ 7] = ROTL64(state[ 7], 6); - state[ 8] = ROTL64(state[ 8], 55); - state[ 9] = ROTL64(state[ 9], 20); - state[10] = ROTL64(state[10], 3); - state[11] = ROTL64(state[11], 10); - state[12] = ROTL64(state[12], 43); - state[13] = ROTL64(state[13], 25); - state[14] = ROTL64(state[14], 39); - state[15] = ROTL64(state[15], 41); - state[16] = ROTL64(state[16], 45); - state[17] = ROTL64(state[17], 15); - state[18] = ROTL64(state[18], 21); - state[19] = ROTL64(state[19], 8); - state[20] = ROTL64(state[20], 18); - state[21] = ROTL64(state[21], 2); - state[22] = ROTL64(state[22], 61); - state[23] = ROTL64(state[23], 56); - state[24] = ROTL64(state[24], 14); - - keccak_pi(state); - keccak_chi(state); - - /* apply iota(state, round) */ - *state ^= keccak_round_constants[round]; - } -} - -/** - * The core transformation. Process the specified block of data. - * - * @param hash the algorithm state - * @param block the message block to process - * @param block_size the size of the processed block in bytes - */ -static void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) -{ - /* expanded loop */ - hash[ 0] ^= le2me_64(block[ 0]); - hash[ 1] ^= le2me_64(block[ 1]); - hash[ 2] ^= le2me_64(block[ 2]); - hash[ 3] ^= le2me_64(block[ 3]); - hash[ 4] ^= le2me_64(block[ 4]); - hash[ 5] ^= le2me_64(block[ 5]); - hash[ 6] ^= le2me_64(block[ 6]); - hash[ 7] ^= le2me_64(block[ 7]); - hash[ 8] ^= le2me_64(block[ 8]); - /* if not sha3-512 */ - if (block_size > 72) { - hash[ 9] ^= le2me_64(block[ 9]); - hash[10] ^= le2me_64(block[10]); - hash[11] ^= le2me_64(block[11]); - hash[12] ^= le2me_64(block[12]); - /* if not sha3-384 */ - if (block_size > 104) { - hash[13] ^= le2me_64(block[13]); - hash[14] ^= le2me_64(block[14]); - hash[15] ^= le2me_64(block[15]); - hash[16] ^= le2me_64(block[16]); - /* if not sha3-256 */ - if (block_size > 136) { - hash[17] ^= le2me_64(block[17]); -#ifdef FULL_SHA3_FAMILY_SUPPORT - /* if not sha3-224 */ - if (block_size > 144) { - hash[18] ^= le2me_64(block[18]); - hash[19] ^= le2me_64(block[19]); - hash[20] ^= le2me_64(block[20]); - hash[21] ^= le2me_64(block[21]); - hash[22] ^= le2me_64(block[22]); - hash[23] ^= le2me_64(block[23]); - hash[24] ^= le2me_64(block[24]); - } -#endif - } - } - } - /* make a permutation of the hash */ - sha3_permutation(hash); -} - -#define SHA3_FINALIZED 0x80000000 - -/** - * Calculate message hash. - * Can be called repeatedly with chunks of the message to be hashed. - * - * @param ctx the algorithm context containing current hashing state - * @param msg message chunk - * @param size length of the message chunk - */ -void sha3_Update(SHA3_CTX *ctx, const unsigned char *msg, size_t size) -{ - size_t idx = (size_t)ctx->rest; - size_t block_size = (size_t)ctx->block_size; - - if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */ - ctx->rest = (unsigned)((ctx->rest + size) % block_size); - - /* fill partial block */ - if (idx) { - size_t left = block_size - idx; - memcpy((char*)ctx->message + idx, msg, (size < left ? size : left)); - if (size < left) return; - - /* process partial block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - msg += left; - size -= left; - } - while (size >= block_size) { - uint64_t *aligned_message_block = NULL; - if (IS_ALIGNED_64(msg)) { - /* the most common case is processing of an already aligned message - without copying it */ - aligned_message_block = (uint64_t*)(void*)msg; - } else { - memcpy(ctx->message, msg, block_size); - aligned_message_block = ctx->message; - } - - sha3_process_block(ctx->hash, aligned_message_block, block_size); - msg += block_size; - size -= block_size; - } - if (size) { - memcpy(ctx->message, msg, size); /* save leftovers */ - } -} - -/** - * Store calculated hash into the given array. - * - * @param ctx the algorithm context containing current hashing state - * @param result calculated hash in binary form - */ -void sha3_Final(SHA3_CTX *ctx, unsigned char* result) -{ - size_t digest_length = 100 - ctx->block_size / 2; - const size_t block_size = ctx->block_size; - - if (!(ctx->rest & SHA3_FINALIZED)) - { - /* clear the rest of the data queue */ - memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); - ((char*)ctx->message)[ctx->rest] |= 0x06; - ((char*)ctx->message)[block_size - 1] |= 0x80; - - /* process final block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ - } - - assert(block_size > digest_length); - if (result) me64_to_le_str(result, ctx->hash, digest_length); - memzero(ctx, sizeof(SHA3_CTX)); -} - -#if USE_KECCAK -/** -* Store calculated hash into the given array. -* -* @param ctx the algorithm context containing current hashing state -* @param result calculated hash in binary form -*/ -void keccak_Final(SHA3_CTX *ctx, unsigned char* result) -{ - size_t digest_length = 100 - ctx->block_size / 2; - const size_t block_size = ctx->block_size; - - if (!(ctx->rest & SHA3_FINALIZED)) - { - /* clear the rest of the data queue */ - memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest); - ((char*)ctx->message)[ctx->rest] |= 0x01; - ((char*)ctx->message)[block_size - 1] |= 0x80; - - /* process final block */ - sha3_process_block(ctx->hash, ctx->message, block_size); - ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ - } - - assert(block_size > digest_length); - if (result) me64_to_le_str(result, ctx->hash, digest_length); - memzero(ctx, sizeof(SHA3_CTX)); -} - -void keccak_256(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - keccak_256_Init(&ctx); - keccak_Update(&ctx, data, len); - keccak_Final(&ctx, digest); -} - -void keccak_512(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - keccak_512_Init(&ctx); - keccak_Update(&ctx, data, len); - keccak_Final(&ctx, digest); -} -#endif /* USE_KECCAK */ - -void sha3_256(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - sha3_256_Init(&ctx); - sha3_Update(&ctx, data, len); - sha3_Final(&ctx, digest); -} - -void sha3_512(const unsigned char* data, size_t len, unsigned char* digest) -{ - SHA3_CTX ctx = {0}; - sha3_512_Init(&ctx); - sha3_Update(&ctx, data, len); - sha3_Final(&ctx, digest); -} diff --git a/trezor-crypto/crypto/shamir.c b/trezor-crypto/crypto/shamir.c deleted file mode 100644 index 6438d30fdba..00000000000 --- a/trezor-crypto/crypto/shamir.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Implementation of the hazardous parts of the SSS library - * - * Copyright (c) 2017 Daan Sprenkels - * Copyright (c) 2019 SatoshiLabs - * - * 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. - * - * This code contains the actual Shamir secret sharing functionality. The - * implementation of this code is based on the idea that the user likes to - * generate/combine 32 shares (in GF(2^8)) at the same time, because a 256 bit - * key will be exactly 32 bytes. Therefore we bitslice all the input and - * unbitslice the output right before returning. - * - * This bitslice approach optimizes natively on all architectures that are 32 - * bit or more. Care is taken to use not too many registers, to ensure that no - * values have to be leaked to the stack. - * - * All functions in this module are implemented constant time and constant - * lookup operations, as all proper crypto code must be. - */ - -#include -#include -#include - -static void bitslice(uint32_t r[8], const uint8_t *x, size_t len) { - size_t bit_idx = 0, arr_idx = 0; - uint32_t cur = 0; - - memset(r, 0, sizeof(uint32_t[8])); - for (arr_idx = 0; arr_idx < len; arr_idx++) { - cur = (uint32_t)x[arr_idx]; - for (bit_idx = 0; bit_idx < 8; bit_idx++) { - r[bit_idx] |= ((cur >> bit_idx) & 1) << arr_idx; - } - } -} - -static void unbitslice(uint8_t *r, const uint32_t x[8], size_t len) { - size_t bit_idx = 0, arr_idx = 0; - uint32_t cur = 0; - - memset(r, 0, sizeof(uint8_t) * len); - for (bit_idx = 0; bit_idx < 8; bit_idx++) { - cur = (uint32_t)x[bit_idx]; - for (arr_idx = 0; arr_idx < len; arr_idx++) { - r[arr_idx] |= ((cur >> arr_idx) & 1) << bit_idx; - } - } -} - -static void bitslice_setall(uint32_t r[8], const uint8_t x) { - size_t idx = 0; - for (idx = 0; idx < 8; idx++) { - r[idx] = -((x >> idx) & 1); - } -} - -/* - * Add (XOR) `r` with `x` and store the result in `r`. - */ -static void gf256_add(uint32_t r[8], const uint32_t x[8]) { - size_t idx = 0; - for (idx = 0; idx < 8; idx++) r[idx] ^= x[idx]; -} - -/* - * Safely multiply two bitsliced polynomials in GF(2^8) reduced by - * x^8 + x^4 + x^3 + x + 1. `r` and `a` may overlap, but overlapping of `r` - * and `b` will produce an incorrect result! If you need to square a polynomial - * use `gf256_square` instead. - */ -static void gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8]) { - /* This function implements Russian Peasant multiplication on two - * bitsliced polynomials. - * - * I personally think that these kinds of long lists of operations - * are often a bit ugly. A double for loop would be nicer and would - * take up a lot less lines of code. - * However, some compilers seem to fail in optimizing these kinds of - * loops. So we will just have to do this by hand. - */ - uint32_t a2[8] = {0}; - memcpy(a2, a, sizeof(uint32_t[8])); - - r[0] = a2[0] & b[0]; /* add (assignment, because r is 0) */ - r[1] = a2[1] & b[0]; - r[2] = a2[2] & b[0]; - r[3] = a2[3] & b[0]; - r[4] = a2[4] & b[0]; - r[5] = a2[5] & b[0]; - r[6] = a2[6] & b[0]; - r[7] = a2[7] & b[0]; - a2[0] ^= a2[7]; /* reduce */ - a2[2] ^= a2[7]; - a2[3] ^= a2[7]; - - r[0] ^= a2[7] & b[1]; /* add */ - r[1] ^= a2[0] & b[1]; - r[2] ^= a2[1] & b[1]; - r[3] ^= a2[2] & b[1]; - r[4] ^= a2[3] & b[1]; - r[5] ^= a2[4] & b[1]; - r[6] ^= a2[5] & b[1]; - r[7] ^= a2[6] & b[1]; - a2[7] ^= a2[6]; /* reduce */ - a2[1] ^= a2[6]; - a2[2] ^= a2[6]; - - r[0] ^= a2[6] & b[2]; /* add */ - r[1] ^= a2[7] & b[2]; - r[2] ^= a2[0] & b[2]; - r[3] ^= a2[1] & b[2]; - r[4] ^= a2[2] & b[2]; - r[5] ^= a2[3] & b[2]; - r[6] ^= a2[4] & b[2]; - r[7] ^= a2[5] & b[2]; - a2[6] ^= a2[5]; /* reduce */ - a2[0] ^= a2[5]; - a2[1] ^= a2[5]; - - r[0] ^= a2[5] & b[3]; /* add */ - r[1] ^= a2[6] & b[3]; - r[2] ^= a2[7] & b[3]; - r[3] ^= a2[0] & b[3]; - r[4] ^= a2[1] & b[3]; - r[5] ^= a2[2] & b[3]; - r[6] ^= a2[3] & b[3]; - r[7] ^= a2[4] & b[3]; - a2[5] ^= a2[4]; /* reduce */ - a2[7] ^= a2[4]; - a2[0] ^= a2[4]; - - r[0] ^= a2[4] & b[4]; /* add */ - r[1] ^= a2[5] & b[4]; - r[2] ^= a2[6] & b[4]; - r[3] ^= a2[7] & b[4]; - r[4] ^= a2[0] & b[4]; - r[5] ^= a2[1] & b[4]; - r[6] ^= a2[2] & b[4]; - r[7] ^= a2[3] & b[4]; - a2[4] ^= a2[3]; /* reduce */ - a2[6] ^= a2[3]; - a2[7] ^= a2[3]; - - r[0] ^= a2[3] & b[5]; /* add */ - r[1] ^= a2[4] & b[5]; - r[2] ^= a2[5] & b[5]; - r[3] ^= a2[6] & b[5]; - r[4] ^= a2[7] & b[5]; - r[5] ^= a2[0] & b[5]; - r[6] ^= a2[1] & b[5]; - r[7] ^= a2[2] & b[5]; - a2[3] ^= a2[2]; /* reduce */ - a2[5] ^= a2[2]; - a2[6] ^= a2[2]; - - r[0] ^= a2[2] & b[6]; /* add */ - r[1] ^= a2[3] & b[6]; - r[2] ^= a2[4] & b[6]; - r[3] ^= a2[5] & b[6]; - r[4] ^= a2[6] & b[6]; - r[5] ^= a2[7] & b[6]; - r[6] ^= a2[0] & b[6]; - r[7] ^= a2[1] & b[6]; - a2[2] ^= a2[1]; /* reduce */ - a2[4] ^= a2[1]; - a2[5] ^= a2[1]; - - r[0] ^= a2[1] & b[7]; /* add */ - r[1] ^= a2[2] & b[7]; - r[2] ^= a2[3] & b[7]; - r[3] ^= a2[4] & b[7]; - r[4] ^= a2[5] & b[7]; - r[5] ^= a2[6] & b[7]; - r[6] ^= a2[7] & b[7]; - r[7] ^= a2[0] & b[7]; - - memzero(a2, sizeof(a2)); -} - -/* - * Square `x` in GF(2^8) and write the result to `r`. `r` and `x` may overlap. - */ -static void gf256_square(uint32_t r[8], const uint32_t x[8]) { - uint32_t r8 = 0, r10 = 0, r12 = 0, r14 = 0; - /* Use the Freshman's Dream rule to square the polynomial - * Assignments are done from 7 downto 0, because this allows the user - * to execute this function in-place (e.g. `gf256_square(r, r);`). - */ - r14 = x[7]; - r12 = x[6]; - r10 = x[5]; - r8 = x[4]; - r[6] = x[3]; - r[4] = x[2]; - r[2] = x[1]; - r[0] = x[0]; - - /* Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8 */ - r[7] = r14; /* r[7] was 0 */ - r[6] ^= r14; - r10 ^= r14; - /* Skip, because r13 is always 0 */ - r[4] ^= r12; - r[5] = r12; /* r[5] was 0 */ - r[7] ^= r12; - r8 ^= r12; - /* Skip, because r11 is always 0 */ - r[2] ^= r10; - r[3] = r10; /* r[3] was 0 */ - r[5] ^= r10; - r[6] ^= r10; - r[1] = r14; /* r[1] was 0 */ - r[2] ^= r14; /* Substitute r9 by r14 because they will always be equal*/ - r[4] ^= r14; - r[5] ^= r14; - r[0] ^= r8; - r[1] ^= r8; - r[3] ^= r8; - r[4] ^= r8; -} - -/* - * Invert `x` in GF(2^8) and write the result to `r` - */ -static void gf256_inv(uint32_t r[8], uint32_t x[8]) { - uint32_t y[8] = {0}, z[8] = {0}; - - gf256_square(y, x); // y = x^2 - gf256_square(y, y); // y = x^4 - gf256_square(r, y); // r = x^8 - gf256_mul(z, r, x); // z = x^9 - gf256_square(r, r); // r = x^16 - gf256_mul(r, r, z); // r = x^25 - gf256_square(r, r); // r = x^50 - gf256_square(z, r); // z = x^100 - gf256_square(z, z); // z = x^200 - gf256_mul(r, r, z); // r = x^250 - gf256_mul(r, r, y); // r = x^254 - - memzero(y, sizeof(y)); - memzero(z, sizeof(z)); -} - -bool shamir_interpolate(uint8_t *result, uint8_t result_index, - const uint8_t *share_indices, - const uint8_t **share_values, uint8_t share_count, - size_t len) { - size_t i = 0, j = 0; - uint32_t x[8] = {0}; - uint32_t xs[share_count][8]; - memset(xs, 0, sizeof(xs)); - uint32_t ys[share_count][8]; - memset(ys, 0, sizeof(ys)); - uint32_t num[8] = {~0}; /* num is the numerator (=1) */ - uint32_t denom[8] = {0}; - uint32_t tmp[8] = {0}; - uint32_t secret[8] = {0}; - bool ret = true; - - if (len > SHAMIR_MAX_LEN) return false; - - /* Collect the x and y values */ - for (i = 0; i < share_count; i++) { - bitslice_setall(xs[i], share_indices[i]); - bitslice(ys[i], share_values[i], len); - } - bitslice_setall(x, result_index); - - for (i = 0; i < share_count; i++) { - memcpy(tmp, x, sizeof(uint32_t[8])); - gf256_add(tmp, xs[i]); - gf256_mul(num, num, tmp); - } - - /* Use Lagrange basis polynomials to calculate the secret coefficient */ - for (i = 0; i < share_count; i++) { - /* The code below assumes that none of the share_indices are equal to - * result_index. We need to treat that as a special case. */ - if (share_indices[i] != result_index) { - memcpy(denom, x, sizeof(denom)); - gf256_add(denom, xs[i]); - } else { - bitslice_setall(denom, 1); - gf256_add(secret, ys[i]); - } - for (j = 0; j < share_count; j++) { - if (i == j) continue; - memcpy(tmp, xs[i], sizeof(uint32_t[8])); - gf256_add(tmp, xs[j]); - gf256_mul(denom, denom, tmp); - } - if ((denom[0] | denom[1] | denom[2] | denom[3] | denom[4] | denom[5] | - denom[6] | denom[7]) == 0) { - /* The share_indices are not unique. */ - ret = false; - break; - } - gf256_inv(tmp, denom); /* inverted denominator */ - gf256_mul(tmp, tmp, num); /* basis polynomial */ - gf256_mul(tmp, tmp, ys[i]); /* scaled coefficient */ - gf256_add(secret, tmp); - } - - if (ret == true) { - unbitslice(result, secret, len); - } - - memzero(x, sizeof(x)); - memzero(xs, sizeof(xs)); - memzero(ys, sizeof(ys)); - memzero(num, sizeof(num)); - memzero(denom, sizeof(denom)); - memzero(tmp, sizeof(tmp)); - memzero(secret, sizeof(secret)); - return ret; -} diff --git a/trezor-crypto/crypto/slip39.c b/trezor-crypto/crypto/slip39.c deleted file mode 100644 index ec1adf20169..00000000000 --- a/trezor-crypto/crypto/slip39.c +++ /dev/null @@ -1,151 +0,0 @@ -/** - * This file is part of the TREZOR project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * 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 -#include -#include -#include - -/** - * Returns word at position `index`. - */ -const char* get_word(uint16_t index) { - if (index >= WORDS_COUNT) { - return NULL; - } - - return slip39_wordlist[index]; -} - -/** - * Finds the index of a given word. - * Returns true on success and stores result in `index`. - */ -bool word_index(uint16_t* index, const char* word, uint8_t word_length) { - uint16_t lo = 0; - uint16_t hi = WORDS_COUNT; - uint16_t mid = 0; - - while ((hi - lo) > 1) { - mid = (hi + lo) / 2; - if (strncmp(slip39_wordlist[mid], word, word_length) > 0) { - hi = mid; - } else { - lo = mid; - } - } - if (strncmp(slip39_wordlist[lo], word, word_length) != 0) { - return false; - } - *index = lo; - return true; -} - -/** - * Returns the index of the first sequence in words_button_seq[] which is not - * less than the given sequence. Returns WORDS_COUNT if there is no such - * sequence. - */ -static uint16_t find_sequence(uint16_t sequence) { - if (sequence <= words_button_seq[0].sequence) { - return 0; - } - - uint16_t lo = 0; - uint16_t hi = WORDS_COUNT; - - while (hi - lo > 1) { - uint16_t mid = (hi + lo) / 2; - if (words_button_seq[mid].sequence >= sequence) { - hi = mid; - } else { - lo = mid; - } - } - - return hi; -} - -/** - * Returns a word matching the button sequence prefix or NULL if no match is - * found. - */ -const char* button_sequence_to_word(uint16_t sequence) { - if (sequence == 0) { - return slip39_wordlist[words_button_seq[0].index]; - } - - uint16_t multiplier = 1; - while (sequence < 1000) { - sequence *= 10; - multiplier *= 10; - } - - uint16_t i = find_sequence(sequence); - if (i >= WORDS_COUNT || - words_button_seq[i].sequence - sequence >= multiplier) { - return NULL; - } - - return slip39_wordlist[words_button_seq[i].index]; -} - -/** - * Calculates which buttons on the T9 keyboard can still be pressed after the - * prefix was entered. Returns a 9-bit bitmask, where each bit specifies which - * buttons can be pressed (there are still words in this combination). The least - * significant bit corresponds to the first button. - * - * Example: 110000110 - second, third, eighth and ninth button still can be - * pressed. - */ -uint16_t slip39_word_completion_mask(uint16_t prefix) { - if (prefix >= 1000) { - // Four char prefix -> the mask is zero. - return 0; - } - - // Determine the range of sequences [min, max), which have the given prefix. - uint16_t min = prefix; - uint16_t max = prefix + 1; - uint16_t divider = 1; - while (max <= 1000) { - min *= 10; - max *= 10; - divider *= 10; - } - divider /= 10; - - // Determine the range we will be searching in words_button_seq[]. - min = find_sequence(min); - max = find_sequence(max); - - uint16_t bitmap = 0; - for (uint16_t i = min; i < max; ++i) { - uint8_t digit = (words_button_seq[i].sequence / divider) % 10; - bitmap |= 1 << (digit - 1); - } - - return bitmap; -} diff --git a/trezor-crypto/crypto/sodium/keypair.c b/trezor-crypto/crypto/sodium/keypair.c deleted file mode 100644 index 0375de0c59a..00000000000 --- a/trezor-crypto/crypto/sodium/keypair.c +++ /dev/null @@ -1,63 +0,0 @@ -#include - -#include - -/* Perform a fixed-base multiplication of the Edwards base point, - (which is efficient due to precalculated tables), then convert - to the Curve25519 montgomery-format public key. In particular, - convert Curve25519's "montgomery" x-coordinate into an Ed25519 - "edwards" y-coordinate: - - mont_x = (ed_y + 1) / (1 - ed_y) - - with projective coordinates: - - mont_x = (ed_y + ed_z) / (ed_z - ed_y) - - NOTE: ed_y=1 is converted to mont_x=0 since fe_invert is mod-exp -*/ -int ed25519_pk_to_curve25519(unsigned char *curve25519_pk, const unsigned char *ed25519_pk) { - ge25519_p3 A; - fe25519 x; - fe25519 one_minus_y; - - if (ge25519_has_small_order(ed25519_pk) != 0 || - ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || - ge25519_is_on_main_subgroup(&A) == 0) { - return -1; - } - fe25519_1(one_minus_y); - fe25519_sub(one_minus_y, one_minus_y, A.Y); - fe25519_invert(one_minus_y, one_minus_y); - fe25519_1(x); - fe25519_add(x, x, A.Y); - fe25519_mul(x, x, one_minus_y); - fe25519_tobytes(curve25519_pk, x); - - return 0; -} - -/* Convert the Curve25519 public key into an Ed25519 public key. In -particular, convert Curve25519's "montgomery" x-coordinate into an -Ed25519 "edwards" y-coordinate: - -ed_y = (mont_x - 1) / (mont_x + 1) - -NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp -*/ -int curve25519_pk_to_ed25519(unsigned char *ed25519_pk, const unsigned char *curve25519_pk) { - fe25519 x; - fe25519 tmp; - fe25519 one_minus_y; - - fe25519_frombytes(x, curve25519_pk); - fe25519_1(one_minus_y); - fe25519_add(one_minus_y, x, one_minus_y); - fe25519_invert(one_minus_y, one_minus_y); - fe25519_1(tmp); - fe25519_sub(x, x, tmp); - fe25519_mul(x, x, one_minus_y); - fe25519_tobytes(ed25519_pk, x); - - return 0; -} \ No newline at end of file diff --git a/trezor-crypto/crypto/sodium/private/ed25519_ref10.c b/trezor-crypto/crypto/sodium/private/ed25519_ref10.c deleted file mode 100644 index 48256483900..00000000000 --- a/trezor-crypto/crypto/sodium/private/ed25519_ref10.c +++ /dev/null @@ -1,481 +0,0 @@ -#include -#include -#include -#include - -#include - -/* - * Field arithmetic: - * Use 5*51 bit limbs on 64-bit systems with support for 128 bit arithmetic, - * and 10*25.5 bit limbs elsewhere. - * - * Functions used elsewhere that are candidates for inlining are defined - * via "private/curve25519_ref10.h". - */ - -#include -#include - -void fe25519_invert(fe25519 out, const fe25519 z) { - fe25519 t0; - fe25519 t1; - fe25519 t2; - fe25519 t3; - int i; - - fe25519_sq(t0, z); - fe25519_sq(t1, t0); - fe25519_sq(t1, t1); - fe25519_mul(t1, z, t1); - fe25519_mul(t0, t0, t1); - fe25519_sq(t2, t0); - fe25519_mul(t1, t1, t2); - fe25519_sq(t2, t1); - for (i = 1; i < 5; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t2, t1); - for (i = 1; i < 10; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t2, t2, t1); - fe25519_sq(t3, t2); - for (i = 1; i < 20; ++i) { - fe25519_sq(t3, t3); - } - fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 10; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t2, t1); - for (i = 1; i < 50; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t2, t2, t1); - fe25519_sq(t3, t2); - for (i = 1; i < 100; ++i) { - fe25519_sq(t3, t3); - } - fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 50; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 5; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(out, t1, t0); -} - -void fe25519_pow22523(fe25519 out, const fe25519 z) { - fe25519 t0; - fe25519 t1; - fe25519 t2; - int i; - - fe25519_sq(t0, z); - fe25519_sq(t1, t0); - fe25519_sq(t1, t1); - fe25519_mul(t1, z, t1); - fe25519_mul(t0, t0, t1); - fe25519_sq(t0, t0); - fe25519_mul(t0, t1, t0); - fe25519_sq(t1, t0); - for (i = 1; i < 5; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(t0, t1, t0); - fe25519_sq(t1, t0); - for (i = 1; i < 10; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(t1, t1, t0); - fe25519_sq(t2, t1); - for (i = 1; i < 20; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 10; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(t0, t1, t0); - fe25519_sq(t1, t0); - for (i = 1; i < 50; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(t1, t1, t0); - fe25519_sq(t2, t1); - for (i = 1; i < 100; ++i) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 50; ++i) { - fe25519_sq(t1, t1); - } - fe25519_mul(t0, t1, t0); - fe25519_sq(t0, t0); - fe25519_sq(t0, t0); - fe25519_mul(out, t0, z); -} - -/* - r = p + q - */ - -void ge25519_add2(ge25519_p1p1_1 *r, const ge25519_p3 *p, const ge25519_cached *q) { - fe25519 t0; - - fe25519_add(r->X, p->Y, p->X); - fe25519_sub(r->Y, p->Y, p->X); - fe25519_mul(r->Z, r->X, q->YplusX); - fe25519_mul(r->Y, r->Y, q->YminusX); - fe25519_mul(r->T, q->T2d, p->T); - fe25519_mul(r->X, p->Z, q->Z); - fe25519_add(t0, r->X, r->X); - fe25519_sub(r->X, r->Z, r->Y); - fe25519_add(r->Y, r->Z, r->Y); - fe25519_add(r->Z, t0, r->T); - fe25519_sub(r->T, t0, r->T); -} - -int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) { - fe25519 u; - fe25519 v; - fe25519 v3; - fe25519 vxx; - fe25519 m_root_check, p_root_check; - - fe25519_frombytes(h->Y, s); - fe25519_1(h->Z); - fe25519_sq(u, h->Y); - fe25519_mul(v, u, d); - fe25519_sub(u, u, h->Z); /* u = y^2-1 */ - fe25519_add(v, v, h->Z); /* v = dy^2+1 */ - - fe25519_sq(v3, v); - fe25519_mul(v3, v3, v); /* v3 = v^3 */ - fe25519_sq(h->X, v3); - fe25519_mul(h->X, h->X, v); - fe25519_mul(h->X, h->X, u); /* x = uv^7 */ - - fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ - fe25519_mul(h->X, h->X, v3); - fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ - - fe25519_sq(vxx, h->X); - fe25519_mul(vxx, vxx, v); - fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ - if (fe25519_iszero(m_root_check) == 0) { - fe25519_add(p_root_check, vxx, u); /* vx^2+u */ - if (fe25519_iszero(p_root_check) == 0) { - return -1; - } - fe25519_mul(h->X, h->X, sqrtm1); - } - - if (fe25519_isnegative(h->X) == (s[31] >> 7)) { - fe25519_neg(h->X, h->X); - } - fe25519_mul(h->T, h->X, h->Y); - - return 0; -} - -/* - r = p - */ - -void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1_1 *p) { - fe25519_mul(r->X, p->X, p->T); - fe25519_mul(r->Y, p->Y, p->Z); - fe25519_mul(r->Z, p->Z, p->T); - fe25519_mul(r->T, p->X, p->Y); -} - -/* - r = 2 * p - */ - -void ge25519_p2_dbl(ge25519_p1p1_1 *r, const ge25519_p2 *p) { - fe25519 t0; - - fe25519_sq(r->X, p->X); - fe25519_sq(r->Z, p->Y); - fe25519_sq2(r->T, p->Z); - fe25519_add(r->Y, p->X, p->Y); - fe25519_sq(t0, r->Y); - fe25519_add(r->Y, r->Z, r->X); - fe25519_sub(r->Z, r->Z, r->X); - fe25519_sub(r->X, t0, r->Y); - fe25519_sub(r->T, r->T, r->Z); -} - -void ge25519_p3_0(ge25519_p3 *h) { - fe25519_0(h->X); - fe25519_1(h->Y); - fe25519_1(h->Z); - fe25519_0(h->T); -} - -void ge25519_cached_0(ge25519_cached *h) { - fe25519_1(h->YplusX); - fe25519_1(h->YminusX); - fe25519_1(h->Z); - fe25519_0(h->T2d); -} - -/* - r = p - */ - -void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p) { - fe25519_add(r->YplusX, p->Y, p->X); - fe25519_sub(r->YminusX, p->Y, p->X); - fe25519_copy(r->Z, p->Z); - fe25519_mul(r->T2d, p->T, d2); -} - -/* - r = p - */ - -void ge25519_p3_to_p2(ge25519_p2 *r, const ge25519_p3 *p) { - fe25519_copy(r->X, p->X); - fe25519_copy(r->Y, p->Y); - fe25519_copy(r->Z, p->Z); -} - -void ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h) { - fe25519 recip; - fe25519 x; - fe25519 y; - - fe25519_invert(recip, h->Z); - fe25519_mul(x, h->X, recip); - fe25519_mul(y, h->Y, recip); - fe25519_tobytes(s, y); - s[31] ^= fe25519_isnegative(x) << 7; -} - -/* - r = 2 * p - */ - -void ge25519_p3_dbl(ge25519_p1p1_1 *r, const ge25519_p3 *p) { - ge25519_p2 q; - ge25519_p3_to_p2(&q, p); - ge25519_p2_dbl(r, &q); -} - -void ge25519_precomp_0(ge25519_precomp *h) { - fe25519_1(h->yplusx); - fe25519_1(h->yminusx); - fe25519_0(h->xy2d); -} - -unsigned char equal(signed char b, signed char c) { - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint32_t y = x; /* 0: yes; 1..255: no */ - - y -= 1; /* 4294967295: yes; 0..254: no */ - y >>= 31; /* 1: yes; 0: no */ - - return y; -} - -unsigned char negative(signed char b) { - /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - uint64_t x = b; - - x >>= 63; /* 1: yes; 0: no */ - - return x; -} - -void ge25519_cmov(ge25519_precomp *t, const ge25519_precomp *u, unsigned char b) { - fe25519_cmov(t->yplusx, u->yplusx, b); - fe25519_cmov(t->yminusx, u->yminusx, b); - fe25519_cmov(t->xy2d, u->xy2d, b); -} - -void ge25519_cmov_cached(ge25519_cached *t, const ge25519_cached *u, unsigned char b) { - fe25519_cmov(t->YplusX, u->YplusX, b); - fe25519_cmov(t->YminusX, u->YminusX, b); - fe25519_cmov(t->Z, u->Z, b); - fe25519_cmov(t->T2d, u->T2d, b); -} - -/* - r = p - q - */ - -void ge25519_sub(ge25519_p1p1_1 *r, const ge25519_p3 *p, const ge25519_cached *q) { - fe25519 t0; - - fe25519_add(r->X, p->Y, p->X); - fe25519_sub(r->Y, p->Y, p->X); - fe25519_mul(r->Z, r->X, q->YminusX); - fe25519_mul(r->Y, r->Y, q->YplusX); - fe25519_mul(r->T, q->T2d, p->T); - fe25519_mul(r->X, p->Z, q->Z); - fe25519_add(t0, r->X, r->X); - fe25519_sub(r->X, r->Z, r->Y); - fe25519_add(r->Y, r->Z, r->Y); - fe25519_sub(r->Z, t0, r->T); - fe25519_add(r->T, t0, r->T); -} - -void ge25519_tobytes(unsigned char *s, const ge25519_p2 *h) { - fe25519 recip; - fe25519 x; - fe25519 y; - - fe25519_invert(recip, h->Z); - fe25519_mul(x, h->X, recip); - fe25519_mul(y, h->Y, recip); - fe25519_tobytes(s, y); - s[31] ^= fe25519_isnegative(x) << 7; -} - -/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */ -void ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *A) { - const signed char aslide[253] = { - 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, - 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, - 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, - 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, - 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - ge25519_cached Ai[8]; - ge25519_p1p1_1 t; - ge25519_p3 u; - ge25519_p3 A2; - int i; - - ge25519_p3_to_cached(&Ai[0], A); - ge25519_p3_dbl(&t, A); - ge25519_p1p1_to_p3(&A2, &t); - ge25519_add2(&t, &A2, &Ai[0]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[1], &u); - ge25519_add2(&t, &A2, &Ai[1]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[2], &u); - ge25519_add2(&t, &A2, &Ai[2]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[3], &u); - ge25519_add2(&t, &A2, &Ai[3]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[4], &u); - ge25519_add2(&t, &A2, &Ai[4]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[5], &u); - ge25519_add2(&t, &A2, &Ai[5]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[6], &u); - ge25519_add2(&t, &A2, &Ai[6]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[7], &u); - - ge25519_p3_0(r); - - for (i = 252; i >= 0; --i) { - ge25519_p3_dbl(&t, r); - - if (aslide[i] > 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_add2(&t, &u, &Ai[aslide[i] / 2]); - } else if (aslide[i] < 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); - } - - ge25519_p1p1_to_p3(r, &t); - } -} - -int ge25519_is_on_main_subgroup(const ge25519_p3 *p) { - ge25519_p3 pl; - - ge25519_mul_l(&pl, p); - - return fe25519_iszero(pl.X); -} - -#ifndef CRYPTO_ALIGN -#if defined(__INTEL_COMPILER) || defined(_MSC_VER) -#define CRYPTO_ALIGN(x) __declspec(align(x)) -#else -#define CRYPTO_ALIGN(x) __attribute__((aligned(x))) -#endif -#endif - -#define COMPILER_ASSERT(X) (void)sizeof(char[(X) ? 1 : -1]) - -int ge25519_has_small_order(const unsigned char s[32]) { - CRYPTO_ALIGN(16) - const unsigned char blacklist[][32] = { - /* 0 (order 4) */ - {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, 0x00}, - /* 1 (order 1) */ - {0x01, 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}, - /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 - (order 8) */ - {0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, - 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, - 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05}, - /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 - (order 8) */ - {0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, - 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, - 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a}, - /* p-1 (order 2) */ - {0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, - /* p (=0, order 4) */ - {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, - /* p+1 (=1, order 1) */ - {0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}}; - unsigned char c[7] = {0}; - unsigned int k; - size_t i, j; - - COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); - for (j = 0; j < 31; j++) { - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= s[j] ^ blacklist[i][j]; - } - } - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; - } - k = 0; - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - k |= (c[i] - 1); - } - return (int)((k >> 8) & 1); -} \ No newline at end of file diff --git a/trezor-crypto/crypto/sodium/private/ed25519_ref10_fe_25_5.c b/trezor-crypto/crypto/sodium/private/ed25519_ref10_fe_25_5.c deleted file mode 100644 index f0b495e05c7..00000000000 --- a/trezor-crypto/crypto/sodium/private/ed25519_ref10_fe_25_5.c +++ /dev/null @@ -1,885 +0,0 @@ -#include - -/* - h = 0 - */ - -void fe25519_0(fe25519 h) { - memset(&h[0], 0, 10 * sizeof h[0]); -} - -/* - h = 1 - */ - -void fe25519_1(fe25519 h) { - h[0] = 1; - h[1] = 0; - memset(&h[2], 0, 8 * sizeof h[0]); -} - -/* - h = f + g - Can overlap h with f or g. - * - Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - * - Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - */ - -void fe25519_add(fe25519 h, const fe25519 f, const fe25519 g) { - int32_t h0 = f[0] + g[0]; - int32_t h1 = f[1] + g[1]; - int32_t h2 = f[2] + g[2]; - int32_t h3 = f[3] + g[3]; - int32_t h4 = f[4] + g[4]; - int32_t h5 = f[5] + g[5]; - int32_t h6 = f[6] + g[6]; - int32_t h7 = f[7] + g[7]; - int32_t h8 = f[8] + g[8]; - int32_t h9 = f[9] + g[9]; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* - h = f - g - Can overlap h with f or g. - * - Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - * - Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - */ - -void fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g) { - int32_t h0 = f[0] - g[0]; - int32_t h1 = f[1] - g[1]; - int32_t h2 = f[2] - g[2]; - int32_t h3 = f[3] - g[3]; - int32_t h4 = f[4] - g[4]; - int32_t h5 = f[5] - g[5]; - int32_t h6 = f[6] - g[6]; - int32_t h7 = f[7] - g[7]; - int32_t h8 = f[8] - g[8]; - int32_t h9 = f[9] - g[9]; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* - h = -f - * - Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - * - Postconditions: - |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - */ - -void fe25519_neg(fe25519 h, const fe25519 f) { - int32_t h0 = -f[0]; - int32_t h1 = -f[1]; - int32_t h2 = -f[2]; - int32_t h3 = -f[3]; - int32_t h4 = -f[4]; - int32_t h5 = -f[5]; - int32_t h6 = -f[6]; - int32_t h7 = -f[7]; - int32_t h8 = -f[8]; - int32_t h9 = -f[9]; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* - Replace (f,g) with (g,g) if b == 1; - replace (f,g) with (f,g) if b == 0. - * - Preconditions: b in {0,1}. - */ - -void fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) { - const uint32_t mask = (uint32_t)(-(int32_t)b); - - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t x0 = f0 ^ g[0]; - int32_t x1 = f1 ^ g[1]; - int32_t x2 = f2 ^ g[2]; - int32_t x3 = f3 ^ g[3]; - int32_t x4 = f4 ^ g[4]; - int32_t x5 = f5 ^ g[5]; - int32_t x6 = f6 ^ g[6]; - int32_t x7 = f7 ^ g[7]; - int32_t x8 = f8 ^ g[8]; - int32_t x9 = f9 ^ g[9]; - - x0 &= mask; - x1 &= mask; - x2 &= mask; - x3 &= mask; - x4 &= mask; - x5 &= mask; - x6 &= mask; - x7 &= mask; - x8 &= mask; - x9 &= mask; - - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; -} - -/* - h = f - */ - -void fe25519_copy(fe25519 h, const fe25519 f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; -} - -/* - return 1 if f is in {1,3,5,...,q-2} - return 0 if f is in {0,2,4,...,q-1} - - Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - */ - -int fe25519_isnegative(const fe25519 f) { - unsigned char s[32]; - - fe25519_tobytes(s, f); - - return s[0] & 1; -} - -int sodium_is_zero(const unsigned char *n, const size_t nlen) { - size_t i; - volatile unsigned char d = 0U; - - for (i = 0U; i < nlen; i++) { - d |= n[i]; - } - return 1 & ((d - 1) >> 8); -} - -/* - return 1 if f == 0 - return 0 if f != 0 - - Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - */ - -int fe25519_iszero(const fe25519 f) { - unsigned char s[32]; - - fe25519_tobytes(s, f); - - return sodium_is_zero(s, 32); -} - -/* - h = f * g - Can overlap h with f or g. - * - Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - * - Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. - */ - -/* - Notes on implementation strategy: - * - Using schoolbook multiplication. - Karatsuba would save a little in some cost models. - * - Most multiplications by 2 and 19 are 32-bit precomputations; - cheaper than 64-bit postcomputations. - * - There is one remaining multiplication by 19 in the carry chain; - one *19 precomputation can be merged into this, - but the resulting data flow is considerably less clean. - * - There are 12 carries below. - 10 of them are 2-way parallelizable and vectorizable. - Can get away with 11 carries, but then data flow is much deeper. - * - With tighter constraints on inputs can squeeze carries into int32. - */ - -void fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - - int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ - int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ - int32_t g3_19 = 19 * g3; - int32_t g4_19 = 19 * g4; - int32_t g5_19 = 19 * g5; - int32_t g6_19 = 19 * g6; - int32_t g7_19 = 19 * g7; - int32_t g8_19 = 19 * g8; - int32_t g9_19 = 19 * g9; - int32_t f1_2 = 2 * f1; - int32_t f3_2 = 2 * f3; - int32_t f5_2 = 2 * f5; - int32_t f7_2 = 2 * f7; - int32_t f9_2 = 2 * f9; - - int64_t f0g0 = f0 * (int64_t)g0; - int64_t f0g1 = f0 * (int64_t)g1; - int64_t f0g2 = f0 * (int64_t)g2; - int64_t f0g3 = f0 * (int64_t)g3; - int64_t f0g4 = f0 * (int64_t)g4; - int64_t f0g5 = f0 * (int64_t)g5; - int64_t f0g6 = f0 * (int64_t)g6; - int64_t f0g7 = f0 * (int64_t)g7; - int64_t f0g8 = f0 * (int64_t)g8; - int64_t f0g9 = f0 * (int64_t)g9; - int64_t f1g0 = f1 * (int64_t)g0; - int64_t f1g1_2 = f1_2 * (int64_t)g1; - int64_t f1g2 = f1 * (int64_t)g2; - int64_t f1g3_2 = f1_2 * (int64_t)g3; - int64_t f1g4 = f1 * (int64_t)g4; - int64_t f1g5_2 = f1_2 * (int64_t)g5; - int64_t f1g6 = f1 * (int64_t)g6; - int64_t f1g7_2 = f1_2 * (int64_t)g7; - int64_t f1g8 = f1 * (int64_t)g8; - int64_t f1g9_38 = f1_2 * (int64_t)g9_19; - int64_t f2g0 = f2 * (int64_t)g0; - int64_t f2g1 = f2 * (int64_t)g1; - int64_t f2g2 = f2 * (int64_t)g2; - int64_t f2g3 = f2 * (int64_t)g3; - int64_t f2g4 = f2 * (int64_t)g4; - int64_t f2g5 = f2 * (int64_t)g5; - int64_t f2g6 = f2 * (int64_t)g6; - int64_t f2g7 = f2 * (int64_t)g7; - int64_t f2g8_19 = f2 * (int64_t)g8_19; - int64_t f2g9_19 = f2 * (int64_t)g9_19; - int64_t f3g0 = f3 * (int64_t)g0; - int64_t f3g1_2 = f3_2 * (int64_t)g1; - int64_t f3g2 = f3 * (int64_t)g2; - int64_t f3g3_2 = f3_2 * (int64_t)g3; - int64_t f3g4 = f3 * (int64_t)g4; - int64_t f3g5_2 = f3_2 * (int64_t)g5; - int64_t f3g6 = f3 * (int64_t)g6; - int64_t f3g7_38 = f3_2 * (int64_t)g7_19; - int64_t f3g8_19 = f3 * (int64_t)g8_19; - int64_t f3g9_38 = f3_2 * (int64_t)g9_19; - int64_t f4g0 = f4 * (int64_t)g0; - int64_t f4g1 = f4 * (int64_t)g1; - int64_t f4g2 = f4 * (int64_t)g2; - int64_t f4g3 = f4 * (int64_t)g3; - int64_t f4g4 = f4 * (int64_t)g4; - int64_t f4g5 = f4 * (int64_t)g5; - int64_t f4g6_19 = f4 * (int64_t)g6_19; - int64_t f4g7_19 = f4 * (int64_t)g7_19; - int64_t f4g8_19 = f4 * (int64_t)g8_19; - int64_t f4g9_19 = f4 * (int64_t)g9_19; - int64_t f5g0 = f5 * (int64_t)g0; - int64_t f5g1_2 = f5_2 * (int64_t)g1; - int64_t f5g2 = f5 * (int64_t)g2; - int64_t f5g3_2 = f5_2 * (int64_t)g3; - int64_t f5g4 = f5 * (int64_t)g4; - int64_t f5g5_38 = f5_2 * (int64_t)g5_19; - int64_t f5g6_19 = f5 * (int64_t)g6_19; - int64_t f5g7_38 = f5_2 * (int64_t)g7_19; - int64_t f5g8_19 = f5 * (int64_t)g8_19; - int64_t f5g9_38 = f5_2 * (int64_t)g9_19; - int64_t f6g0 = f6 * (int64_t)g0; - int64_t f6g1 = f6 * (int64_t)g1; - int64_t f6g2 = f6 * (int64_t)g2; - int64_t f6g3 = f6 * (int64_t)g3; - int64_t f6g4_19 = f6 * (int64_t)g4_19; - int64_t f6g5_19 = f6 * (int64_t)g5_19; - int64_t f6g6_19 = f6 * (int64_t)g6_19; - int64_t f6g7_19 = f6 * (int64_t)g7_19; - int64_t f6g8_19 = f6 * (int64_t)g8_19; - int64_t f6g9_19 = f6 * (int64_t)g9_19; - int64_t f7g0 = f7 * (int64_t)g0; - int64_t f7g1_2 = f7_2 * (int64_t)g1; - int64_t f7g2 = f7 * (int64_t)g2; - int64_t f7g3_38 = f7_2 * (int64_t)g3_19; - int64_t f7g4_19 = f7 * (int64_t)g4_19; - int64_t f7g5_38 = f7_2 * (int64_t)g5_19; - int64_t f7g6_19 = f7 * (int64_t)g6_19; - int64_t f7g7_38 = f7_2 * (int64_t)g7_19; - int64_t f7g8_19 = f7 * (int64_t)g8_19; - int64_t f7g9_38 = f7_2 * (int64_t)g9_19; - int64_t f8g0 = f8 * (int64_t)g0; - int64_t f8g1 = f8 * (int64_t)g1; - int64_t f8g2_19 = f8 * (int64_t)g2_19; - int64_t f8g3_19 = f8 * (int64_t)g3_19; - int64_t f8g4_19 = f8 * (int64_t)g4_19; - int64_t f8g5_19 = f8 * (int64_t)g5_19; - int64_t f8g6_19 = f8 * (int64_t)g6_19; - int64_t f8g7_19 = f8 * (int64_t)g7_19; - int64_t f8g8_19 = f8 * (int64_t)g8_19; - int64_t f8g9_19 = f8 * (int64_t)g9_19; - int64_t f9g0 = f9 * (int64_t)g0; - int64_t f9g1_38 = f9_2 * (int64_t)g1_19; - int64_t f9g2_19 = f9 * (int64_t)g2_19; - int64_t f9g3_38 = f9_2 * (int64_t)g3_19; - int64_t f9g4_19 = f9 * (int64_t)g4_19; - int64_t f9g5_38 = f9_2 * (int64_t)g5_19; - int64_t f9g6_19 = f9 * (int64_t)g6_19; - int64_t f9g7_38 = f9_2 * (int64_t)g7_19; - int64_t f9g8_19 = f9 * (int64_t)g8_19; - int64_t f9g9_38 = f9_2 * (int64_t)g9_19; - - int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + - f8g2_19 + f9g1_38; - int64_t h1 = - f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; - int64_t h2 = - f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; - int64_t h3 = - f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; - int64_t h4 = - f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; - int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; - int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; - int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; - int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; - int64_t h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; - - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - /* - |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) - i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 - |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) - i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 - */ - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - /* |h0| <= 2^25 */ - /* |h4| <= 2^25 */ - /* |h1| <= 1.71*2^59 */ - /* |h5| <= 1.71*2^59 */ - - carry1 = (h1 + (int64_t)(1L << 24)) >> 25; - h2 += carry1; - h1 -= carry1 * ((uint64_t)1L << 25); - carry5 = (h5 + (int64_t)(1L << 24)) >> 25; - h6 += carry5; - h5 -= carry5 * ((uint64_t)1L << 25); - /* |h1| <= 2^24; from now on fits into int32 */ - /* |h5| <= 2^24; from now on fits into int32 */ - /* |h2| <= 1.41*2^60 */ - /* |h6| <= 1.41*2^60 */ - - carry2 = (h2 + (int64_t)(1L << 25)) >> 26; - h3 += carry2; - h2 -= carry2 * ((uint64_t)1L << 26); - carry6 = (h6 + (int64_t)(1L << 25)) >> 26; - h7 += carry6; - h6 -= carry6 * ((uint64_t)1L << 26); - /* |h2| <= 2^25; from now on fits into int32 unchanged */ - /* |h6| <= 2^25; from now on fits into int32 unchanged */ - /* |h3| <= 1.71*2^59 */ - /* |h7| <= 1.71*2^59 */ - - carry3 = (h3 + (int64_t)(1L << 24)) >> 25; - h4 += carry3; - h3 -= carry3 * ((uint64_t)1L << 25); - carry7 = (h7 + (int64_t)(1L << 24)) >> 25; - h8 += carry7; - h7 -= carry7 * ((uint64_t)1L << 25); - /* |h3| <= 2^24; from now on fits into int32 unchanged */ - /* |h7| <= 2^24; from now on fits into int32 unchanged */ - /* |h4| <= 1.72*2^34 */ - /* |h8| <= 1.41*2^60 */ - - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - carry8 = (h8 + (int64_t)(1L << 25)) >> 26; - h9 += carry8; - h8 -= carry8 * ((uint64_t)1L << 26); - /* |h4| <= 2^25; from now on fits into int32 unchanged */ - /* |h8| <= 2^25; from now on fits into int32 unchanged */ - /* |h5| <= 1.01*2^24 */ - /* |h9| <= 1.71*2^59 */ - - carry9 = (h9 + (int64_t)(1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= carry9 * ((uint64_t)1L << 25); - /* |h9| <= 2^24; from now on fits into int32 unchanged */ - /* |h0| <= 1.1*2^39 */ - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - /* |h0| <= 2^25; from now on fits into int32 unchanged */ - /* |h1| <= 1.01*2^24 */ - - h[0] = (int32_t)h0; - h[1] = (int32_t)h1; - h[2] = (int32_t)h2; - h[3] = (int32_t)h3; - h[4] = (int32_t)h4; - h[5] = (int32_t)h5; - h[6] = (int32_t)h6; - h[7] = (int32_t)h7; - h[8] = (int32_t)h8; - h[9] = (int32_t)h9; -} - -/* - h = f * f - Can overlap h with f. - * - Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - * - Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. - */ - -void fe25519_sq(fe25519 h, const fe25519 f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - - int64_t f0f0 = f0 * (int64_t)f0; - int64_t f0f1_2 = f0_2 * (int64_t)f1; - int64_t f0f2_2 = f0_2 * (int64_t)f2; - int64_t f0f3_2 = f0_2 * (int64_t)f3; - int64_t f0f4_2 = f0_2 * (int64_t)f4; - int64_t f0f5_2 = f0_2 * (int64_t)f5; - int64_t f0f6_2 = f0_2 * (int64_t)f6; - int64_t f0f7_2 = f0_2 * (int64_t)f7; - int64_t f0f8_2 = f0_2 * (int64_t)f8; - int64_t f0f9_2 = f0_2 * (int64_t)f9; - int64_t f1f1_2 = f1_2 * (int64_t)f1; - int64_t f1f2_2 = f1_2 * (int64_t)f2; - int64_t f1f3_4 = f1_2 * (int64_t)f3_2; - int64_t f1f4_2 = f1_2 * (int64_t)f4; - int64_t f1f5_4 = f1_2 * (int64_t)f5_2; - int64_t f1f6_2 = f1_2 * (int64_t)f6; - int64_t f1f7_4 = f1_2 * (int64_t)f7_2; - int64_t f1f8_2 = f1_2 * (int64_t)f8; - int64_t f1f9_76 = f1_2 * (int64_t)f9_38; - int64_t f2f2 = f2 * (int64_t)f2; - int64_t f2f3_2 = f2_2 * (int64_t)f3; - int64_t f2f4_2 = f2_2 * (int64_t)f4; - int64_t f2f5_2 = f2_2 * (int64_t)f5; - int64_t f2f6_2 = f2_2 * (int64_t)f6; - int64_t f2f7_2 = f2_2 * (int64_t)f7; - int64_t f2f8_38 = f2_2 * (int64_t)f8_19; - int64_t f2f9_38 = f2 * (int64_t)f9_38; - int64_t f3f3_2 = f3_2 * (int64_t)f3; - int64_t f3f4_2 = f3_2 * (int64_t)f4; - int64_t f3f5_4 = f3_2 * (int64_t)f5_2; - int64_t f3f6_2 = f3_2 * (int64_t)f6; - int64_t f3f7_76 = f3_2 * (int64_t)f7_38; - int64_t f3f8_38 = f3_2 * (int64_t)f8_19; - int64_t f3f9_76 = f3_2 * (int64_t)f9_38; - int64_t f4f4 = f4 * (int64_t)f4; - int64_t f4f5_2 = f4_2 * (int64_t)f5; - int64_t f4f6_38 = f4_2 * (int64_t)f6_19; - int64_t f4f7_38 = f4 * (int64_t)f7_38; - int64_t f4f8_38 = f4_2 * (int64_t)f8_19; - int64_t f4f9_38 = f4 * (int64_t)f9_38; - int64_t f5f5_38 = f5 * (int64_t)f5_38; - int64_t f5f6_38 = f5_2 * (int64_t)f6_19; - int64_t f5f7_76 = f5_2 * (int64_t)f7_38; - int64_t f5f8_38 = f5_2 * (int64_t)f8_19; - int64_t f5f9_76 = f5_2 * (int64_t)f9_38; - int64_t f6f6_19 = f6 * (int64_t)f6_19; - int64_t f6f7_38 = f6 * (int64_t)f7_38; - int64_t f6f8_38 = f6_2 * (int64_t)f8_19; - int64_t f6f9_38 = f6 * (int64_t)f9_38; - int64_t f7f7_38 = f7 * (int64_t)f7_38; - int64_t f7f8_38 = f7_2 * (int64_t)f8_19; - int64_t f7f9_76 = f7_2 * (int64_t)f9_38; - int64_t f8f8_19 = f8 * (int64_t)f8_19; - int64_t f8f9_38 = f8 * (int64_t)f9_38; - int64_t f9f9_38 = f9 * (int64_t)f9_38; - - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - - carry1 = (h1 + (int64_t)(1L << 24)) >> 25; - h2 += carry1; - h1 -= carry1 * ((uint64_t)1L << 25); - carry5 = (h5 + (int64_t)(1L << 24)) >> 25; - h6 += carry5; - h5 -= carry5 * ((uint64_t)1L << 25); - - carry2 = (h2 + (int64_t)(1L << 25)) >> 26; - h3 += carry2; - h2 -= carry2 * ((uint64_t)1L << 26); - carry6 = (h6 + (int64_t)(1L << 25)) >> 26; - h7 += carry6; - h6 -= carry6 * ((uint64_t)1L << 26); - - carry3 = (h3 + (int64_t)(1L << 24)) >> 25; - h4 += carry3; - h3 -= carry3 * ((uint64_t)1L << 25); - carry7 = (h7 + (int64_t)(1L << 24)) >> 25; - h8 += carry7; - h7 -= carry7 * ((uint64_t)1L << 25); - - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - carry8 = (h8 + (int64_t)(1L << 25)) >> 26; - h9 += carry8; - h8 -= carry8 * ((uint64_t)1L << 26); - - carry9 = (h9 + (int64_t)(1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= carry9 * ((uint64_t)1L << 25); - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - - h[0] = (int32_t)h0; - h[1] = (int32_t)h1; - h[2] = (int32_t)h2; - h[3] = (int32_t)h3; - h[4] = (int32_t)h4; - h[5] = (int32_t)h5; - h[6] = (int32_t)h6; - h[7] = (int32_t)h7; - h[8] = (int32_t)h8; - h[9] = (int32_t)h9; -} - -/* - h = 2 * f * f - Can overlap h with f. - * - Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - * - Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. - */ - -void fe25519_sq2(fe25519 h, const fe25519 f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - - int64_t f0f0 = f0 * (int64_t)f0; - int64_t f0f1_2 = f0_2 * (int64_t)f1; - int64_t f0f2_2 = f0_2 * (int64_t)f2; - int64_t f0f3_2 = f0_2 * (int64_t)f3; - int64_t f0f4_2 = f0_2 * (int64_t)f4; - int64_t f0f5_2 = f0_2 * (int64_t)f5; - int64_t f0f6_2 = f0_2 * (int64_t)f6; - int64_t f0f7_2 = f0_2 * (int64_t)f7; - int64_t f0f8_2 = f0_2 * (int64_t)f8; - int64_t f0f9_2 = f0_2 * (int64_t)f9; - int64_t f1f1_2 = f1_2 * (int64_t)f1; - int64_t f1f2_2 = f1_2 * (int64_t)f2; - int64_t f1f3_4 = f1_2 * (int64_t)f3_2; - int64_t f1f4_2 = f1_2 * (int64_t)f4; - int64_t f1f5_4 = f1_2 * (int64_t)f5_2; - int64_t f1f6_2 = f1_2 * (int64_t)f6; - int64_t f1f7_4 = f1_2 * (int64_t)f7_2; - int64_t f1f8_2 = f1_2 * (int64_t)f8; - int64_t f1f9_76 = f1_2 * (int64_t)f9_38; - int64_t f2f2 = f2 * (int64_t)f2; - int64_t f2f3_2 = f2_2 * (int64_t)f3; - int64_t f2f4_2 = f2_2 * (int64_t)f4; - int64_t f2f5_2 = f2_2 * (int64_t)f5; - int64_t f2f6_2 = f2_2 * (int64_t)f6; - int64_t f2f7_2 = f2_2 * (int64_t)f7; - int64_t f2f8_38 = f2_2 * (int64_t)f8_19; - int64_t f2f9_38 = f2 * (int64_t)f9_38; - int64_t f3f3_2 = f3_2 * (int64_t)f3; - int64_t f3f4_2 = f3_2 * (int64_t)f4; - int64_t f3f5_4 = f3_2 * (int64_t)f5_2; - int64_t f3f6_2 = f3_2 * (int64_t)f6; - int64_t f3f7_76 = f3_2 * (int64_t)f7_38; - int64_t f3f8_38 = f3_2 * (int64_t)f8_19; - int64_t f3f9_76 = f3_2 * (int64_t)f9_38; - int64_t f4f4 = f4 * (int64_t)f4; - int64_t f4f5_2 = f4_2 * (int64_t)f5; - int64_t f4f6_38 = f4_2 * (int64_t)f6_19; - int64_t f4f7_38 = f4 * (int64_t)f7_38; - int64_t f4f8_38 = f4_2 * (int64_t)f8_19; - int64_t f4f9_38 = f4 * (int64_t)f9_38; - int64_t f5f5_38 = f5 * (int64_t)f5_38; - int64_t f5f6_38 = f5_2 * (int64_t)f6_19; - int64_t f5f7_76 = f5_2 * (int64_t)f7_38; - int64_t f5f8_38 = f5_2 * (int64_t)f8_19; - int64_t f5f9_76 = f5_2 * (int64_t)f9_38; - int64_t f6f6_19 = f6 * (int64_t)f6_19; - int64_t f6f7_38 = f6 * (int64_t)f7_38; - int64_t f6f8_38 = f6_2 * (int64_t)f8_19; - int64_t f6f9_38 = f6 * (int64_t)f9_38; - int64_t f7f7_38 = f7 * (int64_t)f7_38; - int64_t f7f8_38 = f7_2 * (int64_t)f8_19; - int64_t f7f9_76 = f7_2 * (int64_t)f9_38; - int64_t f8f8_19 = f8 * (int64_t)f8_19; - int64_t f8f9_38 = f8 * (int64_t)f9_38; - int64_t f9f9_38 = f9 * (int64_t)f9_38; - - int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; - int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; - int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; - int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; - int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; - int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; - int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; - int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; - int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; - int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; - - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - h0 += h0; - h1 += h1; - h2 += h2; - h3 += h3; - h4 += h4; - h5 += h5; - h6 += h6; - h7 += h7; - h8 += h8; - h9 += h9; - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - - carry1 = (h1 + (int64_t)(1L << 24)) >> 25; - h2 += carry1; - h1 -= carry1 * ((uint64_t)1L << 25); - carry5 = (h5 + (int64_t)(1L << 24)) >> 25; - h6 += carry5; - h5 -= carry5 * ((uint64_t)1L << 25); - - carry2 = (h2 + (int64_t)(1L << 25)) >> 26; - h3 += carry2; - h2 -= carry2 * ((uint64_t)1L << 26); - carry6 = (h6 + (int64_t)(1L << 25)) >> 26; - h7 += carry6; - h6 -= carry6 * ((uint64_t)1L << 26); - - carry3 = (h3 + (int64_t)(1L << 24)) >> 25; - h4 += carry3; - h3 -= carry3 * ((uint64_t)1L << 25); - carry7 = (h7 + (int64_t)(1L << 24)) >> 25; - h8 += carry7; - h7 -= carry7 * ((uint64_t)1L << 25); - - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - carry8 = (h8 + (int64_t)(1L << 25)) >> 26; - h9 += carry8; - h8 -= carry8 * ((uint64_t)1L << 26); - - carry9 = (h9 + (int64_t)(1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= carry9 * ((uint64_t)1L << 25); - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - - h[0] = (int32_t)h0; - h[1] = (int32_t)h1; - h[2] = (int32_t)h2; - h[3] = (int32_t)h3; - h[4] = (int32_t)h4; - h[5] = (int32_t)h5; - h[6] = (int32_t)h6; - h[7] = (int32_t)h7; - h[8] = (int32_t)h8; - h[9] = (int32_t)h9; -} \ No newline at end of file diff --git a/trezor-crypto/crypto/sodium/private/fe_25_5/fe.c b/trezor-crypto/crypto/sodium/private/fe_25_5/fe.c deleted file mode 100644 index bdc215c6095..00000000000 --- a/trezor-crypto/crypto/sodium/private/fe_25_5/fe.c +++ /dev/null @@ -1,237 +0,0 @@ -#include - -uint64_t load_3(const unsigned char *in) { - uint64_t result; - - result = (uint64_t)in[0]; - result |= ((uint64_t)in[1]) << 8; - result |= ((uint64_t)in[2]) << 16; - - return result; -} - -uint64_t load_4(const unsigned char *in) { - uint64_t result; - - result = (uint64_t)in[0]; - result |= ((uint64_t)in[1]) << 8; - result |= ((uint64_t)in[2]) << 16; - result |= ((uint64_t)in[3]) << 24; - - return result; -} - -/* - Ignores top bit of h. - */ - -void fe25519_frombytes(fe25519 h, const unsigned char *s) { - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (int64_t)(1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= carry9 * ((uint64_t)1L << 25); - carry1 = (h1 + (int64_t)(1L << 24)) >> 25; - h2 += carry1; - h1 -= carry1 * ((uint64_t)1L << 25); - carry3 = (h3 + (int64_t)(1L << 24)) >> 25; - h4 += carry3; - h3 -= carry3 * ((uint64_t)1L << 25); - carry5 = (h5 + (int64_t)(1L << 24)) >> 25; - h6 += carry5; - h5 -= carry5 * ((uint64_t)1L << 25); - carry7 = (h7 + (int64_t)(1L << 24)) >> 25; - h8 += carry7; - h7 -= carry7 * ((uint64_t)1L << 25); - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t)1L << 26); - carry2 = (h2 + (int64_t)(1L << 25)) >> 26; - h3 += carry2; - h2 -= carry2 * ((uint64_t)1L << 26); - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t)1L << 26); - carry6 = (h6 + (int64_t)(1L << 25)) >> 26; - h7 += carry6; - h6 -= carry6 * ((uint64_t)1L << 26); - carry8 = (h8 + (int64_t)(1L << 25)) >> 26; - h9 += carry8; - h8 -= carry8 * ((uint64_t)1L << 26); - - h[0] = (int32_t)h0; - h[1] = (int32_t)h1; - h[2] = (int32_t)h2; - h[3] = (int32_t)h3; - h[4] = (int32_t)h4; - h[5] = (int32_t)h5; - h[6] = (int32_t)h6; - h[7] = (int32_t)h7; - h[8] = (int32_t)h8; - h[9] = (int32_t)h9; -} - -/* - Preconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - - Write p=2^255-19; q=floor(h/p). - Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). - - Proof: - Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. - Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. - - Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). - Then 0> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - - carry0 = h0 >> 26; - h1 += carry0; - h0 -= carry0 * ((uint32_t)1L << 26); - carry1 = h1 >> 25; - h2 += carry1; - h1 -= carry1 * ((uint32_t)1L << 25); - carry2 = h2 >> 26; - h3 += carry2; - h2 -= carry2 * ((uint32_t)1L << 26); - carry3 = h3 >> 25; - h4 += carry3; - h3 -= carry3 * ((uint32_t)1L << 25); - carry4 = h4 >> 26; - h5 += carry4; - h4 -= carry4 * ((uint32_t)1L << 26); - carry5 = h5 >> 25; - h6 += carry5; - h5 -= carry5 * ((uint32_t)1L << 25); - carry6 = h6 >> 26; - h7 += carry6; - h6 -= carry6 * ((uint32_t)1L << 26); - carry7 = h7 >> 25; - h8 += carry7; - h7 -= carry7 * ((uint32_t)1L << 25); - carry8 = h8 >> 26; - h9 += carry8; - h8 -= carry8 * ((uint32_t)1L << 26); - carry9 = h9 >> 25; - h9 -= carry9 * ((uint32_t)1L << 25); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - - Goal: Output h0+...+2^230 h9. - */ - -void fe25519_tobytes(unsigned char *s, const fe25519 h) { - fe25519 t; - - fe25519_reduce(t, h); - s[0] = t[0] >> 0; - s[1] = t[0] >> 8; - s[2] = t[0] >> 16; - s[3] = (t[0] >> 24) | (t[1] * ((uint32_t)1 << 2)); - s[4] = t[1] >> 6; - s[5] = t[1] >> 14; - s[6] = (t[1] >> 22) | (t[2] * ((uint32_t)1 << 3)); - s[7] = t[2] >> 5; - s[8] = t[2] >> 13; - s[9] = (t[2] >> 21) | (t[3] * ((uint32_t)1 << 5)); - s[10] = t[3] >> 3; - s[11] = t[3] >> 11; - s[12] = (t[3] >> 19) | (t[4] * ((uint32_t)1 << 6)); - s[13] = t[4] >> 2; - s[14] = t[4] >> 10; - s[15] = t[4] >> 18; - s[16] = t[5] >> 0; - s[17] = t[5] >> 8; - s[18] = t[5] >> 16; - s[19] = (t[5] >> 24) | (t[6] * ((uint32_t)1 << 1)); - s[20] = t[6] >> 7; - s[21] = t[6] >> 15; - s[22] = (t[6] >> 23) | (t[7] * ((uint32_t)1 << 3)); - s[23] = t[7] >> 5; - s[24] = t[7] >> 13; - s[25] = (t[7] >> 21) | (t[8] * ((uint32_t)1 << 4)); - s[26] = t[8] >> 4; - s[27] = t[8] >> 12; - s[28] = (t[8] >> 20) | (t[9] * ((uint32_t)1 << 6)); - s[29] = t[9] >> 2; - s[30] = t[9] >> 10; - s[31] = t[9] >> 18; -} \ No newline at end of file diff --git a/trezor-crypto/crypto/test.db b/trezor-crypto/crypto/test.db deleted file mode 100644 index e9c03593f91..00000000000 Binary files a/trezor-crypto/crypto/test.db and /dev/null differ diff --git a/trezor-crypto/crypto/tests/CMakeLists.txt b/trezor-crypto/crypto/tests/CMakeLists.txt deleted file mode 100644 index 0765cae1f44..00000000000 --- a/trezor-crypto/crypto/tests/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# -# Copyright © 2017 Trust Wallet. - -enable_testing() - -find_library(check PATH ${CMAKE_SOURCE_DIR}/build/local/lib/pkgconfig NO_DEFAULT_PATH) - -# Test executable -add_executable(TrezorCryptoTests test_check.c) -target_link_libraries(TrezorCryptoTests TrezorCrypto check) -target_link_directories(TrezorCryptoTests PRIVATE ${PREFIX}/lib) -target_include_directories(TrezorCryptoTests PRIVATE ${CMAKE_SOURCE_DIR}/src ${PREFIX}/include) - -add_test(NAME test_check COMMAND TrezorCryptoTests) diff --git a/trezor-crypto/crypto/tests/aestst.c b/trezor-crypto/crypto/tests/aestst.c deleted file mode 100644 index eedfb6be0a9..00000000000 --- a/trezor-crypto/crypto/tests/aestst.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - --------------------------------------------------------------------------- - 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 -#include - -#include -#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; -} diff --git a/trezor-crypto/crypto/tests/aestst.h b/trezor-crypto/crypto/tests/aestst.h deleted file mode 100644 index 3c5461c3c84..00000000000 --- a/trezor-crypto/crypto/tests/aestst.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 diff --git a/trezor-crypto/crypto/tests/test_check.c b/trezor-crypto/crypto/tests/test_check.c deleted file mode 100644 index 138dd253fa0..00000000000 --- a/trezor-crypto/crypto/tests/test_check.c +++ /dev/null @@ -1,9437 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef VALGRIND -#include -#include -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if USE_MONERO // [wallet-core] -#include "../monero/monero.h" -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef VALGRIND -/* - * This is a clever trick to make Valgrind's Memcheck verify code - * is constant-time with respect to secret data. - */ - -/* Call after secret data is written, before first use */ -#define MARK_SECRET_DATA(addr, len) VALGRIND_MAKE_MEM_UNDEFINED(addr, len) -/* Call before secret data is freed or to mark non-secret data (public keys or - * signatures) */ -#define UNMARK_SECRET_DATA(addr, len) VALGRIND_MAKE_MEM_DEFINED(addr, len) -#else -#define MARK_SECRET_DATA(addr, len) -#define UNMARK_SECRET_DATA(addr, len) -#endif - -#define FROMHEX_MAXLEN 512 - -#define VERSION_PUBLIC 0x0488b21e -#define VERSION_PRIVATE 0x0488ade4 - -#define DECRED_VERSION_PUBLIC 0x02fda926 -#define DECRED_VERSION_PRIVATE 0x02fda4e8 - -const uint8_t *fromhex(const char *str) { - static uint8_t buf[FROMHEX_MAXLEN]; - size_t len = strlen(str) / 2; - if (len > FROMHEX_MAXLEN) len = FROMHEX_MAXLEN; - for (size_t i = 0; i < len; i++) { - uint8_t c = 0; - if (str[i * 2] >= '0' && str[i * 2] <= '9') c += (str[i * 2] - '0') << 4; - if ((str[i * 2] & ~0x20) >= 'A' && (str[i * 2] & ~0x20) <= 'F') - c += (10 + (str[i * 2] & ~0x20) - 'A') << 4; - if (str[i * 2 + 1] >= '0' && str[i * 2 + 1] <= '9') - c += (str[i * 2 + 1] - '0'); - if ((str[i * 2 + 1] & ~0x20) >= 'A' && (str[i * 2 + 1] & ~0x20) <= 'F') - c += (10 + (str[i * 2 + 1] & ~0x20) - 'A'); - buf[i] = c; - } - return buf; -} - -void nem_private_key(const char *reversed_hex, ed25519_secret_key private_key) { - const uint8_t *reversed_key = fromhex(reversed_hex); - for (size_t j = 0; j < sizeof(ed25519_secret_key); j++) { - private_key[j] = reversed_key[sizeof(ed25519_secret_key) - j - 1]; - } -} - -START_TEST(test_bignum_read_be) { - bignum256 a; - uint8_t input[32]; - - memcpy( - input, - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - 32); - - bn_read_be(input, &a); - - bignum256 b = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b, - 0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}}; - - for (int i = 0; i < 9; i++) { - ck_assert_uint_eq(a.val[i], b.val[i]); - } -} -END_TEST - -START_TEST(test_bignum_write_be) { - bignum256 a = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b, - 0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}}; - uint8_t tmp[32]; - - bn_write_be(&a, tmp); - - ck_assert_mem_eq( - tmp, - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - 32); -} -END_TEST - -START_TEST(test_bignum_is_equal) { - bignum256 a = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b, - 0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}}; - bignum256 b = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b, - 0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}}; - bignum256 c = {{ - 0, - }}; - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - ck_assert_int_eq(bn_is_equal(&c, &c), 1); - ck_assert_int_eq(bn_is_equal(&a, &c), 0); -} -END_TEST - -START_TEST(test_bignum_zero) { - bignum256 a; - bignum256 b; - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - bn_zero(&b); - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_is_zero) { - bignum256 a; - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - ck_assert_int_eq(bn_is_zero(&a), 1); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000001"), - &a); - ck_assert_int_eq(bn_is_zero(&a), 0); - - bn_read_be( - fromhex( - "1000000000000000000000000000000000000000000000000000000000000000"), - &a); - ck_assert_int_eq(bn_is_zero(&a), 0); - - bn_read_be( - fromhex( - "f000000000000000000000000000000000000000000000000000000000000000"), - &a); - ck_assert_int_eq(bn_is_zero(&a), 0); -} -END_TEST - -START_TEST(test_bignum_one) { - bignum256 a; - bignum256 b; - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000001"), - &a); - bn_one(&b); - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_read_le) { - bignum256 a; - bignum256 b; - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - &a); - bn_read_le( - fromhex( - "d58b6de8051f031eeca2c6d7fbe1b5d37c4314fe1068f96352dd0d8b85ce5ec5"), - &b); - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_write_le) { - bignum256 a; - bignum256 b; - uint8_t tmp[32]; - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - &a); - bn_write_le(&a, tmp); - - bn_read_le(tmp, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - bn_read_be( - fromhex( - "d58b6de8051f031eeca2c6d7fbe1b5d37c4314fe1068f96352dd0d8b85ce5ec5"), - &a); - bn_read_be(tmp, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_read_uint32) { - bignum256 a; - bignum256 b; - - // lowest 30 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000003fffffff"), - &a); - bn_read_uint32(0x3fffffff, &b); - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // bit 31 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000040000000"), - &a); - bn_read_uint32(0x40000000, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_read_uint64) { - bignum256 a; - bignum256 b; - - // lowest 30 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000003fffffff"), - &a); - bn_read_uint64(0x3fffffff, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // bit 31 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000040000000"), - &a); - bn_read_uint64(0x40000000, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // bit 33 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000100000000"), - &a); - bn_read_uint64(0x100000000LL, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // bit 61 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000002000000000000000"), - &a); - bn_read_uint64(0x2000000000000000LL, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // all 64 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000ffffffffffffffff"), - &a); - bn_read_uint64(0xffffffffffffffffLL, &b); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_write_uint32) { - bignum256 a; - - // lowest 29 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000001fffffff"), - &a); - ck_assert_uint_eq(bn_write_uint32(&a), 0x1fffffff); - - // lowest 30 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000003fffffff"), - &a); - ck_assert_uint_eq(bn_write_uint32(&a), 0x3fffffff); - - // bit 31 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000040000000"), - &a); - ck_assert_uint_eq(bn_write_uint32(&a), 0x40000000); -} -END_TEST - -START_TEST(test_bignum_write_uint64) { - bignum256 a; - - // lowest 30 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000003fffffff"), - &a); - ck_assert_uint_eq(bn_write_uint64(&a), 0x3fffffff); - - // bit 31 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000040000000"), - &a); - ck_assert_uint_eq(bn_write_uint64(&a), 0x40000000); - - // bit 33 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000100000000"), - &a); - ck_assert_uint_eq(bn_write_uint64(&a), 0x100000000LL); - - // bit 61 set - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000002000000000000000"), - &a); - ck_assert_uint_eq(bn_write_uint64(&a), 0x2000000000000000LL); - - // all 64 bits set - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000ffffffffffffffff"), - &a); - ck_assert_uint_eq(bn_write_uint64(&a), 0xffffffffffffffffLL); -} -END_TEST - -START_TEST(test_bignum_copy) { - bignum256 a; - bignum256 b; - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - &a); - bn_copy(&a, &b); - - ck_assert_int_eq(bn_is_equal(&a, &b), 1); -} -END_TEST - -START_TEST(test_bignum_is_even) { - bignum256 a; - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - &a); - ck_assert_int_eq(bn_is_even(&a), 0); - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd2"), - &a); - ck_assert_int_eq(bn_is_even(&a), 1); - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd0"), - &a); - ck_assert_int_eq(bn_is_even(&a), 1); -} -END_TEST - -START_TEST(test_bignum_is_odd) { - bignum256 a; - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), - &a); - ck_assert_int_eq(bn_is_odd(&a), 1); - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd2"), - &a); - ck_assert_int_eq(bn_is_odd(&a), 0); - - bn_read_be( - fromhex( - "c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd0"), - &a); - ck_assert_int_eq(bn_is_odd(&a), 0); -} -END_TEST - -START_TEST(test_bignum_is_less) { - bignum256 a; - bignum256 b; - - bn_read_uint32(0x1234, &a); - bn_read_uint32(0x8765, &b); - - ck_assert_int_eq(bn_is_less(&a, &b), 1); - ck_assert_int_eq(bn_is_less(&b, &a), 0); - - bn_zero(&a); - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &b); - - ck_assert_int_eq(bn_is_less(&a, &b), 1); - ck_assert_int_eq(bn_is_less(&b, &a), 0); -} -END_TEST - -START_TEST(test_bignum_bitcount) { - bignum256 a, b; - - bn_zero(&a); - ck_assert_int_eq(bn_bitcount(&a), 0); - - bn_one(&a); - ck_assert_int_eq(bn_bitcount(&a), 1); - - // test for 10000 and 11111 when i=5 - for (int i = 2; i <= 256; i++) { - bn_one(&a); - bn_one(&b); - for (int j = 2; j <= i; j++) { - bn_lshift(&a); - bn_lshift(&b); - bn_addi(&b, 1); - } - ck_assert_int_eq(bn_bitcount(&a), i); - ck_assert_int_eq(bn_bitcount(&b), i); - } - - bn_read_uint32(0x3fffffff, &a); - ck_assert_int_eq(bn_bitcount(&a), 30); - - bn_read_uint32(0xffffffff, &a); - ck_assert_int_eq(bn_bitcount(&a), 32); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - ck_assert_int_eq(bn_bitcount(&a), 256); -} -END_TEST - -START_TEST(test_bignum_digitcount) { - bignum256 a; - - bn_zero(&a); - ck_assert_int_eq(bn_digitcount(&a), 1); - - // test for (10^i) and (10^i) - 1 - uint64_t m = 1; - for (int i = 0; i <= 19; i++, m *= 10) { - bn_read_uint64(m, &a); - ck_assert_int_eq(bn_digitcount(&a), i + 1); - - uint64_t n = m - 1; - bn_read_uint64(n, &a); - ck_assert_int_eq(bn_digitcount(&a), n == 0 ? 1 : i); - } - - bn_read_uint32(0x3fffffff, &a); - ck_assert_int_eq(bn_digitcount(&a), 10); - - bn_read_uint32(0xffffffff, &a); - ck_assert_int_eq(bn_digitcount(&a), 10); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - ck_assert_int_eq(bn_digitcount(&a), 78); -} -END_TEST - -START_TEST(test_bignum_format_uint64) { - char buf[128], str[128]; - size_t r; - // test for (10^i) and (10^i) - 1 - uint64_t m = 1; - for (int i = 0; i <= 19; i++, m *= 10) { - sprintf(str, "%" PRIu64, m); - r = bn_format_uint64(m, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, strlen(str)); - ck_assert_str_eq(buf, str); - - uint64_t n = m - 1; - sprintf(str, "%" PRIu64, n); - r = bn_format_uint64(n, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, strlen(str)); - ck_assert_str_eq(buf, str); - } -} -END_TEST - -START_TEST(test_bignum_format) { - bignum256 a; - char buf[128]; - size_t r; - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, NULL, 20, 0, true, buf, sizeof(buf)); - ck_assert_uint_eq(r, 22); - ck_assert_str_eq(buf, "0.00000000000000000000"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, NULL, 0, 5, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, NULL, 0, -5, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, "", "", 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, "SFFX", 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1 + 4); - ck_assert_str_eq(buf, "0SFFX"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, "PRFX", NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 4 + 1); - ck_assert_str_eq(buf, "PRFX0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, "PRFX", "SFFX", 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 4 + 1 + 4); - ck_assert_str_eq(buf, "PRFX0SFFX"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - &a); - r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "0"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000001"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "1"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000001"), - &a); - r = bn_format(&a, NULL, NULL, 6, 6, true, buf, sizeof(buf)); - ck_assert_uint_eq(r, 8); - ck_assert_str_eq(buf, "1.000000"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000002"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "2"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000005"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "5"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000009"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "9"); - - bn_read_be( - fromhex( - "000000000000000000000000000000000000000000000000000000000000000a"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 2); - ck_assert_str_eq(buf, "10"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000014"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 2); - ck_assert_str_eq(buf, "20"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000032"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 2); - ck_assert_str_eq(buf, "50"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000063"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 2); - ck_assert_str_eq(buf, "99"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000000064"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 3); - ck_assert_str_eq(buf, "100"); - - bn_read_be( - fromhex( - "00000000000000000000000000000000000000000000000000000000000000c8"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 3); - ck_assert_str_eq(buf, "200"); - - bn_read_be( - fromhex( - "00000000000000000000000000000000000000000000000000000000000001f4"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 3); - ck_assert_str_eq(buf, "500"); - - bn_read_be( - fromhex( - "00000000000000000000000000000000000000000000000000000000000003e7"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 3); - ck_assert_str_eq(buf, "999"); - - bn_read_be( - fromhex( - "00000000000000000000000000000000000000000000000000000000000003e8"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 4); - ck_assert_str_eq(buf, "1000"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000000000000989680"), - &a); - r = bn_format(&a, NULL, NULL, 7, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 1); - ck_assert_str_eq(buf, "1"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 0, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 78); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "7584007913129639935"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 1, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 79); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "758400791312963993.5"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 2, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 79); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "75840079131296399.35"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 8, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 79); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "75840079131.29639935"); - - bn_read_be( - fromhex( - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3bbb00"), - &a); - r = bn_format(&a, NULL, NULL, 8, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 70); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "75840079131"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 79); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "7.584007913129639935"); - - bn_read_be( - fromhex( - "fffffffffffffffffffffffffffffffffffffffffffffffff7e52fe5afe40000"), - &a); - r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 60); - ck_assert_str_eq( - buf, "115792089237316195423570985008687907853269984665640564039457"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 78, 0, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 80); - ck_assert_str_eq(buf, - "0." - "11579208923731619542357098500868790785326998466564056403945" - "7584007913129639935"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, NULL, NULL, 0, 10, false, buf, sizeof(buf)); - ck_assert_uint_eq(r, 88); - ck_assert_str_eq(buf, - "11579208923731619542357098500868790785326998466564056403945" - "75840079131296399350000000000"); - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - r = bn_format(&a, "quite a long prefix", "even longer suffix", 60, 0, false, - buf, sizeof(buf)); - ck_assert_uint_eq(r, 116); - ck_assert_str_eq(buf, - "quite a long " - "prefix115792089237316195." - "42357098500868790785326998466564056403945758400791312963993" - "5even longer suffix"); - - bn_read_be( - fromhex( - "0000000000000000000000000000000000000000000000000123456789abcdef"), - &a); - memset(buf, 'a', sizeof(buf)); - r = bn_format(&a, "prefix", "suffix", 10, 0, false, buf, 31); - ck_assert_str_eq(buf, "prefix8198552.9216486895suffix"); - ck_assert_uint_eq(r, 30); - - memset(buf, 'a', sizeof(buf)); - r = bn_format(&a, "prefix", "suffix", 10, 0, false, buf, 30); - ck_assert_uint_eq(r, 0); - ck_assert_str_eq(buf, ""); -} -END_TEST - -START_TEST(test_bignum_sqrt) { - uint32_t quadratic_residua[] = { - 1, 2, 4, 8, 9, 11, 15, 16, 17, 18, 19, 21, 22, 25, 29, - 30, 31, 32, 34, 35, 36, 38, 39, 42, 43, 44, 47, 49, 50, 58, - 59, 60, 61, 62, 64, 65, 67, 68, 69, 70, 71, 72, 76, 78, 81, - 83, 84, 86, 88, 91, 94, 98, 99, 100, 103, 107, 111, 115, 116, 118, - 120, 121, 122, 123, 124, 127, 128, 130, 131, 134, 135, 136, 137, 138, 139, - 140, 142, 144, 149, 152, 153, 156, 159, 161, 162, 165, 166, 167, 168, 169, - 171, 172, 176, 181, 182, 185, 187, 188, 189, 191, 193, 196, 197, 198, 200, - 205, 206, 209, 214, 219, 222, 223, 225, 229, 230, 231, 232, 233, 236, 237, - 239, 240, 242, 244, 246, 248, 254, 255, 256, 259, 260, 261, 262, 265, 267, - 268, 269, 270, 272, 274, 275, 276, 277, 278, 279, 280, 281, 284, 285, 287, - 288, 289, 291, 293, 298, 299, 303, 304, 306, 311, 312, 315, 318, 319, 322, - 323, 324, 327, 330, 331, 332, 334, 336, 337, 338, 339, 341, 342, 344, 349, - 351, 352, 353, 357, 359, 361, 362, 364, 365, 370, 371, 373, 374, 375, 376, - 378, 379, 382, 383, 385, 386, 387, 389, 392, 394, 395, 396, 399, 400, 409, - 410, 412, 418, 421, 423, 425, 428, 429, 431, 435, 438, 439, 441, 443, 444, - 445, 446, 450, 453, 458, 460, 461, 462, 463, 464, 465, 466, 467, 471, 472, - 473, 474, 475, 478, 479, 480, 481, 484, 485, 487, 488, 489, 492, 493, 496, - 503, 505, 508, 510, 511, 512, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 527, 529, 530, 531, 533, 534, 536, 537, 538, 539, 540, 541, 544, 545, 547, - 548, 549, 550, 551, 552, 553, 554, 556, 557, 558, 560, 562, 563, 565, 568, - 570, 571, 574, 576, 578, 582, 585, 586, 587, 589, 595, 596, 597, 598, 599, - 603, 606, 607, 608, 609, 612, 613, 619, 621, 622, 623, 624, 625, 630, 633, - 636, 638, 639, 644, 645, 646, 648, 649, 651, 653, 654, 660, 662, 663, 664, - 665, 668, 671, 672, 673, 674, 676, 678, 679, 681, 682, 684, 688, 689, 698, - 702, 704, 705, 706, 707, 714, 715, 718, 722, 723, 724, 725, 728, 729, 730, - 731, 733, 735, 737, 740, 741, 742, 746, 747, 748, 750, 751, 752, 753, 755, - 756, 758, 759, 761, 763, 764, 766, 769, 770, 771, 772, 774, 775, 778, 781, - 784, 785, 788, 789, 790, 791, 792, 797, 798, 799, 800, 813, 815, 817, 818, - 819, 820, 823, 824, 833, 836, 841, 842, 846, 849, 850, 851, 856, 857, 858, - 862, 865, 870, 875, 876, 878, 882, 885, 886, 887, 888, 890, 891, 892, 893, - 895, 899, 900, 903, 906, 907, 911, 913, 915, 916, 919, 920, 921, 922, 924, - 926, 927, 928, 930, 931, 932, 934, 937, 939, 942, 943, 944, 946, 948, 949, - 950, 951, 953, 956, 958, 960, 961, 962, 963, 968, 970, 971, 974, 975, 976, - 977, 978, 984, 986, 987, 992, 995, 999}; - - bignum256 a, b; - - bn_zero(&a); - b = a; - bn_sqrt(&b, &secp256k1.prime); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - bn_one(&a); - b = a; - bn_sqrt(&b, &secp256k1.prime); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - - // test some quadratic residua - for (size_t i = 0; i < sizeof(quadratic_residua) / sizeof(*quadratic_residua); - i++) { - bn_read_uint32(quadratic_residua[i], &a); - b = a; - bn_sqrt(&b, &secp256k1.prime); - bn_multiply(&b, &b, &secp256k1.prime); - bn_mod(&b, &secp256k1.prime); - ck_assert_int_eq(bn_is_equal(&a, &b), 1); - } -} -END_TEST - -// https://tools.ietf.org/html/rfc4648#section-10 -START_TEST(test_base32_rfc4648) { - static const struct { - const char *decoded; - const char *encoded; - const char *encoded_lowercase; - } tests[] = { - {"", "", ""}, - {"f", "MY", "my"}, - {"fo", "MZXQ", "mzxq"}, - {"foo", "MZXW6", "mzxw6"}, - {"foob", "MZXW6YQ", "mzxw6yq"}, - {"fooba", "MZXW6YTB", "mzxw6ytb"}, - {"foobar", "MZXW6YTBOI", "mzxw6ytboi"}, - }; - - char buffer[64]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - const char *in = tests[i].decoded; - const char *out = tests[i].encoded; - const char *out_lowercase = tests[i].encoded_lowercase; - - size_t inlen = strlen(in); - size_t outlen = strlen(out); - - ck_assert_uint_eq(outlen, base32_encoded_length(inlen)); - ck_assert_uint_eq(inlen, base32_decoded_length(outlen)); - - ck_assert(base32_encode((uint8_t *)in, inlen, buffer, sizeof(buffer), - BASE32_ALPHABET_RFC4648) != NULL); - ck_assert_str_eq(buffer, out); - - char *ret = (char *)base32_decode(out, outlen, (uint8_t *)buffer, - sizeof(buffer), BASE32_ALPHABET_RFC4648); - ck_assert(ret != NULL); - *ret = '\0'; - ck_assert_str_eq(buffer, in); - - ret = (char *)base32_decode(out_lowercase, outlen, (uint8_t *)buffer, - sizeof(buffer), BASE32_ALPHABET_RFC4648); - ck_assert(ret != NULL); - *ret = '\0'; - ck_assert_str_eq(buffer, in); - } -} -END_TEST - -// from -// https://github.com/bitcoin/bitcoin/blob/master/src/test/data/base58_keys_valid.json -START_TEST(test_base58) { - static const char *base58_vector[] = { - "0065a16059864a2fdbc7c99a4723a8395bc6f188eb", - "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", - "0574f209f6ea907e2ea48f74fae05782ae8a665257", - "3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", - "6f53c0307d6851aa0ce7825ba883c6bd9ad242b486", - "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", - "c46349a418fc4578d10a372b54b45c280cc8c4382f", - "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", - "80eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", - "5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", - "8055c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c401", - "Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", - "ef36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", - "9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", - "efb9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f301", - "cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", - "006d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4", - "1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", - "05fcc5460dd6e2487c7d75b1963625da0e8f4c5975", - "3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", - "6ff1d470f9b02370fdec2e6b708b08ac431bf7a5f7", - "n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", - "c4c579342c2c4c9220205e2cdc285617040c924a0a", - "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", - "80a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", - "5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", - "807d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb401", - "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", - "efd6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", - "93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", - "efa81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d901", - "cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", - "007987ccaa53d02c8873487ef919677cd3db7a6912", - "1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", - "0563bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb", - "3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", - "6fef66444b5b17f14e8fae6e7e19b045a78c54fd79", - "n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", - "c4c3e55fceceaa4391ed2a9677f4a4d34eacd021a0", - "2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", - "80e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", - "5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", - "808248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c01", - "L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", - "ef44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", - "927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", - "efd1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c6901", - "cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", - "00adc1cc2081a27206fae25792f28bbc55b831549d", - "1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", - "05188f91a931947eddd7432d6e614387e32b244709", - "33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", - "6f1694f5bc1a7295b600f40018a618a6ea48eeb498", - "mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", - "c43b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3", - "2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", - "80091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", - "5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", - "80ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af01", - "L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", - "efb4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", - "92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", - "efe7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef01", - "cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", - "00c4c1b72491ede1eedaca00618407ee0b772cad0d", - "1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", - "05f6fe69bcb548a829cce4c57bf6fff8af3a5981f9", - "3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", - "6f261f83568a098a8638844bd7aeca039d5f2352c0", - "mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", - "c4e930e1834a4d234702773951d627cce82fbb5d2e", - "2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", - "80d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", - "5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", - "80b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b301", - "L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", - "ef037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", - "91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", - "ef6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de01", - "cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", - "005eadaf9bb7121f0f192561a5a62f5e5f54210292", - "19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", - "053f210e7277c899c3a155cc1c90f4106cbddeec6e", - "37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", - "6fc8a3c2a09a298592c3e180f02487cd91ba3400b5", - "myoqcgYiehufrsnnkqdqbp69dddVDMopJu", - "c499b31df7c9068d1481b596578ddbb4d3bd90baeb", - "2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", - "80c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", - "5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", - "8007f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd01", - "KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", - "efea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", - "93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", - "ef0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c01", - "cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", - "001ed467017f043e91ed4c44b4e8dd674db211c4e6", - "13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", - "055ece0cadddc415b1980f001785947120acdb36fc", - "3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", - 0, - 0, - }; - const char **raw = base58_vector; - const char **str = base58_vector + 1; - uint8_t rawn[34]; - char strn[53]; - int r; - while (*raw && *str) { - int len = strlen(*raw) / 2; - - memcpy(rawn, fromhex(*raw), len); - r = base58_encode_check(rawn, len, HASHER_SHA2D, strn, sizeof(strn)); - ck_assert_int_eq((size_t)r, strlen(*str) + 1); - ck_assert_str_eq(strn, *str); - - r = base58_decode_check(strn, HASHER_SHA2D, rawn, len); - ck_assert_int_eq(r, len); - ck_assert_mem_eq(rawn, fromhex(*raw), len); - - raw += 2; - str += 2; - } -} -END_TEST - -#if USE_GRAPHENE - -// Graphene Base85CheckEncoding -START_TEST(test_base58gph) { - static const char *base58_vector[] = { - "02e649f63f8e8121345fd7f47d0d185a3ccaa843115cd2e9392dcd9b82263bc680", - "6dumtt9swxCqwdPZBGXh9YmHoEjFFnNfwHaTqRbQTghGAY2gRz", - "021c7359cd885c0e319924d97e3980206ad64387aff54908241125b3a88b55ca16", - "5725vivYpuFWbeyTifZ5KevnHyqXCi5hwHbNU9cYz1FHbFXCxX", - "02f561e0b57a552df3fa1df2d87a906b7a9fc33a83d5d15fa68a644ecb0806b49a", - "6kZKHSuxqAwdCYsMvwTcipoTsNE2jmEUNBQufGYywpniBKXWZK", - "03e7595c3e6b58f907bee951dc29796f3757307e700ecf3d09307a0cc4a564eba3", - "8b82mpnH8YX1E9RHnU2a2YgLTZ8ooevEGP9N15c1yFqhoBvJur", - 0, - 0, - }; - const char **raw = base58_vector; - const char **str = base58_vector + 1; - uint8_t rawn[34]; - char strn[53]; - int r; - while (*raw && *str) { - int len = strlen(*raw) / 2; - - memcpy(rawn, fromhex(*raw), len); - r = base58gph_encode_check(rawn, len, strn, sizeof(strn)); - ck_assert_int_eq((size_t)r, strlen(*str) + 1); - ck_assert_str_eq(strn, *str); - - r = base58gph_decode_check(strn, rawn, len); - ck_assert_int_eq(r, len); - ck_assert_mem_eq(rawn, fromhex(*raw), len); - - raw += 2; - str += 2; - } -} -END_TEST - -#endif - -START_TEST(test_bignum_divmod) { - uint32_t r; - int i; - - bignum256 a; - uint32_t ar[] = {15, 14, 55, 29, 44, 24, 53, 49, 18, 55, 2, 28, 5, 4, 12, - 43, 18, 37, 28, 14, 30, 46, 12, 11, 17, 10, 10, 13, 24, 45, - 4, 33, 44, 42, 2, 46, 34, 43, 45, 28, 21, 18, 13, 17}; - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &a); - - i = 0; - while (!bn_is_zero(&a) && i < 44) { - bn_divmod58(&a, &r); - ck_assert_uint_eq(r, ar[i]); - i++; - } - ck_assert_int_eq(i, 44); - - bignum256 b; - uint32_t br[] = {935, 639, 129, 913, 7, 584, 457, 39, 564, - 640, 665, 984, 269, 853, 907, 687, 8, 985, - 570, 423, 195, 316, 237, 89, 792, 115}; - - bn_read_be( - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - &b); - i = 0; - while (!bn_is_zero(&b) && i < 26) { - bn_divmod1000(&b, &r); - ck_assert_uint_eq(r, br[i]); - i++; - } - ck_assert_int_eq(i, 26); -} -END_TEST - -// test vector 1 from -// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-1 -START_TEST(test_bip32_vector_1) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - SECP256K1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqji" - "ChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2" - "gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 0); - ck_assert_uint_eq(fingerprint, 0x3442193e); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4" - "cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP" - "6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1); - ck_assert_uint_eq(fingerprint, 0x5c1bd648); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSx" - "qu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFH" - "KkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 2); - ck_assert_uint_eq(fingerprint, 0xbef5a2f9); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptW" - "mT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgq" - "FJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'/2] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 2); - ck_assert_uint_eq(fingerprint, 0xee7ab90c); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Ty" - "h8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJ" - "AyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'/2/1000000000] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1000000000); - ck_assert_uint_eq(fingerprint, 0xd880d7d8); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8" - "kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNT" - "EcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); -} -END_TEST - -// test vector 2 from -// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-2 -START_TEST(test_bip32_vector_2) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, SECP256K1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGds" - "o3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSC" - "Gu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0xbd16bee5); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT" - "3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGm" - "XUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483647); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x5a61ff8e); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYE" - "eEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ" - "85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 1); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0xd8ab4937); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd" - "25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5Ew" - "VvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1/2147483646'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483646); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x78412e3a); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz" - "7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJ" - "bZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1/2147483646'/2] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 2); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x31a507b8); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c"), - 33); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw" - "7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLF" - "bdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, SECP256K1_NAME, &node); - - // test public derivation - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_public_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0xbd16bee5); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), - 33); -} -END_TEST - -// test vector 3 from -// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-3 -START_TEST(test_bip32_vector_3) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed( - fromhex( - "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45" - "d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"), - 64, SECP256K1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7" - "KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhR" - "oP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu" - "2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrAD" - "WgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); -} -END_TEST - -// test vector 4 from -// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vector-4 -START_TEST(test_bip32_vector_4) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed( - fromhex( - "3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678"), - 32, SECP256K1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_int_eq(fingerprint, 0x00000000); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7f" - "RDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuy" - "u5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaAL" - "mPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xf" - "FEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 1); - ck_assert_int_eq(r, 1); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - hdnode_serialize_private(&node, fingerprint, VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJ" - "eHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1"); - r = hdnode_deserialize_private(str, VERSION_PRIVATE, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, VERSION_PUBLIC, str, sizeof(str)); - ck_assert_str_eq(str, - "xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d" - "88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt"); - r = hdnode_deserialize_public(str, VERSION_PUBLIC, SECP256K1_NAME, &node2, - NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); -} -END_TEST - -START_TEST(test_bip32_compare) { - HDNode node1, node2, node3; - int i, r; - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node1); - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node2); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - for (i = 0; i < 100; i++) { - memcpy(&node3, &node1, sizeof(HDNode)); - ck_assert_int_eq(hdnode_fill_public_key(&node3), 0); - r = hdnode_private_ckd(&node1, i); - ck_assert_int_eq(r, 1); - r = hdnode_public_ckd(&node2, i); - ck_assert_int_eq(r, 1); - r = hdnode_public_ckd(&node3, i); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(node1.depth, node2.depth); - ck_assert_uint_eq(node1.depth, node3.depth); - ck_assert_uint_eq(node1.child_num, node2.child_num); - ck_assert_uint_eq(node1.child_num, node3.child_num); - ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32); - ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32); - ck_assert_mem_eq( - node2.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_mem_eq( - node3.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node1), 0); - ck_assert_mem_eq(node1.public_key, node2.public_key, 33); - ck_assert_mem_eq(node1.public_key, node3.public_key, 33); - } -} -END_TEST - -START_TEST(test_bip32_optimized) { - HDNode root; - hdnode_from_seed((uint8_t *)"NothingToSeeHere", 16, SECP256K1_NAME, &root); - ck_assert_int_eq(hdnode_fill_public_key(&root), 0); - - curve_point pub; - ecdsa_read_pubkey(&secp256k1, root.public_key, &pub); - - HDNode node; - char addr1[MAX_ADDR_SIZE], addr2[MAX_ADDR_SIZE]; - - for (int i = 0; i < 40; i++) { - // unoptimized - memcpy(&node, &root, sizeof(HDNode)); - hdnode_public_ckd(&node, i); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ecdsa_get_address(node.public_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - addr1, sizeof(addr1)); - // optimized - hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0, - HASHER_SHA2_RIPEMD, HASHER_SHA2D, addr2, - sizeof(addr2), 0); - // check - ck_assert_str_eq(addr1, addr2); - } -} -END_TEST - -#if USE_BIP32_CACHE - -START_TEST(test_bip32_cache_1) { - HDNode node1, node2; - int i, r; - - // test 1 .. 8 - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node1); - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node2); - - uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, - 0x80000005, 0x80000006, 0x80000007, 0x80000008}; - - for (i = 0; i < 8; i++) { - r = hdnode_private_ckd(&node1, ii[i]); - ck_assert_int_eq(r, 1); - } - r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); - - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node1); - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node2); - - // test 1 .. 7, 20 - ii[7] = 20; - for (i = 0; i < 8; i++) { - r = hdnode_private_ckd(&node1, ii[i]); - ck_assert_int_eq(r, 1); - } - r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); - - // test different root node - hdnode_from_seed( - fromhex( - "000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node1); - hdnode_from_seed( - fromhex( - "000000002ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &node2); - - for (i = 0; i < 8; i++) { - r = hdnode_private_ckd(&node1, ii[i]); - ck_assert_int_eq(r, 1); - } - r = hdnode_private_ckd_cached(&node2, ii, 8, NULL); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq(&node1, &node2, sizeof(HDNode)); -} -END_TEST - -START_TEST(test_bip32_cache_2) { - HDNode nodea[9], nodeb[9]; - int i, j, r; - - for (j = 0; j < 9; j++) { - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d627" - "88f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &(nodea[j])); - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d627" - "88f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, SECP256K1_NAME, &(nodeb[j])); - } - - uint32_t ii[] = {0x80000001, 0x80000002, 0x80000003, 0x80000004, - 0x80000005, 0x80000006, 0x80000007, 0x80000008}; - for (j = 0; j < 9; j++) { - // non cached - for (i = 1; i <= j; i++) { - r = hdnode_private_ckd(&(nodea[j]), ii[i - 1]); - ck_assert_int_eq(r, 1); - } - // cached - r = hdnode_private_ckd_cached(&(nodeb[j]), ii, j, NULL); - ck_assert_int_eq(r, 1); - } - - ck_assert_mem_eq(&(nodea[0]), &(nodeb[0]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[1]), &(nodeb[1]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[2]), &(nodeb[2]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[3]), &(nodeb[3]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[4]), &(nodeb[4]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[5]), &(nodeb[5]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[6]), &(nodeb[6]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[7]), &(nodeb[7]), sizeof(HDNode)); - ck_assert_mem_eq(&(nodea[8]), &(nodeb[8]), sizeof(HDNode)); -} -END_TEST -#endif - -START_TEST(test_bip32_nist_seed) { - HDNode node; - - // init m - hdnode_from_seed( - fromhex( - "a7305bc8df8d0951f0cb224c0e95d7707cbdf2c6ce7e8d481fec69c7ff5e9446"), - 32, NIST256P1_NAME, &node); - - // [Chain m] - ck_assert_mem_eq( - node.private_key, - fromhex( - "3b8c18469a4634517d6d0b65448f8e6c62091b45540a1743c5846be55d47d88f"), - 32); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "7762f9729fed06121fd13f326884c82f59aa95c57ac492ce8c9654e60efd130c"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0383619fadcde31063d8c5cb00dbfe1713f3e6fa169d8541a798752a1c1ca0cb20"), - 33); - - // init m - hdnode_from_seed( - fromhex( - "aa305bc8df8d0951f0cb29ad4568d7707cbdf2c6ce7e8d481fec69c7ff5e9446"), - 32, NIST256P1_NAME, &node); - - // [Chain m] - ck_assert_mem_eq( - node.chain_code, - fromhex( - "a81d21f36f987fa0be3b065301bfb6aa9deefbf3dfef6744c37b9a4abc3c68f1"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0e49dc46ce1d8c29d9b80a05e40f5d0cd68cbf02ae98572186f5343be18084bf"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03aaa4c89acd9a98935330773d3dae55122f3591bac4a40942681768de8df6ba63"), - 33); -} -END_TEST - -START_TEST(test_bip32_nist_vector_1) { - HDNode node; - uint32_t fingerprint; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - NIST256P1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "beeb672fe4621673f722f38529c07392fecaa61015c80c34f29ce8b41b3cb6ea"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "612091aaa12e22dd2abef664f8a01a82cae99ad7441b7ef8110424915c268bc2"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0266874dc6ade47b3ecd096745ca09bcd29638dd52c2c12117b11ed3e458cfa9e8"), - 33); - - // [Chain m/0'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 0); - ck_assert_uint_eq(fingerprint, 0xbe6105b5); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "3460cea53e6a6bb5fb391eeef3237ffd8724bf0a40e94943c98b83825342ee11"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "6939694369114c67917a182c59ddb8cafc3004e63ca5d3b84403ba8613debc0c"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0384610f5ecffe8fda089363a41f56a5c7ffc1d81b59a612d0d649b2d22355590c"), - 33); - - // [Chain m/0'/1] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1); - ck_assert_uint_eq(fingerprint, 0x9b02312f); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "4187afff1aafa8445010097fb99d23aee9f599450c7bd140b6826ac22ba21d0c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "284e9d38d07d21e4e281b645089a94f4cf5a5a81369acf151a1c3a57f18b2129"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03526c63f8d0b4bbbf9c80df553fe66742df4676b241dabefdef67733e070f6844"), - 33); - - // [Chain m/0'/1/2'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 2); - ck_assert_uint_eq(fingerprint, 0xb98005c1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "98c7514f562e64e74170cc3cf304ee1ce54d6b6da4f880f313e8204c2a185318"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "694596e8a54f252c960eb771a3c41e7e32496d03b954aeb90f61635b8e092aa7"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0359cf160040778a4b14c5f4d7b76e327ccc8c4a6086dd9451b7482b5a4972dda0"), - 33); - - // [Chain m/0'/1/2'/2] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 2); - ck_assert_uint_eq(fingerprint, 0x0e9f3274); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "ba96f776a5c3907d7fd48bde5620ee374d4acfd540378476019eab70790c63a0"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "5996c37fd3dd2679039b23ed6f70b506c6b56b3cb5e424681fb0fa64caf82aaa"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "029f871f4cb9e1c97f9f4de9ccd0d4a2f2a171110c61178f84430062230833ff20"), - 33); - - // [Chain m/0'/1/2'/2/1000000000] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1000000000); - ck_assert_uint_eq(fingerprint, 0x8b2b5c4b); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "b9b7b82d326bb9cb5b5b121066feea4eb93d5241103c9e7a18aad40f1dde8059"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "21c4f269ef0a5fd1badf47eeacebeeaa3de22eb8e5b0adcd0f27dd99d34d0119"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02216cd26d31147f72427a453c443ed2cde8a1e53c9cc44e5ddf739725413fe3f4"), - 33); -} -END_TEST - -START_TEST(test_bip32_nist_vector_2) { - HDNode node; - uint32_t fingerprint; - int r; - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, NIST256P1_NAME, &node); - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "96cd4465a9644e31528eda3592aa35eb39a9527769ce1855beafc1b81055e75d"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa"), - 33); - - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x607f628f); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "d7d065f63a62624888500cdb4f88b6d59c2927fee9e6d0cdff9cad555884df6e"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), - 33); - - // [Chain m/0/2147483647'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483647); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x946d2a54); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f235b2bc5c04606ca9c30027a84f353acf4e4683edbd11f635d0dcc1cd106ea6"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "96d2ec9316746a75e7793684ed01e3d51194d81a42a3276858a5b7376d4b94b9"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02f89c5deb1cae4fedc9905f98ae6cbf6cbab120d8cb85d5bd9a91a72f4c068c76"), - 33); - - // [Chain m/0/2147483647'/1] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 1); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x218182d8); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "7c0b833106235e452eba79d2bdd58d4086e663bc8cc55e9773d2b5eeda313f3b"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "974f9096ea6873a915910e82b29d7c338542ccde39d2064d1cc228f371542bbc"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03abe0ad54c97c1d654c1852dfdc32d6d3e487e75fa16f0fd6304b9ceae4220c64"), - 33); - - // [Chain m/0/2147483647'/1/2147483646'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483646); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x931223e4); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "5794e616eadaf33413aa309318a26ee0fd5163b70466de7a4512fd4b1a5c9e6a"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "da29649bbfaff095cd43819eda9a7be74236539a29094cd8336b07ed8d4eff63"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03cb8cb067d248691808cd6b5a5a06b48e34ebac4d965cba33e6dc46fe13d9b933"), - 33); - - // [Chain m/0/2147483647'/1/2147483646'/2] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 2); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x956c4629); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "3bfb29ee8ac4484f09db09c2079b520ea5616df7820f071a20320366fbe226a7"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "bb0a77ba01cc31d77205d51d08bd313b979a71ef4de9b062f8958297e746bd67"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "020ee02e18967237cf62672983b253ee62fa4dd431f8243bfeccdf39dbe181387f"), - 33); - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, NIST256P1_NAME, &node); - - // test public derivation - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_public_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x607f628f); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_mem_eq( - node.public_key, - fromhex( - "039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), - 33); -} -END_TEST - -START_TEST(test_bip32_nist_compare) { - HDNode node1, node2, node3; - int i, r; - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, NIST256P1_NAME, &node1); - hdnode_from_seed( - fromhex( - "301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788" - "f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), - 64, NIST256P1_NAME, &node2); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - for (i = 0; i < 100; i++) { - memcpy(&node3, &node1, sizeof(HDNode)); - ck_assert_int_eq(hdnode_fill_public_key(&node3), 0); - r = hdnode_private_ckd(&node1, i); - ck_assert_int_eq(r, 1); - r = hdnode_public_ckd(&node2, i); - ck_assert_int_eq(r, 1); - r = hdnode_public_ckd(&node3, i); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(node1.depth, node2.depth); - ck_assert_uint_eq(node1.depth, node3.depth); - ck_assert_uint_eq(node1.child_num, node2.child_num); - ck_assert_uint_eq(node1.child_num, node3.child_num); - ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32); - ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32); - ck_assert_mem_eq( - node2.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_mem_eq( - node3.private_key, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node1), 0); - ck_assert_mem_eq(node1.public_key, node2.public_key, 33); - ck_assert_mem_eq(node1.public_key, node3.public_key, 33); - } -} -END_TEST - -START_TEST(test_bip32_nist_repeat) { - HDNode node, node2; - uint32_t fingerprint; - int r; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - NIST256P1_NAME, &node); - - // [Chain m/28578'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 28578); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0xbe6105b5); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "e94c8ebe30c2250a14713212f6449b20f3329105ea15b652ca5bdfc68f6c65c2"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "06f0db126f023755d0b8d86d4591718a5210dd8d024e3e14b6159d63f53aa669"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02519b5554a4872e8c9c1c847115363051ec43e93400e030ba3c36b52a3e70a5b7"), - 33); - - memcpy(&node2, &node, sizeof(HDNode)); - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node2, 33941); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x3e2b7bc6); - ck_assert_mem_eq( - node2.chain_code, - fromhex( - "9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), - 32); - ck_assert_mem_eq( - node2.private_key, - fromhex( - "092154eed4af83e078ff9b84322015aefe5769e31270f62c3f66c33888335f3a"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq( - node2.public_key, - fromhex( - "0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), - 33); - - memcpy(&node2, &node, sizeof(HDNode)); - memzero(&node2.private_key, 32); - r = hdnode_public_ckd(&node2, 33941); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x3e2b7bc6); - ck_assert_mem_eq( - node2.chain_code, - fromhex( - "9e87fe95031f14736774cd82f25fd885065cb7c358c1edf813c72af535e83071"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq( - node2.public_key, - fromhex( - "0235bfee614c0d5b2cae260000bb1d0d84b270099ad790022c1ae0b2e782efe120"), - 33); -} -END_TEST - -// test vector 1 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors -START_TEST(test_bip32_ed25519_vector_1) { - HDNode node; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - ED25519_NAME, &node); - - // [Chain m] - ck_assert_mem_eq( - node.chain_code, - fromhex( - "90046a93de5380a72b5e45010748567d5ea02bbf6522f979e05c0d8d8ca9fffb"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "2b4be7f19ee27bbf30c667b642d5f4aa69fd169872f8fc3059c08ebae2eb19e7"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "01a4b2856bfec510abab89753fac1ac0e1112364e7d250545963f135f2a33188ed"), - 33); - - // [Chain m/0'] - hdnode_private_ckd_prime(&node, 0); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "8b59aa11380b624e81507a27fedda59fea6d0b779a778918a2fd3590e16e9c69"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "68e0fe46dfb67e368c75379acec591dad19df3cde26e63b93a8e704f1dade7a3"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "018c8a13df77a28f3445213a0f432fde644acaa215fc72dcdf300d5efaa85d350c"), - 33); - - // [Chain m/0'/1'] - hdnode_private_ckd_prime(&node, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "a320425f77d1b5c2505a6b1b27382b37368ee640e3557c315416801243552f14"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "b1d0bad404bf35da785a64ca1ac54b2617211d2777696fbffaf208f746ae84f2"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "011932a5270f335bed617d5b935c80aedb1a35bd9fc1e31acafd5372c30f5c1187"), - 33); - - // [Chain m/0'/1'/2'] - hdnode_private_ckd_prime(&node, 2); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "2e69929e00b5ab250f49c3fb1c12f252de4fed2c1db88387094a0f8c4c9ccd6c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "92a5b23c0b8a99e37d07df3fb9966917f5d06e02ddbd909c7e184371463e9fc9"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "01ae98736566d30ed0e9d2f4486a64bc95740d89c7db33f52121f8ea8f76ff0fc1"), - 33); - - // [Chain m/0'/1'/2'/2'] - hdnode_private_ckd_prime(&node, 2); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "8f6d87f93d750e0efccda017d662a1b31a266e4a6f5993b15f5c1f07f74dd5cc"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "30d1dc7e5fc04c31219ab25a27ae00b50f6fd66622f6e9c913253d6511d1e662"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "018abae2d66361c879b900d204ad2cc4984fa2aa344dd7ddc46007329ac76c429c"), - 33); - - // [Chain m/0'/1'/2'/2'/1000000000'] - hdnode_private_ckd_prime(&node, 1000000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "68789923a0cac2cd5a29172a475fe9e0fb14cd6adb5ad98a3fa70333e7afa230"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "8f94d394a8e8fd6b1bc2f3f49f5c47e385281d5c17e65324b0f62483e37e8793"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "013c24da049451555d51a7014a37337aa4e12d41e485abccfa46b47dfb2af54b7a"), - 33); -} -END_TEST - -// test vector 2 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors -START_TEST(test_bip32_ed25519_vector_2) { - HDNode node; - int r; - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, ED25519_NAME, &node); - - // [Chain m] - ck_assert_mem_eq( - node.chain_code, - fromhex( - "ef70a74db9c3a5af931b5fe73ed8e1a53464133654fd55e7a66f8570b8e33c3b"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "171cb88b1b3c1db25add599712e36245d75bc65a1a5c9e18d76f9f2b1eab4012"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "018fe9693f8fa62a4305a140b9764c5ee01e455963744fe18204b4fb948249308a"), - 33); - - // [Chain m/0'] - r = hdnode_private_ckd_prime(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "0b78a3226f915c082bf118f83618a618ab6dec793752624cbeb622acb562862d"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "1559eb2bbec5790b0c65d8693e4d0875b1747f4970ae8b650486ed7470845635"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0186fab68dcb57aa196c77c5f264f215a112c22a912c10d123b0d03c3c28ef1037"), - 33); - - // [Chain m/0'/2147483647'] - r = hdnode_private_ckd_prime(&node, 2147483647); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "138f0b2551bcafeca6ff2aa88ba8ed0ed8de070841f0c4ef0165df8181eaad7f"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "ea4f5bfe8694d8bb74b7b59404632fd5968b774ed545e810de9c32a4fb4192f4"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "015ba3b9ac6e90e83effcd25ac4e58a1365a9e35a3d3ae5eb07b9e4d90bcf7506d"), - 33); - - // [Chain m/0'/2147483647'/1'] - r = hdnode_private_ckd_prime(&node, 1); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "73bd9fff1cfbde33a1b846c27085f711c0fe2d66fd32e139d3ebc28e5a4a6b90"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "3757c7577170179c7868353ada796c839135b3d30554bbb74a4b1e4a5a58505c"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "012e66aa57069c86cc18249aecf5cb5a9cebbfd6fadeab056254763874a9352b45"), - 33); - - // [Chain m/0'/2147483647'/1'/2147483646'] - r = hdnode_private_ckd_prime(&node, 2147483646); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "0902fe8a29f9140480a00ef244bd183e8a13288e4412d8389d140aac1794825a"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "5837736c89570de861ebc173b1086da4f505d4adb387c6a1b1342d5e4ac9ec72"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "01e33c0f7d81d843c572275f287498e8d408654fdf0d1e065b84e2e6f157aab09b"), - 33); - - // [Chain m/0'/2147483647'/1'/2147483646'/2'] - r = hdnode_private_ckd_prime(&node, 2); - ck_assert_int_eq(r, 1); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "5d70af781f3a37b829f0d060924d5e960bdc02e85423494afc0b1a41bbe196d4"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "551d333177df541ad876a60ea71f00447931c0a9da16f227c11ea080d7391b8d"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0147150c75db263559a70d5778bf36abbab30fb061ad69f69ece61a72b0cfa4fc0"), - 33); -} -END_TEST - -// test vector 1 from -// https://github.com/decred/dcrd/blob/master/hdkeychain/extendedkey_test.go -START_TEST(test_bip32_decred_vector_1) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - SECP256K1_NAME, &node); - - // secp256k1_decred_info.bip32_name != "Bitcoin seed" so we cannot use it in - // hdnode_from_seed - node.curve = &secp256k1_decred_info; - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3hCznBesA6jBtmoyVFPfyMSZ1qYZ3WdjdebquvkEfmRfxC9VFEFi2YD" - "aJqHnx7uGe75eGSa3Mn3oHK11hBW7KZUrPxwbCPBmuCi1nwm182s"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZ9169KDAEUnyoBhjjmT2VaEodr6pUTDoqCEAeqgbfr2JfkB88BbK77j" - "bTYbcYXb2FVz7DKBdW4P618yd51MwF8DjKVopSbS7Lkgi6bowX5w"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 0); - ck_assert_uint_eq(fingerprint, 0xbc495588); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3kUQDBztdyjKuwnaL3hfKYpT7W6X2huYH5d61YSWFBebSYwEBHAXJkC" - "pQ7rvMAxPzKqxVCGLvBqWvGxXjAyMJsV1XwKkfnQCM9KctC8k8bk"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZCGVaKZBiMo7pMgLaZm1qmchjWenTeVcUdFQkTNsFGFEA6xs4EW8PKi" - "qYqP7HBAitt9Hw16VQkQ1tjsZQSHNWFc6bEK6bLqrbco24FzBTY4"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1); - ck_assert_uint_eq(fingerprint, 0xc67bc2ef); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3nRtCZ5VAoHW4RUwQgRafSNRPUDFrmsgyY71A5eoZceVfuyL9SbZe2r" - "cbwDW2UwpkEniE4urffgbypegscNchPajWzy9QS4cRxF8QYXsZtq"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZEDyZgdnFBMHxqNhfCUwBfAg1UmXHiTmB5jKtzbAZhF8PTzy2PwAicN" - "dkg1CmW6TARxQeUbgC7nAQenJts4YoG3KMiqcjsjgeMvwLc43w6C"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd_prime(&node, 2); - ck_assert_uint_eq(fingerprint, 0xe7072187); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3pYtkZK168vgrU38gXkUSjHQ2LGpEUzQ9fXrR8fGUR59YviSnm6U82X" - "jQYhpJEUPnVcC9bguJBQU5xVM4VFcDHu9BgScGPA6mQMH4bn5Cth"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZGLz7gsJAWzUksvtw3opxx5eeLq5fRaUMDABA3bdUVfnGUk5fiS5Cc3" - "kZGTjWtYr3jrEavQQnAF6jv2WCpZtFX4uFgifXqev6ED1TM9rTCB"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'/2] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 2); - ck_assert_uint_eq(fingerprint, 0xbcbbc1c4); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3r7zqYFjT3NiNzdnwGxGpYh6S1TJCp1zA6mSEGaqLBJFnCB94cRMp7Y" - "YLR49aTZHZ7ya1CXwQJ6rodKeU9NgQTxkPSK7pzgZRgjYkQ7rgJh"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZHv6Cfp2XRSWHQXZBo1dLmVM421Zdkc4MePkyBXCLFttVkCmwZkxth4" - "ZV9PzkFP3DtD5xcVq2CPSYpJMWMaoxu1ixz4GNZFVcE2xnHP6chJ"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0'/1/2'/2/1000000000] - fingerprint = hdnode_fingerprint(&node); - hdnode_private_ckd(&node, 1000000000); - ck_assert_uint_eq(fingerprint, 0xe58b52e4); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3tJXnTDSb3uE6Euo6WvvhFKfBMNfxuJt5smqyPoHEoomoBMQyhYoQSK" - "JAHWtWxmuqdUVb8q9J2NaTkF6rYm6XDrSotkJ55bM21fffa7VV97"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZL6d9amjfRy1zeoZM2zHDU7uoMvwPqtxHRQAiJjeEtQQWjP3retQV1q" - "KJyzUd6ZJNgbJGXjtc5pdoBcTTYTLoxQzvV9JJCzCjB2eCWpRf8T"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); -} -END_TEST - -// test vector 2 from -// https://github.com/decred/dcrd/blob/master/hdkeychain/extendedkey_test.go -START_TEST(test_bip32_decred_vector_2) { - HDNode node, node2, node3; - uint32_t fingerprint; - char str[XPUB_MAXLEN]; - int r; - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, SECP256K1_NAME, &node); - - // secp256k1_decred_info.bip32_name != "Bitcoin seed" so we cannot use it in - // hdnode_from_seed - node.curve = &secp256k1_decred_info; - - // [Chain m] - fingerprint = 0; - ck_assert_uint_eq(fingerprint, 0x00000000); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3hCznBesA6jBtPKJbQTxRZAKG2gyj8tZKEPaCsV4e9YYFBAgRP2eTSP" - "Aeu4r8dTMt9q51j2Vdt5zNqj7jbtovvocrP1qLj6WUTLF9xYQt4y"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZ9169KDAEUnynoD4qvXJwmxZt3FFA5UdWn1twnRReE9AxjCKJLNFY1u" - "BoegbFmwzA4Du7yqnu8tLivhrCCH6P3DgBS1HH5vmf8MpNXvvYT9"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x2524c9d3); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3jMy45BuuDETfxi59P8NTSjHPrNVq4wPRfLgRd57923L2hosj5NUEqi" - "LYQ4i7fJtUpiXZLr2wUeToJY2Tm5sCpAJdajEHDmieVJiPQNXwu9"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZBA4RCkCybJFaNbqPuBiyfXY1rvmG1XTdCy1AY1U96dxkFqWc2i5KRE" - "Mh7NYPpy7ZPMhdpFMAesex3JdFDfX4J5FEW3HjSacqEYPfwb9Cj7"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483647); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x6035c6ad); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3mgHPRgK838mLK6T1p6WeBoJoJtXA1pGTHjqFuyHekcM7UTuER8fGwe" - "RRsoLqSuHa98uskVPnJnfWZEBUC1AVmXnSCPDvUFKydXNnnPHTuQ"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZDUNkZEcCRCZEizDGL9sAQbZRKSnaxQLeqN9zpueeqCyq2VY7NUGMXA" - "SacsK96S8XzNjq3YgFgwLtj8MJBToW6To9U5zxuazEyh89bjR1xA"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 1); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x36fc7080); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3oFqwZZ9bJcUmhAeJyyshvrTWtrAsHfcRYQbEzNiiH5nGvM6wVTDn6w" - "oQEz92b2EHTYZBtLi82jKEnxSouA3cVaW8YWBsw5c3f4mwAhA3d2"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZF3wJh7SfggGg74QZW3EE9ei8uQSJEFgd62uyuK5iMgQzUNjpSnprgT" - "pYz3d6Q3fXXtEEXQqpzWcP4LUVuXFsgA8JKt1Hot5kyUk4pPRhDz"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1/2147483646'] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd_prime(&node, 2147483646); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x45309b4c); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3qF3177i87wMirg6sraDvqty8yZg6THpXFPSXuM5AShBiiUQbq8FhSZ" - "DGkYmBNR3RKfBrxzkKDBpsRFJfTnQfLsvpPPqRnakat6hHQA43X9"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZH38NEg1CW19dGZs8NdaT4hDkz7wXPstio1mGpHSAXHpSGW3UnTrn25" - "ERT1Mp8ae5GMoQHMbgQiPrChMXQMdx3UqS8YqFkT1pqait8fY92u"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // [Chain m/0/2147483647'/1/2147483646'/2] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_private_ckd(&node, 2); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x3491a5e6); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key, - fromhex( - "024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c"), - 33); - hdnode_serialize_private(&node, fingerprint, DECRED_VERSION_PRIVATE, str, - sizeof(str)); - ck_assert_str_eq(str, - "dprv3s15tfqzxhw8Kmo7RBEqMeyvC7uGekLniSmvbs3bckpxQ6ks1KKqfmH" - "144Jgh3PLxkyZRcS367kp7DrtUmnG16NpnsoNhxSXRgKbJJ7MUQR"); - r = hdnode_deserialize_private(str, DECRED_VERSION_PRIVATE, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_int_eq(hdnode_fill_public_key(&node2), 0); - ck_assert_mem_eq(&node, &node2, sizeof(HDNode)); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZJoBFoQJ35zvEBgsfhJBssnAp8TY5gvruzQFLmyxcqRb7enVtGfSkLo" - "2CkAZJMpa6T2fx6fUtvTgXtUvSVgAZ56bEwGxQsToeZfFV8VadE1"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - memcpy(&node3, &node, sizeof(HDNode)); - memzero(&node3.private_key, 32); - ck_assert_mem_eq(&node2, &node3, sizeof(HDNode)); - - // init m - hdnode_deserialize_public( - "dpubZF4LSCdF9YKZfNzTVYhz4RBxsjYXqms8AQnMBHXZ8GUKoRSigG7kQnKiJt5pzk93Q8Fx" - "cdVBEkQZruSXduGtWnkwXzGnjbSovQ97dCxqaXc", - DECRED_VERSION_PUBLIC, SECP256K1_DECRED_NAME, &node, NULL); - - // test public derivation - // [Chain m/0] - fingerprint = hdnode_fingerprint(&node); - r = hdnode_public_ckd(&node, 0); - ck_assert_int_eq(r, 1); - ck_assert_uint_eq(fingerprint, 0x6a19cfb3); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "dcfe00831741a3a4803955147cdfc7053d69b167b1d03b5f9e63934217a005fd"), - 32); - ck_assert_mem_eq( - node.public_key, - fromhex( - "029555ea7bde276cd2c42c4502f40b5d16469fb310ae3aeee2a9000455f41b0866"), - 33); - hdnode_serialize_public(&node, fingerprint, DECRED_VERSION_PUBLIC, str, - sizeof(str)); - ck_assert_str_eq(str, - "dpubZHJs2Z3PtHbbpaXQCi5wBKPhU8tC5ztBKUYBCYNGKk8eZ1EmBs3MhnL" - "JbxHFMAahGnDnZT7qZxC7AXKP8PB6BDNUZgkG77moNMRmXyQ6s6s"); - r = hdnode_deserialize_public(str, DECRED_VERSION_PUBLIC, - SECP256K1_DECRED_NAME, &node2, NULL); - ck_assert_int_eq(r, 0); - ck_assert_mem_eq(&node2, &node, sizeof(HDNode)); -} -END_TEST - -static void test_ecdsa_get_public_key33_helper(int (*ecdsa_get_public_key33_fn)( - const ecdsa_curve *, const uint8_t *, uint8_t *)) { - uint8_t privkey[32] = {0}; - uint8_t pubkey[65] = {0}; - const ecdsa_curve *curve = &secp256k1; - int res = 0; - - memcpy( - privkey, - fromhex( - "c46f5b217f04ff28886a89d3c762ed84e5fa318d1c9a635d541131e69f1f49f5"), - 32); - res = ecdsa_get_public_key33_fn(curve, privkey, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "0232b062e9153f573c220b1be0299d6447e81577274bf11a7c08dff71384c6b6ec"), - 33); - - memcpy( - privkey, - fromhex( - "3b90a4de80fb00d77795762c389d1279d4b4ab5992ae3cde6bc12ca63116f74c"), - 32); - res = ecdsa_get_public_key33_fn(curve, privkey, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "0332b062e9153f573c220b1be0299d6447e81577274bf11a7c08dff71384c6b6ec"), - 33); -} - -START_TEST(test_ecdsa_get_public_key33) { - test_ecdsa_get_public_key33_helper(ecdsa_get_public_key33); -} -END_TEST - -static void test_ecdsa_get_public_key65_helper(int (*ecdsa_get_public_key65_fn)( - const ecdsa_curve *, const uint8_t *, uint8_t *)) { - uint8_t privkey[32] = {0}; - uint8_t pubkey[65] = {0}; - const ecdsa_curve *curve = &secp256k1; - int res = 0; - - memcpy( - privkey, - fromhex( - "c46f5b217f04ff28886a89d3c762ed84e5fa318d1c9a635d541131e69f1f49f5"), - 32); - res = ecdsa_get_public_key65_fn(curve, privkey, pubkey); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "0432b062e9153f573c220b1be0299d6447e81577274bf11a7c08dff71384c6b6ec" - "179ca56b637a57e0fcd28cefa10c9433dc30532682647f4daa053d43d5cc960a"), - 65); -} - -START_TEST(test_ecdsa_get_public_key65) { - test_ecdsa_get_public_key65_helper(ecdsa_get_public_key65); -} -END_TEST - -static void test_ecdsa_recover_pub_from_sig_helper(int ( - *ecdsa_recover_pub_from_sig_fn)(const ecdsa_curve *, uint8_t *, - const uint8_t *, const uint8_t *, int)) { - int res; - uint8_t digest[32]; - uint8_t pubkey[65]; - const ecdsa_curve *curve = &secp256k1; - - // sha2(sha2("\x18Bitcoin Signed Message:\n\x0cHello World!")) - memcpy( - digest, - fromhex( - "de4e9524586d6fce45667f9ff12f661e79870c4105fa0fb58af976619bb11432"), - 32); - // r = 2: Four points should exist - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000020123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 0); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "043fc5bf5fec35b6ffe6fd246226d312742a8c296bfa57dd22da509a2e348529b7dd" - "b9faf8afe1ecda3c05e7b2bda47ee1f5a87e952742b22afca560b29d972fcf"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000020123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 1); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "0456d8089137b1fd0d890f8c7d4a04d0fd4520a30b19518ee87bd168ea12ed809032" - "9274c4c6c0d9df04515776f2741eeffc30235d596065d718c3973e19711ad0"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000020123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 2); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "04cee0e740f41aab39156844afef0182dea2a8026885b10454a2d539df6f6df9023a" - "bfcb0f01c50bef3c0fa8e59a998d07441e18b1c60583ef75cc8b912fb21a15"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000020123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 3); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "0490d2bd2e9a564d6e1d8324fc6ad00aa4ae597684ecf4abea58bdfe7287ea4fa729" - "68c2e5b0b40999ede3d7898d94e82c3f8dc4536a567a4bd45998c826a4c4b2"), - 65); - // The point at infinity is not considered to be a valid public key. - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "220cf4c7b6d568f2256a8c30cc1784a625a28c3627dac404aa9a9ecd08314ec81a88" - "828f20d69d102bab5de5f6ee7ef040cb0ff7b8e1ba3f29d79efb5250f47d"), - digest, 0); - ck_assert_int_eq(res, 1); - - memcpy( - digest, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000000"), - 32); - // r = 7: No point P with P.x = 7, but P.x = (order + 7) exists - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000070123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 2); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "044d81bb47a31ffc6cf1f780ecb1e201ec47214b651650867c07f13ad06e12a1b040" - "de78f8dbda700f4d3cd7ee21b3651a74c7661809699d2be7ea0992b0d39797"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000070123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 3); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "044d81bb47a31ffc6cf1f780ecb1e201ec47214b651650867c07f13ad06e12a1b0bf" - "21870724258ff0b2c32811de4c9ae58b3899e7f69662d41815f66c4f2c6498"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000070123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 0); - ck_assert_int_eq(res, 1); - - memcpy( - digest, - fromhex( - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - 32); - // r = 1: Two points P with P.x = 1, but P.x = (order + 7) doesn't exist - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000010123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 0); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "045d330b2f89dbfca149828277bae852dd4aebfe136982cb531a88e9e7a89463fe71" - "519f34ea8feb9490c707f14bc38c9ece51762bfd034ea014719b7c85d2871b"), - 65); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000010123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 1); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq( - pubkey, - fromhex( - "049e609c3950e70d6f3e3f3c81a473b1d5ca72739d51debdd80230ae80cab05134a9" - "4285375c834a417e8115c546c41da83a263087b79ef1cae25c7b3c738daa2b"), - 65); - - // r = 0 is always invalid - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000010123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 2); - ck_assert_int_eq(res, 1); - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000000123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 0); - ck_assert_int_eq(res, 1); - // r >= order is always invalid - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 0); - ck_assert_int_eq(res, 1); - // check that overflow of r is handled - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "000000000000000000000000000000014551231950B75FC4402DA1722FC9BAEE0123" - "456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), - digest, 2); - ck_assert_int_eq(res, 1); - // s = 0 is always invalid - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "00000000000000000000000000000000000000000000000000000000000000020000" - "000000000000000000000000000000000000000000000000000000000000"), - digest, 0); - ck_assert_int_eq(res, 1); - // s >= order is always invalid - res = ecdsa_recover_pub_from_sig_fn( - curve, pubkey, - fromhex( - "0000000000000000000000000000000000000000000000000000000000000002ffff" - "fffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), - digest, 0); - ck_assert_int_eq(res, 1); -} - -START_TEST(test_ecdsa_recover_pub_from_sig) { - test_ecdsa_recover_pub_from_sig_helper(ecdsa_recover_pub_from_sig); -} -END_TEST - -static void test_ecdsa_verify_digest_helper(int (*ecdsa_verify_digest_fn)( - const ecdsa_curve *, const uint8_t *, const uint8_t *, const uint8_t *)) { - int res; - uint8_t digest[32]; - uint8_t pubkey[65]; - uint8_t sig[64]; - const ecdsa_curve *curve = &secp256k1; - - // Signature verification for a digest which is equal to the group order. - // https://github.com/trezor/trezor-firmware/pull/1374 - memcpy( - pubkey, - fromhex( - "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179848" - "3ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"), - sizeof(pubkey)); - memcpy( - digest, - fromhex( - "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), - sizeof(digest)); - memcpy(sig, - fromhex( - "a0b37f8fba683cc68f6574cd43b39f0343a50008bf6ccea9d13231d9e7e2e1e41" - "1edc8d307254296264aebfc3dc76cd8b668373a072fd64665b50000e9fcce52"), - sizeof(sig)); - res = ecdsa_verify_digest_fn(curve, pubkey, sig, digest); - ck_assert_int_eq(res, 0); -} - -START_TEST(test_ecdsa_verify_digest) { - test_ecdsa_verify_digest_helper(ecdsa_verify_digest); -} -END_TEST - -#define test_deterministic(KEY, MSG, K) \ - do { \ - sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \ - init_rfc6979(fromhex(KEY), buf, NULL, &rng); \ - generate_k_rfc6979(&k, &rng); \ - bn_write_be(&k, buf); \ - ck_assert_mem_eq(buf, fromhex(K), 32); \ - } while (0) - -START_TEST(test_rfc6979) { - bignum256 k; - uint8_t buf[32]; - rfc6979_state rng; - - test_deterministic( - "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721", - "sample", - "a6e3c57dd01abe90086538398355dd4c3b17aa873382b0f24d6129493d8aad60"); - test_deterministic( - "cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50", - "sample", - "2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3"); - test_deterministic( - "0000000000000000000000000000000000000000000000000000000000000001", - "Satoshi Nakamoto", - "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15"); - test_deterministic( - "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "Satoshi Nakamoto", - "33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90"); - test_deterministic( - "f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181", - "Alan Turing", - "525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1"); - test_deterministic( - "0000000000000000000000000000000000000000000000000000000000000001", - "All those moments will be lost in time, like tears in rain. Time to " - "die...", - "38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3"); - test_deterministic( - "e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2", - "There is a computer disease that anybody who works with computers knows " - "about. It's a very serious disease and it interferes completely with " - "the work. The trouble with computers is that you 'play' with them!", - "1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d"); -} -END_TEST - -static void test_ecdsa_sign_digest_deterministic_helper( - int (*ecdsa_sign_digest_fn)(const ecdsa_curve *, const uint8_t *, - const uint8_t *, uint8_t *, uint8_t *, - int (*)(uint8_t by, uint8_t sig[64]))) { - static struct { - const char *priv_key; - const char *digest; - const char *sig; - } tests[] = { - {"312155017c70a204106e034520e0cdf17b3e54516e2ece38e38e38e38e38e38e", - "ffffffffffffffffffffffffffffffff20202020202020202020202020202020", - "e3d70248ea2fc771fc8d5e62d76b9cfd5402c96990333549eaadce1ae9f737eb" - "5cfbdc7d1e0ec18cc9b57bbb18f0a57dc929ec3c4dfac9073c581705015f6a8a"}, - {"312155017c70a204106e034520e0cdf17b3e54516e2ece38e38e38e38e38e38e", - "2020202020202020202020202020202020202020202020202020202020202020", - "40666188895430715552a7e4c6b53851f37a93030fb94e043850921242db78e8" - "75aa2ac9fd7e5a19402973e60e64382cdc29a09ebf6cb37e92f23be5b9251aee"}, - }; - - const ecdsa_curve *curve = &secp256k1; - uint8_t priv_key[32] = {0}; - uint8_t digest[32] = {0}; - uint8_t expected_sig[64] = {0}; - uint8_t computed_sig[64] = {0}; - int res = 0; - - for (size_t i = 0; i < sizeof(tests) / sizeof(*tests); i++) { - memcpy(priv_key, fromhex(tests[i].priv_key), 32); - memcpy(digest, fromhex(tests[i].digest), 32); - memcpy(expected_sig, fromhex(tests[i].sig), 64); - - res = - ecdsa_sign_digest_fn(curve, priv_key, digest, computed_sig, NULL, NULL); - ck_assert_int_eq(res, 0); - ck_assert_mem_eq(expected_sig, computed_sig, 64); - } -} - -START_TEST(test_ecdsa_sign_digest_deterministic) { - test_ecdsa_sign_digest_deterministic_helper(ecdsa_sign_digest); -} -END_TEST - -// test vectors from -// http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors -START_TEST(test_aes) { - aes_encrypt_ctx ctxe; - aes_decrypt_ctx ctxd; - uint8_t ibuf[16], obuf[16], iv[16], cbuf[16]; - const char **ivp, **plainp, **cipherp; - - // ECB - static const char *ecb_vector[] = { - // plain cipher - "6bc1bee22e409f96e93d7e117393172a", - "f3eed1bdb5d2a03c064b5a7e3db181f8", - "ae2d8a571e03ac9c9eb76fac45af8e51", - "591ccb10d410ed26dc5ba74a31362870", - "30c81c46a35ce411e5fbc1191a0a52ef", - "b6ed21b99ca6f4f9f153e7b1beafed1d", - "f69f2445df4f9b17ad2b417be66c3710", - "23304b7a39f9f3ff067d8d8f9e24ecc7", - 0, - 0, - }; - plainp = ecb_vector; - cipherp = ecb_vector + 1; - while (*plainp && *cipherp) { - // encrypt - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(ibuf, fromhex(*plainp), 16); - aes_ecb_encrypt(ibuf, obuf, 16, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); - // decrypt - aes_decrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxd); - memcpy(ibuf, fromhex(*cipherp), 16); - aes_ecb_decrypt(ibuf, obuf, 16, &ctxd); - ck_assert_mem_eq(obuf, fromhex(*plainp), 16); - plainp += 2; - cipherp += 2; - } - - // CBC - static const char *cbc_vector[] = { - // iv plain cipher - "000102030405060708090A0B0C0D0E0F", - "6bc1bee22e409f96e93d7e117393172a", - "f58c4c04d6e5f1ba779eabfb5f7bfbd6", - "F58C4C04D6E5F1BA779EABFB5F7BFBD6", - "ae2d8a571e03ac9c9eb76fac45af8e51", - "9cfc4e967edb808d679f777bc6702c7d", - "9CFC4E967EDB808D679F777BC6702C7D", - "30c81c46a35ce411e5fbc1191a0a52ef", - "39f23369a9d9bacfa530e26304231461", - "39F23369A9D9BACFA530E26304231461", - "f69f2445df4f9b17ad2b417be66c3710", - "b2eb05e2c39be9fcda6c19078c6a9d1b", - 0, - 0, - 0, - }; - ivp = cbc_vector; - plainp = cbc_vector + 1; - cipherp = cbc_vector + 2; - while (*plainp && *cipherp) { - // encrypt - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*plainp), 16); - aes_cbc_encrypt(ibuf, obuf, 16, iv, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); - // decrypt - aes_decrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxd); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*cipherp), 16); - aes_cbc_decrypt(ibuf, obuf, 16, iv, &ctxd); - ck_assert_mem_eq(obuf, fromhex(*plainp), 16); - ivp += 3; - plainp += 3; - cipherp += 3; - } - - // CFB - static const char *cfb_vector[] = { - "000102030405060708090A0B0C0D0E0F", - "6bc1bee22e409f96e93d7e117393172a", - "DC7E84BFDA79164B7ECD8486985D3860", - "DC7E84BFDA79164B7ECD8486985D3860", - "ae2d8a571e03ac9c9eb76fac45af8e51", - "39ffed143b28b1c832113c6331e5407b", - "39FFED143B28B1C832113C6331E5407B", - "30c81c46a35ce411e5fbc1191a0a52ef", - "df10132415e54b92a13ed0a8267ae2f9", - "DF10132415E54B92A13ED0A8267AE2F9", - "f69f2445df4f9b17ad2b417be66c3710", - "75a385741ab9cef82031623d55b1e471", - 0, - 0, - 0, - }; - ivp = cfb_vector; - plainp = cfb_vector + 1; - cipherp = cfb_vector + 2; - while (*plainp && *cipherp) { - // encrypt - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*plainp), 16); - aes_cfb_encrypt(ibuf, obuf, 16, iv, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); - // decrypt (uses encryption) - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*cipherp), 16); - aes_cfb_decrypt(ibuf, obuf, 16, iv, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*plainp), 16); - ivp += 3; - plainp += 3; - cipherp += 3; - } - - // OFB - static const char *ofb_vector[] = { - "000102030405060708090A0B0C0D0E0F", - "6bc1bee22e409f96e93d7e117393172a", - "dc7e84bfda79164b7ecd8486985d3860", - "B7BF3A5DF43989DD97F0FA97EBCE2F4A", - "ae2d8a571e03ac9c9eb76fac45af8e51", - "4febdc6740d20b3ac88f6ad82a4fb08d", - "E1C656305ED1A7A6563805746FE03EDC", - "30c81c46a35ce411e5fbc1191a0a52ef", - "71ab47a086e86eedf39d1c5bba97c408", - "41635BE625B48AFC1666DD42A09D96E7", - "f69f2445df4f9b17ad2b417be66c3710", - "0126141d67f37be8538f5a8be740e484", - 0, - 0, - 0, - }; - ivp = ofb_vector; - plainp = ofb_vector + 1; - cipherp = ofb_vector + 2; - while (*plainp && *cipherp) { - // encrypt - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*plainp), 16); - aes_ofb_encrypt(ibuf, obuf, 16, iv, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); - // decrypt (uses encryption) - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - memcpy(iv, fromhex(*ivp), 16); - memcpy(ibuf, fromhex(*cipherp), 16); - aes_ofb_decrypt(ibuf, obuf, 16, iv, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*plainp), 16); - ivp += 3; - plainp += 3; - cipherp += 3; - } - - // CTR - static const char *ctr_vector[] = { - // plain cipher - "6bc1bee22e409f96e93d7e117393172a", - "601ec313775789a5b7a7f504bbf3d228", - "ae2d8a571e03ac9c9eb76fac45af8e51", - "f443e3ca4d62b59aca84e990cacaf5c5", - "30c81c46a35ce411e5fbc1191a0a52ef", - "2b0930daa23de94ce87017ba2d84988d", - "f69f2445df4f9b17ad2b417be66c3710", - "dfc9c58db67aada613c2dd08457941a6", - 0, - 0, - }; - // encrypt - plainp = ctr_vector; - cipherp = ctr_vector + 1; - memcpy(cbuf, fromhex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 16); - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - while (*plainp && *cipherp) { - memcpy(ibuf, fromhex(*plainp), 16); - aes_ctr_encrypt(ibuf, obuf, 16, cbuf, aes_ctr_cbuf_inc, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*cipherp), 16); - plainp += 2; - cipherp += 2; - } - // decrypt (uses encryption) - plainp = ctr_vector; - cipherp = ctr_vector + 1; - memcpy(cbuf, fromhex("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"), 16); - aes_encrypt_key256( - fromhex( - "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), - &ctxe); - while (*plainp && *cipherp) { - memcpy(ibuf, fromhex(*cipherp), 16); - aes_ctr_decrypt(ibuf, obuf, 16, cbuf, aes_ctr_cbuf_inc, &ctxe); - ck_assert_mem_eq(obuf, fromhex(*plainp), 16); - plainp += 2; - cipherp += 2; - } -} -END_TEST - -#define TEST1 "abc" -#define TEST2_1 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" -#define TEST2_2a "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" -#define TEST2_2b "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" -#define TEST2_2 TEST2_2a TEST2_2b -#define TEST3 "a" /* times 1000000 */ -#define TEST4a "01234567012345670123456701234567" -#define TEST4b "01234567012345670123456701234567" -/* an exact multiple of 512 bits */ -#define TEST4 TEST4a TEST4b /* times 10 */ - -#define TEST7_1 "\x49\xb2\xae\xc2\x59\x4b\xbe\x3a\x3b\x11\x75\x42\xd9\x4a\xc8" -#define TEST8_1 \ - "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46" -#define TEST9_1 \ - "\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4\xa2\xe7\x1a\xe7\x02\x20" \ - "\xaa\xce\xc8\x96\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea\xaa\x10" \ - "\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e\x43\x66\x5a\x5a\xf2\xcd\x03\xfe" \ - "\x67\x8e\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2\x8b\x91\x09\xf4" \ - "\x69\xda\xc9\x2a\xaa\xb3\xaa\x7c\x11\xa1\xb3\x2a" -#define TEST10_1 \ - "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f" \ - "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15" \ - "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92" \ - "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f" \ - "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" \ - "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca" \ - "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b" \ - "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60" \ - "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80" \ - "\x7c\x7d\x52\x3d\x6d\x79\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27" \ - "\xcd\xbb\xfb" -#define length(x) (sizeof(x) - 1) - -// test vectors from rfc-4634 -START_TEST(test_sha1) { - struct { - const char *test; - int length; - int repeatcount; - int extrabits; - int numberExtrabits; - const char *result; - } tests[] = { - /* 1 */ {TEST1, length(TEST1), 1, 0, 0, - "A9993E364706816ABA3E25717850C26C9CD0D89D"}, - /* 2 */ - {TEST2_1, length(TEST2_1), 1, 0, 0, - "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"}, - /* 3 */ - {TEST3, length(TEST3), 1000000, 0, 0, - "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"}, - /* 4 */ - {TEST4, length(TEST4), 10, 0, 0, - "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452"}, - /* 5 */ {"", 0, 0, 0x98, 5, "29826B003B906E660EFF4027CE98AF3531AC75BA"}, - /* 6 */ {"\x5e", 1, 1, 0, 0, "5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2"}, - /* 7 */ - {TEST7_1, length(TEST7_1), 1, 0x80, 3, - "6239781E03729919C01955B3FFA8ACB60B988340"}, - /* 8 */ - {TEST8_1, length(TEST8_1), 1, 0, 0, - "82ABFF6605DBE1C17DEF12A394FA22A82B544A35"}, - /* 9 */ - {TEST9_1, length(TEST9_1), 1, 0xE0, 3, - "8C5B2A5DDAE5A97FC7F9D85661C672ADBF7933D4"}, - /* 10 */ - {TEST10_1, length(TEST10_1), 1, 0, 0, - "CB0082C8F197D260991BA6A460E76E202BAD27B3"}}; - - for (int i = 0; i < 10; i++) { - SHA1_CTX ctx; - uint8_t digest[SHA1_DIGEST_LENGTH]; - sha1_Init(&ctx); - /* extra bits are not supported */ - if (tests[i].numberExtrabits) continue; - for (int j = 0; j < tests[i].repeatcount; j++) { - sha1_Update(&ctx, (const uint8_t *)tests[i].test, tests[i].length); - } - sha1_Final(&ctx, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA1_DIGEST_LENGTH); - } -} -END_TEST - -#define TEST7_256 "\xbe\x27\x46\xc6\xdb\x52\x76\x5f\xdb\x2f\x88\x70\x0f\x9a\x73" -#define TEST8_256 \ - "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" -#define TEST9_256 \ - "\x3e\x74\x03\x71\xc8\x10\xc2\xb9\x9f\xc0\x4e\x80\x49\x07\xef\x7c" \ - "\xf2\x6b\xe2\x8b\x57\xcb\x58\xa3\xe2\xf3\xc0\x07\x16\x6e\x49\xc1" \ - "\x2e\x9b\xa3\x4c\x01\x04\x06\x91\x29\xea\x76\x15\x64\x25\x45\x70" \ - "\x3a\x2b\xd9\x01\xe1\x6e\xb0\xe0\x5d\xeb\xa0\x14\xeb\xff\x64\x06" \ - "\xa0\x7d\x54\x36\x4e\xff\x74\x2d\xa7\x79\xb0\xb3" -#define TEST10_256 \ - "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ - "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ - "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ - "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ - "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ - "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ - "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ - "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ - "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ - "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ - "\x3d\x54\xd6" - -// test vectors from rfc-4634 -START_TEST(test_sha256) { - struct { - const char *test; - int length; - int repeatcount; - int extrabits; - int numberExtrabits; - const char *result; - } tests[] = { - /* 1 */ {TEST1, length(TEST1), 1, 0, 0, - "BA7816BF8F01CFEA4141" - "40DE5DAE2223B00361A396177A9CB410FF61F20015AD"}, - /* 2 */ - {TEST2_1, length(TEST2_1), 1, 0, 0, - "248D6A61D20638B8" - "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1"}, - /* 3 */ - {TEST3, length(TEST3), 1000000, 0, 0, - "CDC76E5C9914FB92" - "81A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0"}, - /* 4 */ - {TEST4, length(TEST4), 10, 0, 0, - "594847328451BDFA" - "85056225462CC1D867D877FB388DF0CE35F25AB5562BFBB5"}, - /* 5 */ - {"", 0, 0, 0x68, 5, - "D6D3E02A31A84A8CAA9718ED6C2057BE" - "09DB45E7823EB5079CE7A573A3760F95"}, - /* 6 */ - {"\x19", 1, 1, 0, 0, - "68AA2E2EE5DFF96E3355E6C7EE373E3D" - "6A4E17F75F9518D843709C0C9BC3E3D4"}, - /* 7 */ - {TEST7_256, length(TEST7_256), 1, 0x60, 3, - "77EC1DC8" - "9C821FF2A1279089FA091B35B8CD960BCAF7DE01C6A7680756BEB972"}, - /* 8 */ - {TEST8_256, length(TEST8_256), 1, 0, 0, - "175EE69B02BA" - "9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8"}, - /* 9 */ - {TEST9_256, length(TEST9_256), 1, 0xA0, 3, - "3E9AD646" - "8BBBAD2AC3C2CDC292E018BA5FD70B960CF1679777FCE708FDB066E9"}, - /* 10 */ - {TEST10_256, length(TEST10_256), 1, 0, 0, - "97DBCA7D" - "F46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC"}, - }; - - for (int i = 0; i < 10; i++) { - SHA256_CTX ctx; - uint8_t digest[SHA256_DIGEST_LENGTH]; - sha256_Init(&ctx); - /* extra bits are not supported */ - if (tests[i].numberExtrabits) continue; - for (int j = 0; j < tests[i].repeatcount; j++) { - sha256_Update(&ctx, (const uint8_t *)tests[i].test, tests[i].length); - } - sha256_Final(&ctx, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA256_DIGEST_LENGTH); - } -} -END_TEST - -#define TEST7_512 "\x08\xec\xb5\x2e\xba\xe1\xf7\x42\x2d\xb6\x2b\xcd\x54\x26\x70" -#define TEST8_512 \ - "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" -#define TEST9_512 \ - "\x3a\xdd\xec\x85\x59\x32\x16\xd1\x61\x9a\xa0\x2d\x97\x56\x97\x0b" \ - "\xfc\x70\xac\xe2\x74\x4f\x7c\x6b\x27\x88\x15\x10\x28\xf7\xb6\xa2" \ - "\x55\x0f\xd7\x4a\x7e\x6e\x69\xc2\xc9\xb4\x5f\xc4\x54\x96\x6d\xc3" \ - "\x1d\x2e\x10\xda\x1f\x95\xce\x02\xbe\xb4\xbf\x87\x65\x57\x4c\xbd" \ - "\x6e\x83\x37\xef\x42\x0a\xdc\x98\xc1\x5c\xb6\xd5\xe4\xa0\x24\x1b" \ - "\xa0\x04\x6d\x25\x0e\x51\x02\x31\xca\xc2\x04\x6c\x99\x16\x06\xab" \ - "\x4e\xe4\x14\x5b\xee\x2f\xf4\xbb\x12\x3a\xab\x49\x8d\x9d\x44\x79" \ - "\x4f\x99\xcc\xad\x89\xa9\xa1\x62\x12\x59\xed\xa7\x0a\x5b\x6d\xd4" \ - "\xbd\xd8\x77\x78\xc9\x04\x3b\x93\x84\xf5\x49\x06" -#define TEST10_512 \ - "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ - "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ - "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ - "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ - "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ - "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ - "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ - "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ - "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ - "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" \ - "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1" \ - "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8" \ - "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b" \ - "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7" \ - "\xfb\x40\xd2" - -// test vectors from rfc-4634 -START_TEST(test_sha512) { - struct { - const char *test; - int length; - int repeatcount; - int extrabits; - int numberExtrabits; - const char *result; - } tests[] = {/* 1 */ {TEST1, length(TEST1), 1, 0, 0, - "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" - "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" - "454D4423643CE80E2A9AC94FA54CA49F"}, - /* 2 */ - {TEST2_2, length(TEST2_2), 1, 0, 0, - "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" - "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" - "C7D329EEB6DD26545E96E55B874BE909"}, - /* 3 */ - {TEST3, length(TEST3), 1000000, 0, 0, - "E718483D0CE769644E2E42C7BC15B4638E1F98B13B204428" - "5632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31B" - "EB009C5C2C49AA2E4EADB217AD8CC09B"}, - /* 4 */ - {TEST4, length(TEST4), 10, 0, 0, - "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024" - "DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB51" - "0813A39CD5A84C4ACAA64D3F3FB7BAE9"}, - /* 5 */ - {"", 0, 0, 0xB0, 5, - "D4EE29A9E90985446B913CF1D1376C836F4BE2C1CF3CADA0" - "720A6BF4857D886A7ECB3C4E4C0FA8C7F95214E41DC1B0D2" - "1B22A84CC03BF8CE4845F34DD5BDBAD4"}, - /* 6 */ - {"\xD0", 1, 1, 0, 0, - "9992202938E882E73E20F6B69E68A0A7149090423D93C81B" - "AB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA8306826C4A" - "D6E74CECE9631BFA8A549B4AB3FBBA15"}, - /* 7 */ - {TEST7_512, length(TEST7_512), 1, 0x80, 3, - "ED8DC78E8B01B69750053DBB7A0A9EDA0FB9E9D292B1ED71" - "5E80A7FE290A4E16664FD913E85854400C5AF05E6DAD316B" - "7359B43E64F8BEC3C1F237119986BBB6"}, - /* 8 */ - {TEST8_512, length(TEST8_512), 1, 0, 0, - "CB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75ACBD" - "D1C153C9828924C3DDEDAAFE669C5FDD0BC66F630F677398" - "8213EB1B16F517AD0DE4B2F0C95C90F8"}, - /* 9 */ - {TEST9_512, length(TEST9_512), 1, 0x80, 3, - "32BA76FC30EAA0208AEB50FFB5AF1864FDBF17902A4DC0A6" - "82C61FCEA6D92B783267B21080301837F59DE79C6B337DB2" - "526F8A0A510E5E53CAFED4355FE7C2F1"}, - /* 10 */ - {TEST10_512, length(TEST10_512), 1, 0, 0, - "C665BEFB36DA189D78822D10528CBF3B12B3EEF726039909" - "C1A16A270D48719377966B957A878E720584779A62825C18" - "DA26415E49A7176A894E7510FD1451F5"}}; - - for (int i = 0; i < 10; i++) { - SHA512_CTX ctx; - uint8_t digest[SHA512_DIGEST_LENGTH]; - sha512_Init(&ctx); - /* extra bits are not supported */ - if (tests[i].numberExtrabits) continue; - for (int j = 0; j < tests[i].repeatcount; j++) { - sha512_Update(&ctx, (const uint8_t *)tests[i].test, tests[i].length); - } - sha512_Final(&ctx, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].result), SHA512_DIGEST_LENGTH); - } -} -END_TEST - -// test vectors from http://www.di-mgt.com.au/sha_testvectors.html -START_TEST(test_sha3_256) { - static const struct { - const char *data; - const char *hash; - } tests[] = { - { - "", - "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", - }, - { - "abc", - "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", - }, - { - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", - }, - { - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijkl" - "mnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", - "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", - }, - }; - - uint8_t digest[SHA3_256_DIGEST_LENGTH]; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t len = strlen(tests[i].data); - sha3_256((uint8_t *)tests[i].data, len, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), SHA3_256_DIGEST_LENGTH); - - // Test progressive hashing. - size_t part_len = len; - SHA3_CTX ctx; - sha3_256_Init(&ctx); - sha3_Update(&ctx, (uint8_t *)tests[i].data, part_len); - sha3_Update(&ctx, NULL, 0); - sha3_Update(&ctx, (uint8_t *)tests[i].data + part_len, len - part_len); - sha3_Final(&ctx, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), SHA3_256_DIGEST_LENGTH); - } -} -END_TEST - -// test vectors from http://www.di-mgt.com.au/sha_testvectors.html -START_TEST(test_sha3_512) { - static const struct { - const char *data; - const char *hash; - } tests[] = { - { - "", - "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2" - "123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", - }, - { - "abc", - "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e1" - "16e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", - }, - { - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee69" - "1fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e", - }, - { - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijkl" - "mnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", - "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3" - "261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185", - }, - }; - - uint8_t digest[SHA3_512_DIGEST_LENGTH]; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t len = strlen(tests[i].data); - sha3_512((uint8_t *)tests[i].data, len, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), SHA3_512_DIGEST_LENGTH); - - // Test progressive hashing. - size_t part_len = len; - SHA3_CTX ctx; - sha3_512_Init(&ctx); - sha3_Update(&ctx, (const uint8_t *)tests[i].data, part_len); - sha3_Update(&ctx, NULL, 0); - sha3_Update(&ctx, (const uint8_t *)tests[i].data + part_len, - len - part_len); - sha3_Final(&ctx, digest); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), SHA3_512_DIGEST_LENGTH); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/0.test-sha3-256.dat -START_TEST(test_keccak_256) { - static const struct { - const char *hash; - size_t length; - const char *data; - } tests[] = { - { - "4e9e79ab7434f6c7401fb3305d55052ee829b9e46d5d05d43b59fefb32e9a619", - 293, - "a6151d4904e18ec288243028ceda30556e6c42096af7150d6a7232ca5dba52bd2192" - "e23daa5fa2bea3d4bd95efa2389cd193fcd3376e70a5c097b32c1c62c80af9d71021" - "1545f7cdddf63747420281d64529477c61e721273cfd78f8890abb4070e97baa52ac" - "8ff61c26d195fc54c077def7a3f6f79b36e046c1a83ce9674ba1983ec2fb58947de6" - "16dd797d6499b0385d5e8a213db9ad5078a8e0c940ff0cb6bf92357ea5609f778c3d" - "1fb1e7e36c35db873361e2be5c125ea7148eff4a035b0cce880a41190b2e22924ad9" - "d1b82433d9c023924f2311315f07b88bfd42850047bf3be785c4ce11c09d7e02065d" - "30f6324365f93c5e7e423a07d754eb314b5fe9db4614275be4be26af017abdc9c338" - "d01368226fe9af1fb1f815e7317bdbb30a0f36dc69", - }, - { - "c1268babc42d00c3463dc388222100f7e525a74a64665c39f112f788ddb5da42", - 376, - "9db801077952c2324e0044a4994edfb09b3edfcf669bfdd029f4bf42d5b0eab3056b" - "0bf82708ca7bfadba43c9de806b10a19d0f00c2351ef1086b6b108f306e035c6b61b" - "2e70fd7087ba848601c8a3f626a66666423717ef305a1068bfa3a1f7ffc1e5a78cb6" - "182ffc8a577ca2a821630bf900d0fbba848bdf94b77c5946771b6c3f8c02269bc772" - "ca56098f724536d96be68c284ee1d81697989d40029b8ea63ac1fd85f8b3cae8b194" - "f6834ff65a5858f9498ddbb467995eb2d49cdfc6c05d92038c6e9aaeee85f8222b37" - "84165f12a2c3df4c7a142e26dddfd831d07e22dfecc0eded48a69c8a9e1b97f1a4e0" - "efcd4edd310de0edf82af38a6e4d5ab2a19da586e61210d4f75e7a07e2201f9c8154" - "ca52a414a70d2eb2ac1c5b9a2900b4d871f62fa56f70d03b3dd3704bd644808c45a1" - "3231918ea884645b8ec054e8bab2935a66811fe590ddc119ae901dfeb54fc2a87c1e" - "0a236778baab2fa8843709c6676d3c1888ba19d75ec52d73a7d035c143179b938237" - "26b7", - }, - { - "e83b50e8c83cb676a7dd64c055f53e5110d5a4c62245ceb8f683fd87b2b3ec77", - 166, - "c070a957550b7b34113ee6543a1918d96d241f27123425db7f7b9004e047ffbe0561" - "2e7fa8c54b23c83ea427e625e97b7a28b09a70bf6d91e478eeed01d7907931c29ea8" - "6e70f2cdcfb243ccf7f24a1619abf4b5b9e6f75cbf63fc02baf4a820a9790a6b053e" - "50fd94e0ed57037cfc2bab4d95472b97d3c25f434f1cc0b1ede5ba7f15907a42a223" - "933e5e2dfcb518c3531975268c326d60fa911fbb7997eee3ba87656c4fe7", - }, - { - "8ebd2c9d4ff00e285a9b6b140bfc3cef672016f0098100e1f6f250220af7ce1a", - 224, - "b502fbdce4045e49e147eff5463d4b3f37f43461518868368e2c78008c84c2db79d1" - "2b58107034f67e7d0abfee67add0342dd23dce623f26b9156def87b1d7ac15a6e073" - "01f832610fe869ada13a2b0e3d60aa6bb81bc04487e2e800f5106b0402ee0331df74" - "5e021b5ea5e32faf1c7fc1322041d221a54191c0af19948b5f34411937182e30d5cd" - "39b5a6c959d77d92d21bb1de51f1b3411cb6eec00600429916227fb62d2c88e69576" - "f4ac8e5efcde8efa512cc80ce7fb0dfaa6c74d26e898cefe9d4f7dce232a69f2a6a9" - "477aa08366efcdfca117c89cb79eba15a23755e0", - }, - { - "db3961fdddd0c314289efed5d57363459a6700a7bd015e7a03d3e1d03f046401", - 262, - "22e203a98ba2c43d8bc3658f0a48a35766df356d6a5e98b0c7222d16d85a00b31720" - "7d4aef3fc7cabb67b9d8f5838de0b733e1fd59c31f0667e53286972d7090421ad90d" - "54db2ea40047d0d1700c86f53dbf48da532396307e68edad877dcae481848801b0a5" - "db44dbdba6fc7c63b5cd15281d57ca9e6be96f530b209b59d6127ad2bd8750f3f807" - "98f62521f0d5b42633c2f5a9aaefbed38779b7aded2338d66850b0bb0e33c48e040c" - "99f2dcee7a7ebb3d7416e1c5bf038c19d09682dab67c96dbbfad472e45980aa27d1b" - "301b15f7de4d4f549bad2501931c9d4f1a3b1692dcb4b1b834ddd4a636126702307d" - "daeec61841693b21887d56e76cc2069dafb557fd6682160f", - }, - { - "25dd3acacd6bf688c0eace8d33eb7cc550271969142deb769a05b4012f7bb722", - 122, - "99e7f6e0ed46ec866c43a1ab494998d47e9309a79fde2a629eb63bb2160a5ffd0f22" - "06de9c32dd20e9b23e57ab7422cf82971cc2873ec0e173fe93281c7b33e1c76ac792" - "23a6f435f230bdd30260c00d00986c72a399d3ba70f6e783d834bbf8a6127844def5" - "59b8b6db742b2cfd715f7ff29e7b42bf7d567beb", - }, - { - "00d747c9045c093484290afc161437f11c2ddf5f8a9fc2acae9c7ef5fcf511e5", - 440, - "50c392f97f8788377f0ab2e2aab196cb017ad157c6f9d022673d39072cc198b06622" - "a5cbd269d1516089fa59e28c3373a92bd54b2ebf1a79811c7e40fdd7bce200e80983" - "fda6e77fc44c44c1b5f87e01cef2f41e1141103f73364e9c2f25a4597e6517ef31b3" - "16300b770c69595e0fa6d011df1566a8676a88c7698562273bbfa217cc69d4b5c89a" - "8907b902f7dc14481fefc7da4a810c15a60f5641aae854d2f8cc50cbc393015560f0" - "1c94e0d0c075dbcb150ad6eba29dc747919edcaf0231dba3eb3f2b1a87e136a1f0fd" - "4b3d8ee61bad2729e9526a32884f7bcfa41e361add1b4c51dc81463528372b4ec321" - "244de0c541ba00df22b8773cdf4cf898510c867829fa6b4ff11f9627338b9686d905" - "cb7bcdf085080ab842146e0035c808be58cce97827d8926a98bd1ff7c529be3bc14f" - "68c91b2ca4d2f6fc748f56bcf14853b7f8b9aa6d388f0fd82f53fdc4bacf9d9ba10a" - "165f404cf427e199f51bf6773b7c82531e17933f6d8b8d9181e22f8921a2dbb20fc7" - "c8023a87e716e245017c399d0942934f5e085219b3f8d26a196bf8b239438b8e561c" - "28a61ff08872ecb052c5fcb19e2fdbc09565924a50ebee1461c4b414219d4257", - }, - { - "dadcde7c3603ef419d319ba3d50cf00ad57f3e81566fd11b9b6f461cbb9dcb0f", - 338, - "18e1df97abccc91e07dc7b7ffab5ee8919d5610721453176aa2089fb96d9a477e147" - "6f507fa1129f04304e960e8017ff41246cacc0153055fc4b1dc6168a74067ebb077c" - "b5aa80a9df6e8b5b821e906531159668c4c164b9e511d8724aedbe17c1f41da88094" - "17d3c30b79ea5a2e3c961f6bac5436d9af6be24a36eebcb17863fed82c0eb8962339" - "eb612d58659dddd2ea06a120b3a2d8a17050be2de367db25a5bef4290c209bdb4c16" - "c4df5a1fe1ead635169a1c35f0a56bc07bcf6ef0e4c2d8573ed7a3b58030fa268c1a" - "5974b097288f01f34d5a1087946410688016882c6c7621aad680d9a25c7a3e5dbcbb" - "07ffdb7243b91031c08a121b40785e96b7ee46770c760f84aca8f36b7c7da64d25c8" - "f73b4d88ff3acb7eeefc0b75144dffea66d2d1f6b42b905b61929ab3f38538393ba5" - "ca9d3c62c61f46fa63789cac14e4e1d8722bf03cceef6e3de91f783b0072616c", - }, - { - "d184e84a2507fc0f187b640dd5b849a366c0383d9cbdbc6fa30904f054111255", - 141, - "13b8df9c1bcfddd0aa39b3055f52e2bc36562b6677535994b173f07041d141699db4" - "2589d6091ef0e71b645b41ab57577f58c98da966562d24823158f8e1d43b54edea4e" - "61dd66fe8c59ad8405f5a0d9a3eb509a77ae3d8ae4adf926fd3d8d31c3dcccfc1408" - "14541010937024cc554e1daaee1b333a66316e7fbebb07ac8dfb134a918b9090b141" - "68012c4824", - }, - { - "20c19635364a00b151d0168fe5ae03bac6dd7d06030475b40d2e8c577a192f53", - 84, - "e1e96da4b7d8dcc2b316006503a990ea26a5b200cb7a7edfc14f5ce827f06d8d232e" - "c95b1acdc1422ffc16da11d258f0c7b378f026d64c74b2fb41df8bfd3cd30066caec" - "dc6f76c8163de9309d9fd0cf33d54a29", - }, - { - "86cc2c428d469e43fb4ee8d38dffbf5128d20d1659dbc45edf4a855399ca730e", - 319, - "30391840ad14e66c53e1a5aaa03989ff059940b60c44c3b21295a93d023f2e6c7cdc" - "f60208b7d87a7605fb5cee94630d94cad90bc6955328357fa37fea47c09f9cee759c" - "31537187321c7d572e3554eeb90f441a9494575454dfbf8cfd86128da15de9418821" - "ca158856eb84ff6a29a2c8380711e9e6d4955388374fcd3c1ca45b49e0679fc7157f" - "96bc6e4f86ce20a89c12d4449b1ca7056e0b7296fc646f68f6ddbfa6a48e384d63ab" - "68bc75fd69a2add59b8e41c4a0f753935df9a703d7df82a430798b0a67710a780614" - "85a9d15de16f154582082459b4462485ce8a82d35ac6b9498ae40df3a23d5f00e0e8" - "6661cb02c52f677fd374c32969ec63028b5dd2c1d4bce67a6d9f79ba5e7eeb5a2763" - "dc9fe2a05aa2ebaad36aaec2541e343a677fb4e6b6a180eff33c93744a4624f6a79f" - "054c6c9e9c5b6928dbe7ba5fca", - }, - { - "e80eee72a76e6957f7cb7f68c41b92f0ad9aac6e58aa8fc272c1e7364af11c70", - 108, - "3c210ed15889ae938781d2cebd49d4a8007f163ffba1f7669bccdccf6ad5a1418299" - "d5f4348f5cd03b0ba9e6999ab154e46836c3546feb395d17bcc60f23d7ba0e8efe6a" - "a616c00b6bf552fe1cb5e28e3e7bc39dfc20c63ae3901035e91ddd110e43fe59ed74" - "4beeedb6bc1e", - }, - { - "f971bbae97dd8a034835269fb246867de358a889de6de13672e771d6fb4c89b7", - 468, - "64e9a3a99c021df8bea59368cfe1cd3b0a4aca33ffcd5cf6028d9307c0b904b8037d" - "056a3c12803f196f74c4d360a3132452d365922b1157e5b0d76f91fb94bebfdcb4d5" - "0fa23ed5be3d3c5712219e8666debc8abcd5e6c69a542761a6cbbd1b3c0f05248752" - "04b64d2788465f90cb19b6f6da9f8bec6d6e684196e713549ec83e47cbaeff77838a" - "c4936b312562e2de17c970449d49d214ec2597c6d4f642e6c94a613a0c53285abccd" - "7794a3d72241808594fb4e6e4d5d2c310ef1cdcbfd34805ca2408f554797a6cfd49d" - "0f25ed8927f206acb127e6436e1234902489ec2e7f3058e26c0eba80341bc7ad0da8" - "b8bd80bd1b43c9099269e3f8b68445c69b79d8cf5693d4a0d47a44f9e9114dbb3399" - "2d2ea9d3b5b86e4ea57a44a638848de4ac365bb6bb7855305ade62b07ebf0954d70b" - "7c2fb5e6fcc154c7a36fb1756df5f20a84d35696627ebf22d44f40f805c0878ad110" - "bc17dcd66821084ca87902e05bc0afa61161086956b85a6ea900d35c7784d4c361a4" - "3fe294e267d5762408be58962cdb4f45a9c0efd7d2335916df3acb98ccfbcf5ee395" - "30540e5f3d3c5f3326a9a536d7bfa37aae2b143e2499b81bf0670e3a418c26c7dc82" - "b293d9bd182dd6435670514237df88d8286e19ce93e0a0db2790", - }, - { - "b97fd51f4e4eaa40c7a2853010fc46be5be2f43b9520ea0c533b68f728c978a2", - 214, - "ced3a43193caceb269d2517f4ecb892bb7d57d7201869e28e669b0b17d1c44d286e0" - "2734e2210ea9009565832975cc6303b9b6008fe1165b99ae5f1b29962ef042ebad8b" - "676d7433ed2fe0d0d6f4f32b2cb4c519da61552328c2caea799bb2fd907308173a1c" - "d2b798fb0df7d2eaf2ff0be733af74f42889e211843fc80b09952ae7eb246725b91d" - "31c1f7a5503fdf3bc9c269c76519cf2dc3225e862436b587bb74adbad88c773056cf" - "ea3bddb1f6533c01125eeae0986e5c817359912c9d0472bf8320b824ee097f82a8e0" - "5b9f53a5be7d153225de", - }, - { - "f0fecf766e4f7522568b3be71843cce3e5fcb10ea96b1a236c8c0a71c9ad55c9", - 159, - "8aca4de41275f5c4102f66266d70cff1a2d56f58df8d12061c64cb6cd8f616a5bf19" - "c2bb3c91585c695326f561a2d0eb4eef2e202d82dcc9089e4bee82b62a199a11963c" - "d08987d3abd5914def2cdd3c1e4748d46b654f338e3959121e869c18d5327e88090d" - "0ba0ac6762a2b14514cc505af7499f1a22f421dbe978494f9ffe1e88f1c59228f21d" - "a5bc9fcc911d022300a443bca17258bdd6cfbbf52fde61", - }, - { - "5c4f16043c0084bf98499fc7dc4d674ce9c730b7135210acdbf5e41d3dcf317b", - 87, - "01bbc193d0ee2396a7d8267ad63f18149667b31d8f7f48c8bb0c634755febc9ef1a7" - "9e93c475f6cd137ee37d4dc243ea2fdcdc0d098844af2208337b7bbf6930e39e74e2" - "3952ac1a19b4d38b83810a10c3b069e4fafb06", - }, - { - "14b61fc981f7d9449b7b6a2d57eb48cc8f7896f4dced2005291b2a2f38cb4a63", - 358, - "cbc1709a531438d5ead32cea20a9e4ddc0101ec555ab42b2e378145013cc05a97b9e" - "2c43c89bfa63ae5e9e9ce1fc022035c6b68f0a906ee1f53396d9dbe41cb2bc4bfeb1" - "44b005b0f40e0fec872d9c4aca9929ba3cbacd84c58ab43c26f10d345a24692bbd55" - "a76506876768e8e32a461bf160cee953da88920d36ad4aff6eea7126aa6f44a7a6fc" - "e770ce43f0f90a20590bdaad3ffcda30ca8e3700f832c62caa5df030c16bcf74aff4" - "92466f781eb69863a80663535fc154abd7cfdd02eef1019221cf608b9780f807e507" - "fbbf559b1dfe4e971b4d08fe45263a3c697ba90f9f71bec97e12438b4b12f6a84ab6" - "6872b888097089d76c9c2502d9ed2eece6bef8eee1d439782e218f5cc75d38f98860" - "12cdcb4bbe6caf812e97c5a336bcceae38b1109e3243a291ce23d097aaee7d9a711d" - "e6886749a7a6d15d7e7cbc4a51b1b4da9fcf139e4a6fd7dc0bc017db624b17fc9b8f" - "847592ed42467c25ad9fe96acbf20c0ffd18", - }, - { - "47ec7f3a362becbb110867995a0f066a66152603c4d433f11bf51870c67e2864", - 354, - "0636983353c9ea3f75256ed00b70e8b7cfc6f4e4c0ba3aa9a8da59b6e6ad9dfb5bc2" - "c49f48cc0b4237f87dedf34b888e54ecebf1d435bcd4aab72eb4ce39e5262fb68c6f" - "86423dac123bf59e903989eda7df4a982822d0831521403cedcfe9a5bbea648bb2e7" - "ef8cd81442ea5abe468b3ee8b06376ef8099447255c2fdc1b73af37fe0e0b852ffbc" - "9339868db756680db99e6e9837dbd28c39a69f229044ad7ec772524a6e01f679d25f" - "dc2e736a2418e5dfd7c2ab1348d0f821b777c975244c6cfc2fca5c36ccae7cf1d07b" - "190a9d17a088a1276bd096250b92f53b29b6ef88ef69d744b56fb2ec5078cc0b68a9" - "106943ef242b466097b9e29df11eb5cb0c06c29d7917410ba1097215d6aa4dafd90a" - "dff0c3e7221b9e8832613bd9aca8bcc6b2aa7b43acedcbc11aee1b5ba56f77a210be" - "7cf3485ee813e1126c3eeccd8419bbf22c412cad32cc0fc7a73aca4e379651caac3d" - "13d6cf5ca05508fd2d96f3ad94e7", - }, - { - "73778e7f1943646a89d3c78909e0afbe584071ba5230546a39cd73e44e36d78a", - 91, - "6217504a26b3395855eab6ddeb79f2e3490d74b80eff343721150ee0c1c02b071867" - "43589f93c22a03dc5ed29fb5bf592de0a089763e83e5b95f9dd524d66c8da3e04c18" - "14e65e68b2810c1b517648aabc266ad62896c51864a7f4", - }, - { - "35ef6868e750cf0c1d5285992c231d93ec644670fb79cf85324067a9f77fde78", - 185, - "0118b7fb15f927a977e0b330b4fa351aeeec299d6ba090eb16e5114fc4a6749e5915" - "434a123c112697390c96ea2c26dc613eb5c75f5ecfb6c419317426367e34da0ddc6d" - "7b7612cefa70a22fea0025f5186593b22449dab71f90a49f7de7352e54e0c0bd8837" - "e661ca2127c3313a7268cafdd5ccfbf3bdd7c974b0e7551a2d96766579ef8d2e1f37" - "6af74cd1ab62162fc2dc61a8b7ed4163c1caccf20ed73e284da2ed257ec974eee96b" - "502acb2c60a04886465e44debb0317", - }, - }; - - uint8_t hash[SHA3_256_DIGEST_LENGTH]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - keccak_256(fromhex(tests[i].data), tests[i].length, hash); - ck_assert_mem_eq(hash, fromhex(tests[i].hash), SHA3_256_DIGEST_LENGTH); - - // Test progressive hashing. - size_t part_len = tests[i].length / 2; - SHA3_CTX ctx = {0}; - keccak_256_Init(&ctx); - keccak_Update(&ctx, fromhex(tests[i].data), part_len); - keccak_Update(&ctx, fromhex(tests[i].data), 0); - keccak_Update(&ctx, fromhex(tests[i].data) + part_len, - tests[i].length - part_len); - keccak_Final(&ctx, hash); - ck_assert_mem_eq(hash, fromhex(tests[i].hash), SHA3_256_DIGEST_LENGTH); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/monero-project/monero/master/tests/hash/tests-extra-blake.txt -START_TEST(test_blake256) { - static const struct { - const char *hash; - const char *data; - } tests[] = { - { - "716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a", - "", - }, - { - "e104256a2bc501f459d03fac96b9014f593e22d30f4de525fa680c3aa189eb4f", - "cc", - }, - { - "8f341148be7e354fdf38b693d8c6b4e0bd57301a734f6fd35cd85b8491c3ddcd", - "41fb", - }, - { - "bc334d1069099f10c601883ac6f3e7e9787c6aa53171f76a21923cc5ad3ab937", - "1f877c", - }, - { - "b672a16f53982bab1e77685b71c0a5f6703ffd46a1c834be69f614bd128d658e", - "c1ecfdfc", - }, - { - "d9134b2899057a7d8d320cc99e3e116982bc99d3c69d260a7f1ed3da8be68d99", - "21f134ac57", - }, - { - "637923bd29a35aa3ecbbd2a50549fc32c14cf0fdcaf41c3194dd7414fd224815", - "c6f50bb74e29", - }, - { - "70c092fd5c8c21e9ef4bbc82a5c7819e262a530a748caf285ff0cba891954f1e", - "119713cc83eeef", - }, - { - "fdf092993edbb7a0dc7ca67f04051bbd14481639da0808947aff8bfab5abed4b", - "4a4f202484512526", - }, - { - "6f6fc234bf35beae1a366c44c520c59ad5aa70351b5f5085e21e1fe2bfcee709", - "1f66ab4185ed9b6375", - }, - { - "4fdaf89e2a0e78c000061b59455e0ea93a4445b440e7562c8f0cfa165c93de2e", - "eed7422227613b6f53c9", - }, - { - "d6b780eee9c811f664393dc2c58b5a68c92b3c9fe9ceb70371d33ece63b5787e", - "eaeed5cdffd89dece455f1", - }, - { - "d0015071d3e7ed048c764850d76406eceae52b8e2e6e5a2c3aa92ae880485b34", - "5be43c90f22902e4fe8ed2d3", - }, - { - "9b0207902f9932f7a85c24722e93e31f6ed2c75c406509aa0f2f6d1cab046ce4", - "a746273228122f381c3b46e4f1", - }, - { - "258020d5b04a814f2b72c1c661e1f5a5c395d9799e5eee8b8519cf7300e90cb1", - "3c5871cd619c69a63b540eb5a625", - }, - { - "4adae3b55baa907fefc253365fdd99d8398befd0551ed6bf9a2a2784d3c304d1", - "fa22874bcc068879e8ef11a69f0722", - }, - { - "6dd10d772f8d5b4a96c3c5d30878cd9a1073fa835bfe6d2b924fa64a1fab1711", - "52a608ab21ccdd8a4457a57ede782176", - }, - { - "0b8741ddf2259d3af2901eb1ae354f22836442c965556f5c1eb89501191cb46a", - "82e192e4043ddcd12ecf52969d0f807eed", - }, - { - "f48a754ca8193a82643150ab94038b5dd170b4ebd1e0751b78cfb0a98fa5076a", - "75683dcb556140c522543bb6e9098b21a21e", - }, - { - "5698409ab856b74d9fa5e9b259dfa46001f89041752da424e56e491577b88c86", - "06e4efe45035e61faaf4287b4d8d1f12ca97e5", - }, - }; - - uint8_t hash[BLAKE256_DIGEST_LENGTH]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t len = strlen(tests[i].data) / 2; - blake256(fromhex(tests[i].data), len, hash); - ck_assert_mem_eq(hash, fromhex(tests[i].hash), BLAKE256_DIGEST_LENGTH); - - // Test progressive hashing. - size_t part_len = len / 2; - BLAKE256_CTX ctx; - blake256_Init(&ctx); - blake256_Update(&ctx, fromhex(tests[i].data), part_len); - blake256_Update(&ctx, NULL, 0); - blake256_Update(&ctx, fromhex(tests[i].data) + part_len, len - part_len); - blake256_Final(&ctx, hash); - ck_assert_mem_eq(hash, fromhex(tests[i].hash), BLAKE256_DIGEST_LENGTH); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2b-kat.txt -START_TEST(test_blake2b) { - static const struct { - const char *msg; - const char *hash; - } tests[] = { - { - "", - "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e9" - "96e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568", - }, - { - "000102", - "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e" - "364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1", - }, - { - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" - "22232425262728292a2b2c2d2e2f3031323334353637", - "f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e7684" - "2d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2", - }, - { - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" - "22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243" - "4445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465" - "666768696a6b6c6d6e6f", - "227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c5" - "28fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f", - }, - }; - - uint8_t key[BLAKE2B_KEY_LENGTH]; - memcpy(key, - fromhex( - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2" - "02122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"), - BLAKE2B_KEY_LENGTH); - - uint8_t digest[BLAKE2B_DIGEST_LENGTH]; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t msg_len = strlen(tests[i].msg) / 2; - tc_blake2b_Key(fromhex(tests[i].msg), msg_len, key, sizeof(key), digest, - sizeof(digest)); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), sizeof(digest)); - - // Test progressive hashing. - size_t part_len = msg_len / 2; - BLAKE2B_CTX ctx; - ck_assert_int_eq(tc_blake2b_InitKey(&ctx, sizeof(digest), key, sizeof(key)), - 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, fromhex(tests[i].msg), part_len), 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, NULL, 0), 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, fromhex(tests[i].msg) + part_len, - msg_len - part_len), - 0); - ck_assert_int_eq(tc_blake2b_Final(&ctx, digest, sizeof(digest)), 0); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), BLAKE2B_DIGEST_LENGTH); - } -} -END_TEST - -// Blake2b-256 personalized, a la ZCash -// Test vectors from https://zips.z.cash/zip-0243 -START_TEST(test_blake2bp) { - static const struct { - const char *msg; - const char *personal; - const char *hash; - } tests[] = { - { - "", - "ZcashPrevoutHash", - "d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136", - }, - { - "", - "ZcashSequencHash", - "a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272", - - }, - { - "e7719811893e0000095200ac6551ac636565b2835a0805750200025151", - "ZcashOutputsHash", - "ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a", - }, - { - "0bbe32a598c22adfb48cef72ba5d4287c0cefbacfd8ce195b4963c34a94bba7a1" - "75dae4b090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b" - "63396e2b41d", - "ZcashPrevoutHash", - "cacf0f5210cce5fa65a59f314292b3111d299e7d9d582753cf61e1e408552ae4", - }}; - - uint8_t digest[32]; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t msg_len = strlen(tests[i].msg) / 2; - - // Test progressive hashing. - size_t part_len = msg_len / 2; - BLAKE2B_CTX ctx; - ck_assert_int_eq( - tc_blake2b_InitPersonal(&ctx, sizeof(digest), tests[i].personal, - strlen(tests[i].personal)), - 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, fromhex(tests[i].msg), part_len), 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, NULL, 0), 0); - ck_assert_int_eq(tc_blake2b_Update(&ctx, fromhex(tests[i].msg) + part_len, - msg_len - part_len), - 0); - ck_assert_int_eq(tc_blake2b_Final(&ctx, digest, sizeof(digest)), 0); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), sizeof(digest)); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2s-kat.txt -START_TEST(test_blake2s) { - static const struct { - const char *msg; - const char *hash; - } tests[] = { - { - "", - "48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49", - }, - { - "000102", - "1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b", - }, - { - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" - "22232425262728292a2b2c2d2e2f3031323334353637", - "2966b3cfae1e44ea996dc5d686cf25fa053fb6f67201b9e46eade85d0ad6b806", - }, - { - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021" - "22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243" - "4445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465" - "666768696a6b6c6d6e6f", - "90a83585717b75f0e9b725e055eeeeb9e7a028ea7e6cbc07b20917ec0363e38c", - }, - }; - - uint8_t key[BLAKE2S_KEY_LENGTH]; - memcpy( - key, - fromhex( - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"), - BLAKE2S_KEY_LENGTH); - - uint8_t digest[BLAKE2S_DIGEST_LENGTH]; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t msg_len = strlen(tests[i].msg) / 2; - blake2s_Key(fromhex(tests[i].msg), msg_len, key, sizeof(key), digest, - sizeof(digest)); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), sizeof(digest)); - - // Test progressive hashing. - size_t part_len = msg_len / 2; - BLAKE2S_CTX ctx; - ck_assert_int_eq(blake2s_InitKey(&ctx, sizeof(digest), key, sizeof(key)), - 0); - ck_assert_int_eq(blake2s_Update(&ctx, fromhex(tests[i].msg), part_len), 0); - ck_assert_int_eq(blake2s_Update(&ctx, NULL, 0), 0); - ck_assert_int_eq(blake2s_Update(&ctx, fromhex(tests[i].msg) + part_len, - msg_len - part_len), - 0); - ck_assert_int_eq(blake2s_Final(&ctx, digest, sizeof(digest)), 0); - ck_assert_mem_eq(digest, fromhex(tests[i].hash), BLAKE2S_DIGEST_LENGTH); - } -} -END_TEST - -#include - -START_TEST(test_chacha_drbg) { - char entropy[] = - "06032cd5eed33f39265f49ecb142c511da9aff2af71203bffaf34a9ca5bd9c0d"; - char nonce[] = "0e66f71edc43e42a45ad3c6fc6cdc4df"; - char reseed[] = - "01920a4e669ed3a85ae8a33b35a74ad7fb2a6bb4cf395ce00334a9c9a5a5d552"; - char expected[] = - "e172c5d18f3e8c77e9f66f9e1c24560772117161a9a0a237ab490b0769ad5d910f5dfb36" - "22edc06c18be0495c52588b200893d90fd80ff2149ead0c45d062c90f5890149c0f9591c" - "41bf4110865129a0fe524f210cca1340bd16f71f57906946cbaaf1fa863897d70d203b5a" - "f9996f756eec08861ee5875f9d915adcddc38719"; - uint8_t result[128]; - uint8_t null_bytes[128] = {0}; - - uint8_t nonce_bytes[16]; - memcpy(nonce_bytes, fromhex(nonce), sizeof(nonce_bytes)); - CHACHA_DRBG_CTX ctx; - chacha_drbg_init(&ctx, fromhex(entropy), strlen(entropy) / 2, nonce_bytes, - strlen(nonce) / 2); - chacha_drbg_reseed(&ctx, fromhex(reseed), strlen(reseed) / 2, NULL, 0); - chacha_drbg_generate(&ctx, result, sizeof(result)); - chacha_drbg_generate(&ctx, result, sizeof(result)); - ck_assert_mem_eq(result, fromhex(expected), sizeof(result)); - - for (size_t i = 0; i <= sizeof(result); ++i) { - chacha_drbg_init(&ctx, fromhex(entropy), strlen(entropy) / 2, nonce_bytes, - strlen(nonce) / 2); - chacha_drbg_reseed(&ctx, fromhex(reseed), strlen(reseed) / 2, NULL, 0); - chacha_drbg_generate(&ctx, result, sizeof(result) - 13); - memset(result, 0, sizeof(result)); - chacha_drbg_generate(&ctx, result, i); - ck_assert_mem_eq(result, fromhex(expected), i); - ck_assert_mem_eq(result + i, null_bytes, sizeof(result) - i); - } -} -END_TEST - -START_TEST(test_pbkdf2_hmac_sha256) { - uint8_t k[64]; - - // test vectors from - // https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors - pbkdf2_hmac_sha256((const uint8_t *)"password", 8, (const uint8_t *)"salt", 4, - 1, k, 32); - ck_assert_mem_eq( - k, - fromhex( - "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"), - 32); - - pbkdf2_hmac_sha256((const uint8_t *)"password", 8, (const uint8_t *)"salt", 4, - 2, k, 32); - ck_assert_mem_eq( - k, - fromhex( - "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"), - 32); - - pbkdf2_hmac_sha256((const uint8_t *)"password", 8, (const uint8_t *)"salt", 4, - 4096, k, 32); - ck_assert_mem_eq( - k, - fromhex( - "c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a"), - 32); - - pbkdf2_hmac_sha256((const uint8_t *)"passwordPASSWORDpassword", 3 * 8, - (const uint8_t *)"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 9 * 4, 4096, k, 40); - ck_assert_mem_eq(k, - fromhex("348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4" - "e2a1fb8dd53e1c635518c7dac47e9"), - 40); - - pbkdf2_hmac_sha256((const uint8_t *)"pass\x00word", 9, - (const uint8_t *)"sa\x00lt", 5, 4096, k, 16); - ck_assert_mem_eq(k, fromhex("89b69d0516f829893c696226650a8687"), 16); - - // test vector from https://tools.ietf.org/html/rfc7914.html#section-11 - pbkdf2_hmac_sha256((const uint8_t *)"passwd", 6, (const uint8_t *)"salt", 4, - 1, k, 64); - ck_assert_mem_eq( - k, - fromhex( - "55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca" - "9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783"), - 64); -} -END_TEST - -// test vectors from -// http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors -START_TEST(test_pbkdf2_hmac_sha512) { - uint8_t k[64]; - - pbkdf2_hmac_sha512((uint8_t *)"password", 8, (const uint8_t *)"salt", 4, 1, k, - 64); - ck_assert_mem_eq( - k, - fromhex( - "867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d" - "470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"), - 64); - - pbkdf2_hmac_sha512((uint8_t *)"password", 8, (const uint8_t *)"salt", 4, 2, k, - 64); - ck_assert_mem_eq( - k, - fromhex( - "e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76c" - "ab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"), - 64); - - pbkdf2_hmac_sha512((uint8_t *)"password", 8, (const uint8_t *)"salt", 4, 4096, - k, 64); - ck_assert_mem_eq( - k, - fromhex( - "d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f" - "30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"), - 64); - - pbkdf2_hmac_sha512((uint8_t *)"passwordPASSWORDpassword", 3 * 8, - (const uint8_t *)"saltSALTsaltSALTsaltSALTsaltSALTsalt", - 9 * 4, 4096, k, 64); - ck_assert_mem_eq( - k, - fromhex( - "8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b" - "59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"), - 64); -} -END_TEST - -START_TEST(test_hmac_drbg) { - char entropy[] = - "06032cd5eed33f39265f49ecb142c511da9aff2af71203bffaf34a9ca5bd9c0d"; - char nonce[] = "0e66f71edc43e42a45ad3c6fc6cdc4df"; - char reseed[] = - "01920a4e669ed3a85ae8a33b35a74ad7fb2a6bb4cf395ce00334a9c9a5a5d552"; - char expected[] = - "76fc79fe9b50beccc991a11b5635783a83536add03c157fb30645e611c2898bb2b1bc215" - "000209208cd506cb28da2a51bdb03826aaf2bd2335d576d519160842e7158ad0949d1a9e" - "c3e66ea1b1a064b005de914eac2e9d4f2d72a8616a80225422918250ff66a41bd2f864a6" - "a38cc5b6499dc43f7f2bd09e1e0f8f5885935124"; - uint8_t result[128]; - uint8_t null_bytes[128] = {0}; - - uint8_t nonce_bytes[16]; - memcpy(nonce_bytes, fromhex(nonce), sizeof(nonce_bytes)); - HMAC_DRBG_CTX ctx; - hmac_drbg_init(&ctx, fromhex(entropy), strlen(entropy) / 2, nonce_bytes, - strlen(nonce) / 2); - hmac_drbg_reseed(&ctx, fromhex(reseed), strlen(reseed) / 2, NULL, 0); - hmac_drbg_generate(&ctx, result, sizeof(result)); - hmac_drbg_generate(&ctx, result, sizeof(result)); - ck_assert_mem_eq(result, fromhex(expected), sizeof(result)); - - for (size_t i = 0; i <= sizeof(result); ++i) { - hmac_drbg_init(&ctx, fromhex(entropy), strlen(entropy) / 2, nonce_bytes, - strlen(nonce) / 2); - hmac_drbg_reseed(&ctx, fromhex(reseed), strlen(reseed) / 2, NULL, 0); - hmac_drbg_generate(&ctx, result, sizeof(result) - 13); - memset(result, 0, sizeof(result)); - hmac_drbg_generate(&ctx, result, i); - ck_assert_mem_eq(result, fromhex(expected), i); - ck_assert_mem_eq(result + i, null_bytes, sizeof(result) - i); - } -} -END_TEST - -START_TEST(test_mnemonic) { - static const char *vectors[] = { - "00000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon about", - "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a698" - "7599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "yellow", - "2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe12" - "96106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607", - "80808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage above", - "d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12" - "eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8", - "ffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", - "ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a1333257291" - "7f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069", - "000000000000000000000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon agent", - "035895f2f481b1b0f01fcf8c289c794660b289981a78f8106447707fdd9666ca06da5a9a" - "565181599b79f53b844d8a71dd9f439c52a3d7b3e8a79c906ac845fa", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal will", - "f2b94508732bcbacbcc020faefecfc89feafa6649a5491b8c952cede496c214a0c7b3c39" - "2d168748f2d4a612bada0753b52a1c7ac53c1e93abd5c6320b9e95dd", - "808080808080808080808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter always", - "107d7c02a5aa6f38c58083ff74f04c607c2d2c0ecc55501dadd72d025b751bc27fe913ff" - "b796f841c49b1d33b610cf0e91d3aa239027f5e99fe4ce9e5088cd65", - "ffffffffffffffffffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "when", - "0cd6e5d827bb62eb8fc1e262254223817fd068a74b5b449cc2f667c3f1f985a76379b433" - "48d952e2265b4cd129090758b3e3c2c49103b5051aac2eaeb890a528", - "0000000000000000000000000000000000000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon art", - "bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d" - "73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal winner thank year wave sausage " - "worth title", - "bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad" - "717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87", - "8080808080808080808080808080808080808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter advice cage absurd " - "amount doctor acoustic bless", - "c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af" - "0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "zoo zoo zoo zoo zoo vote", - "dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a" - "5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad", - "77c2b00716cec7213839159e404db50d", - "jelly better achieve collect unaware mountain thought cargo oxygen act " - "hood bridge", - "b5b6d0127db1a9d2226af0c3346031d77af31e918dba64287a1b44b8ebf63cdd52676f67" - "2a290aae502472cf2d602c051f3e6f18055e84e4c43897fc4e51a6ff", - "b63a9c59a6e641f288ebc103017f1da9f8290b3da6bdef7b", - "renew stay biology evidence goat welcome casual join adapt armor " - "shuffle fault little machine walk stumble urge swap", - "9248d83e06f4cd98debf5b6f010542760df925ce46cf38a1bdb4e4de7d21f5c39366941c" - "69e1bdbf2966e0f6e6dbece898a0e2f0a4c2b3e640953dfe8b7bbdc5", - "3e141609b97933b66a060dcddc71fad1d91677db872031e85f4c015c5e7e8982", - "dignity pass list indicate nasty swamp pool script soccer toe leaf " - "photo multiply desk host tomato cradle drill spread actor shine dismiss " - "champion exotic", - "ff7f3184df8696d8bef94b6c03114dbee0ef89ff938712301d27ed8336ca89ef9635da20" - "af07d4175f2bf5f3de130f39c9d9e8dd0472489c19b1a020a940da67", - "0460ef47585604c5660618db2e6a7e7f", - "afford alter spike radar gate glance object seek swamp infant panel " - "yellow", - "65f93a9f36b6c85cbe634ffc1f99f2b82cbb10b31edc7f087b4f6cb9e976e9faf76ff41f" - "8f27c99afdf38f7a303ba1136ee48a4c1e7fcd3dba7aa876113a36e4", - "72f60ebac5dd8add8d2a25a797102c3ce21bc029c200076f", - "indicate race push merry suffer human cruise dwarf pole review arch " - "keep canvas theme poem divorce alter left", - "3bbf9daa0dfad8229786ace5ddb4e00fa98a044ae4c4975ffd5e094dba9e0bb289349dbe" - "2091761f30f382d4e35c4a670ee8ab50758d2c55881be69e327117ba", - "2c85efc7f24ee4573d2b81a6ec66cee209b2dcbd09d8eddc51e0215b0b68e416", - "clutch control vehicle tonight unusual clog visa ice plunge glimpse " - "recipe series open hour vintage deposit universe tip job dress radar " - "refuse motion taste", - "fe908f96f46668b2d5b37d82f558c77ed0d69dd0e7e043a5b0511c48c2f1064694a956f8" - "6360c93dd04052a8899497ce9e985ebe0c8c52b955e6ae86d4ff4449", - "eaebabb2383351fd31d703840b32e9e2", - "turtle front uncle idea crush write shrug there lottery flower risk " - "shell", - "bdfb76a0759f301b0b899a1e3985227e53b3f51e67e3f2a65363caedf3e32fde42a66c40" - "4f18d7b05818c95ef3ca1e5146646856c461c073169467511680876c", - "7ac45cfe7722ee6c7ba84fbc2d5bd61b45cb2fe5eb65aa78", - "kiss carry display unusual confirm curtain upgrade antique rotate hello " - "void custom frequent obey nut hole price segment", - "ed56ff6c833c07982eb7119a8f48fd363c4a9b1601cd2de736b01045c5eb8ab4f57b0794" - "03485d1c4924f0790dc10a971763337cb9f9c62226f64fff26397c79", - "4fa1a8bc3e6d80ee1316050e862c1812031493212b7ec3f3bb1b08f168cabeef", - "exile ask congress lamp submit jacket era scheme attend cousin alcohol " - "catch course end lucky hurt sentence oven short ball bird grab wing top", - "095ee6f817b4c2cb30a5a797360a81a40ab0f9a4e25ecd672a3f58a0b5ba0687c096a6b1" - "4d2c0deb3bdefce4f61d01ae07417d502429352e27695163f7447a8c", - "18ab19a9f54a9274f03e5209a2ac8a91", - "board flee heavy tunnel powder denial science ski answer betray cargo " - "cat", - "6eff1bb21562918509c73cb990260db07c0ce34ff0e3cc4a8cb3276129fbcb300bddfe00" - "5831350efd633909f476c45c88253276d9fd0df6ef48609e8bb7dca8", - "18a2e1d81b8ecfb2a333adcb0c17a5b9eb76cc5d05db91a4", - "board blade invite damage undo sun mimic interest slam gaze truly " - "inherit resist great inject rocket museum chief", - "f84521c777a13b61564234bf8f8b62b3afce27fc4062b51bb5e62bdfecb23864ee6ecf07" - "c1d5a97c0834307c5c852d8ceb88e7c97923c0a3b496bedd4e5f88a9", - "15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419", - "beyond stage sleep clip because twist token leaf atom beauty genius " - "food business side grid unable middle armed observe pair crouch tonight " - "away coconut", - "b15509eaa2d09d3efd3e006ef42151b30367dc6e3aa5e44caba3fe4d3e352e65101fbdb8" - "6a96776b91946ff06f8eac594dc6ee1d3e82a42dfe1b40fef6bcc3fd", - 0, - 0, - 0, - }; - - const char **a, **b, **c, *m; - uint8_t seed[64]; - - a = vectors; - b = vectors + 1; - c = vectors + 2; - int buf_size = 308; - char buf[buf_size]; - while (*a && *b && *c) { - m = mnemonic_from_data(fromhex(*a), strlen(*a) / 2, buf, buf_size); - ck_assert_str_eq(m, *b); - mnemonic_to_seed(m, "TREZOR", seed, 0); - ck_assert_mem_eq(seed, fromhex(*c), strlen(*c) / 2); -#if USE_BIP39_CACHE - // try second time to check whether caching results work - mnemonic_to_seed(m, "TREZOR", seed, 0); - ck_assert_mem_eq(seed, fromhex(*c), strlen(*c) / 2); -#endif - a += 3; - b += 3; - c += 3; - memzero(buf, buf_size); - } -} -END_TEST - -START_TEST(test_mnemonic_check) { - static const char *vectors_ok[] = { - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon about", - "legal winner thank year wave sausage worth useful legal winner thank " - "yellow", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage above", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon agent", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal will", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter always", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "when", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon art", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal winner thank year wave sausage " - "worth title", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter advice cage absurd " - "amount doctor acoustic bless", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "zoo zoo zoo zoo zoo vote", - "jelly better achieve collect unaware mountain thought cargo oxygen act " - "hood bridge", - "renew stay biology evidence goat welcome casual join adapt armor " - "shuffle fault little machine walk stumble urge swap", - "dignity pass list indicate nasty swamp pool script soccer toe leaf " - "photo multiply desk host tomato cradle drill spread actor shine dismiss " - "champion exotic", - "afford alter spike radar gate glance object seek swamp infant panel " - "yellow", - "indicate race push merry suffer human cruise dwarf pole review arch " - "keep canvas theme poem divorce alter left", - "clutch control vehicle tonight unusual clog visa ice plunge glimpse " - "recipe series open hour vintage deposit universe tip job dress radar " - "refuse motion taste", - "turtle front uncle idea crush write shrug there lottery flower risk " - "shell", - "kiss carry display unusual confirm curtain upgrade antique rotate hello " - "void custom frequent obey nut hole price segment", - "exile ask congress lamp submit jacket era scheme attend cousin alcohol " - "catch course end lucky hurt sentence oven short ball bird grab wing top", - "board flee heavy tunnel powder denial science ski answer betray cargo " - "cat", - "board blade invite damage undo sun mimic interest slam gaze truly " - "inherit resist great inject rocket museum chief", - "beyond stage sleep clip because twist token leaf atom beauty genius " - "food business side grid unable middle armed observe pair crouch tonight " - "away coconut", - 0, - }; - static const char *vectors_fail[] = { - "above abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon about", - "above winner thank year wave sausage worth useful legal winner thank " - "yellow", - "above advice cage absurd amount doctor acoustic avoid letter advice " - "cage above", - "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", - "above abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon agent", - "above winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal will", - "above advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter always", - "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "when", - "above abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon art", - "above winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal winner thank year wave sausage " - "worth title", - "above advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter advice cage absurd " - "amount doctor acoustic bless", - "above zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "zoo zoo zoo zoo zoo zoo vote", - "above better achieve collect unaware mountain thought cargo oxygen act " - "hood bridge", - "above stay biology evidence goat welcome casual join adapt armor " - "shuffle fault little machine walk stumble urge swap", - "above pass list indicate nasty swamp pool script soccer toe leaf photo " - "multiply desk host tomato cradle drill spread actor shine dismiss " - "champion exotic", - "above alter spike radar gate glance object seek swamp infant panel " - "yellow", - "above race push merry suffer human cruise dwarf pole review arch keep " - "canvas theme poem divorce alter left", - "above control vehicle tonight unusual clog visa ice plunge glimpse " - "recipe series open hour vintage deposit universe tip job dress radar " - "refuse motion taste", - "above front uncle idea crush write shrug there lottery flower risk " - "shell", - "above carry display unusual confirm curtain upgrade antique rotate " - "hello void custom frequent obey nut hole price segment", - "above ask congress lamp submit jacket era scheme attend cousin alcohol " - "catch course end lucky hurt sentence oven short ball bird grab wing top", - "above flee heavy tunnel powder denial science ski answer betray cargo " - "cat", - "above blade invite damage undo sun mimic interest slam gaze truly " - "inherit resist great inject rocket museum chief", - "above stage sleep clip because twist token leaf atom beauty genius food " - "business side grid unable middle armed observe pair crouch tonight away " - "coconut", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon about", - "winner thank year wave sausage worth useful legal winner thank yellow", - "advice cage absurd amount doctor acoustic avoid letter advice cage " - "above", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon agent", - "winner thank year wave sausage worth useful legal winner thank year " - "wave sausage worth useful legal will", - "advice cage absurd amount doctor acoustic avoid letter advice cage " - "absurd amount doctor acoustic avoid letter always", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon art", - "winner thank year wave sausage worth useful legal winner thank year " - "wave sausage worth useful legal winner thank year wave sausage worth " - "title", - "advice cage absurd amount doctor acoustic avoid letter advice cage " - "absurd amount doctor acoustic avoid letter advice cage absurd amount " - "doctor acoustic bless", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "zoo zoo zoo zoo vote", - "better achieve collect unaware mountain thought cargo oxygen act hood " - "bridge", - "stay biology evidence goat welcome casual join adapt armor shuffle " - "fault little machine walk stumble urge swap", - "pass list indicate nasty swamp pool script soccer toe leaf photo " - "multiply desk host tomato cradle drill spread actor shine dismiss " - "champion exotic", - "alter spike radar gate glance object seek swamp infant panel yellow", - "race push merry suffer human cruise dwarf pole review arch keep canvas " - "theme poem divorce alter left", - "control vehicle tonight unusual clog visa ice plunge glimpse recipe " - "series open hour vintage deposit universe tip job dress radar refuse " - "motion taste", - "front uncle idea crush write shrug there lottery flower risk shell", - "carry display unusual confirm curtain upgrade antique rotate hello void " - "custom frequent obey nut hole price segment", - "ask congress lamp submit jacket era scheme attend cousin alcohol catch " - "course end lucky hurt sentence oven short ball bird grab wing top", - "flee heavy tunnel powder denial science ski answer betray cargo cat", - "blade invite damage undo sun mimic interest slam gaze truly inherit " - "resist great inject rocket museum chief", - "stage sleep clip because twist token leaf atom beauty genius food " - "business side grid unable middle armed observe pair crouch tonight away " - "coconut", - 0, - }; - - const char **m; - int r; - m = vectors_ok; - while (*m) { - r = mnemonic_check(*m); - ck_assert_int_eq(r, 1); - m++; - } - m = vectors_fail; - while (*m) { - r = mnemonic_check(*m); - ck_assert_int_eq(r, 0); - m++; - } -} -END_TEST - -START_TEST(test_mnemonic_to_bits) { - static const char *vectors[] = { - "00000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon about", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "yellow", - "80808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage above", - "ffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", - "000000000000000000000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon agent", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal will", - "808080808080808080808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter always", - "ffffffffffffffffffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "when", - "0000000000000000000000000000000000000000000000000000000000000000", - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon art", - "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "legal winner thank year wave sausage worth useful legal winner thank " - "year wave sausage worth useful legal winner thank year wave sausage " - "worth title", - "8080808080808080808080808080808080808080808080808080808080808080", - "letter advice cage absurd amount doctor acoustic avoid letter advice " - "cage absurd amount doctor acoustic avoid letter advice cage absurd " - "amount doctor acoustic bless", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo " - "zoo zoo zoo zoo zoo vote", - "77c2b00716cec7213839159e404db50d", - "jelly better achieve collect unaware mountain thought cargo oxygen act " - "hood bridge", - "b63a9c59a6e641f288ebc103017f1da9f8290b3da6bdef7b", - "renew stay biology evidence goat welcome casual join adapt armor " - "shuffle fault little machine walk stumble urge swap", - "3e141609b97933b66a060dcddc71fad1d91677db872031e85f4c015c5e7e8982", - "dignity pass list indicate nasty swamp pool script soccer toe leaf " - "photo multiply desk host tomato cradle drill spread actor shine dismiss " - "champion exotic", - "0460ef47585604c5660618db2e6a7e7f", - "afford alter spike radar gate glance object seek swamp infant panel " - "yellow", - "72f60ebac5dd8add8d2a25a797102c3ce21bc029c200076f", - "indicate race push merry suffer human cruise dwarf pole review arch " - "keep canvas theme poem divorce alter left", - "2c85efc7f24ee4573d2b81a6ec66cee209b2dcbd09d8eddc51e0215b0b68e416", - "clutch control vehicle tonight unusual clog visa ice plunge glimpse " - "recipe series open hour vintage deposit universe tip job dress radar " - "refuse motion taste", - "eaebabb2383351fd31d703840b32e9e2", - "turtle front uncle idea crush write shrug there lottery flower risk " - "shell", - "7ac45cfe7722ee6c7ba84fbc2d5bd61b45cb2fe5eb65aa78", - "kiss carry display unusual confirm curtain upgrade antique rotate hello " - "void custom frequent obey nut hole price segment", - "4fa1a8bc3e6d80ee1316050e862c1812031493212b7ec3f3bb1b08f168cabeef", - "exile ask congress lamp submit jacket era scheme attend cousin alcohol " - "catch course end lucky hurt sentence oven short ball bird grab wing top", - "18ab19a9f54a9274f03e5209a2ac8a91", - "board flee heavy tunnel powder denial science ski answer betray cargo " - "cat", - "18a2e1d81b8ecfb2a333adcb0c17a5b9eb76cc5d05db91a4", - "board blade invite damage undo sun mimic interest slam gaze truly " - "inherit resist great inject rocket museum chief", - "15da872c95a13dd738fbf50e427583ad61f18fd99f628c417a61cf8343c90419", - "beyond stage sleep clip because twist token leaf atom beauty genius " - "food business side grid unable middle armed observe pair crouch tonight " - "away coconut", - 0, - 0, - }; - - const char **a, **b; - uint8_t mnemonic_bits[64]; - - a = vectors; - b = vectors + 1; - while (*a && *b) { - int mnemonic_bits_len = mnemonic_to_bits(*b, mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len % 33, 0); - mnemonic_bits_len = mnemonic_bits_len * 4 / 33; - ck_assert_uint_eq((size_t)mnemonic_bits_len, strlen(*a) / 2); - ck_assert_mem_eq(mnemonic_bits, fromhex(*a), mnemonic_bits_len); - a += 2; - b += 2; - } -} -END_TEST - -START_TEST(test_mnemonic_find_word) { - ck_assert_int_eq(-1, mnemonic_find_word("aaaa")); - ck_assert_int_eq(-1, mnemonic_find_word("zzzz")); - for (int i = 0; i < BIP39_WORD_COUNT; i++) { - const char *word = mnemonic_get_word(i); - int index = mnemonic_find_word(word); - ck_assert_int_eq(i, index); - } -} -END_TEST - -START_TEST(test_slip39_get_word) { - static const struct { - const int index; - const char *expected_word; - } vectors[] = {{573, "member"}, - {0, "academic"}, - {1023, "zero"}, - {245, "drove"}, - {781, "satoshi"}}; - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); i++) { - const char *a = get_word(vectors[i].index); - ck_assert_str_eq(a, vectors[i].expected_word); - } -} -END_TEST - -START_TEST(test_slip39_word_index) { - uint16_t index; - static const struct { - const char *word; - bool expected_result; - uint16_t expected_index; - } vectors[] = {{"academic", true, 0}, - {"zero", true, 1023}, - {"drove", true, 245}, - {"satoshi", true, 781}, - {"member", true, 573}, - // 9999 value is never checked since the word is not in list - {"fakeword", false, 9999}}; - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); i++) { - bool result = word_index(&index, vectors[i].word, strlen(vectors[i].word)); - ck_assert_int_eq(result, vectors[i].expected_result); - if (result) { - ck_assert_uint_eq(index, vectors[i].expected_index); - } - } -} -END_TEST - -START_TEST(test_slip39_word_completion_mask) { - static const struct { - const uint16_t prefix; - const uint16_t expected_mask; - } vectors[] = { - {12, 0xFD}, // 011111101 - {21, 0xF8}, // 011111000 - {75, 0xAD}, // 010101101 - {4, 0x1F7}, // 111110111 - {738, 0x6D}, // 001101101 - {9, 0x6D}, // 001101101 - {0, 0x1FF}, // 111111111 - {10, 0x00}, // 000000000 - {255, 0x00}, // 000000000 - {203, 0x00}, // 000000000 - {9999, 0x00}, // 000000000 - {20000, 0x00}, // 000000000 - }; - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); i++) { - uint16_t mask = slip39_word_completion_mask(vectors[i].prefix); - ck_assert_uint_eq(mask, vectors[i].expected_mask); - } -} -END_TEST - -START_TEST(test_slip39_sequence_to_word) { - static const struct { - const uint16_t prefix; - const char *expected_word; - } vectors[] = { - {7945, "swimming"}, {646, "pipeline"}, {5, "laden"}, {34, "fiber"}, - {62, "ocean"}, {0, "academic"}, {10, NULL}, {255, NULL}, - {203, NULL}, {9999, NULL}, {20000, NULL}, - }; - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); i++) { - const char *word = button_sequence_to_word(vectors[i].prefix); - if (vectors[i].expected_word != NULL) { - ck_assert_str_eq(word, vectors[i].expected_word); - } else { - ck_assert_ptr_eq(word, NULL); - } - } -} -END_TEST - -START_TEST(test_slip39_word_completion) { - const char t9[] = {1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, - 6, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9}; - for (size_t i = 0; i < WORDS_COUNT; ++i) { - const char *word = slip39_wordlist[i]; - uint16_t prefix = t9[word[0] - 'a']; - for (size_t j = 1; j < 4; ++j) { - uint16_t mask = slip39_word_completion_mask(prefix); - uint8_t next = t9[word[j] - 'a']; - ck_assert_uint_ne(mask & (1 << (next - 1)), 0); - prefix = prefix * 10 + next; - } - ck_assert_str_eq(button_sequence_to_word(prefix), word); - } -} -END_TEST - -START_TEST(test_shamir) { -#define SHAMIR_MAX_COUNT 16 - static const struct { - const uint8_t result[SHAMIR_MAX_LEN]; - uint8_t result_index; - const uint8_t share_indices[SHAMIR_MAX_COUNT]; - const uint8_t share_values[SHAMIR_MAX_COUNT][SHAMIR_MAX_LEN]; - uint8_t share_count; - size_t len; - bool ret; - } vectors[] = {{{7, 151, 168, 57, 186, 104, 218, 21, 209, 96, 106, - 152, 252, 35, 210, 208, 43, 47, 13, 21, 142, 122, - 24, 42, 149, 192, 95, 24, 240, 24, 148, 110}, - 0, - {2}, - { - {7, 151, 168, 57, 186, 104, 218, 21, 209, 96, 106, - 152, 252, 35, 210, 208, 43, 47, 13, 21, 142, 122, - 24, 42, 149, 192, 95, 24, 240, 24, 148, 110}, - }, - 1, - 32, - true}, - - {{53}, - 255, - {14, 10, 1, 13, 8, 7, 3, 11, 9, 4, 6, 0, 5, 12, 15, 2}, - { - {114}, - {41}, - {116}, - {67}, - {198}, - {109}, - {232}, - {39}, - {90}, - {241}, - {156}, - {75}, - {46}, - {181}, - {144}, - {175}, - }, - 16, - 1, - true}, - - {{91, 188, 226, 91, 254, 197, 225}, - 1, - {5, 1, 10}, - { - {129, 18, 104, 86, 236, 73, 176}, - {91, 188, 226, 91, 254, 197, 225}, - {69, 53, 151, 204, 224, 37, 19}, - }, - 3, - 7, - true}, - - {{0}, - 1, - {5, 1, 1}, - { - {129, 18, 104, 86, 236, 73, 176}, - {91, 188, 226, 91, 254, 197, 225}, - {69, 53, 151, 204, 224, 37, 19}, - }, - 3, - 7, - false}, - - {{0}, - 255, - {3, 12, 3}, - { - {100, 176, 99, 142, 115, 192, 138}, - {54, 139, 99, 172, 29, 137, 58}, - {216, 119, 222, 40, 87, 25, 147}, - }, - 3, - 7, - false}, - - {{163, 120, 30, 243, 179, 172, 196, 137, 119, 17}, - 3, - {1, 0, 12}, - {{80, 180, 198, 131, 111, 251, 45, 181, 2, 242}, - {121, 9, 79, 98, 132, 164, 9, 165, 19, 230}, - {86, 52, 173, 138, 189, 223, 122, 102, 248, 157}}, - 3, - 10, - true}}; - - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); ++i) { - uint8_t result[SHAMIR_MAX_LEN]; - const uint8_t *share_values[SHAMIR_MAX_COUNT]; - for (size_t j = 0; j < vectors[i].share_count; ++j) { - share_values[j] = vectors[i].share_values[j]; - } - ck_assert_int_eq(shamir_interpolate(result, vectors[i].result_index, - vectors[i].share_indices, share_values, - vectors[i].share_count, vectors[i].len), - vectors[i].ret); - if (vectors[i].ret == true) { - ck_assert_mem_eq(result, vectors[i].result, vectors[i].len); - } - } -} -END_TEST - -START_TEST(test_address) { - char address[36]; - uint8_t pub_key[65]; - - memcpy( - pub_key, - fromhex( - "0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), - 33); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "139MaMHp3Vjo8o4x8N1ZLWEtovLGvBsg6s"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mhfJsQNnrXB3uuYZqvywARTDfuvyjg4RBh"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "MxiimznnxsqMfLKTQBL8Z2PoY9jKpjgkCu"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LMNJqZbe89yrPbm7JVzrcXJf28hZ1rKPaH"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FXK52G2BbzRLaQ651U12o23DU5cEQdhvU6"); - ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "34PyTHn74syS796eTgsyoLfwoBC3cwLn6p"); - - memcpy( - pub_key, - fromhex( - "025b1654a0e78d28810094f6c5a96b8efb8a65668b578f170ac2b1f83bc63ba856"), - 33); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "19Ywfm3witp6C1yBMy4NRYHY2347WCRBfQ"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mp4txp8vXvFLy8So5Y2kFTVrt2epN6YzdP"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "N58JsQYveGueiZDgdnNwe4SSkGTAToutAY"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LTmtvyMmoZ49SpfLY73fhZMJEFRPdyohKh"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "Fdif7fnKHPVddczJF53qt45rgCL51yWN6x"); - ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "35trq6eeuHf6VL9L8pQv46x3vegHnHoTuB"); - - memcpy( - pub_key, - fromhex( - "03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), - 33); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "1FWE2bn3MWhc4QidcF6AvEWpK77sSi2cAP"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mv2BKes2AY8rqXCFKp4Yk9j9B6iaMfWRLN"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "NB5bEFH2GtoAawy8t4Qk8kfj3LWvQs3MhB"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LZjBHp5sSAwfKDQnnP5UCFaaXKV9YheGxQ"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FjfwUWWQv1P9W1jkVM5eNkK8yGPq5XyZZy"); - ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "3456DYaKUWuY6RWWw8Hp5CftHLcQN29h9Y"); - - memcpy( - pub_key, - fromhex( - "03aeb03abeee0f0f8b4f7a5d65ce31f9570cef9f72c2dd8a19b4085a30ab033d48"), - 33); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "1yrZb8dhdevoqpUEGi2tUccUEeiMKeLcs"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mgVoreDcWf6BaxJ5wqgQiPpwLEFRLSr8U8"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "MwZDmEdcd1kVLP4yW62c6zmXCU3mNbveDo"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LLCopoSTnHtz4eWdQQhLAVgNgT1zTi4QBK"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FW9a1Vs1G8LUFSqb7NhWLzQw8PvfwAxmxA"); - ecdsa_get_address_segwit_p2sh(pub_key, 5, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "3DBU4tJ9tkMR9fnmCtjW48kjvseoNLQZXd"); - - memcpy( - pub_key, - fromhex( - "0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054" - "201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), - 65); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "194SZbL75xCCGBbKtMsyWLE5r9s2V6mhVM"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "moaPreR5tydT3J4wbvrMLFSQi9TjPCiZc6"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "N4domEq61LHkniqqABCYirNzaPG5NRU8GH"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LTHPpodwAcSFWzHV4VsGnMHr4NEJajMnKX"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FdEA1W4UeSsjhncSmTsSxr2QWK8z2xGkjc"); - - memcpy( - pub_key, - fromhex( - "0498010f8a687439ff497d3074beb4519754e72c4b6220fb669224749591dde416f3" - "961f8ece18f8689bb32235e436874d2174048b86118a00afbd5a4f33a24f0f"), - 65); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "1A2WfBD4BJFwYHFPc5KgktqtbdJLBuVKc4"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mpYTxEJ2zKhCKPj1KeJ4ap4DTcu39T3uzD"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "N5bsrpi36gMW4pVtsteFyQzoKrhPE7nkxK"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LUFTvPWtFxVzo5wYnDJz2uueoqfcMYiuxH"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FeCE75wRjnwUytGWVBKADQeDFnaHpJ8t3B"); - - memcpy( - pub_key, - fromhex( - "04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2" - "a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf19b77a4d"), - 65); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "19J81hrPnQxg9UGx45ibTieCkb2ttm8CLL"); - ecdsa_get_address(pub_key, 111, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "mop5JkwNbSPvvakZmegyHdrXcadbjLazww"); - ecdsa_get_address(pub_key, 52, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "N4sVDMMNho4Eg1XTKu3AgEo7UpRwq3aNbn"); - ecdsa_get_address(pub_key, 48, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "LTX5GvADs5CjQGy7EDhtjjhxxoQB2Uhicd"); - ecdsa_get_address(pub_key, 36, HASHER_SHA2_RIPEMD, HASHER_GROESTLD_TRUNC, - address, sizeof(address)); - ck_assert_str_eq(address, "FdTqTcamLueDb5J4wBi4vESXQkJrS54H6k"); -} -END_TEST - -START_TEST(test_pubkey_validity) { - uint8_t pub_key[65]; - curve_point pub; - int res; - const ecdsa_curve *curve = &secp256k1; - - memcpy( - pub_key, - fromhex( - "0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), - 33); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "025b1654a0e78d28810094f6c5a96b8efb8a65668b578f170ac2b1f83bc63ba856"), - 33); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), - 33); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "03aeb03abeee0f0f8b4f7a5d65ce31f9570cef9f72c2dd8a19b4085a30ab033d48"), - 33); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054" - "201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), - 65); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "0498010f8a687439ff497d3074beb4519754e72c4b6220fb669224749591dde416f3" - "961f8ece18f8689bb32235e436874d2174048b86118a00afbd5a4f33a24f0f"), - 65); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2" - "a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf19b77a4d"), - 65); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 1); - - memcpy( - pub_key, - fromhex( - "04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2" - "a59ebddbdac9e87b816307a7ed5b826b8f40b92719086238e1bebf00000000"), - 65); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 0); - - memcpy( - pub_key, - fromhex( - "04f80490839af36d13701ec3f9eebdac901b51c362119d74553a3c537faff31b17e2" - "a59ebddbdac9e87b816307a7ed5b8211111111111111111111111111111111"), - 65); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 0); - - memcpy(pub_key, fromhex("00"), 1); - res = ecdsa_read_pubkey(curve, pub_key, &pub); - ck_assert_int_eq(res, 0); -} -END_TEST - -START_TEST(test_pubkey_uncompress) { - uint8_t pub_key[65]; - uint8_t uncompressed[65]; - int res; - const ecdsa_curve *curve = &secp256k1; - - memcpy( - pub_key, - fromhex( - "0226659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), - 33); - res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - uncompressed, - fromhex( - "0426659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37b3" - "cfbad6b39a8ce8cb3a675f53b7b57e120fe067b8035d771fd99e3eba7cf4de"), - 65); - - memcpy( - pub_key, - fromhex( - "03433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7fe"), - 33); - res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - uncompressed, - fromhex( - "04433f246a12e6486a51ff08802228c61cf895175a9b49ed4766ea9a9294a3c7feeb" - "4c25bcb840f720a16e8857a011e6b91e0ab2d03dbb5f9762844bb21a7b8ca7"), - 65); - - memcpy( - pub_key, - fromhex( - "0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054" - "201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), - 65); - res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - uncompressed, - fromhex( - "0496e8f2093f018aff6c2e2da5201ee528e2c8accbf9cac51563d33a7bb74a016054" - "201c025e2a5d96b1629b95194e806c63eb96facaedc733b1a4b70ab3b33e3a"), - 65); - - memcpy(pub_key, fromhex("00"), 1); - res = ecdsa_uncompress_pubkey(curve, pub_key, uncompressed); - ck_assert_int_eq(res, 0); -} -END_TEST - -START_TEST(test_wif) { - uint8_t priv_key[32]; - char wif[53]; - - memcpy( - priv_key, - fromhex( - "1111111111111111111111111111111111111111111111111111111111111111"), - 32); - ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp"); - ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "cN9spWsvaxA8taS7DFMxnk1yJD2gaF2PX1npuTpy3vuZFJdwavaw"); - - memcpy( - priv_key, - fromhex( - "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"), - 32); - ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "L4ezQvyC6QoBhxB4GVs9fAPhUKtbaXYUn8YTqoeXwbevQq4U92vN"); - ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "cV1ysqy3XUVSsPeKeugH2Utm6ZC1EyeArAgvxE73SiJvfa6AJng7"); - - memcpy( - priv_key, - fromhex( - "47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"), - 32); - ecdsa_get_wif(priv_key, 0x80, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "KydbzBtk6uc7M6dXwEgTEH2sphZxSPbmDSz6kUUHi4eUpSQuhEbq"); - ecdsa_get_wif(priv_key, 0xEF, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "cPzbT6tbXyJNWY6oKeVabbXwSvsN6qhTHV8ZrtvoDBJV5BRY1G5Q"); -} -END_TEST - -START_TEST(test_address_decode) { - int res; - uint8_t decode[MAX_ADDR_RAW_SIZE]; - - res = ecdsa_address_decode("1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("00c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); - - res = ecdsa_address_decode("myTPjxggahXyAzuMcYp5JTkbybANyLsYBW", 111, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("6fc4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); - - res = ecdsa_address_decode("NEWoeZ6gh4CGvRgFAoAGh4hBqpxizGT6gZ", 52, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("34c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); - - res = ecdsa_address_decode("LdAPi7uXrLLmeh7u57pzkZc3KovxEDYRJq", 48, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("30c4c5d791fcb4654a1ef5e03fe0ad3d9c598f9827"), 21); - - res = ecdsa_address_decode("1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("0079fbfc3f34e7745860d76137da68f362380c606c"), 21); - - res = ecdsa_address_decode("mrdwvWkma2D6n9mGsbtkazedQQuoksnqJV", 111, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("6f79fbfc3f34e7745860d76137da68f362380c606c"), 21); - - res = ecdsa_address_decode("N7hMq7AmgNsQXaYARrEwybbDGei9mcPNqr", 52, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("3479fbfc3f34e7745860d76137da68f362380c606c"), 21); - - res = ecdsa_address_decode("LWLwtfycqf1uFqypLAug36W4kdgNwrZdNs", 48, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("3079fbfc3f34e7745860d76137da68f362380c606c"), 21); - - // invalid char - res = ecdsa_address_decode("1JwSSubhmg6i000jtyqhUYYH7bZg3Lfy1T", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); - - // invalid address - res = ecdsa_address_decode("1111Subhmg6iPtRjtyqhUYYH7bZg3Lfy1T", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); - - // invalid version - res = ecdsa_address_decode("LWLwtfycqf1uFqypLAug36W4kdgNwrZdNs", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); -} -END_TEST - -START_TEST(test_ecdsa_der) { - static const struct { - const char *r; - const char *s; - const char *der; - } vectors[] = { - { - "9a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8b70771", - "2b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5ede781", - "30450221009a0b7be0d4ed3146ee262b42202841834698bb3ee39c24e7437df208b8" - "b7077102202b79ab1e7736219387dffe8d615bbdba87e11477104b867ef47afed1a5" - "ede781", - }, - { - "6666666666666666666666666666666666666666666666666666666666666666", - "7777777777777777777777777777777777777777777777777777777777777777", - "30440220666666666666666666666666666666666666666666666666666666666666" - "66660220777777777777777777777777777777777777777777777777777777777777" - "7777", - }, - { - "6666666666666666666666666666666666666666666666666666666666666666", - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "30450220666666666666666666666666666666666666666666666666666666666666" - "6666022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - "eeeeee", - }, - { - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "7777777777777777777777777777777777777777777777777777777777777777", - "3045022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - "eeeeee02207777777777777777777777777777777777777777777777777777777777" - "777777", - }, - { - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "3046022100eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - "eeeeee022100ffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffff", - }, - { - "0000000000000000000000000000000000000000000000000000000000000066", - "0000000000000000000000000000000000000000000000000000000000000077", - "3006020166020177", - }, - { - "0000000000000000000000000000000000000000000000000000000000000066", - "00000000000000000000000000000000000000000000000000000000000000ee", - "3007020166020200ee", - }, - { - "00000000000000000000000000000000000000000000000000000000000000ee", - "0000000000000000000000000000000000000000000000000000000000000077", - "3007020200ee020177", - }, - { - "00000000000000000000000000000000000000000000000000000000000000ee", - "00000000000000000000000000000000000000000000000000000000000000ff", - "3008020200ee020200ff", - }, - { - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "3006020100020100", - }, - }; - - uint8_t sig[64]; - uint8_t der[72]; - uint8_t out[72]; - for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); ++i) { - size_t der_len = strlen(vectors[i].der) / 2; - memcpy(der, fromhex(vectors[i].der), der_len); - memcpy(sig, fromhex(vectors[i].r), 32); - memcpy(sig + 32, fromhex(vectors[i].s), 32); - ck_assert_int_eq(ecdsa_sig_to_der(sig, out), der_len); - ck_assert_mem_eq(out, der, der_len); - ck_assert_int_eq(ecdsa_sig_from_der(der, der_len, out), 0); - ck_assert_mem_eq(out, sig, 64); - } -} -END_TEST - -static void test_codepoints_curve(const ecdsa_curve *curve) { - int i, j; - bignum256 a; - curve_point p, p1; - for (i = 0; i < 64; i++) { - for (j = 0; j < 8; j++) { - bn_zero(&a); - a.val[(4 * i) / BN_BITS_PER_LIMB] = (uint32_t)(2 * j + 1) - << (4 * i % BN_BITS_PER_LIMB); - bn_normalize(&a); - // note that this is not a trivial test. We add 64 curve - // points in the table to get that particular curve point. - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point)); - bn_zero(&p.y); // test that point_multiply curve, is not a noop - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &curve->cp[i][j], sizeof(curve_point)); - // mul 2 test. this should catch bugs - bn_lshift(&a); - bn_mod(&a, &curve->order); - p1 = curve->cp[i][j]; - point_double(curve, &p1); - // note that this is not a trivial test. We add 64 curve - // points in the table to get that particular curve point. - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &p1, sizeof(curve_point)); - bn_zero(&p.y); // test that point_multiply curve, is not a noop - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &p1, sizeof(curve_point)); - } - } -} - -START_TEST(test_codepoints_secp256k1) { test_codepoints_curve(&secp256k1); } -END_TEST -START_TEST(test_codepoints_nist256p1) { test_codepoints_curve(&nist256p1); } -END_TEST - -static void test_mult_border_cases_curve(const ecdsa_curve *curve) { - bignum256 a; - curve_point p; - curve_point expected; - bn_zero(&a); // a == 0 - scalar_multiply(curve, &a, &p); - ck_assert(point_is_infinity(&p)); - point_multiply(curve, &a, &p, &p); - ck_assert(point_is_infinity(&p)); - point_multiply(curve, &a, &curve->G, &p); - ck_assert(point_is_infinity(&p)); - - bn_addi(&a, 1); // a == 1 - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point)); - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &curve->G, sizeof(curve_point)); - - bn_subtract(&curve->order, &a, &a); // a == -1 - expected = curve->G; - bn_subtract(&curve->prime, &expected.y, &expected.y); - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); - - bn_subtract(&curve->order, &a, &a); - bn_addi(&a, 1); // a == 2 - expected = curve->G; - point_add(curve, &expected, &expected); - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); - - bn_subtract(&curve->order, &a, &a); // a == -2 - expected = curve->G; - point_add(curve, &expected, &expected); - bn_subtract(&curve->prime, &expected.y, &expected.y); - scalar_multiply(curve, &a, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); - point_multiply(curve, &a, &curve->G, &p); - ck_assert_mem_eq(&p, &expected, sizeof(curve_point)); -} - -START_TEST(test_mult_border_cases_secp256k1) { - test_mult_border_cases_curve(&secp256k1); -} -END_TEST -START_TEST(test_mult_border_cases_nist256p1) { - test_mult_border_cases_curve(&nist256p1); -} -END_TEST - -static void test_scalar_mult_curve(const ecdsa_curve *curve) { - int i; - // get two "random" numbers - bignum256 a = curve->G.x; - bignum256 b = curve->G.y; - curve_point p1, p2, p3; - for (i = 0; i < 1000; i++) { - /* test distributivity: (a + b)G = aG + bG */ - bn_mod(&a, &curve->order); - bn_mod(&b, &curve->order); - scalar_multiply(curve, &a, &p1); - scalar_multiply(curve, &b, &p2); - bn_addmod(&a, &b, &curve->order); - bn_mod(&a, &curve->order); - scalar_multiply(curve, &a, &p3); - point_add(curve, &p1, &p2); - ck_assert_mem_eq(&p2, &p3, sizeof(curve_point)); - // new "random" numbers - a = p3.x; - b = p3.y; - } -} - -START_TEST(test_scalar_mult_secp256k1) { test_scalar_mult_curve(&secp256k1); } -END_TEST -START_TEST(test_scalar_mult_nist256p1) { test_scalar_mult_curve(&nist256p1); } -END_TEST - -static void test_point_mult_curve(const ecdsa_curve *curve) { - int i; - // get two "random" numbers and a "random" point - bignum256 a = curve->G.x; - bignum256 b = curve->G.y; - curve_point p = curve->G; - curve_point p1, p2, p3; - for (i = 0; i < 200; i++) { - /* test distributivity: (a + b)P = aP + bP */ - bn_mod(&a, &curve->order); - bn_mod(&b, &curve->order); - ck_assert_int_eq(point_multiply(curve, &a, &p, &p1), 0); - ck_assert_int_eq(point_multiply(curve, &b, &p, &p2), 0); - bn_addmod(&a, &b, &curve->order); - bn_mod(&a, &curve->order); - ck_assert_int_eq(point_multiply(curve, &a, &p, &p3), 0); - point_add(curve, &p1, &p2); - ck_assert_mem_eq(&p2, &p3, sizeof(curve_point)); - // new "random" numbers and a "random" point - a = p1.x; - b = p1.y; - p = p3; - } -} - -START_TEST(test_point_mult_secp256k1) { test_point_mult_curve(&secp256k1); } -END_TEST -START_TEST(test_point_mult_nist256p1) { test_point_mult_curve(&nist256p1); } -END_TEST - -static void test_scalar_point_mult_curve(const ecdsa_curve *curve) { - int i; - // get two "random" numbers - bignum256 a = curve->G.x; - bignum256 b = curve->G.y; - curve_point p1, p2; - for (i = 0; i < 200; i++) { - /* test commutativity and associativity: - * a(bG) = (ab)G = b(aG) - */ - bn_mod(&a, &curve->order); - bn_mod(&b, &curve->order); - ck_assert_int_eq(scalar_multiply(curve, &a, &p1), 0); - ck_assert_int_eq(point_multiply(curve, &b, &p1, &p1), 0); - - ck_assert_int_eq(scalar_multiply(curve, &b, &p2), 0); - ck_assert_int_eq(point_multiply(curve, &a, &p2, &p2), 0); - - ck_assert_mem_eq(&p1, &p2, sizeof(curve_point)); - - bn_multiply(&a, &b, &curve->order); - bn_mod(&b, &curve->order); - ck_assert_int_eq(scalar_multiply(curve, &b, &p2), 0); - - ck_assert_mem_eq(&p1, &p2, sizeof(curve_point)); - - // new "random" numbers - a = p1.x; - b = p1.y; - } -} - -START_TEST(test_scalar_point_mult_secp256k1) { - test_scalar_point_mult_curve(&secp256k1); -} -END_TEST -START_TEST(test_scalar_point_mult_nist256p1) { - test_scalar_point_mult_curve(&nist256p1); -} -END_TEST - -START_TEST(test_ed25519) { - // test vectors from - // https://github.com/torproject/tor/blob/master/src/test/ed25519_vectors.inc - static const char *vectors[] = { - "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d3" - "6", // secret - "c2247870536a192d142d056abefca68d6193158e7c1a59c1654c954eccaff89" - "4", // public - "d23188eac3773a316d46006fa59c095060be8b1a23582a0dd99002a82a0662bd" - "246d8449e172e04c5f46ac0d1404cebe4aabd8a75a1457aa06cae41f3334f10" - "4", // selfsig - "fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128" - "d", - "1519a3b15816a1aafab0b213892026ebf5c0dc232c58b21088d88cb90e9b940" - "d", - "3a785ac1201c97ee5f6f0d99323960d5f264c7825e61aa7cc81262f15bef75eb" - "4fa5723add9b9d45b12311b6d403eb3ac79ff8e4e631fc3cd51e4ad2185b200" - "b", - "67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0" - "e", - "081faa81992e360ea22c06af1aba096e7a73f1c665bc8b3e4e531c46455fd1d" - "d", - "cf431fd0416bfbd20c9d95ef9b723e2acddffb33900edc72195dea95965d52d8" - "88d30b7b8a677c0bd8ae1417b1e1a0ec6700deadd5d8b54b6689275e04a0450" - "9", - "d51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a" - "6", - "73cfa1189a723aad7966137cbffa35140bb40d7e16eae4c40b79b5f0360dd65" - "a", - "2375380cd72d1a6c642aeddff862be8a5804b916acb72c02d9ed052c1561881a" - "a658a5af856fcd6d43113e42f698cd6687c99efeef7f2ce045824440d26c5d0" - "0", - "5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb43" - "3", - "66c1a77104d86461b6f98f73acf3cd229c80624495d2d74d6fda1e940080a96" - "b", - "2385a472f599ca965bbe4d610e391cdeabeba9c336694b0d6249e551458280be" - "122c2441dd9746a81bbfb9cd619364bab0df37ff4ceb7aefd24469c39d3bc50" - "8", - "eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b8" - "6", - "d21c294db0e64cb2d8976625786ede1d9754186ae8197a64d72f68c792eecc1" - "9", - "e500cd0b8cfff35442f88008d894f3a2fa26ef7d3a0ca5714ae0d3e2d40caae5" - "8ba7cdf69dd126994dad6be536fcda846d89dd8138d1683cc144c8853dce760" - "7", - "4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533" - "d", - "c4d58b4cf85a348ff3d410dd936fa460c4f18da962c01b1963792b9dcc8a6ea" - "6", - "d187b9e334b0050154de10bf69b3e4208a584e1a65015ec28b14bcc252cf84b8" - "baa9c94867daa60f2a82d09ba9652d41e8dde292b624afc8d2c26441b95e3c0" - "e", - "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290" - "b", - "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4" - "a", - "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079" - "c9afe0afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60" - "d", - 0, - 0, - 0, - }; - const char **ssk, **spk, **ssig; - ssk = vectors; - spk = vectors + 1; - ssig = vectors + 2; - ed25519_public_key pk; - ed25519_secret_key sk; - ed25519_signature sig; - while (*ssk && *spk && *ssig) { - memcpy(sk, fromhex(*ssk), 32); - MARK_SECRET_DATA(sk, sizeof(sk)); - - ed25519_publickey(sk, pk); - UNMARK_SECRET_DATA(pk, sizeof(pk)); - ck_assert_mem_eq(pk, fromhex(*spk), 32); - - ed25519_sign(pk, 32, sk, sig); - UNMARK_SECRET_DATA(sig, sizeof(sig)); - ck_assert_mem_eq(sig, fromhex(*ssig), 64); - - ssk += 3; - spk += 3; - ssig += 3; - - UNMARK_SECRET_DATA(sk, sizeof(sk)); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/2.test-sign.dat -START_TEST(test_ed25519_keccak) { - static const struct { - const char *private_key; - const char *public_key; - const char *signature; - size_t length; - const char *data; - } tests[] = { - { - "abf4cf55a2b3f742d7543d9cc17f50447b969e6e06f5ea9195d428ab12b7318d", - "8a558c728c21c126181e5e654b404a45b4f0137ce88177435a69978cc6bec1f4", - "d9cec0cc0e3465fab229f8e1d6db68ab9cc99a18cb0435f70deb6100948576cd5c0a" - "a1feb550bdd8693ef81eb10a556a622db1f9301986827b96716a7134230c", - 41, - "8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e3" - "48e917116690b9", - }, - { - "6aa6dad25d3acb3385d5643293133936cdddd7f7e11818771db1ff2f9d3f9215", - "bbc8cbb43dda3ecf70a555981a351a064493f09658fffe884c6fab2a69c845c6", - "98bca58b075d1748f1c3a7ae18f9341bc18e90d1beb8499e8a654c65d8a0b4fbd2e0" - "84661088d1e5069187a2811996ae31f59463668ef0f8cb0ac46a726e7902", - 49, - "e4a92208a6fc52282b620699191ee6fb9cf04daf48b48fd542c5e43daa9897763a19" - "9aaa4b6f10546109f47ac3564fade0", - }, - { - "8e32bc030a4c53de782ec75ba7d5e25e64a2a072a56e5170b77a4924ef3c32a9", - "72d0e65f1ede79c4af0ba7ec14204e10f0f7ea09f2bc43259cd60ea8c3a087e2", - "ef257d6e73706bb04878875c58aa385385bf439f7040ea8297f7798a0ea30c1c5eff" - "5ddc05443f801849c68e98111ae65d088e726d1d9b7eeca2eb93b677860c", - 40, - "13ed795344c4448a3b256f23665336645a853c5c44dbff6db1b9224b5303b6447fbf" - "8240a2249c55", - }, - { - "c83ce30fcb5b81a51ba58ff827ccbc0142d61c13e2ed39e78e876605da16d8d7", - "3ec8923f9ea5ea14f8aaa7e7c2784653ed8c7de44e352ef9fc1dee81fc3fa1a3", - "0c684e71b35fed4d92b222fc60561db34e0d8afe44bdd958aaf4ee965911bef59912" - "36f3e1bced59fc44030693bcac37f34d29e5ae946669dc326e706e81b804", - 49, - "a2704638434e9f7340f22d08019c4c8e3dbee0df8dd4454a1d70844de11694f4c8ca" - "67fdcb08fed0cec9abb2112b5e5f89", - }, - { - "2da2a0aae0f37235957b51d15843edde348a559692d8fa87b94848459899fc27", - "d73d0b14a9754eec825fcb25ef1cfa9ae3b1370074eda53fc64c22334a26c254", - "6f17f7b21ef9d6907a7ab104559f77d5a2532b557d95edffd6d88c073d87ac00fc83" - "8fc0d05282a0280368092a4bd67e95c20f3e14580be28d8b351968c65e03", - 40, - "d2488e854dbcdfdb2c9d16c8c0b2fdbc0abb6bac991bfe2b14d359a6bc99d66c00fd" - "60d731ae06d0", - }, - { - "0c066261fb1b18ebf2a9bcdeda81eb47d5a3745438b3d0b9d19b75885ad0a154", - "2e5773f0e725024bc0359ce93a44e15d6507e7b160b6c592200385fee4a269cf", - "13b5d2dd1b04f62cc2ec1544fed256423684f2dbca4538ceddda1d15c59dc7196c87" - "840ea303ea30f4f6914a6ec9167841980c1d717f47fd641225068de88507", - 41, - "f15cb706e29fcfbcb324e38cbac62bb355deddb845c142e970f0c029ea4d05e59fd6" - "adf85573cf1775", - }, - { - "ef3d8e22a592f04c3a31aa736e10901757a821d053f1a49a525b4ec91eacdee3", - "72a2b4910a502b30e13a96aba643c59c79328c1ba1462be6f254e817ef157fee", - "95f2437a0210d2d2f125a3c377ed666c0d596cd104185e70204924a182a11a6eb3bd" - "ba4395bbfc3f4e827d38805752657ee52d1ce0f17e70f59bfd4999282509", - 50, - "6c3e4387345740b8d62cf0c9dec48f98c292539431b2b54020d8072d9cb55f0197f7" - "d99ff066afcf9e41ea8b7aea78eb082d", - }, - { - "f7fb79743e9ba957d2a4f1bd95ceb1299552abecaf758bf840d2dc2c09f3e3cb", - "8b7d7531280f76a8abac8293d87508e3953894087112ae01b6ad32485d4e9b67", - "c868ecf31cee783fe8799ac7e6a662431c822967351d8b79687f4ddf608f79a080c4" - "ff9eed4fdee8c99fe1be905f734cae2a172f1cfdb00771625c0695a5260e", - 42, - "55d8e60c307ee533b1af9ff677a2de40a6eace722bcc9eb5d79907b420e533bc06db" - "674dafbd9f43d672", - }, - { - "8cc9a2469a77fad18b44b871b2b6932cd354641d2d1e84403f746c4fff829791", - "aed5da202d4983dac560faf6704dc76ac111616318570e244043e82ed1bbcd2b", - "aee9616db4135150818eaffa3e4503c2d7e9e834847a4c7d0a8856e952761d361a65" - "7104d36950c9b75770ded00d56a96e06f383fa2406bc935dcf51f272300e", - 42, - "d9b8be2f71b83261304e333d6e35563dc3c36c2eb5a23e1461b6e95aa7c6f381f9c3" - "bd39deaa1b6df2f9", - }, - { - "a247abbef0c1affbf021d1aff128888550532fc0edd77bc39f6ef5312317ec47", - "98ededbad1e5ad7a0d5a0cf4fcd7a794eb5c6900a65e7e921884a636f19b131d", - "f8cc02933851432f0c5df0b70f2067f740ccb72de7d6fa1e9a9b0d6de1402b9c6c52" - "5fd848e45aaaac1423b52880ec3474a2f64b38db6fc8e008d95a310e6e0c", - 47, - "4a5f07eb713932532fc3132c96efdc45862fe7a954c1d2ae4640afdf4728fb58c65e" - "8a4ebfe0d53d5797d5146442b9", - }, - { - "163d69079ddad1f16695c47d81c3b72f869b2fdd50e6e47113db6c85051a6ede", - "93fe602642ee5773f4aaf6a3bc21e98e354035225353f419e78e43c3ec36c88a", - "da747fa2cb47aae1effc1e4cfde0e39fa79937948592a712a7665bf948b8311e7f3f" - "80f966301679520d5c2afa3eadd60e061f0d264887500d8d03a17e10fd02", - 41, - "65fe5c1a0214a59644892e5ac4216f09fbb4e191b89bfb63d6540177d25ef9e37148" - "50b8453bd6b2b6", - }, - { - "7b061bf90eb760971b9ec66a96fd6609635ca4b531f33e3c126b9ae6fdb3d491", - "cb392ebb6912df4111efeeb1278160daf9da396e9291b83979a5ac479f7276d2", - "f6eebe86f7ea672e0707ee518e1798d6fbd118c11b2aa30be07d10e3882e3721f203" - "0f9f044b77c3a7a9a2f1feba7e7ce75d1f7f3807a96a764fded35d341d02", - 45, - "a17f5ce39b9ba7b7cf1147e515d6aa84b22fd0e2d8323a91367198fc6c3aff04ebb2" - "1fc2bdbe7bc0364e8040a9", - }, - { - "c9f8ccbf761cec00ab236c52651e76b5f46d90f8936d44d40561ed5c277104de", - "a3192641e343b669ffd43677c2e5cd4efaed174e876141f1d773bd6cfe30d875", - "d44f884ec9eae2e99e74194b5acc769b7aa369aaad359e92ba6ff0fe629af2a9a715" - "6c19b720e7de8c7f03c039563f160948073cab6f99b26a56a8bb1023ba08", - 47, - "3d7e33b0ecead8269966e9dcd192b73eb8a12573fc8a5fdfbe5753541026ef2e49f5" - "280cba9bc2515a049b3a1c1b49", - }, - { - "ebfa409ac6f987df476858dd35310879bf564eeb62984a52115d2e6c24590124", - "7bb1601fe7215f3f4da9c8ab5e804dc58f57ba41b03223f57ec80d9c9a2dd0e1", - "f3e7c1abfcc9f35556cb1e4c5a2b34445177ac188312d9148f1d1d8467ea8411fa3c" - "da031d023034e45bbe407ef7d1b937bfb098266138857d35cb4efe407306", - 52, - "0c37564f718eda683aa6f3e9ab2487620b1a8b5c8f20adb3b2d7550af0d635371e53" - "1f27cebe76a2abcc96de0875bdae987a45ac", - }, - { - "f993f61902b7da332f2bb001baa7accaf764d824eb0cd073315f7ec43158b8fb", - "55fc8e0da1b454cab6ddefb235311db2b01504bf9ac3f71c7e3f3d0d1f09f80b", - "178bd147673c0ca330e45da63cbd1f1811906bd5284bb44e4bb00f7d7163d1f39697" - "5610b6f71c1ae4686466fad4c5e7bb9685099e21ca4f1a45bb3fcf56ae0c", - 42, - "b7dd613bc9c364d9eeb9a52636d72bc881dfc81a836b6537bbb928bff5b738313589" - "47ea9edea1570550", - }, - { - "05188c09c31b4bb63f0d49b47ccc1654c2aba907b8c6c0a82ee403e950169167", - "e096d808dfabe8e44eb74950199dadcd586f9de6b141a0ce85ab94b3d97866eb", - "669491c8eb7cedbbc0252f3eafb048b39a2a37f60ac87837777c72c879ac8b726c39" - "e10060750c2f539102999b71889746111bc5f71ec8c158cc81cf566aef03", - 44, - "bb8e22469d1c7f1d5418563e8781f69eccb56678bd36d8919f358c2778562ff6b50d" - "e916c12d44f1a778a7f3", - }, - { - "eabe57e1a916ebbffa4ba7abc7f23e83d4deb1338816cc1784d7495d92e98d0b", - "3aad275642f48a46ed1032f3de9f4053e0fd35cf217e065d2e4579c3683932f7", - "b2e9dac2c83942ca374f29c8eff5a30c377c3db3c1c645e593e524d17484e7705b11" - "f79573e2d63495fc3ce3bf216a209f0cb7bea477ae0f8bd297f193af8805", - 44, - "3f2c2d6682ee597f2a92d7e560ac53d5623550311a4939d68adfb904045ed8d215a9" - "fdb757a2368ea4d89f5f", - }, - { - "fef7b893b4b517fab68ca12d36b603bc00826bf3c9b31a05149642ae10bb3f55", - "b3fb891868708dfa5da5b9b5234058767ab42c117f12c3228c02a1976d1c0f83", - "6243e289314b7c7587802909a9be6173a916b36f9de1e164954dfe5d1ebd57c869a7" - "9552d770e13b51855502be6b15e7be42a3675298a81284df58e609b06503", - 47, - "38c69f884045cdbeebe4478fdbd1ccc6cf00a08d8a3120c74e7167d3a2e26a67a043" - "b8e5bd198f7b0ce0358cef7cf9", - }, - { - "16228bec9b724300a37e88e535fc1c58548d34d7148b57c226f2b3af974c1822", - "3c92423a8360c9a5d9a093730d72831bec4601dcadfe84de19fc8c8f91fc3d4b", - "6aebfa9a4294ec888d54bcb517fcb6821e4c16d2708a2afe701f431a28149ff4f139" - "f9d16a52a63f1f91baf4c8dea37710c73f25c263a8035a39cc118ad0280f", - 44, - "a3d7b122cd4431b396b20d8cc46cc73ed4a5253a44a76fc83db62cdc845a2bf7081d" - "069a857955a161cccf84", - }, - { - "2dc3f5f0a0bc32c6632534e1e8f27e59cbe0bf7617d31aff98098e974c828be7", - "b998a416edc28ded988dcacb1caf2bd96c87354b0d1eeccb6980e54a3104f21f", - "76a2ddfc4bea48c47e0c82bcbfee28a37c61ec626af39a468e643e0ef9f6533056a5" - "a0b44e64d614ba3c641a40e5b003a99463445ae2c3c8e1e9882092d74b07", - 42, - "bdae276d738b9758ea3d322b54fd12fe82b767e8d817d8ef3d41f78705748e28d15e" - "9c506962a1b85901", - }, - }; - - ed25519_secret_key private_key; - ed25519_public_key public_key; - ed25519_signature signature; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - nem_private_key(tests[i].private_key, private_key); - MARK_SECRET_DATA(private_key, sizeof(private_key)); - - ed25519_publickey_keccak(private_key, public_key); - UNMARK_SECRET_DATA(public_key, sizeof(public_key)); - ck_assert_mem_eq(public_key, fromhex(tests[i].public_key), 32); - - ed25519_sign_keccak(fromhex(tests[i].data), tests[i].length, private_key, - signature); - UNMARK_SECRET_DATA(signature, sizeof(signature)); - ck_assert_mem_eq(signature, fromhex(tests[i].signature), 64); - - UNMARK_SECRET_DATA(private_key, sizeof(private_key)); - } -} -END_TEST - -START_TEST(test_ed25519_cosi) { - const int MAXN = 10; - ed25519_secret_key keys[MAXN]; - ed25519_public_key pubkeys[MAXN]; - ed25519_secret_key nonces[MAXN]; - ed25519_public_key Rs[MAXN]; - ed25519_cosi_signature sigs[MAXN]; - uint8_t msg[32]; - rfc6979_state rng; - int res; - - init_rfc6979( - fromhex( - "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36"), - fromhex( - "26659c1cf7321c178c07437150639ff0c5b7679c7ea195253ed9abda2e081a37"), - NULL, &rng); - - for (int N = 1; N < 11; N++) { - ed25519_public_key pk; - ed25519_public_key R; - ed25519_signature sig; - /* phase 0: create priv/pubkeys and combine pubkeys */ - for (int j = 0; j < N; j++) { - generate_rfc6979(keys[j], &rng); - ed25519_publickey(keys[j], pubkeys[j]); - } - res = ed25519_cosi_combine_publickeys(pk, pubkeys, N); - ck_assert_int_eq(res, 0); - - generate_rfc6979(msg, &rng); - - /* phase 1: create nonces, commitments (R values) and combine commitments */ - for (int j = 0; j < N; j++) { - generate_rfc6979(nonces[j], &rng); - ed25519_publickey(nonces[j], Rs[j]); - } - res = ed25519_cosi_combine_publickeys(R, Rs, N); - ck_assert_int_eq(res, 0); - - MARK_SECRET_DATA(keys, sizeof(keys)); - /* phase 2: sign and combine signatures */ - for (int j = 0; j < N; j++) { - ed25519_cosi_sign(msg, sizeof(msg), keys[j], nonces[j], R, pk, sigs[j]); - } - UNMARK_SECRET_DATA(sigs, sizeof(sigs)); - - ed25519_cosi_combine_signatures(sig, R, sigs, N); - - /* check signature */ - res = ed25519_sign_open(msg, sizeof(msg), pk, sig); - ck_assert_int_eq(res, 0); - - UNMARK_SECRET_DATA(keys, sizeof(keys)); - } -} -END_TEST - -START_TEST(test_ed25519_modl_add) { - char tests[][3][65] = { - { - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - }, - - {"eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a", - "0000000000000000000000000000000000000000000000000000000000000000", - "eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a", - "eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a"}, - - {"0100000000000000000000000000000000000000000000000000000000000000", - "0200000000000000000000000000000000000000000000000000000000000000", - "0300000000000000000000000000000000000000000000000000000000000000"}, - - {"e3d3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0a00000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000"}, - - {"f7bb3bf42b3e58e2edd06f173fc7bfbc7aaf657217946b75648447101136aa08", - "3c16b013109cc27ff39805be2abe04ba4cd6a8526a1d3023047693e950936c06", - "33d2eb073cda1a62e16975d56985c476c7850ec581b19b9868fadaf961c9160f"}, - }; - - unsigned char buff[32]; - bignum256modm a = {0}, b = {0}, c = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i][0]), 32); - expand256_modm(b, fromhex(tests[i][1]), 32); - add256_modm(c, a, b); - contract256_modm(buff, c); - ck_assert_mem_eq(buff, fromhex(tests[i][2]), 32); - } -} -END_TEST - -START_TEST(test_ed25519_modl_neg) { - char tests[][2][65] = { - {"05d0f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "e803000000000000000000000000000000000000000000000000000000000000"}, - - {"4d4df45c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "a086010000000000000000000000000000000000000000000000000000000000"}, - - {"25958944a1b7d4073975ca48996a1d740d0ed98ceec366760c5358da681e9608", - "c83e6c1879ab3d509d272d5a458fc1a0f2f12673113c9989f3aca72597e16907"}, - - {"0100000000000000000000000000000000000000000000000000000000000000", - "ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010"}, - - {"ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0100000000000000000000000000000000000000000000000000000000000000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000"}, - }; - - unsigned char buff[32]; - bignum256modm a = {0}, b = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i][0]), 32); - neg256_modm(b, a); - contract256_modm((unsigned char *)buff, b); - ck_assert_mem_eq(buff, fromhex(tests[i][1]), 32); - } -} -END_TEST - -START_TEST(test_ed25519_modl_sub) { - char tests[][3][65] = { - { - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - }, - - {"eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a", - "53732f60e51ee3a48d21d2d526548c0dadbb79a185678fd7710613d0e76aad0c", - "8859d1d1deee0767a4ff1b72a3e0d0327573c69bbff5fc07cfa61414e6ef3b0e"}, - - {"9d91e26dbe7a14fdca9f5b20d13e828dc8c1ffe03fe90136a6bba507436ce500", - "9ca406705ccce65eb8cbf63706d3df09fcc67216c0dc3990270731aacbb2e607", - "eec0d15a7c1140f6e8705c8ba9658198ccfa8cca7f0cc8a57eb4745d77b9fe08"}, - - {"eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a", - "0000000000000000000000000000000000000000000000000000000000000000", - "eef80ad5a9aad8b35b84f6a4eb3a7e2b222f403d455d8cdf40ad27e4cd5ae90a"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "39897fbebf137a34572b014b0638ac0186d17874e3cc142ebdfe24327f5b8509", - "b44a769e5a4f98237f71f657d8c132137a2e878b1c33ebd14201dbcd80a47a06"}, - - {"0200000000000000000000000000000000000000000000000000000000000000", - "e3d3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0c00000000000000000000000000000000000000000000000000000000000000"}, - - {"e3d3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0800000000000000000000000000000000000000000000000000000000000000", - "dbd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010"}, - - {"ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0000000000000000000000000000000000000000000000000000000000000000", - "ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010", - "0100000000000000000000000000000000000000000000000000000000000000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000010", - "edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "ffffff3f00000000000000000000000000000000000000000000000000000010", - "eed3f51c1a631258d69cf7a2def9de1400000000000000000000000000000000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000010"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "e75f947f11d49d25a137fac8757538a980dec23811235cf63c48ee6bc6e4ed03", - "067461dd088f74323565fdd96884a66b7f213dc7eedca309c3b71194391b120c"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "ecd3f55c1a631258d69cf7a2def9de140000000000000000000000000000ff0f", - "0100000000000000000000000000000000000000000000000000000000000100"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "edd3f55c1a631258d69cf7a2def9de140000000000000000000004000000ff0f", - "0000000000000000000000000000000000000000000000000000fcffffff0000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "edd3f55c1a631258d69cf7a2def9de150000c0ffffffffffffffffffffffff0f", - "000000000000000000000000000000ffffff3f00000000000000000000000000"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "edd3f55c1a631258d69cf7a2def9de1200000000000000000000000000000110", - "edd3f55c1a631258d69cf7a2def9de160000000000000000000000000000ff0f"}, - - {"0000000000000000000000000000000000000000000000000000000000000000", - "edd3f55c1a631258d69cf7a2def9de1300000000000000000000000000000010", - "0000000000000000000000000000000100000000000000000000000000000000"}, - }; - - unsigned char buff[32]; - bignum256modm a = {0}, b = {0}, c = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i][0]), 32); - expand256_modm(b, fromhex(tests[i][1]), 32); - sub256_modm(c, a, b); - contract256_modm(buff, c); - ck_assert_mem_eq(buff, fromhex(tests[i][2]), 32); - } -} -END_TEST - -#if USE_MONERO - -START_TEST(test_ge25519_double_scalarmult_vartime2) { - char tests[][5][65] = { - {"c537208ed4985e66e9f7a35c9a69448a732ba93960bbbd2823604f7ae9e3ed08", - "365233e5af17c8888d5ce508787464f4642e91a6212b1b104e6c3769535601b1", - "a84f871580176708b4ac21843cb197ad96e8456034442b50859c83c5807b9901", - "f022360d1bce903fa3ac58ae42f997328b31f477b8d576a9f6d26fc1d08f14ea", - "bf25da82c6b210948b823ae48422a2dcd205d3c94842e68ac27e5cbeaa704ebc"}, - {"4abfabc0dda33588a98127ef3bfe724fed286395fe15932e898b5621661ea102", - "e5fd79d03f5df8edfc8def663dcb96bba6cadf857f2ae6f6f51f52f8d14079b7", - "4754c286b23e3c1b50054fe3937ebdc4ec01b28da5d05fb6111798b42fc5bf06", - "b7e7f9464b98de5bfcf6b02c1b7053cc359df407ad59d943523c6d2ee773b2f6", - "6d7d5f729bfa4882dbff8e477cd2b4c354ba347f10e7b178a24f3f16a4e0fec6"}, - {"19f2af4d04cb8181f1fe0d01fe9bb9ecc476c67ceb4a9830dae1bc7fe5fe3b04", - "d3c462f4f30991220387a1fbbd1ba1dc45ce058c70a8fb1475071e7b4f0fc463", - "577790e025c1fd2014db44a8d613c4e2ab1f248a4a6d14b5d39cbbafd7b20f06", - "1376c6837f131f6cd1a45b1056297d2314aa0ac5f7d581d2d878261eb3259b4d", - "ce790760ada87dd819b59e4f6765d836d346567ec34f02bbcfcae0585c1d758f"}, - {"cf209db9e7ee85f1e648924ec97edd86b56a833b25707519d4fbe64fd50e150a", - "804f0806087dc665a26230ed5fd44c062980ee182a6bd7dbdb33df018c983778", - "30d3c448cb08935309753b3051366f52328ca1d9a0b63c72b989edee0da32b0e", - "98e3c973a7e85b5eab8111521c66ca584bed5597f060ab0c6b5cdeece502ac48", - "2646276e1305396a1b2473690066011a39789570a09e10ce1a013c8f32cd5bea"}, - {"b0a0ffeea67b656c4c585ba58ff528a6f45d2f915db98e4a14a8ff17f27fc105", - "4fabe16274f6af526ee053028485db6acd13804e02dcdddccc4183a319ab9e1c", - "1e140bb08a936ac6b7437644ca0769f3c165c7aa5501d49f064a0346179b4008", - "68fc1be64fb68761542a655b8dbebf50980f1fbc1845528df8d8a06bf89a1495", - "7dab86994b47014efe38493fc2b62ffcead806da6e0d73c992db8cb5618a19dc"}, - {"0fee422c2294b06ca83bc3704384dffc580e7ff5921881e51a755e5f9b80af03", - "4359a663ead3f7ffc3a0ead5c3c2bde348017e7bfa620f21759c32e469a16dfe", - "532066e3eec29334fffc37b17178dfbac3bee15f7845f01449ddbaf5e57a7b0c", - "32e46c2fb99402837631c8175db31cdd334c145f922be9070d62e6d9c493c3ea", - "8c7b7d2d61cdb648960434d894787426a76d16dd46949c7aa4b85dcf1054b4d5"}, - {"3a712d5b7ceb5257dcf6e6bb06548de6ef3deba5d456cd91fc305a12b46b5d01", - "5e7da62e3ec42cf3e554639dd4d2006754ee6839b720cadba94a26b73b1665ee", - "2a518ecab17a2d9dde219c775bcf4f2306b190bef2dea34fb65b8e4dccc13405", - "3b5d66a4dfb068923b3bc21cc8b40b59e12f845e0b85a86d394db0fa310bf185", - "2ec17f1cc0be093e9cdb741a991c0f417230dea275cd7babdad35e949e250521"}, - {"5f815f2d65cef584c5e5d48b2d3d3e4cae310d70b328f88af6e9f63c52b4c90d", - "8a539a8c6b2339922b31cf4bc064f1fedeb3912fd89585d79dfcff2a60aee295", - "385f7132b72db04146b9e472736b32adfca29556b4775a743c18e2bfab939007", - "884aaf96d625968ddb2582922a87abca131272884c47f6b86890ebccf0a79d5b", - "a7afdaf24fe8472d8b89e95c3ce4a40bdf700af7cedee44ed3aa5ccca09839bd"}, - {"a043340d072df16a8ab5135f8c1d601bff14c5aba01b9212b886ad71fe164506", - "52f6de5fa0fae32d4020a54d395319509d6b92092a0bf849fb34e73f8e71fc99", - "37d7472d360164da29e6dcb8f9796976022571c5df4ddf7e30e9a579ba13d509", - "8c369e3fd5b1112e4437b1f09e987acca4966f2f8c5227eb15ace240a2c64cc7", - "fc795fe7baff5c3ac98366e6882f25874ea2b0a649d16f139e5c54ea47042a1e"}, - {"97a3268db03fa184c8cba020bf216fc789292fa9615a28962385b86870ffd70f", - "a76c215587022bb9252ece4c5afeb0e65b820834cd41ac76e6c062d3eea75dc6", - "8310271017154cbddf7005e24eb9a9a86777b3f42fa5e35095eafaac4eb24802", - "b822665c2406083c851ecaa91ea67aa740c057e7679b5755cee60a6c63f17fd6", - "f83e2444527056eba595d49bde40b2e8da76d2c145f203331d26e94560993fbc"}, - {"edaad13efad39f26298e86ba8d06a46e59122232c9529bd22f2f656595421e00", - "f38e56a79f5159eb3b581dea537ec12c9c6fac381b2cf6073e27fc621197cb62", - "1eea79485954b5958d9d5478f86133af1088806d923535d483b115ab23099a0f", - "b32c5e57d57db7a349f4ab845f12a5045c52b4a7a5bce7fd54a1a255b0118185", - "3bfb42b4ffd2c6cfc8cce9e4187dc6fbcaecd9d44a4ca1d2b68b97410bb25b81"}, - {"b15eaebe0fc83cb11d755a6f067b710204d4a59101078d8286454b652879080a", - "4667a2e61d9df1690f5c33c4168e480f7e26d2f0998168ebdc0a39712946f741", - "125379da1a88bfdf5b928f8795d3ea5415ef8c3d9106eb16934c3842873fd707", - "8727a692a25e38b1afa98e3dd5bf88815dec6d9810c1fd8a31b56b3de8630f1e", - "540883dde400b909e9955a276c20e13d99252ebe542750b8bfbbe5c3b87c51e3"}, - {"e42bdd4af3121bea644a90a76b2007615621ee5b842b9a74c4334ac309478706", - "6dc4ab715d3bb975ebfd0f08e2b6f3f39922d0121ae518a8f8d2952ea2fe0b5d", - "0285059b0095c97f4a50d43c7726c64c2830bf2b55dfa934ebba7ad71064dc07", - "f738c0a3cee31fd8f438f282aa6c823fccfa49cf7b5c86fbf9d56bf0394b6d8d", - "a1bd106841e55010decd95a170a1d0dd11780fd00759819e024b15ea3a83b4be"}, - {"5077c30fd08795dbdc7a230c050ca07e316fa3b040fd0dac45907036ab25dd0e", - "96f0897f000e49e2439a9166cab40ebc125a31b82851f0541516c19683e7bfaf", - "2b67d79a2efdc6451508e7f3c97c4a61b135bb839c02338bb444ef8208dd970b", - "7ef4cd7cdc29c2b88ccff49898b5d0b7be5993f93c5772476feec9dc57d7b6e3", - "62449b901b25760c964704b28efc184fbd5947e83851ebaf3bbfeb6f742f679f"}, - {"a4b3ce6928fe8f77d13e65ae255eee8310ab0d75bca47028b4570f0511a66006", - "4e9da8d77ee337e3bcce3730ccfff2121728641c7bb4fdeb2155890f998af09a", - "ff01a5075569d0f6afee45da065c72f5841f46ce772917ef75eb4d230473580f", - "36ca32da8a10f4083f5a60ee21868d9d448548d49c56f19cbe6005005e34f816", - "99df362a3b762cc1cbb70bc5ddff3c8614ed306037013102e387ef32e7f2494f"}, - {"074aa76351dceb752aa09887d9aca932d5821f58eedb4988fd64d8548e3f2c09", - "588b4552f3b98b2f77aee2ef8cc72f88acd424c4373b3e3626393ed2ea24cbda", - "f2d9175633f2e3c661b01172b4b4176850cd5b3098ffb0f927e0a5e19c1c8a02", - "a6c34868736b2517fd46f57a4e30805ffd475e44a8b1413078f43d9cb3d6edd6", - "46e1e7d7b1e939dd5c07c8363af01f4f9dae7c3d10f237ff9776ddc4a1903771"}, - {"ae1c8abd5a542208ee0aa93ffbf0b8e5a957edc4854fe2b48153c5c85bbf3d08", - "5e084b9541a70bd5bef400be6525c5a806a5b7fb12de38b07dcd35a22c57edbe", - "d95f179a215fb322d81720bf3aecde78d6d676d6f941455d0e0920f1e3619707", - "c3e5d43221824de51d8f95705de69c80a2440c0483ca88549d639aee15390429", - "df9fea42d3b5ac243244abb4ca4948a69493becddc5d5906f9a4e4c5645b0eab"}, - {"2f1c5adedb7341dc7638bafacc6024bd48255197ea2347fc05714b9341dd4403", - "47f55263001542f796c928988f641f59d0cd43294fc8d8616b184bfe9dddf368", - "aa5e884e782ab116151c609680c37b1a49b52f23bce5e2ebf28dd8532510d20b", - "ef2d6d97ad1a18edfce6450c1e70295b2c7ed2bc749ea8b438a523eae078d1f3", - "2396a355c6ae8e2ac24da8f55a674c96fc4cc69b38678b2bd8eb91b96f462bca"}, - {"0242e14105ced74e91cf4d4dcd22a9c09279018901d2fb8319eb54c2a1c4900a", - "fcb62a6c520d31fa46efeb4a1000330653b3402f575c2ddc0c688f527e7b97be", - "73a7e2e0602e5345f040dedc4db67f6d8e37c5fca3bbb124fa43963d76dbbb08", - "152bf4a3305c656f77e292b1256cc470da4d3f6efc3667199db4316d7f431174", - "c21ba2080013dfb225e06378d9ac27df623df552526cfddbf9e71bb1d4705dd9"}, - {"07fab4fc7b02fbcf868ffb0326cf60425fef2af1fbad83a8926cc62c2b5dff05", - "29ff12c5e052eb5829e8334e0e082c5edde1f293d2b4ed499a79bcca20e48010", - "97afb3dd9167877b432a23503aad1ab39188b9be07cc124ceb3fbdbd8d8b890a", - "ed121240a2f4591eeedbfd880305ccd17e522673900b03279fb66e73583514ae", - "b27f209e88ce5701766565e231e8123adb1df9c9f1dc461920acbc2b38d9f6d7"}, - }; - - unsigned char buff[32]; - bignum256modm a = {0}, b = {0}; - ge25519 A, B, R; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i][0]), 32); - expand256_modm(b, fromhex(tests[i][2]), 32); - ge25519_unpack_negative_vartime(&A, fromhex(tests[i][1])); - curve25519_neg(A.x, A.x); - curve25519_neg(A.t, A.t); - ge25519_unpack_negative_vartime(&B, fromhex(tests[i][3])); - curve25519_neg(B.x, B.x); - curve25519_neg(B.t, B.t); - ge25519_double_scalarmult_vartime2(&R, &A, a, &B, b); - ge25519_pack(buff, &R); - ck_assert_mem_eq(buff, fromhex(tests[i][4]), 32); - } -} -END_TEST - -#endif - -static void test_bip32_ecdh_init_node(HDNode *node, const char *seed_str, - const char *curve_name) { - hdnode_from_seed((const uint8_t *)seed_str, strlen(seed_str), curve_name, - node); - ck_assert_int_eq(hdnode_fill_public_key(node), 0); - if (node->public_key[0] == 1) { - node->public_key[0] = 0x40; // Curve25519 public keys start with 0x40 byte - } -} - -static void test_bip32_ecdh(const char *curve_name, int expected_key_size, - const uint8_t *expected_key) { - int res, key_size; - HDNode alice, bob; - uint8_t session_key1[expected_key_size], session_key2[expected_key_size]; - - test_bip32_ecdh_init_node(&alice, "Alice", curve_name); - test_bip32_ecdh_init_node(&bob, "Bob", curve_name); - - // Generate shared key from Alice's secret key and Bob's public key - res = hdnode_get_shared_key(&alice, bob.public_key, session_key1, &key_size); - ck_assert_int_eq(res, 0); - ck_assert_int_eq(key_size, expected_key_size); - ck_assert_mem_eq(session_key1, expected_key, key_size); - - // Generate shared key from Bob's secret key and Alice's public key - res = hdnode_get_shared_key(&bob, alice.public_key, session_key2, &key_size); - ck_assert_int_eq(res, 0); - ck_assert_int_eq(key_size, expected_key_size); - ck_assert_mem_eq(session_key2, expected_key, key_size); -} - -START_TEST(test_bip32_ecdh_nist256p1) { - test_bip32_ecdh( - NIST256P1_NAME, 65, - fromhex( - "044aa56f917323f071148cd29aa423f6bee96e7fe87f914d0b91a0f95388c6631646" - "ea92e882773d7b0b1bec356b842c8559a1377673d3965fb931c8fe51e64873")); -} -END_TEST - -START_TEST(test_bip32_ecdh_curve25519) { - test_bip32_ecdh(CURVE25519_NAME, 33, - fromhex("04f34e35516325bb0d4a58507096c444a05ba13524ccf66910f1" - "1ce96c62224169")); -} -END_TEST - -START_TEST(test_bip32_ecdh_errors) { - HDNode node; - const uint8_t peer_public_key[65] = {0}; // invalid public key - uint8_t session_key[65]; - int res, key_size = 0; - - test_bip32_ecdh_init_node(&node, "Seed", ED25519_NAME); - res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(key_size, 0); - - test_bip32_ecdh_init_node(&node, "Seed", CURVE25519_NAME); - res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(key_size, 0); - - test_bip32_ecdh_init_node(&node, "Seed", NIST256P1_NAME); - res = hdnode_get_shared_key(&node, peer_public_key, session_key, &key_size); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(key_size, 0); -} -END_TEST - -START_TEST(test_output_script) { - static const char *vectors[] = { - "76A914010966776006953D5567439E5E39F86A0D273BEE88AC", - "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", - "A914010966776006953D5567439E5E39F86A0D273BEE87", - "31nVrspaydBz8aMpxH9WkS2DuhgqS1fCuG", - "0014010966776006953D5567439E5E39F86A0D273BEE", - "p2xtZoXeX5X8BP8JfFhQK2nD3emtjch7UeFm", - "00200102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20", - "7XhPD7te3C6CVKnJWUhrTJbFTwudhHqfrjpS59AS6sMzL4RYFiCNg", - 0, - 0, - }; - const char **scr, **adr; - scr = vectors; - adr = vectors + 1; - char address[60]; - while (*scr && *adr) { - int r = - script_output_to_address(fromhex(*scr), strlen(*scr) / 2, address, 60); - ck_assert_uint_eq((size_t)r, strlen(*adr) + 1); - ck_assert_str_eq(address, *adr); - scr += 2; - adr += 2; - } -} -END_TEST - -#if USE_ETHEREUM - -START_TEST(test_ethereum_pubkeyhash) { - uint8_t pubkeyhash[20]; - int res; - HDNode node; - - // init m - hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, - SECP256K1_NAME, &node); - - // [Chain m] - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("056db290f8ba3250ca64a45d16284d04bc6f5fbf"), 20); - - // [Chain m/0'] - hdnode_private_ckd_prime(&node, 0); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("bf6e48966d0dcf553b53e7b56cb2e0e72dca9e19"), 20); - - // [Chain m/0'/1] - hdnode_private_ckd(&node, 1); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("29379f45f515c494483298225d1b347f73d1babf"), 20); - - // [Chain m/0'/1/2'] - hdnode_private_ckd_prime(&node, 2); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("d8e85fbbb4b3b3c71c4e63a5580d0c12fb4d2f71"), 20); - - // [Chain m/0'/1/2'/2] - hdnode_private_ckd(&node, 2); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("1d3462d2319ac0bfc1a52e177a9d372492752130"), 20); - - // [Chain m/0'/1/2'/2/1000000000] - hdnode_private_ckd(&node, 1000000000); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("73659c60270d326c06ac204f1a9c63f889a3d14b"), 20); - - // init m - hdnode_from_seed( - fromhex( - "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c" - "999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), - 64, SECP256K1_NAME, &node); - - // [Chain m] - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("6dd2a6f3b05fd15d901fbeec61b87a34bdcfb843"), 20); - - // [Chain m/0] - hdnode_private_ckd(&node, 0); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("abbcd4471a0b6e76a2f6fdc44008fe53831e208e"), 20); - - // [Chain m/0/2147483647'] - hdnode_private_ckd_prime(&node, 2147483647); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("40ef2cef1b2588ae862e7a511162ec7ff33c30fd"), 20); - - // [Chain m/0/2147483647'/1] - hdnode_private_ckd(&node, 1); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("3f2e8905488f795ebc84a39560d133971ccf9b50"), 20); - - // [Chain m/0/2147483647'/1/2147483646'] - hdnode_private_ckd_prime(&node, 2147483646); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("a5016fdf975f767e4e6f355c7a82efa69bf42ea7"), 20); - - // [Chain m/0/2147483647'/1/2147483646'/2] - hdnode_private_ckd(&node, 2); - res = hdnode_get_ethereum_pubkeyhash(&node, pubkeyhash); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(pubkeyhash, - fromhex("8ff2a9f7e7917804e8c8ec150d931d9c5a6fbc50"), 20); -} -END_TEST - -START_TEST(test_ethereum_address) { - static const char *vectors[] = {"0x52908400098527886E0F7030069857D2E4169EE7", - "0x8617E340B3D01FA5F11F306F4090FD50E238070D", - "0xde709f2102306220921060314715629080e2fb77", - "0x27b1fdb04752bbc536007a920d24acb045561c26", - "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", - "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", - "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", - "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", - "0x5A4EAB120fB44eb6684E5e32785702FF45ea344D", - "0x5be4BDC48CeF65dbCbCaD5218B1A7D37F58A0741", - "0xa7dD84573f5ffF821baf2205745f768F8edCDD58", - "0x027a49d11d118c0060746F1990273FcB8c2fC196", - "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", - 0}; - uint8_t addr[20]; - char address[43]; - const char **vec = vectors; - while (*vec) { - memcpy(addr, fromhex(*vec + 2), 20); - ethereum_address_checksum(addr, address, false, 0); - ck_assert_str_eq(address, *vec); - vec++; - } -} -END_TEST - -// test vectors from -// https://github.com/rsksmart/RSKIPs/blob/master/IPs/RSKIP60.md -START_TEST(test_rsk_address) { - uint8_t addr[20]; - char address[43]; - - static const char *rskip60_chain30[] = { - "0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD", - "0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359", - "0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB", - "0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB", 0}; - const char **vec = rskip60_chain30; - while (*vec) { - memcpy(addr, fromhex(*vec + 2), 20); - ethereum_address_checksum(addr, address, true, 30); - ck_assert_str_eq(address, *vec); - vec++; - } - - static const char *rskip60_chain31[] = { - "0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd", - "0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359", - "0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB", - "0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB", 0}; - vec = rskip60_chain31; - while (*vec) { - memcpy(addr, fromhex(*vec + 2), 20); - ethereum_address_checksum(addr, address, true, 31); - ck_assert_str_eq(address, *vec); - vec++; - } -} -END_TEST - -#endif - -#if USE_NEM -// test vectors from -// https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/1.test-keys.dat -START_TEST(test_nem_address) { - static const struct { - const char *private_key; - const char *public_key; - const char *address; - } tests[] = { - { - "575dbb3062267eff57c970a336ebbc8fbcfe12c5bd3ed7bc11eb0481d7704ced", - "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", - "NDD2CT6LQLIYQ56KIXI3ENTM6EK3D44P5JFXJ4R4", - }, - { - "5b0e3fa5d3b49a79022d7c1e121ba1cbbf4db5821f47ab8c708ef88defc29bfe", - "96eb2a145211b1b7ab5f0d4b14f8abc8d695c7aee31a3cfc2d4881313c68eea3", - "NABHFGE5ORQD3LE4O6B7JUFN47ECOFBFASC3SCAC", - }, - { - "738ba9bb9110aea8f15caa353aca5653b4bdfca1db9f34d0efed2ce1325aeeda", - "2d8425e4ca2d8926346c7a7ca39826acd881a8639e81bd68820409c6e30d142a", - "NAVOZX4HDVOAR4W6K4WJHWPD3MOFU27DFHC7KZOZ", - }, - { - "e8bf9bc0f35c12d8c8bf94dd3a8b5b4034f1063948e3cc5304e55e31aa4b95a6", - "4feed486777ed38e44c489c7c4e93a830e4c4a907fa19a174e630ef0f6ed0409", - "NBZ6JK5YOCU6UPSSZ5D3G27UHAPHTY5HDQMGE6TT", - }, - { - "c325ea529674396db5675939e7988883d59a5fc17a28ca977e3ba85370232a83", - "83ee32e4e145024d29bca54f71fa335a98b3e68283f1a3099c4d4ae113b53e54", - "NCQW2P5DNZ5BBXQVGS367DQ4AHC3RXOEVGRCLY6V", - }, - { - "a811cb7a80a7227ae61f6da536534ee3c2744e3c7e4b85f3e0df3c6a9c5613df", - "6d34c04f3a0e42f0c3c6f50e475ae018cfa2f56df58c481ad4300424a6270cbb", - "NA5IG3XFXZHIPJ5QLKX2FBJPEZYPMBPPK2ZRC3EH", - }, - { - "9c66de1ec77f4dfaaebdf9c8bc599ca7e8e6f0bc71390ffee2c9dd3f3619242a", - "a8fefd72a3b833dc7c7ed7d57ed86906dac22f88f1f4331873eb2da3152a3e77", - "NAABHVFJDBM74XMJJ52R7QN2MTTG2ZUXPQS62QZ7", - }, - { - "c56bc16ecf727878c15e24f4ae68569600ac7b251218a44ef50ce54175776edc", - "c92f761e6d83d20068fd46fe4bd5b97f4c6ba05d23180679b718d1f3e4fb066e", - "NCLK3OLMHR3F2E3KSBUIZ4K5PNWUDN37MLSJBJZP", - }, - { - "9dd73599283882fa1561ddfc9be5830b5dd453c90465d3fe5eeb646a3606374e", - "eaf16a4833e59370a04ccd5c63395058de34877b48c17174c71db5ed37b537ed", - "ND3AHW4VTI5R5QE5V44KIGPRU5FBJ5AFUCJXOY5H", - }, - { - "d9639dc6f49dad02a42fd8c217f1b1b4f8ce31ccd770388b645e639c72ff24fa", - "0f74a2f537cd9c986df018994dde75bdeee05e35eb9fe27adf506ca8475064f7", - "NCTZ4YAP43ONK3UYTASQVNDMBO24ZHJE65F3QPYE", - }, - { - "efc1992cd50b70ca55ac12c07aa5d026a8b78ffe28a7dbffc9228b26e02c38c1", - "2ebff201255f6cf948c78f528658b99a7c13ac791942fa22d59af610558111f5", - "NDQ2TMCMXBSFPZQPE2YKH6XLC24HD6LUMN6Z4GIC", - }, - { - "143a815e92e43f3ed1a921ee48cd143931b88b7c3d8e1e981f743c2a5be3c5ba", - "419ed11d48730e4ae2c93f0ea4df853b8d578713a36dab227517cf965861af4e", - "NA32IDDW2C53BDSBJNFL3Z6UU3J5CJZJMCZDXCF4", - }, - { - "bc1a082f5ac6fdd3a83ade211e5986ac0551bad6c7da96727ec744e5df963e2a", - "a160e6f9112233a7ce94202ed7a4443e1dac444b5095f9fecbb965fba3f92cac", - "NADUCEQLC3FTGB25GTA5HOUTB53CBVQNVOIP7NTJ", - }, - { - "4e47b4c6f4c7886e49ec109c61f4af5cfbb1637283218941d55a7f9fe1053f72", - "fbb91b16df828e21a9802980a44fc757c588bc1382a4cea429d6fa2ae0333f56", - "NBAF3BFLLPWH33MYE6VUPP5T6DQBZBKIDEQKZQOE", - }, - { - "efc4389da48ce49f85365cfa578c746530e9eac42db1b64ec346119b1becd347", - "2232f24dda0f2ded3ecd831210d4e8521a096b50cadd5a34f3f7083374e1ec12", - "NBOGTK2I2ATOGGD7ZFJHROG5MWL7XCKAUKSWIVSA", - }, - { - "bdba57c78ca7da16a3360efd13f06276284db8c40351de7fcd38ba0c35ac754d", - "c334c6c0dad5aaa2a0d0fb4c6032cb6a0edd96bf61125b5ea9062d5a00ee0eee", - "NCLERTEFYXKLK7RA4MVACEFMXMK3P7QMWTM7FBW2", - }, - { - "20694c1ec3c4a311bcdb29ed2edc428f6d4f9a4c429ad6a5bf3222084e35695f", - "518c4de412efa93de06a55947d11f697639443916ec8fcf04ebc3e6d17d0bd93", - "NB5V4BPIJHXVONO7UGMJDPFARMFA73BOBNOOYCOV", - }, - { - "e0d4f3760ac107b33c22c2cac24ab2f520b282684f5f66a4212ff95d926323ce", - "b3d16f4ead9de67c290144da535a0ed2504b03c05e5f1ceb8c7863762f786857", - "NC4PBAO5TPCAVQKBVOC4F6DMZP3CFSQBU46PSKBD", - }, - { - "efa9afc617412093c9c7a7c211a5332dd556f941e1a88c494ec860608610eea2", - "7e7716e4cebceb731d6f1fd28676f34888e9a0000fcfa1471db1c616c2ddf559", - "NCFW2LPXIWLBWAQN2QVIWEOD7IVDO3HQBD2OU56K", - }, - { - "d98499b3db61944684ce06a91735af4e14105338473fcf6ebe2b0bcada3dfd21", - "114171230ad6f8522a000cdc73fbc5c733b30bb71f2b146ccbdf34499f79a810", - "NCUKWDY3J3THKQHAKOK5ALF6ANJQABZHCH7VN6DP", - }, - }; - - HDNode node; - ed25519_secret_key private_key; - uint8_t chain_code[32]; - char address[41]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - nem_private_key(tests[i].private_key, private_key); - - ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, - ED25519_KECCAK_NAME, &node)); - - ck_assert(hdnode_get_nem_address(&node, NEM_NETWORK_MAINNET, address)); - ck_assert_str_eq(address, tests[i].address); - - ck_assert_mem_eq(&node.public_key[1], fromhex(tests[i].public_key), 32); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/3.test-derive.dat -START_TEST(test_nem_derive) { - static const struct { - const char *salt; - const char *private_key; - const char *public_key; - const char *mul; - const char *shared_key; - } tests[] = { - { - "ad63ac08f9afc85eb0bf4f8881ca6eaa0215924c87aa2f137d56109bb76c6f98", - "e8857f8e488d4e6d4b71bcd44bb4cff49208c32651e1f6500c3b58cafeb8def6", - "9d8e5f200b05a2638fb084a375408cabd6d5989590d96e3eea5f2cb34668178e", - "a8352060ba5718745ee4d78b9df564e0fbe13f50d50ab15a8dd524159d81d18b", - "990a5f611c65fbcde735378bdec38e1039c5466503511e8c645bbe42795c752b", - }, - { - "96104f0a28f9cca40901c066cd435134662a3b053eb6c8df80ee0d05dc941963", - "d7f67b5f52cbcd1a1367e0376a8eb1012b634acfcf35e8322bae8b22bb9e8dea", - "9735c92d150dcee0ade5a8d1822f46a4db22c9cda25f33773ae856fe374a3e8a", - "ea14d521d83328dba70982d42094300585818cc2da609fdb1f73bb32235576ff", - "b498aa21d4ba4879ea9fd4225e93bacc760dcd9c119f8f38ab0716457d1a6f85", - }, - { - "d8f94a0bbb1de80aea17aab42e2ffb982e73fc49b649a318479e951e392d8728", - "d026ddb445fb3bbf3020e4b55ed7b5f9b7fd1278c34978ca1a6ed6b358dadbae", - "d19e6beca3b26b9d1abc127835ebeb7a6c19c33dec8ec472e1c4d458202f4ec8", - "0d561f54728ad837ae108ec66c2ece2bb3b26041d3ee9b77fdc6d36d9ebfb2e3", - "d012afe3d1d932304e613c91545bf571cf2c7281d6cafa8e81393a551f675540", - }, - { - "3f8c969678a8abdbfb76866a142c284a6f01636c1c1607947436e0d2c30d5245", - "c522b38c391d1c3fa539cc58802bc66ac34bb3c73accd7f41b47f539bedcd016", - "ea5b6a0053237f7712b1d2347c447d3e83e0f2191762d07e1f53f8eb7f2dfeaa", - "23cccd3b63a9456e4425098b6df36f28c8999461a85e4b2b0c8d8f53c62c9ea9", - "7e27efa50eed1c2ac51a12089cbab6a192624709c7330c016d5bc9af146584c1", - }, - { - "e66415c58b981c7f1f2b8f45a42149e9144616ff6de49ff83d97000ac6f6f992", - "2f1b82be8e65d610a4e588f000a89a733a9de98ffc1ac9d55e138b3b0a855da0", - "65aeda1b47f66c978a4a41d4dcdfbd8eab5cdeb135695c2b0c28f54417b1486d", - "43e5b0a5cc8146c03ac63e6f8cf3d8825a9ca1ed53ea4a88304af4ddf5461b33", - "bb4ab31c334e55d378937978c90bb33779b23cd5ef4c68342a394f4ec8fa1ada", - }, - { - "58487c9818c9d28ddf97cb09c13331941e05d0b62bf4c35ee368de80b552e4d1", - "f3869b68183b2e4341307653e8f659bd7cd20e37ea5c00f5a9e203a8fa92359a", - "c7e4153a18b4162f5c1f60e1ba483264aa5bb3f4889dca45b434fcd30b9cf56f", - "5ae9408ab3156b8828c3e639730bd5e5db93d7afe2cee3fcda98079316c5bb3a", - "0224d85ae8f17bfe127ec24b8960b7639a0dbde9c8c39a0575b939448687bb14", - }, - { - "ad66f3b654844e53d6fb3568134fae75672ba63868c113659d3ca58c2c39d24f", - "d38f2ef8dfdc7224fef596130c3f4ff68ac83d3f932a56ee908061466ac28572", - "d0c79d0340dc66f0a895ce5ad60a933cf6be659569096fb9d4b81e5d32292372", - "1ea22db4708ed585ab541a4c70c3069f8e2c0c1faa188ddade3efaa53c8329f6", - "886a7187246934aedf2794748deadfe038c9fd7e78d4b7be76c5a651440ac843", - }, - { - "eed48604eab279c6ad8128aa83483a3da0928271a4cae1a5745671284e1fb89d", - "e2342a8450fc0adfa0ea2fbd0b1d28f100f0a3a905a3da29de34d1353afa7df7", - "d2dbe07e0f2dbc3dbb01c70092e3c4247d12827ddcd8d76534fd740a65c30de2", - "4c4b30eb6a2bfa17312f5729b4212cb51c2eee8fbfaea82a0e957ca68f4f6a30", - "dcae613ac5641ff9d4c3ca58632245f93b0b8657fe4d48bac7b062cc53dd21ad", - }, - { - "f35b315287b268c0d0b386fb5b31810f65e1c4497cffae24527f69a3abac3884", - "049016230dbef7a14a439e5ab2f6d12e78cb8df127db4e0c312673b3c361e350", - "1b3b1925a8a535cd7d78725d25298f45bba8ca3dee2cdaabf14241c9b51b37c4", - "04c9685dae1f8eb72a6438f24a87dc83a56d79c9024edf7e01aa1ae34656f29e", - "b48469d0428c223b93cd1fe34bb2cafd3fb78a8fa15f98f89f1ac9c0ce7c9001", - }, - { - "d6cf082c5d9a96e756a94a2e27703138580a7c7c1af505c96c3abf7ab6802e1d", - "67cd02b0b8b0adcf6fdd4d4d64a1f4193ced68bb8605d0ec941a62011326d140", - "a842d5127c93a435e4672dcadd9fccbfd0e9208c79c5404848b298597eccdbdb", - "d5c6bd6d81b99659d0bafe91025b6ecf73b16c6b07931cf44718b13f00fde3f7", - "8aa160795b587f4be53aa35d26e9b618b4cd6ec765b523bc908e53c258ca8fd4", - }, - { - "dda32c91c95527a645b00dd05d13f0b98ed612a726ce5f5221431430b7660944", - "eba026f92a8ffb5e95060a22e15d597fe838a99a0b2bbcb423c933b6bc718c50", - "7dbaf9c313a1ff9128c54d6cd740c7d0cc46bca588e7910d438dd619ca4fd69a", - "5bb20a145de83ba27a0c261e1f54bfd7dcea61888fc2eebbe6166876f7b000b8", - "3a96f152ad8bf355cccb307e4a40108aa17f8e925522a2b5bb0b3f1e1a262914", - }, - { - "63c500acbd4ff747f7dadde7d3286482894ac4d7fe68f396712bca29879aa65c", - "9663cd3c2030a5fe4a3ea3cc9a1d182b3a63ade68616aaeb4caf40b495f6f227", - "b1e7d9070ac820d986d839b79f7aa594dcf708473529dad87af8682cc6197374", - "1f7a97584d8db9f395b9ac4447de4b33c5c1f5020187cd4996286a49b07eb8a7", - "4d2a974ec12dcf525b5654d31053460850c3092648b7e15598b7131d2930e9fb", - }, - { - "91f340961029398cc8bcd906388044a6801d24328efdf919d8ed0c609862a073", - "45a588500d00142e2226231c01fd11ac6f842ab6a85872418f5b6a1999f8bd98", - "397233c96069b6f4a57d6e93f759fa327222eaef71fc981afa673b248206df3f", - "062123ef9782e3893f7b2e1d557b4ecce92b9f9aa8577e76380f228b75152f84", - "235848cb04230a16d8978aa7c19fe7fbff3ebe29389ea6eb24fb8bc3cb50afc6", - }, - { - "46120b4da6ba4eb54fb65213cfef99b812c86f7c42a1de1107f8e8c12c0c3b6b", - "cc19a97a99ad71ce348bcf831c0218e6a1f0a8d52186cabe6298b56f24e640f9", - "c54631bb62f0f9d86b3301fcb2a671621e655e578c95504af5f78da83f7fec4f", - "ab73cc20c75260ff3a7cefea8039291d4d15114a07a9250375628cca32225bb6", - "70040a360b6a2dfa881272ef4fa6616e2e8fcc45194fa2a21a1eef1160271cd5", - }, - { - "f0a69ded09f1d731ab9561d0c3a40b7ef30bcb2bf60f92beccd8734e2441403d", - "ea732822a381c46a7ac9999bf5ef85e16b7460b26aaf6c1a1c6ffa8c8c82c923", - "110decbff79c382b1e60af4259564a3c473087792350b24fca98ae9a74ba9dd9", - "81bdee95aecdcf821a9d682f79056f1abdcf1245d2f3b55244447881a283e0d4", - "1bc29d4470ccf97d4e35e8d3cd4b12e3ebf2cb0a82425d35984aeedf7ad0f6f9", - }, - { - "e79cf4536fb1547e57626c0f1a87f71a396fdfb985b00731c0c2876a00645eda", - "04213fc02b59c372e3e7f53faa71a2f73b31064102cb6fc8b68432ba7cdf7eb4", - "ca1c750aaed53bc30dac07d0696ed86bcd7cdbbcbd3d15bb90d90cb5c6117bac", - "c68cd0872a42a3a64e8a229ef7fcad3d722047d5af966f7dda4d4e32d0d57203", - "bfdd3d07563d966d95afe4b8abea4b567265fceea8c4ecddb0946256c33e07b2", - }, - { - "81a40db4cddaf076e0206bd2b0fa7470a72cc456bad34aa3a0469a4859f286be", - "52156799fd86cc63345cdbffd65ef4f5f8df0ffd9906a40af5f41d269bbcff5d", - "54d61aa0b0b17a87f1376fe89cd8cd6b314827c1f1b9e5e7b20e7a7eee2a8335", - "4553fb2cab8555068c32f86ceb692bbf1c2beeaf21627ef1b1be57344b52eea8", - "55096b6710ade3bbe38702458ee13faa10c24413261bc076f17675dcbf2c4ee6", - }, - { - "d28e4a9e6832a3a4dad014a2bf1f666f01093cbba8b9ad4d1dcad3ea10cb42b9", - "8ca134404c8fa199b0c72cb53cfa0adcf196dfa560fb521017cce5cbace3ba59", - "3a6c39a1e5f9f550f1debedd9a0bc84210cce5f9834797db8f14122bf5817e45", - "eb632ca818b4f659630226a339a3ce536b31c8e1e686fea8da3760e8abc20b8e", - "9fbb3fbaf1cd54ee0cd90685f59b082545983f1f662ef701332379306a6ad546", - }, - { - "f9c4bfad9e2a3d98c44c12734881a6f217d6c9523cc210772fad1297993454b4", - "b85960fcadda8d0a0960559b6b7818a0d8d4574b4e928b17c9b498fa9ffab4ef", - "6a1d0ef23ce0b40a7077ecb7b7264945054e3bdb58ee25e1b0ee8b3e19dbfcdc", - "bb145dddcb75074a6a03249fca1aa7d6fa9549e3ed965f138ca5e7071b7878f2", - "87d3faea4a98e41009eb8625611ea0fc12094c295af540c126c14a0f55afa76e", - }, - { - "656df4789a369d220aceb7b318517787d27004ecccedea019d623bcb2d79f5ff", - "acf83e30afb2a5066728ec5d93564c08abe5e68e3a2a2ff953bdcf4d44f9da06", - "bdda65efe56d7890286aada1452f62f85ba157d0b4621ba641de15d8d1c9e331", - "958beef5dc6babc6de383c32ad7dd3a6d6eb8bb3236ed5558eec0f9eb31e5458", - "6f6d4ee36d9d76e462c9635adfbb6073134a276cfc7cb86762004ec47197afa0", - }, - }; - - HDNode node; - ed25519_secret_key private_key; - uint8_t chain_code[32]; - ed25519_public_key public_key, mul; - uint8_t shared_key[SHA3_256_DIGEST_LENGTH]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - nem_private_key(tests[i].private_key, private_key); - - ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, - ED25519_KECCAK_NAME, &node)); - memcpy(public_key, fromhex(tests[i].public_key), 32); - - ck_assert(hdnode_get_nem_shared_key( - &node, public_key, fromhex(tests[i].salt), mul, shared_key)); - ck_assert_mem_eq(mul, fromhex(tests[i].mul), sizeof(mul)); - ck_assert_mem_eq(shared_key, fromhex(tests[i].shared_key), - sizeof(shared_key)); - } -} -END_TEST - -// test vectors from -// https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/4.test-cipher.dat -START_TEST(test_nem_cipher) { - static const struct { - const char *private_key; - const char *public_key; - const char *salt; - const char *iv; - const char *input; - const char *output; - } tests[] = { - { - "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", - "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", - "83616c67f076d356fd1288a6e0fd7a60488ba312a3adf0088b1b33c7655c3e6a", - "a73ff5c32f8fd055b09775817a6a3f95", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "70815da779b1b954d7a7f00c16940e9917a0412a06a444b539bf147603eef87f", - }, - { - "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", - "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", - "703ce0b1d276b10eef35672df03234385a903460db18ba9d4e05b3ad31abb284", - "91246c2d5493867c4fa3e78f85963677", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "564b2f40d42c0efc1bd6f057115a5abd1564cae36d7ccacf5d825d38401aa894", - }, - { - "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", - "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", - "b22e8e8e7373ac31ca7f0f6eb8b93130aba5266772a658593f3a11792e7e8d92", - "9f8e33d82374dad6aac0e3dbe7aea704", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "7cab88d00a3fc656002eccbbd966e1d5d14a3090d92cf502cdbf843515625dcf", - }, - { - "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", - "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", - "af646c54cd153dffe453b60efbceeb85c1e95a414ea0036c4da94afb3366f5d9", - "6acdf8e01acc8074ddc807281b6af888", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "aa70543a485b63a4dd141bb7fd78019092ac6fad731e914280a287c7467bae1a", - }, - { - "3140f94c79f249787d1ec75a97a885980eb8f0a7d9b7aa03e7200296e422b2b6", - "57a70eb553a7b3fd621f0dba6abf51312ea2e2a2a1e19d0305516730f4bcbd21", - "d9c0d386636c8a024935c024589f9cd39e820a16485b14951e690a967830e269", - "f2e9f18aeb374965f54d2f4e31189a8f", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "33d97c216ea6498dfddabf94c2e2403d73efc495e9b284d9d90aaff840217d25", - }, - { - "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", - "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", - "06c227baac1ae3b0b1dc583f4850f13f9ba5d53be4a98fa5c3ea16217847530d", - "3735123e78c44895df6ea33fa57e9a72", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "d5b5d66ba8cee0eb7ecf95b143fa77a46d6de13749e12eff40f5a7e649167ccb", - }, - { - "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", - "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", - "92f55ba5bc6fc2f23e3eedc299357c71518e36ba2447a4da7a9dfe9dfeb107b5", - "1cbc4982e53e370052af97ab088fa942", - "86ddb9e713a8ebf67a51830eff03b837e147c20d75e67b2a54aa29e98c", - "d48ef1ef526d805656cfc932aff259eadb17aa3391dde1877a722cba31d935b2", - }, - { - "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", - "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", - "10f15a39ba49866292a43b7781bc71ca8bbd4889f1616461caf056bcb91b0158", - "c40d531d92bfee969dce91417346c892", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "e6d75afdb542785669b42198577c5b358d95397d71ec6f5835dca46d332cc08dbf73" - "ea790b7bcb169a65719c0d55054c", - }, - { - "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", - "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", - "9c01ed42b219b3bbe1a43ae9d7af5c1dd09363baacfdba8f4d03d1046915e26e", - "059a35d5f83249e632790015ed6518b9", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "5ef11aadff2eccee8b712dab968fa842eb770818ec0e6663ed242ea8b6bbc1c66d62" - "85ee5b5f03d55dfee382fb4fa25d", - }, - { - "d5c0762ecea2cd6b5c56751b58debcb32713aab348f4a59c493e38beb3244f3a", - "66a35941d615b5644d19c2a602c363ada8b1a8a0dac3682623852dcab4afac04", - "bc1067e2a7415ea45ff1ca9894338c591ff15f2e57ae2789ae31b9d5bea0f11e", - "8c73f0d6613898daeefa3cf8b0686d37", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "6d220213b1878cd40a458f2a1e6e3b48040455fdf504dcd857f4f2ca1ad642e3a44f" - "c401d04e339d302f66a9fad3d919", - }, - { - "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", - "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", - "cf4a21cb790552165827b678ca9695fcaf77566d382325112ff79483455de667", - "bfbf5482e06f55b88bdd9e053b7eee6e", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "1198a78c29c215d5c450f7b8513ead253160bc9fde80d9cc8e6bee2efe9713cf5a09" - "d6293c41033271c9e8c22036a28b", - }, - { - "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", - "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", - "eba5eae8aef79114082c3e70baef95bb02edf13b3897e8be7a70272962ef8838", - "af9a56da3da18e2fbd2948a16332532b", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "1062ab5fbbdee9042ad35bdadfd3047c0a2127fe0f001da1be1b0582185edfc9687b" - "e8d68f85795833bb04af9cedd3bb", - }, - { - "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", - "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", - "518f8dfd0c138f1ffb4ea8029db15441d70abd893c3d767dc668f23ba7770e27", - "42d28307974a1b2a2d921d270cfce03b", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "005e49fb7c5da540a84b034c853fc9f78a6b901ea495aed0c2abd4f08f1a96f9ffef" - "c6a57f1ac09e0aea95ca0f03ffd8", - }, - { - "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", - "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", - "582fdf58b53715c26e10ba809e8f2ab70502e5a3d4e9a81100b7227732ab0bbc", - "91f2aad3189bb2edc93bc891e73911ba", - "49de3cd5890e0cd0559f143807ff688ff62789b7236a332b7d7255ec0b4e73e6b3a" - "4", - "821a69cb16c57f0cb866e590b38069e35faec3ae18f158bb067db83a11237d29ab1e" - "6b868b3147236a0958f15c2e2167", - }, - { - "9ef87ba8aa2e664bdfdb978b98bc30fb61773d9298e7b8c72911683eeff41921", - "441e76d7e53be0a967181076a842f69c20fd8c0e3f0ce3aa421b490b059fe094", - "a415b4c006118fb72fc37b2746ef288e23ac45c8ff7ade5f368a31557b6ac93a", - "2b7c5f75606c0b8106c6489ea5657a9e", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "2781d5ee8ef1cb1596f8902b33dfae5045f84a987ca58173af5830dbce386062", - }, - { - "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", - "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", - "47e73ec362ea82d3a7c5d55532ad51d2cdf5316b981b2b2bd542b0efa027e8ea", - "b2193f59030c8d05a7d3577b7f64dd33", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "3f43912db8dd6672b9996e5272e18c4b88fec9d7e8372db9c5f4709a4af1d86f", - }, - { - "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", - "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", - "aaa006c57b6d1e402650577fe9787d8d285f4bacd7c01f998be49c766f8860c7", - "130304ddb9adc8870cf56bcae9487b7f", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "878cc7d8c0ef8dac0182a78eedc8080a402f59d8062a6b4ca8f4a74f3c3b3de7", - }, - { - "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", - "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", - "28dc7ccd6c2a939eef64b8be7b9ae248295e7fcd8471c22fa2f98733fea97611", - "cb13890d3a11bc0a7433738263006710", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "e74ded846bebfa912fa1720e4c1415e6e5df7e7a1a7fedb5665d68f1763209a4", - }, - { - "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", - "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", - "79974fa2cad95154d0873902c153ccc3e7d54b17f2eeb3f29b6344cad9365a9a", - "22123357979d20f44cc8eb0263d84e0e", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "eb14dec7b8b64d81a2ee4db07b0adf144d4f79a519bbf332b823583fa2d45405", - }, - { - "ed93c5a101ab53382ceee4f7e6b5aa112621d3bb9d18891509b1834ede235bcc", - "5a5e14c633d7d269302849d739d80344ff14db51d7bcda86045723f05c4e4541", - "3409a6f8c4dcd9bd04144eb67e55a98696b674735b01bf1196191f29871ef966", - "a823a0965969380ea1f8659ea5fd8fdd", - "24512b714aefd5cbc4bcc4ef44ce6c67ffc447c65460a6c6e4a92e85", - "00a7eb708eae745847173f8217efb05be13059710aee632e3f471ac3c6202b51", - }, - { - "a73a0b2686f7d699c018b6b08a352856e556070caa329c26241aec889eefde10", - "9b493403bee45ae6277430ef8d0c4163ffd81ace2db6c7821205da09a664a86c", - "c25701b9b7328c4ac3d23223d10623bd527c0a98e38ae9c62fbc403c80ab20ae", - "4b4ee0e4443779f3af429a749212f476", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "f39f7d66e0fde39ecdf58be2c0ef361a17cfd6843e310adbe0ec3118cd72800d", - }, - { - "a73a0b2686f7d699c018b6b08a352856e556070caa329c26241aec889eefde10", - "9b493403bee45ae6277430ef8d0c4163ffd81ace2db6c7821205da09a664a86c", - "31d18fdffc480310828778496ff817039df5d6f30bf6d9edd0b4396863d05f93", - "418bcbdf52860a450bfacc96920d02cf", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "0e6ce9889fe7b3cd82794b0ae27c1f5985d2f2a1f398371a138f8db1df1f54de", - }, - { - "e2e4dee102fad0f47f60202269605589cd9cf70f816b34016796c74b766f3041", - "c5ce283033a3255ae14d42dff1e4c18a224ac79d084b285123421b105ee654c9", - "56b4c645f81dbfb6ba0c6d3f1626e1e5cd648eeb36562715f7cd7e9ea86a0d7f", - "dc9bdce76d68d2e4d72267cf4e72b022", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "dc6f046c3008002041517a7c4f3ababe609cf02616fcccda39c075d1be4175f5", - }, - { - "e2e4dee102fad0f47f60202269605589cd9cf70f816b34016796c74b766f3041", - "c5ce283033a3255ae14d42dff1e4c18a224ac79d084b285123421b105ee654c9", - "df180b91986c8c7000792f96d1faa61e30138330430a402322be1855089b0e7f", - "ccf9b77341c866465b474e2f4a3b1cf8", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "94e4ae89041437f39826704f02cb5d775226f34344635e592846417497a5020b", - }, - { - "e2e4dee102fad0f47f60202269605589cd9cf70f816b34016796c74b766f3041", - "c5ce283033a3255ae14d42dff1e4c18a224ac79d084b285123421b105ee654c9", - "a0eee7e84c76e63fdae6e938b43330775eaf17d260e40b98c9e6616b668102a7", - "662c681cfec6f6d052ff0e2c1255f2c2", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "70bba3c48be9c75a144b1888ca3d21a6b21f52eec133981a024390a6a0ba36f9", - }, - { - "e2e4dee102fad0f47f60202269605589cd9cf70f816b34016796c74b766f3041", - "c5ce283033a3255ae14d42dff1e4c18a224ac79d084b285123421b105ee654c9", - "c6acd2d90eb782c3053b366680ffa0e148de81fea198c87bb643869fd97e5cb0", - "908dc33ba80520f2f0f04e7890e3a3c0", - "b6926d0ec82cec86c0d27ec9a33a0e0f", - "f6efe1d76d270aac264aa35d03049d9ce63be1996d543aef00559219c8666f71", - }, - }; - - HDNode node; - ed25519_secret_key private_key; - uint8_t chain_code[32]; - ed25519_public_key public_key; - uint8_t salt[sizeof(public_key)]; - - uint8_t iv[AES_BLOCK_SIZE]; - uint8_t buffer[FROMHEX_MAXLEN]; - - uint8_t input[FROMHEX_MAXLEN]; - uint8_t output[FROMHEX_MAXLEN]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - nem_private_key(tests[i].private_key, private_key); - - ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, - ED25519_KECCAK_NAME, &node)); - memcpy(public_key, fromhex(tests[i].public_key), 32); - memcpy(salt, fromhex(tests[i].salt), sizeof(salt)); - - size_t input_size = strlen(tests[i].input) / 2; - size_t output_size = strlen(tests[i].output) / 2; - - memcpy(input, fromhex(tests[i].input), input_size); - memcpy(output, fromhex(tests[i].output), output_size); - - memcpy(iv, fromhex(tests[i].iv), sizeof(iv)); - ck_assert(hdnode_nem_encrypt(&node, public_key, iv, salt, input, input_size, - buffer)); - ck_assert_uint_eq(output_size, NEM_ENCRYPTED_SIZE(input_size)); - ck_assert_mem_eq(buffer, output, output_size); - - memcpy(iv, fromhex(tests[i].iv), sizeof(iv)); - ck_assert(hdnode_nem_decrypt(&node, public_key, iv, salt, output, - output_size, buffer)); - ck_assert_uint_eq(input_size, NEM_DECRYPTED_SIZE(buffer, output_size)); - ck_assert_mem_eq(buffer, input, input_size); - } -} -END_TEST - -START_TEST(test_nem_transaction_transfer) { - nem_transaction_ctx ctx; - - uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; - - // http://bob.nem.ninja:8765/#/transfer/0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f - - nem_transaction_start( - &ctx, - fromhex( - "e59ef184a612d4c3c4d89b5950eb57262c69862b2f96e59c5043bf41765c482f"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_transfer( - &ctx, NEM_NETWORK_TESTNET, 0, NULL, 0, 0, - "TBGIMRE4SBFRUJXMH7DVF2IBY36L2EDWZ37GVSC4", 50000000000000, NULL, 0, - false, 0)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "0acbf8df91e6a65dc56c56c43d65f31ff2a6a48d06fc66e78c7f3436faf3e74f"), - sizeof(hash)); - - // http://bob.nem.ninja:8765/#/transfer/3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c - - nem_transaction_start( - &ctx, - fromhex( - "994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_transfer( - &ctx, NEM_NETWORK_TESTNET, 14072100, NULL, 194000000, 14075700, - "TBLOODPLWOWMZ2TARX4RFPOSOWLULHXMROBN2WXI", 3000000, - (uint8_t *)"sending you 3 pairs of paddles\n", 31, false, 2)); - - ck_assert( - nem_transaction_write_mosaic(&ctx, "gimre.games.pong", "paddles", 2)); - - ck_assert(nem_transaction_write_mosaic(&ctx, "nem", "xem", 44000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "3409d9ece28d6296d6d5e220a7e3cb8641a3fb235ffcbd20c95da64f003ace6c"), - sizeof(hash)); - - // http://chain.nem.ninja/#/transfer/e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb - - nem_transaction_start( - &ctx, - fromhex( - "8d07f90fb4bbe7715fa327c926770166a11be2e494a970605f2e12557f66c9b9"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_transfer( - &ctx, NEM_NETWORK_MAINNET, 0, NULL, 0, 0, - "NBT3WHA2YXG2IR4PWKFFMO772JWOITTD2V4PECSB", 5175000000000, - (uint8_t *)"Good luck!", 10, false, 0)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "e90e98614c7598fbfa4db5411db1b331d157c2f86b558fb7c943d013ed9f71cb"), - sizeof(hash)); - - // http://chain.nem.ninja/#/transfer/40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c - - nem_transaction_start( - &ctx, - fromhex( - "f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_transfer( - &ctx, NEM_NETWORK_MAINNET, 77229, NULL, 30000000, 80829, - "NALICEPFLZQRZGPRIJTMJOCPWDNECXTNNG7QLSG3", 30000000, - fromhex("4d9dcf9186967d30be93d6d5404ded22812dbbae7c3f0de5" - "01bcd7228cba45bded13000eec7b4c6215fc4d3588168c92" - "18167cec98e6977359153a4132e050f594548e61e0dc61c1" - "53f0f53c5e65c595239c9eb7c4e7d48e0f4bb8b1dd2f5ddc"), - 96, true, 0)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "40e89160e6f83d37f7c82defc0afe2c1605ae8c919134570a51dd27ea1bb516c"), - sizeof(hash)); - - // http://chain.nem.ninja/#/transfer/882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e - - nem_transaction_start( - &ctx, - fromhex( - "f85ab43dad059b9d2331ddacc384ad925d3467f03207182e01296bacfb242d01"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_transfer( - &ctx, NEM_NETWORK_MAINNET, 26730750, NULL, 179500000, 26734350, - "NBE223WPKEBHQPCYUC4U4CDUQCRRFMPZLOQLB5OP", 1000000, - (uint8_t *)"enjoy! :)", 9, false, 1)); - - ck_assert(nem_transaction_write_mosaic(&ctx, "imre.g", "tokens", 1)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "882dca18dcbe075e15e0ec5a1d7e6ccd69cc0f1309ffd3fde227bfbc107b3f6e"), - sizeof(hash)); -} -END_TEST - -START_TEST(test_nem_transaction_multisig) { - nem_transaction_ctx ctx, other_trans; - - uint8_t buffer[1024], inner[1024]; - const uint8_t *signature; - - // http://bob.nem.ninja:8765/#/multisig/7d3a7087023ee29005262016706818579a2b5499eb9ca76bad98c1e6f4c46642 - - nem_transaction_start( - &other_trans, - fromhex( - "abac2ee3d4aaa7a3bfb65261a00cc04c761521527dd3f2cf741e2815cbba83ac"), - inner, sizeof(inner)); - - ck_assert(nem_transaction_create_aggregate_modification( - &other_trans, NEM_NETWORK_TESTNET, 3939039, NULL, 16000000, 3960639, 1, - false)); - - ck_assert(nem_transaction_write_cosignatory_modification( - &other_trans, 2, - fromhex( - "e6cff9b3725a91f31089c3acca0fac3e341c00b1c8c6e9578f66c4514509c3b3"))); - - nem_transaction_start( - &ctx, - fromhex( - "59d89076964742ef2a2089d26a5aa1d2c7a7bb052a46c1de159891e91ad3d76e"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_multisig(&ctx, NEM_NETWORK_TESTNET, 3939039, - NULL, 6000000, 3960639, - &other_trans)); - - signature = fromhex( - "933930a8828b560168bddb3137df9252048678d829aa5135fa27bb306ff6562efb927554" - "62988b852b0314bde058487d00e47816b6fb7df6bcfd7e1f150d1d00"); - ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, - ctx.public_key, signature), - 0); - - nem_transaction_start( - &ctx, - fromhex( - "71cba4f2a28fd19f902ba40e9937994154d9eeaad0631d25d525ec37922567d4"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_multisig_signature(&ctx, NEM_NETWORK_TESTNET, - 3939891, NULL, 6000000, - 3961491, &other_trans)); - - signature = fromhex( - "a849f13bfeeba808a8a4a79d579febe584d831a3a6ad03da3b9d008530b3d7a79fcf7156" - "121cd7ee847029d94af7ea7a683ca8e643dc5e5f489557c2054b830b"); - ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, - ctx.public_key, signature), - 0); - - // http://chain.nem.ninja/#/multisig/1016cf3bdd61bd57b9b2b07b6ff2dee390279d8d899265bdc23d42360abe2e6c - - nem_transaction_start( - &other_trans, - fromhex( - "a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a"), - inner, sizeof(inner)); - - ck_assert(nem_transaction_create_provision_namespace( - &other_trans, NEM_NETWORK_MAINNET, 59414272, NULL, 20000000, 59500672, - "dim", NULL, "NAMESPACEWH4MKFMBCVFERDPOOP4FK7MTBXDPZZA", 5000000000)); - - nem_transaction_start( - &ctx, - fromhex( - "cfe58463f0eaebceb5d00717f8aead49171a5d7c08f6b1299bd534f11715acc9"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_multisig(&ctx, NEM_NETWORK_MAINNET, 59414272, - NULL, 6000000, 59500672, - &other_trans)); - - signature = fromhex( - "52a876a37511068fe214bd710b2284823921ec7318c01e083419a062eae5369c9c11c3ab" - "fdb590f65c717fab82873431d52be62e10338cb5656d1833bbdac70c"); - ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, - ctx.public_key, signature), - 0); - - nem_transaction_start( - &ctx, - fromhex( - "1b49b80203007117d034e45234ffcdf402c044aeef6dbb06351f346ca892bce2"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_multisig_signature(&ctx, NEM_NETWORK_MAINNET, - 59414342, NULL, 6000000, - 59500742, &other_trans)); - - signature = fromhex( - "b9a59239e5d06992c28840034ff7a7f13da9c4e6f4a6f72c1b1806c3b602f83a7d727a34" - "5371f5d15abf958208a32359c6dd77bde92273ada8ea6fda3dc76b00"); - ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, - ctx.public_key, signature), - 0); - - nem_transaction_start( - &ctx, - fromhex( - "7ba4b39209f1b9846b098fe43f74381e43cb2882ccde780f558a63355840aa87"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_multisig_signature(&ctx, NEM_NETWORK_MAINNET, - 59414381, NULL, 6000000, - 59500781, &other_trans)); - - signature = fromhex( - "e874ae9f069f0538008631d2df9f2e8a59944ff182e8672f743d2700fb99224aafb7a0ab" - "09c4e9ea39ee7c8ca04a8a3d6103ae1122d87772e871761d4f00ca01"); - ck_assert_int_eq(ed25519_sign_open_keccak(ctx.buffer, ctx.offset, - ctx.public_key, signature), - 0); -} -END_TEST - -START_TEST(test_nem_transaction_provision_namespace) { - nem_transaction_ctx ctx; - - uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; - - // http://bob.nem.ninja:8765/#/namespace/f7cab28da57204d01a907c697836577a4ae755e6c9bac60dcc318494a22debb3 - - nem_transaction_start( - &ctx, - fromhex( - "84afa1bbc993b7f5536344914dde86141e61f8cbecaf8c9cefc07391f3287cf5"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_provision_namespace( - &ctx, NEM_NETWORK_TESTNET, 56999445, NULL, 20000000, 57003045, "gimre", - NULL, "TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35", 5000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "f7cab28da57204d01a907c697836577a4ae755e6c9bac60dcc318494a22debb3"), - sizeof(hash)); - - // http://bob.nem.ninja:8765/#/namespace/7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d - - nem_transaction_start( - &ctx, - fromhex( - "244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_provision_namespace( - &ctx, NEM_NETWORK_TESTNET, 21496797, NULL, 108000000, 21500397, "misc", - "alice", "TAMESPACEWH4MKFMBCVFERDPOOP4FK7MTDJEYP35", 5000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "7ddd5fe607e1bfb5606e0ac576024c318c8300d237273117d4db32a60c49524d"), - sizeof(hash)); - - // http://chain.nem.ninja/#/namespace/57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569 - - nem_transaction_start( - &ctx, - fromhex( - "9f3c14f304309c8b72b2821339c4428793b1518bea72d58dd01f19d523518614"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_provision_namespace( - &ctx, NEM_NETWORK_MAINNET, 26699717, NULL, 108000000, 26703317, "sex", - NULL, "NAMESPACEWH4MKFMBCVFERDPOOP4FK7MTBXDPZZA", 50000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "57071aad93ca125dc231dc02c07ad8610cd243d35068f9b36a7d231383907569"), - sizeof(hash)); -} -END_TEST - -START_TEST(test_nem_transaction_mosaic_creation) { - nem_transaction_ctx ctx; - - uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; - - // http://bob.nem.ninja:8765/#/mosaic/68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa/0 - - nem_transaction_start( - &ctx, - fromhex( - "994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_creation( - &ctx, NEM_NETWORK_TESTNET, 14070896, NULL, 108000000, 14074496, - "gimre.games.pong", "paddles", "Paddles for the bong game.\n", 0, 10000, - true, true, 0, 0, NULL, NULL, NULL, - "TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC", 50000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "68364353c29105e6d361ad1a42abbccbf419cfc7adb8b74c8f35d8f8bdaca3fa"), - sizeof(hash)); - - // http://bob.nem.ninja:8765/#/mosaic/b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55/0 - - nem_transaction_start( - &ctx, - fromhex( - "244fa194e2509ac0d2fbc18779c2618d8c2ebb61c16a3bcbebcf448c661ba8dc"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_creation( - &ctx, NEM_NETWORK_TESTNET, 21497248, NULL, 108000000, 21500848, - "alice.misc", "bar", "Special offer: get one bar extra by bying one foo!", - 0, 1000, false, true, 1, 1, "TALICE2GMA34CXHD7XLJQ536NM5UNKQHTORNNT2J", - "nem", "xem", "TBMOSAICOD4F54EE5CDMR23CCBGOAM2XSJBR5OLC", 50000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "b2f4a98113ff1f3a8f1e9d7197aa982545297fe0aa3fa6094af8031569953a55"), - sizeof(hash)); - - // http://chain.nem.ninja/#/mosaic/269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b/0 - - nem_transaction_start( - &ctx, - fromhex( - "58956ac77951622dc5f1c938affbf017c458e30e6b21ddb5783d38b302531f23"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_creation( - &ctx, NEM_NETWORK_MAINNET, 26729938, NULL, 108000000, 26733538, "jabo38", - "red_token", - "This token is to celebrate the release of Namespaces and Mosaics on the " - "NEM system. " - "This token was the fist ever mosaic created other than nem.xem. " - "There are only 10,000 Red Tokens that will ever be created. " - "It has no levy and can be traded freely among third parties.", - 2, 10000, false, true, 0, 0, NULL, NULL, NULL, - "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 50000000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "269c6fda657aba3053a0e5b138c075808cc20e244e1182d9b730798b60a1f77b"), - sizeof(hash)); - - // http://chain.nem.ninja/#/mosaic/e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6/0 - - nem_transaction_start( - &ctx, - fromhex( - "a1df5306355766bd2f9a64efdc089eb294be265987b3359093ae474c051d7d5a"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_creation( - &ctx, NEM_NETWORK_MAINNET, 69251020, NULL, 20000000, 69337420, "dim", - "coin", "DIM COIN", 6, 9000000000, false, true, 2, 10, - "NCGGLVO2G3CUACVI5GNX2KRBJSQCN4RDL2ZWJ4DP", "dim", "coin", - "NBMOSAICOD4F54EE5CDMR23CCBGOAM2XSIUX6TRS", 500000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "e8dc14821dbea4831d9051f86158ef348001447968fc22c01644fdaf2bda75c6"), - sizeof(hash)); -} -END_TEST - -START_TEST(test_nem_transaction_mosaic_supply_change) { - nem_transaction_ctx ctx; - - uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; - - // http://bigalice2.nem.ninja:7890/transaction/get?hash=33a50fdd4a54913643a580b2af08b9a5b51b7cee922bde380e84c573a7969c50 - - nem_transaction_start( - &ctx, - fromhex( - "994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_supply_change( - &ctx, NEM_NETWORK_TESTNET, 14071648, NULL, 108000000, 14075248, - "gimre.games.pong", "paddles", 1, 1234)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "33a50fdd4a54913643a580b2af08b9a5b51b7cee922bde380e84c573a7969c50"), - sizeof(hash)); - - // http://bigalice2.nem.ninja:7890/transaction/get?hash=1ce8e8894d077a66ff22294b000825d090a60742ec407efd80eb8b19657704f2 - - nem_transaction_start( - &ctx, - fromhex( - "84afa1bbc993b7f5536344914dde86141e61f8cbecaf8c9cefc07391f3287cf5"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_supply_change( - &ctx, NEM_NETWORK_TESTNET, 14126909, NULL, 108000000, 14130509, - "jabo38_ltd.fuzzy_kittens_cafe", "coupons", 2, 1)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "1ce8e8894d077a66ff22294b000825d090a60742ec407efd80eb8b19657704f2"), - sizeof(hash)); - - // http://bigalice3.nem.ninja:7890/transaction/get?hash=694e493e9576d2bcf60d85747e302ac2e1cc27783187947180d4275a713ff1ff - - nem_transaction_start( - &ctx, - fromhex( - "b7ccc27b21ba6cf5c699a8dc86ba6ba98950442597ff9fa30e0abe0f5f4dd05d"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_supply_change( - &ctx, NEM_NETWORK_MAINNET, 53377685, NULL, 20000000, 53464085, "abvapp", - "abv", 1, 9000000)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "694e493e9576d2bcf60d85747e302ac2e1cc27783187947180d4275a713ff1ff"), - sizeof(hash)); - - // http://bigalice3.nem.ninja:7890/transaction/get?hash=09836334e123970e068d5b411e4d1df54a3ead10acf1ad5935a2cdd9f9680185 - - nem_transaction_start( - &ctx, - fromhex( - "75f001a8641e2ce5c4386883dda561399ed346177411b492a677b73899502f13"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_mosaic_supply_change( - &ctx, NEM_NETWORK_MAINNET, 55176304, NULL, 20000000, 55262704, "sushi", - "wasabi", 2, 20)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "09836334e123970e068d5b411e4d1df54a3ead10acf1ad5935a2cdd9f9680185"), - sizeof(hash)); -} -END_TEST - -START_TEST(test_nem_transaction_aggregate_modification) { - nem_transaction_ctx ctx; - - uint8_t buffer[1024], hash[SHA3_256_DIGEST_LENGTH]; - - // http://bob.nem.ninja:8765/#/aggregate/6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2 - - nem_transaction_start( - &ctx, - fromhex( - "462ee976890916e54fa825d26bdd0235f5eb5b6a143c199ab0ae5ee9328e08ce"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_aggregate_modification( - &ctx, NEM_NETWORK_TESTNET, 0, NULL, 22000000, 0, 2, false)); - - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "994793ba1c789fa9bdea918afc9b06e2d0309beb1081ac5b6952991e4defd324"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "c54d6e33ed1446eedd7f7a80a588dd01857f723687a09200c1917d5524752f8b"))); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "6a55471b17159e5b6cd579c421e95a4e39d92e3f78b0a55ee337e785a601d3a2"), - sizeof(hash)); - - // http://bob.nem.ninja:8765/#/aggregate/1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584 - - nem_transaction_start( - &ctx, - fromhex( - "6bf7849c1eec6a2002995cc457dc00c4e29bad5c88de63f51e42dfdcd7b2131d"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_aggregate_modification( - &ctx, NEM_NETWORK_TESTNET, 6542254, NULL, 40000000, 6545854, 4, true)); - - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "5f53d076c8c3ec3110b98364bc423092c3ec2be2b1b3c40fd8ab68d54fa39295"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "9eb199c2b4d406f64cb7aa5b2b0815264b56ba8fe44d558a6cb423a31a33c4c2"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "94b2323dab23a3faba24fa6ddda0ece4fbb06acfedd74e76ad9fae38d006882b"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "d88c6ee2a2cd3929d0d76b6b14ecb549d21296ab196a2b3a4cb2536bcce32e87"))); - - ck_assert(nem_transaction_write_minimum_cosignatories(&ctx, 2)); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "1fbdae5ba753e68af270930413ae90f671eb8ab58988116684bac0abd5726584"), - sizeof(hash)); - - // http://chain.nem.ninja/#/aggregate/cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c - - nem_transaction_start( - &ctx, - fromhex( - "f41b99320549741c5cce42d9e4bb836d98c50ed5415d0c3c2912d1bb50e6a0e5"), - buffer, sizeof(buffer)); - - ck_assert(nem_transaction_create_aggregate_modification( - &ctx, NEM_NETWORK_MAINNET, 0, NULL, 40000000, 0, 5, false)); - - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "1fbdbdde28daf828245e4533765726f0b7790e0b7146e2ce205df3e86366980b"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "f94e8702eb1943b23570b1b83be1b81536df35538978820e98bfce8f999e2d37"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "826cedee421ff66e708858c17815fcd831a4bb68e3d8956299334e9e24380ba8"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "719862cd7d0f4e875a6a0274c9a1738f38f40ad9944179006a54c34724c1274d"))); - ck_assert(nem_transaction_write_cosignatory_modification( - &ctx, 1, - fromhex( - "43aa69177018fc3e2bdbeb259c81cddf24be50eef9c5386db51d82386c41475a"))); - - keccak_256(ctx.buffer, ctx.offset, hash); - ck_assert_mem_eq( - hash, - fromhex( - "cc64ca69bfa95db2ff7ac1e21fe6d27ece189c603200ebc9778d8bb80ca25c3c"), - sizeof(hash)); -} -END_TEST -#endif - -START_TEST(test_multibyte_address) { - uint8_t priv_key[32]; - char wif[57]; - uint8_t pub_key[33]; - char address[40]; - uint8_t decode[24]; - int res; - - memcpy( - priv_key, - fromhex( - "47f7616ea6f9b923076625b4488115de1ef1187f760e65f89eb6f4f7ff04b012"), - 32); - ecdsa_get_wif(priv_key, 0, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "13QtoXmbhELWcrwD9YA9KzvXy5rTaptiNuFR8L8ArpBNn4xmQj4N"); - ecdsa_get_wif(priv_key, 0x12, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, "3hrF6SFnqzpzABB36uGDf8dJSuUCcMmoJrTmCWMshRkBr2Vx86qJ"); - ecdsa_get_wif(priv_key, 0x1234, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, - "CtPTF9awbVbfDWGepGdVhB3nBhr4HktUGya8nf8dLxgC8tbqBreB9"); - ecdsa_get_wif(priv_key, 0x123456, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, - "uTrDevVQt5QZgoL3iJ1cPWHaCz7ZMBncM7QXZfCegtxiMHqBvWoYJa"); - ecdsa_get_wif(priv_key, 0x12345678, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, - "4zZWMzv1SVbs95pmLXWrXJVp9ntPEam1mfwb6CXBLn9MpWNxLg9huYgv"); - ecdsa_get_wif(priv_key, 0xffffffff, HASHER_SHA2D, wif, sizeof(wif)); - ck_assert_str_eq(wif, - "y9KVfV1RJXcTxpVjeuh6WYWh8tMwnAUeyUwDEiRviYdrJ61njTmnfUjE"); - - memcpy( - pub_key, - fromhex( - "0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71"), - 33); - ecdsa_get_address(pub_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8"); - ecdsa_get_address(pub_key, 0x12, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "8SCrMR2yYF7ciqoDbav7VLLTsVx5dTVPPq"); - ecdsa_get_address(pub_key, 0x1234, HASHER_SHA2_RIPEMD, HASHER_SHA2D, address, - sizeof(address)); - ck_assert_str_eq(address, "ZLH8q1UgMPg8o2s1MD55YVMpPV7vqms9kiV"); - ecdsa_get_address(pub_key, 0x123456, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "3ThqvsQVFnbiF66NwHtfe2j6AKn75DpLKpQSq"); - ecdsa_get_address(pub_key, 0x12345678, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44"); - ecdsa_get_address(pub_key, 0xffffffff, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - address, sizeof(address)); - ck_assert_str_eq(address, "3diW7paWGJyZRLGqMJZ55DMfPExob8QxQHkrfYT"); - - res = ecdsa_address_decode("1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8", 0, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("0079fbfc3f34e7745860d76137da68f362380c606c"), 21); - res = ecdsa_address_decode("8SCrMR2yYF7ciqoDbav7VLLTsVx5dTVPPq", 0x12, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("1279fbfc3f34e7745860d76137da68f362380c606c"), 21); - res = ecdsa_address_decode("ZLH8q1UgMPg8o2s1MD55YVMpPV7vqms9kiV", 0x1234, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq(decode, - fromhex("123479fbfc3f34e7745860d76137da68f362380c606c"), 21); - res = ecdsa_address_decode("3ThqvsQVFnbiF66NwHtfe2j6AKn75DpLKpQSq", 0x123456, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - decode, fromhex("12345679fbfc3f34e7745860d76137da68f362380c606c"), 21); - res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", - 0x12345678, HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - decode, fromhex("1234567879fbfc3f34e7745860d76137da68f362380c606c"), 21); - res = ecdsa_address_decode("3diW7paWGJyZRLGqMJZ55DMfPExob8QxQHkrfYT", - 0xffffffff, HASHER_SHA2D, decode); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - decode, fromhex("ffffffff79fbfc3f34e7745860d76137da68f362380c606c"), 21); - - // wrong length - res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", 0x123456, - HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); - - // wrong address prefix - res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL44", - 0x22345678, HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); - - // wrong checksum - res = ecdsa_address_decode("BrsGxAHga3VbopvSnb3gmLvMBhJNCGuDxBZL45", - 0x12345678, HASHER_SHA2D, decode); - ck_assert_int_eq(res, 0); -} -END_TEST - -// https://tools.ietf.org/html/rfc6229#section-2 -START_TEST(test_rc4_rfc6229) { - static const size_t offsets[] = { - 0x0, 0xf0, 0x1f0, 0x2f0, 0x3f0, 0x5f0, 0x7f0, 0xbf0, 0xff0, - }; - - static const struct { - char key[65]; - char vectors[sizeof(offsets) / sizeof(*offsets)][65]; - } tests[] = { - {"0102030405", - { - "b2396305f03dc027ccc3524a0a1118a8" - "6982944f18fc82d589c403a47a0d0919", - "28cb1132c96ce286421dcaadb8b69eae" - "1cfcf62b03eddb641d77dfcf7f8d8c93", - "42b7d0cdd918a8a33dd51781c81f4041" - "6459844432a7da923cfb3eb4980661f6", - "ec10327bde2beefd18f9277680457e22" - "eb62638d4f0ba1fe9fca20e05bf8ff2b", - "45129048e6a0ed0b56b490338f078da5" - "30abbcc7c20b01609f23ee2d5f6bb7df", - "3294f744d8f9790507e70f62e5bbceea" - "d8729db41882259bee4f825325f5a130", - "1eb14a0c13b3bf47fa2a0ba93ad45b8b" - "cc582f8ba9f265e2b1be9112e975d2d7", - "f2e30f9bd102ecbf75aaade9bc35c43c" - "ec0e11c479dc329dc8da7968fe965681", - "068326a2118416d21f9d04b2cd1ca050" - "ff25b58995996707e51fbdf08b34d875", - }}, - {"01020304050607", - { - "293f02d47f37c9b633f2af5285feb46b" - "e620f1390d19bd84e2e0fd752031afc1", - "914f02531c9218810df60f67e338154c" - "d0fdb583073ce85ab83917740ec011d5", - "75f81411e871cffa70b90c74c592e454" - "0bb87202938dad609e87a5a1b079e5e4", - "c2911246b612e7e7b903dfeda1dad866" - "32828f91502b6291368de8081de36fc2", - "f3b9a7e3b297bf9ad804512f9063eff1" - "8ecb67a9ba1f55a5a067e2b026a3676f", - "d2aa902bd42d0d7cfd340cd45810529f" - "78b272c96e42eab4c60bd914e39d06e3", - "f4332fd31a079396ee3cee3f2a4ff049" - "05459781d41fda7f30c1be7e1246c623", - "adfd3868b8e51485d5e610017e3dd609" - "ad26581c0c5be45f4cea01db2f3805d5", - "f3172ceffc3b3d997c85ccd5af1a950c" - "e74b0b9731227fd37c0ec08a47ddd8b8", - }}, - {"0102030405060708", - { - "97ab8a1bf0afb96132f2f67258da15a8" - "8263efdb45c4a18684ef87e6b19e5b09", - "9636ebc9841926f4f7d1f362bddf6e18" - "d0a990ff2c05fef5b90373c9ff4b870a", - "73239f1db7f41d80b643c0c52518ec63" - "163b319923a6bdb4527c626126703c0f", - "49d6c8af0f97144a87df21d91472f966" - "44173a103b6616c5d5ad1cee40c863d0", - "273c9c4b27f322e4e716ef53a47de7a4" - "c6d0e7b226259fa9023490b26167ad1d", - "1fe8986713f07c3d9ae1c163ff8cf9d3" - "8369e1a965610be887fbd0c79162aafb", - "0a0127abb44484b9fbef5abcae1b579f" - "c2cdadc6402e8ee866e1f37bdb47e42c", - "26b51ea37df8e1d6f76fc3b66a7429b3" - "bc7683205d4f443dc1f29dda3315c87b", - "d5fa5a3469d29aaaf83d23589db8c85b" - "3fb46e2c8f0f068edce8cdcd7dfc5862", - }}, - {"0102030405060708090a", - { - "ede3b04643e586cc907dc21851709902" - "03516ba78f413beb223aa5d4d2df6711", - "3cfd6cb58ee0fdde640176ad0000044d" - "48532b21fb6079c9114c0ffd9c04a1ad", - "3e8cea98017109979084b1ef92f99d86" - "e20fb49bdb337ee48b8d8dc0f4afeffe", - "5c2521eacd7966f15e056544bea0d315" - "e067a7031931a246a6c3875d2f678acb", - "a64f70af88ae56b6f87581c0e23e6b08" - "f449031de312814ec6f319291f4a0516", - "bdae85924b3cb1d0a2e33a30c6d79599" - "8a0feddbac865a09bcd127fb562ed60a", - "b55a0a5b51a12a8be34899c3e047511a" - "d9a09cea3ce75fe39698070317a71339", - "552225ed1177f44584ac8cfa6c4eb5fc" - "7e82cbabfc95381b080998442129c2f8", - "1f135ed14ce60a91369d2322bef25e3c" - "08b6be45124a43e2eb77953f84dc8553", - }}, - {"0102030405060708090a0b0c0d0e0f10", - { - "9ac7cc9a609d1ef7b2932899cde41b97" - "5248c4959014126a6e8a84f11d1a9e1c", - "065902e4b620f6cc36c8589f66432f2b" - "d39d566bc6bce3010768151549f3873f", - "b6d1e6c4a5e4771cad79538df295fb11" - "c68c1d5c559a974123df1dbc52a43b89", - "c5ecf88de897fd57fed301701b82a259" - "eccbe13de1fcc91c11a0b26c0bc8fa4d", - "e7a72574f8782ae26aabcf9ebcd66065" - "bdf0324e6083dcc6d3cedd3ca8c53c16", - "b40110c4190b5622a96116b0017ed297" - "ffa0b514647ec04f6306b892ae661181", - "d03d1bc03cd33d70dff9fa5d71963ebd" - "8a44126411eaa78bd51e8d87a8879bf5", - "fabeb76028ade2d0e48722e46c4615a3" - "c05d88abd50357f935a63c59ee537623", - "ff38265c1642c1abe8d3c2fe5e572bf8" - "a36a4c301ae8ac13610ccbc12256cacc", - }}, - {"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", - { - "eaa6bd25880bf93d3f5d1e4ca2611d91" - "cfa45c9f7e714b54bdfa80027cb14380", - "114ae344ded71b35f2e60febad727fd8" - "02e1e7056b0f623900496422943e97b6", - "91cb93c787964e10d9527d999c6f936b" - "49b18b42f8e8367cbeb5ef104ba1c7cd", - "87084b3ba700bade955610672745b374" - "e7a7b9e9ec540d5ff43bdb12792d1b35", - "c799b596738f6b018c76c74b1759bd90" - "7fec5bfd9f9b89ce6548309092d7e958", - "40f250b26d1f096a4afd4c340a588815" - "3e34135c79db010200767651cf263073", - "f656abccf88dd827027b2ce917d464ec" - "18b62503bfbc077fbabb98f20d98ab34", - "8aed95ee5b0dcbfbef4eb21d3a3f52f9" - "625a1ab00ee39a5327346bddb01a9c18", - "a13a7c79c7e119b5ab0296ab28c300b9" - "f3e4c0a2e02d1d01f7f0a74618af2b48", - }}, - {"833222772a", - { - "80ad97bdc973df8a2e879e92a497efda" - "20f060c2f2e5126501d3d4fea10d5fc0", - "faa148e99046181fec6b2085f3b20ed9" - "f0daf5bab3d596839857846f73fbfe5a", - "1c7e2fc4639232fe297584b296996bc8" - "3db9b249406cc8edffac55ccd322ba12", - "e4f9f7e0066154bbd125b745569bc897" - "75d5ef262b44c41a9cf63ae14568e1b9", - "6da453dbf81e82334a3d8866cb50a1e3" - "7828d074119cab5c22b294d7a9bfa0bb", - "adb89cea9a15fbe617295bd04b8ca05c" - "6251d87fd4aaae9a7e4ad5c217d3f300", - "e7119bd6dd9b22afe8f89585432881e2" - "785b60fd7ec4e9fcb6545f350d660fab", - "afecc037fdb7b0838eb3d70bcd268382" - "dbc1a7b49d57358cc9fa6d61d73b7cf0", - "6349d126a37afcba89794f9804914fdc" - "bf42c3018c2f7c66bfde524975768115", - }}, - {"1910833222772a", - { - "bc9222dbd3274d8fc66d14ccbda6690b" - "7ae627410c9a2be693df5bb7485a63e3", - "3f0931aa03defb300f060103826f2a64" - "beaa9ec8d59bb68129f3027c96361181", - "74e04db46d28648d7dee8a0064b06cfe" - "9b5e81c62fe023c55be42f87bbf932b8", - "ce178fc1826efecbc182f57999a46140" - "8bdf55cd55061c06dba6be11de4a578a", - "626f5f4dce652501f3087d39c92cc349" - "42daac6a8f9ab9a7fd137c6037825682", - "cc03fdb79192a207312f53f5d4dc33d9" - "f70f14122a1c98a3155d28b8a0a8a41d", - "2a3a307ab2708a9c00fe0b42f9c2d6a1" - "862617627d2261eab0b1246597ca0ae9", - "55f877ce4f2e1ddbbf8e13e2cde0fdc8" - "1b1556cb935f173337705fbb5d501fc1", - "ecd0e96602be7f8d5092816cccf2c2e9" - "027881fab4993a1c262024a94fff3f61", - }}, - {"641910833222772a", - { - "bbf609de9413172d07660cb680716926" - "46101a6dab43115d6c522b4fe93604a9", - "cbe1fff21c96f3eef61e8fe0542cbdf0" - "347938bffa4009c512cfb4034b0dd1a7", - "7867a786d00a7147904d76ddf1e520e3" - "8d3e9e1caefcccb3fbf8d18f64120b32", - "942337f8fd76f0fae8c52d7954810672" - "b8548c10f51667f6e60e182fa19b30f7", - "0211c7c6190c9efd1237c34c8f2e06c4" - "bda64f65276d2aacb8f90212203a808e", - "bd3820f732ffb53ec193e79d33e27c73" - "d0168616861907d482e36cdac8cf5749", - "97b0f0f224b2d2317114808fb03af7a0" - "e59616e469787939a063ceea9af956d1", - "c47e0dc1660919c11101208f9e69aa1f" - "5ae4f12896b8379a2aad89b5b553d6b0", - "6b6b098d0c293bc2993d80bf0518b6d9" - "8170cc3ccd92a698621b939dd38fe7b9", - }}, - {"8b37641910833222772a", - { - "ab65c26eddb287600db2fda10d1e605c" - "bb759010c29658f2c72d93a2d16d2930", - "b901e8036ed1c383cd3c4c4dd0a6ab05" - "3d25ce4922924c55f064943353d78a6c", - "12c1aa44bbf87e75e611f69b2c38f49b" - "28f2b3434b65c09877470044c6ea170d", - "bd9ef822de5288196134cf8af7839304" - "67559c23f052158470a296f725735a32", - "8bab26fbc2c12b0f13e2ab185eabf241" - "31185a6d696f0cfa9b42808b38e132a2", - "564d3dae183c5234c8af1e51061c44b5" - "3c0778a7b5f72d3c23a3135c7d67b9f4", - "f34369890fcf16fb517dcaae4463b2dd" - "02f31c81e8200731b899b028e791bfa7", - "72da646283228c14300853701795616f" - "4e0a8c6f7934a788e2265e81d6d0c8f4", - "438dd5eafea0111b6f36b4b938da2a68" - "5f6bfc73815874d97100f086979357d8", - }}, - {"ebb46227c6cc8b37641910833222772a", - { - "720c94b63edf44e131d950ca211a5a30" - "c366fdeacf9ca80436be7c358424d20b", - "b3394a40aabf75cba42282ef25a0059f" - "4847d81da4942dbc249defc48c922b9f", - "08128c469f275342adda202b2b58da95" - "970dacef40ad98723bac5d6955b81761", - "3cb89993b07b0ced93de13d2a11013ac" - "ef2d676f1545c2c13dc680a02f4adbfe", - "b60595514f24bc9fe522a6cad7393644" - "b515a8c5011754f59003058bdb81514e", - "3c70047e8cbc038e3b9820db601da495" - "1175da6ee756de46a53e2b075660b770", - "00a542bba02111cc2c65b38ebdba587e" - "5865fdbb5b48064104e830b380f2aede", - "34b21ad2ad44e999db2d7f0863f0d9b6" - "84a9218fc36e8a5f2ccfbeae53a27d25", - "a2221a11b833ccb498a59540f0545f4a" - "5bbeb4787d59e5373fdbea6c6f75c29b", - }}, - {"c109163908ebe51debb46227c6cc8b37641910833222772a", - { - "54b64e6b5a20b5e2ec84593dc7989da7" - "c135eee237a85465ff97dc03924f45ce", - "cfcc922fb4a14ab45d6175aabbf2d201" - "837b87e2a446ad0ef798acd02b94124f", - "17a6dbd664926a0636b3f4c37a4f4694" - "4a5f9f26aeeed4d4a25f632d305233d9", - "80a3d01ef00c8e9a4209c17f4eeb358c" - "d15e7d5ffaaabc0207bf200a117793a2", - "349682bf588eaa52d0aa1560346aeafa" - "f5854cdb76c889e3ad63354e5f7275e3", - "532c7ceccb39df3236318405a4b1279c" - "baefe6d9ceb651842260e0d1e05e3b90", - "e82d8c6db54e3c633f581c952ba04207" - "4b16e50abd381bd70900a9cd9a62cb23", - "3682ee33bd148bd9f58656cd8f30d9fb" - "1e5a0b8475045d9b20b2628624edfd9e", - "63edd684fb826282fe528f9c0e9237bc" - "e4dd2e98d6960fae0b43545456743391", - }}, - {"1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a", - { - "dd5bcb0018e922d494759d7c395d02d3" - "c8446f8f77abf737685353eb89a1c9eb", - "af3e30f9c095045938151575c3fb9098" - "f8cb6274db99b80b1d2012a98ed48f0e", - "25c3005a1cb85de076259839ab7198ab" - "9dcbc183e8cb994b727b75be3180769c", - "a1d3078dfa9169503ed9d4491dee4eb2" - "8514a5495858096f596e4bcd66b10665", - "5f40d59ec1b03b33738efa60b2255d31" - "3477c7f764a41baceff90bf14f92b7cc", - "ac4e95368d99b9eb78b8da8f81ffa795" - "8c3c13f8c2388bb73f38576e65b7c446", - "13c4b9c1dfb66579eddd8a280b9f7316" - "ddd27820550126698efaadc64b64f66e", - "f08f2e66d28ed143f3a237cf9de73559" - "9ea36c525531b880ba124334f57b0b70", - "d5a39e3dfcc50280bac4a6b5aa0dca7d" - "370b1c1fe655916d97fd0d47ca1d72b8", - }}}; - - RC4_CTX ctx; - uint8_t key[64]; - uint8_t buffer[0x1010]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - size_t length = strlen(tests[i].key) / 2; - memcpy(key, fromhex(tests[i].key), length); - memzero(buffer, sizeof(buffer)); - - rc4_init(&ctx, key, length); - rc4_encrypt(&ctx, buffer, sizeof(buffer)); - - for (size_t j = 0; j < (sizeof(offsets) / sizeof(*offsets)); j++) { - size_t size = strlen(tests[i].vectors[j]) / 2; - ck_assert_mem_eq(&buffer[offsets[j]], fromhex(tests[i].vectors[j]), size); - } - } -} -END_TEST - -static void test_compress_coord(const char *k_raw) { - const ecdsa_curve *curve = &secp256k1; - curve_point expected_coords; - - bignum256 k = {0}; - - bn_read_be(fromhex(k_raw), &k); - - point_multiply(curve, &k, &curve->G, &expected_coords); - - uint8_t compress[33] = {0}; - compress_coords(&expected_coords, compress); - - bignum256 x = {0}, y = {0}; - bn_read_be(compress + 1, &x); - uncompress_coords(curve, compress[0], &x, &y); - - ck_assert(bn_is_equal(&expected_coords.x, &x)); - ck_assert(bn_is_equal(&expected_coords.y, &y)); -} - -START_TEST(test_compress_coords) { - static const char *k_raw[] = { - "dc05960ac673fd59554c98655e26722d007bb7ada0c8ff00883fdee70783d0be", - "41e41e0a218c980411108a0a58cf88f528c828b4d6f0d2c86234bc2504bdc3cd", - "1d963ddcb79f6028a32cadd2421ff7fff969bff5774f73063dab41519b3da175", - "2414141f96da0874dbc374b58861589935b7f940806ddf8d2e6b911f62e240f3", - "01cc1fb182e29f60fe43e22d250de34f2d3f956bbef2aa9b182d09e5d9176873", - "89b3d621d813682692fd61b2baea6b2ea696a44abc76925d29c4887fc4db9367", - "20c80c633e05a3a7dfac05fa0e0a7c7a6b708b02323e687735cff81ea5944f59", - "5a803c263aa93a4f74648066c03e63fb00641193bae93dfa254dabd634e8b49c", - "05efbcc87007797dca68315b9271ac8fb75bddbece53f4dcbfb83fc21cb91fc0", - "0bed78ef43474630bd646eef2d7ec19a1acb8e9eecf6a0a3ac7241ac40a7706f", - }; - - for (int i = 0; i < (int)(sizeof(k_raw) / sizeof(*k_raw)); i++) - test_compress_coord(k_raw[i]); -} -END_TEST - -static int my_strncasecmp(const char *s1, const char *s2, size_t n) { - size_t i = 0; - while (i < n) { - char c1 = s1[i]; - char c2 = s2[i]; - if (c1 >= 'A' && c1 <= 'Z') c1 = (c1 - 'A') + 'a'; - if (c2 >= 'A' && c2 <= 'Z') c2 = (c2 - 'A') + 'a'; - if (c1 < c2) return -1; - if (c1 > c2) return 1; - if (c1 == 0) return 0; - ++i; - } - return 0; -} - -#include "test_check_cashaddr.h" -#include "test_check_zilliqa.h" // [wallet-core] -#if USE_SEGWIT -#include "test_check_segwit.h" -#endif - -#if USE_CARDANO -#include "test_check_cardano.h" -#endif - -#if USE_MONERO -#include "test_check_monero.h" -#endif - -// define test suite and cases -Suite *test_suite(void) { - Suite *s = suite_create("trezor-crypto"); - TCase *tc; - - tc = tcase_create("bignum"); - tcase_add_test(tc, test_bignum_read_be); - tcase_add_test(tc, test_bignum_write_be); - tcase_add_test(tc, test_bignum_is_equal); - tcase_add_test(tc, test_bignum_zero); - tcase_add_test(tc, test_bignum_is_zero); - tcase_add_test(tc, test_bignum_one); - tcase_add_test(tc, test_bignum_read_le); - tcase_add_test(tc, test_bignum_write_le); - tcase_add_test(tc, test_bignum_read_uint32); - tcase_add_test(tc, test_bignum_read_uint64); - tcase_add_test(tc, test_bignum_write_uint32); - tcase_add_test(tc, test_bignum_write_uint64); - tcase_add_test(tc, test_bignum_copy); - tcase_add_test(tc, test_bignum_is_even); - tcase_add_test(tc, test_bignum_is_odd); - tcase_add_test(tc, test_bignum_bitcount); - tcase_add_test(tc, test_bignum_digitcount); - tcase_add_test(tc, test_bignum_is_less); - tcase_add_test(tc, test_bignum_format); - tcase_add_test(tc, test_bignum_format_uint64); - tcase_add_test(tc, test_bignum_sqrt); - suite_add_tcase(s, tc); - - tc = tcase_create("base32"); - tcase_add_test(tc, test_base32_rfc4648); - suite_add_tcase(s, tc); - - tc = tcase_create("base58"); - tcase_add_test(tc, test_base58); - suite_add_tcase(s, tc); - -#if USE_GRAPHENE - tc = tcase_create("base58gph"); - tcase_add_test(tc, test_base58gph); - suite_add_tcase(s, tc); -#endif - - tc = tcase_create("bignum_divmod"); - tcase_add_test(tc, test_bignum_divmod); - suite_add_tcase(s, tc); - - tc = tcase_create("bip32"); - tcase_add_test(tc, test_bip32_vector_1); - tcase_add_test(tc, test_bip32_vector_2); - tcase_add_test(tc, test_bip32_vector_3); - tcase_add_test(tc, test_bip32_vector_4); - tcase_add_test(tc, test_bip32_compare); - tcase_add_test(tc, test_bip32_optimized); -#if USE_BIP32_CACHE - tcase_add_test(tc, test_bip32_cache_1); - tcase_add_test(tc, test_bip32_cache_2); -#endif - suite_add_tcase(s, tc); - - tc = tcase_create("bip32-nist"); - tcase_add_test(tc, test_bip32_nist_seed); - tcase_add_test(tc, test_bip32_nist_vector_1); - tcase_add_test(tc, test_bip32_nist_vector_2); - tcase_add_test(tc, test_bip32_nist_compare); - tcase_add_test(tc, test_bip32_nist_repeat); - suite_add_tcase(s, tc); - - tc = tcase_create("bip32-ed25519"); - tcase_add_test(tc, test_bip32_ed25519_vector_1); - tcase_add_test(tc, test_bip32_ed25519_vector_2); - suite_add_tcase(s, tc); - - tc = tcase_create("bip32-ecdh"); - tcase_add_test(tc, test_bip32_ecdh_nist256p1); - tcase_add_test(tc, test_bip32_ecdh_curve25519); - tcase_add_test(tc, test_bip32_ecdh_errors); - suite_add_tcase(s, tc); - - tc = tcase_create("bip32-decred"); - tcase_add_test(tc, test_bip32_decred_vector_1); - tcase_add_test(tc, test_bip32_decred_vector_2); - suite_add_tcase(s, tc); - - tc = tcase_create("ecdsa"); - tcase_add_test(tc, test_ecdsa_get_public_key33); - tcase_add_test(tc, test_ecdsa_get_public_key65); - tcase_add_test(tc, test_ecdsa_recover_pub_from_sig); - tcase_add_test(tc, test_ecdsa_verify_digest); -#if USE_RFC6979 - tcase_add_test(tc, test_ecdsa_sign_digest_deterministic); -#endif - suite_add_tcase(s, tc); - - tc = tcase_create("rfc6979"); - tcase_add_test(tc, test_rfc6979); - suite_add_tcase(s, tc); - - tc = tcase_create("address"); - tcase_add_test(tc, test_address); - suite_add_tcase(s, tc); - - tc = tcase_create("address_decode"); - tcase_add_test(tc, test_address_decode); - suite_add_tcase(s, tc); - -#if USE_ETHEREUM - tc = tcase_create("ethereum_address"); - tcase_add_test(tc, test_ethereum_address); - suite_add_tcase(s, tc); - - tc = tcase_create("rsk_address"); - tcase_add_test(tc, test_rsk_address); - suite_add_tcase(s, tc); -#endif - - tc = tcase_create("wif"); - tcase_add_test(tc, test_wif); - suite_add_tcase(s, tc); - - tc = tcase_create("ecdsa_der"); - tcase_add_test(tc, test_ecdsa_der); - suite_add_tcase(s, tc); - - tc = tcase_create("aes"); - tcase_add_test(tc, test_aes); - suite_add_tcase(s, tc); - - tc = tcase_create("sha2"); - tcase_add_test(tc, test_sha1); - tcase_add_test(tc, test_sha256); - tcase_add_test(tc, test_sha512); - suite_add_tcase(s, tc); - - tc = tcase_create("sha3"); - tcase_add_test(tc, test_sha3_256); - tcase_add_test(tc, test_sha3_512); - tcase_add_test(tc, test_keccak_256); - suite_add_tcase(s, tc); - - tc = tcase_create("blake"); - tcase_add_test(tc, test_blake256); - suite_add_tcase(s, tc); - - tc = tcase_create("blake2"); - tcase_add_test(tc, test_blake2b); - tcase_add_test(tc, test_blake2bp); - tcase_add_test(tc, test_blake2s); - suite_add_tcase(s, tc); - - tc = tcase_create("chacha_drbg"); - tcase_add_test(tc, test_chacha_drbg); - suite_add_tcase(s, tc); - - tc = tcase_create("pbkdf2"); - tcase_add_test(tc, test_pbkdf2_hmac_sha256); - tcase_add_test(tc, test_pbkdf2_hmac_sha512); - suite_add_tcase(s, tc); - - tc = tcase_create("hmac_drbg"); - tcase_add_test(tc, test_hmac_drbg); - suite_add_tcase(s, tc); - - tc = tcase_create("bip39"); - tcase_add_test(tc, test_mnemonic); - tcase_add_test(tc, test_mnemonic_check); - tcase_add_test(tc, test_mnemonic_to_bits); - tcase_add_test(tc, test_mnemonic_find_word); - suite_add_tcase(s, tc); - - tc = tcase_create("slip39"); - tcase_add_test(tc, test_slip39_get_word); - tcase_add_test(tc, test_slip39_word_index); - tcase_add_test(tc, test_slip39_word_completion_mask); - tcase_add_test(tc, test_slip39_sequence_to_word); - tcase_add_test(tc, test_slip39_word_completion); - suite_add_tcase(s, tc); - - tc = tcase_create("shamir"); - tcase_add_test(tc, test_shamir); - suite_add_tcase(s, tc); - - tc = tcase_create("pubkey_validity"); - tcase_add_test(tc, test_pubkey_validity); - suite_add_tcase(s, tc); - - tc = tcase_create("pubkey_uncompress"); - tcase_add_test(tc, test_pubkey_uncompress); - suite_add_tcase(s, tc); - - tc = tcase_create("codepoints"); - tcase_add_test(tc, test_codepoints_secp256k1); - tcase_add_test(tc, test_codepoints_nist256p1); - suite_add_tcase(s, tc); - - tc = tcase_create("mult_border_cases"); - tcase_add_test(tc, test_mult_border_cases_secp256k1); - tcase_add_test(tc, test_mult_border_cases_nist256p1); - suite_add_tcase(s, tc); - - tc = tcase_create("scalar_mult"); - tcase_add_test(tc, test_scalar_mult_secp256k1); - tcase_add_test(tc, test_scalar_mult_nist256p1); - suite_add_tcase(s, tc); - - tc = tcase_create("point_mult"); - tcase_add_test(tc, test_point_mult_secp256k1); - tcase_add_test(tc, test_point_mult_nist256p1); - suite_add_tcase(s, tc); - - tc = tcase_create("scalar_point_mult"); - tcase_add_test(tc, test_scalar_point_mult_secp256k1); - tcase_add_test(tc, test_scalar_point_mult_nist256p1); - suite_add_tcase(s, tc); - - tc = tcase_create("ed25519"); - tcase_add_test(tc, test_ed25519); - suite_add_tcase(s, tc); - - tc = tcase_create("ed25519_keccak"); - tcase_add_test(tc, test_ed25519_keccak); - suite_add_tcase(s, tc); - - tc = tcase_create("ed25519_cosi"); - tcase_add_test(tc, test_ed25519_cosi); - suite_add_tcase(s, tc); - - tc = tcase_create("ed25519_modm"); - tcase_add_test(tc, test_ed25519_modl_add); - tcase_add_test(tc, test_ed25519_modl_neg); - tcase_add_test(tc, test_ed25519_modl_sub); - suite_add_tcase(s, tc); - -#if USE_MONERO - tc = tcase_create("ed25519_ge"); - tcase_add_test(tc, test_ge25519_double_scalarmult_vartime2); - suite_add_tcase(s, tc); -#endif - - tc = tcase_create("script"); - tcase_add_test(tc, test_output_script); - suite_add_tcase(s, tc); - -#if USE_ETHEREUM - tc = tcase_create("ethereum_pubkeyhash"); - tcase_add_test(tc, test_ethereum_pubkeyhash); - suite_add_tcase(s, tc); -#endif - -#if USE_NEM - tc = tcase_create("nem_address"); - tcase_add_test(tc, test_nem_address); - suite_add_tcase(s, tc); - - tc = tcase_create("nem_encryption"); - tcase_add_test(tc, test_nem_derive); - tcase_add_test(tc, test_nem_cipher); - suite_add_tcase(s, tc); - - tc = tcase_create("nem_transaction"); - tcase_add_test(tc, test_nem_transaction_transfer); - tcase_add_test(tc, test_nem_transaction_multisig); - tcase_add_test(tc, test_nem_transaction_provision_namespace); - tcase_add_test(tc, test_nem_transaction_mosaic_creation); - tcase_add_test(tc, test_nem_transaction_mosaic_supply_change); - tcase_add_test(tc, test_nem_transaction_aggregate_modification); - suite_add_tcase(s, tc); -#endif - - tc = tcase_create("multibyte_address"); - tcase_add_test(tc, test_multibyte_address); - suite_add_tcase(s, tc); - - tc = tcase_create("rc4"); - tcase_add_test(tc, test_rc4_rfc6229); - suite_add_tcase(s, tc); - -#if USE_SEGWIT - tc = tcase_create("segwit"); - tcase_add_test(tc, test_segwit); - suite_add_tcase(s, tc); -#endif - - tc = tcase_create("cashaddr"); - tcase_add_test(tc, test_cashaddr); - suite_add_tcase(s, tc); - - tc = tcase_create("compress_coords"); - tcase_add_test(tc, test_compress_coords); - suite_add_tcase(s, tc); - -#if USE_CARDANO - tc = tcase_create("bip32-cardano"); - - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_1); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_2); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_3); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_4); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_5); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_6); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_7); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_8); - tcase_add_test(tc, test_bip32_cardano_hdnode_vector_9); - - tcase_add_test(tc, test_cardano_ledger_vector_1); - tcase_add_test(tc, test_cardano_ledger_vector_2); - tcase_add_test(tc, test_cardano_ledger_vector_3); - - tcase_add_test(tc, test_ed25519_cardano_sign_vectors); - suite_add_tcase(s, tc); -#endif - -#if USE_MONERO - tc = tcase_create("xmr_base58"); - tcase_add_test(tc, test_xmr_base58); - suite_add_tcase(s, tc); - - tc = tcase_create("xmr_crypto"); - tcase_add_test(tc, test_xmr_getset256_modm); - tcase_add_test(tc, test_xmr_cmp256_modm); - tcase_add_test(tc, test_xmr_copy_check_modm); - tcase_add_test(tc, test_xmr_mulsub256_modm); - tcase_add_test(tc, test_xmr_muladd256_modm); - tcase_add_test(tc, test_xmr_curve25519_set); - tcase_add_test(tc, test_xmr_curve25519_consts); - tcase_add_test(tc, test_xmr_curve25519_tests); - tcase_add_test(tc, test_xmr_curve25519_expand_reduce); - tcase_add_test(tc, test_xmr_ge25519_base); - tcase_add_test(tc, test_xmr_ge25519_check); - tcase_add_test(tc, test_xmr_ge25519_scalarmult_base_wrapper); - tcase_add_test(tc, test_xmr_ge25519_scalarmult); - tcase_add_test(tc, test_xmr_ge25519_ops); - suite_add_tcase(s, tc); - - tc = tcase_create("xmr_xmr"); - tcase_add_test(tc, test_xmr_check_point); - tcase_add_test(tc, test_xmr_h); - tcase_add_test(tc, test_xmr_fast_hash); - tcase_add_test(tc, test_xmr_hasher); - tcase_add_test(tc, test_xmr_hash_to_scalar); - tcase_add_test(tc, test_xmr_hash_to_ec); - tcase_add_test(tc, test_xmr_derivation_to_scalar); - tcase_add_test(tc, test_xmr_generate_key_derivation); - tcase_add_test(tc, test_xmr_derive_private_key); - tcase_add_test(tc, test_xmr_derive_public_key); - tcase_add_test(tc, test_xmr_add_keys2); - tcase_add_test(tc, test_xmr_add_keys3); - tcase_add_test(tc, test_xmr_get_subaddress_secret_key); - tcase_add_test(tc, test_xmr_gen_c); - tcase_add_test(tc, test_xmr_varint); - suite_add_tcase(s, tc); -#endif - - return s; -} - -// run suite -int main(void) { - int number_failed; - Suite *s = test_suite(); - SRunner *sr = srunner_create(s); - srunner_run_all(sr, CK_VERBOSE); - number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - if (number_failed == 0) { - printf("PASSED ALL TESTS\n"); - } - return number_failed; -} diff --git a/trezor-crypto/crypto/tests/test_check_cardano.h b/trezor-crypto/crypto/tests/test_check_cardano.h deleted file mode 100644 index 4f31a55309f..00000000000 --- a/trezor-crypto/crypto/tests/test_check_cardano.h +++ /dev/null @@ -1,571 +0,0 @@ -// https://github.com/input-output-hk/cardano-crypto/blob/master/tests/goldens/cardano/crypto/wallet/BIP39-128 -START_TEST(test_ed25519_cardano_sign_vectors) { - ed25519_public_key public_key; - ed25519_secret_key secret_key; - ed25519_secret_key secret_key_extension; - ed25519_signature signature; - - static const char *vectors[] = { - "6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5" - "3", // private key - "60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8" - "e", // private key extension - "64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe" - "1", // public key - "45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7" - "9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10" - "d", // signature - - "e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830" - "c", // private key - "794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a" - "4", // private key extension - "95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d" - "f", // public key - "f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1" - "9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560" - "f", // signature - - "9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0" - "c", // private key - "b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb" - "b", // private key extension - "79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19" - "f", // public key - "2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a" - "88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800" - "f", // signature - - "52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40" - "c", // private key - "6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580" - "3", // private key extension - "dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d" - "6", // public key - "0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6" - "2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160" - "2", // signature - - "11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0" - "4", // private key - "c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235" - "2", // private key extension - "839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7" - "8", // public key - "e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f" - "9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490" - "5", // signature - - "5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50" - "5", // private key - "ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c" - "d", // private key extension - "75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7" - "6", // public key - "631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb" - "c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890" - "6", // signature - - "624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50" - "d", // private key - "097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0" - "2", // private key extension - "0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0" - "0", // public key - "1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a" - "57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90" - "1", // signature - - 0, - 0, - }; - - const char **test_data; - test_data = vectors; - while (*test_data) { - memcpy(secret_key, fromhex(*test_data), 32); - MARK_SECRET_DATA(secret_key, sizeof(secret_key)); - - memcpy(secret_key_extension, fromhex(*(test_data + 1)), 32); - MARK_SECRET_DATA(secret_key_extension, sizeof(secret_key_extension)); - - ed25519_publickey_ext(secret_key, public_key); - UNMARK_SECRET_DATA(public_key, sizeof(public_key)); - - ck_assert_mem_eq(public_key, fromhex(*(test_data + 2)), 32); - - const uint8_t *message = (const uint8_t *)"Hello World"; - ed25519_sign_ext(message, 11, secret_key, secret_key_extension, signature); - UNMARK_SECRET_DATA(signature, sizeof(signature)); - - ck_assert_mem_eq(signature, fromhex(*(test_data + 3)), 64); - - UNMARK_SECRET_DATA(secret_key, sizeof(secret_key)); - UNMARK_SECRET_DATA(secret_key_extension, sizeof(secret_key_extension)); - - test_data += 4; - } -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_1) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - ck_assert_mem_eq( - cardano_secret, - fromhex( - "08a14df748e477a69d21c97c56db151fc19e2521f31dd0ac5360f269e5b6ea46" - "daeb991f2d2128e2525415c56a07f4366baa26c1e48572a5e073934b6de35fbc" - "affbc325d9027c0f2d9f925b1dcf6c12bf5c1dd08904474066a4f2c00db56173"), - 96); - ck_assert_mem_eq( - node.chain_code, - fromhex( - "affbc325d9027c0f2d9f925b1dcf6c12bf5c1dd08904474066a4f2c00db56173"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "08a14df748e477a69d21c97c56db151fc19e2521f31dd0ac5360f269e5b6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "daeb991f2d2128e2525415c56a07f4366baa26c1e48572a5e073934b6de35fbc"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "9a1d04808b4c0682816961cf666e82a7fd35949658aba5354c517eccf12aacb4"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_2) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "104c6a0736e501c9bfe2966ba3773f5320495b19c3f2ed222234850af2ccd5b1"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "6064bf06b2e981d7c9792b1482eeecd40ec3cfa12143f4a1f149d48ce8b6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "64aa9a16331f14c981b769efcf96addcc4c6db44047fe7a7feae0be23d33bf54"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "c651c14a13c2311fc30a7acf244add1fdac3683e7ba89b4571e4cbcab509b915"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_3) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000001); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "da99870d7e69de2a76f255ba8c7ed22428c7e5b0a8df978753c707c95ec3d4ca"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "c85fa69f4a1891fd98d1d1fc5f0cf9b1d6e44b0e6906744ab23ea766edb6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "b4fc241feffe840b8a54a26ab447f5a5caa31032db3a8091fca14f38b86ed539"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "5a5b0c92530cd366f05cf072509c806f904262c259e79a0080bbd5ee35706bb1"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_4) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "b40c44dfd9be08591b62be7f9991c85f812d8196927f3c824d9fcb17d275089e"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "d064dcf1449d9c3e47f5b422680343561989035bf2e4e23fc34cb61fedb6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "a3071959013af95aaecf78a7a2e1b9838bbbc4864d6a8a2295243782078345cd"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "aaaca5e7adc69a03ef1f5c017ed02879e8ca871df028461ed9bf19fb8fa15038"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_5) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - hdnode_private_ckd(&node, 0x80000002); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "2593896baf92f6ab2c0f253787ab16be0244ba95e0d48ba09da1a7fd3f926c72"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "0811b6d5d6f7120cb05d4ce5453d6ce42825c2a8e53b6d370a6b05ccf4b6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "5bebf1eea68acd04932653d944b064b10baaf5886dd73c185cc285059bf93363"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "1c87a32c5babad2fe33e0586bdc523574c6126f8368bc76598e17ea46201f980"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_6) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0x80000002); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "fe8c6c2ab1e30385513fcffb49dcfe3e7805260425ea76b3b72b9f5bbe3b3d40"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "6019b9f5ef6ca530b657bcdb500de5455db8d51afb951fa045b6fbb3f6b6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "466332cb097934b43008701e7e27044aa56c7859019e4eba18d91a3bea23dff7"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "0b8f04755481ced76b4e5795aaafdb3cbd757c10fe60e9c58f48cf29a7ec3575"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_7) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "ring crime symptom enough erupt lady behave ramp apart settle citizen " - "junk", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 132); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0xBB9ACA00); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "ff77c08d37471c1d4cedd3fae2642c009324d9712492efc74dedab09c9bf973c"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "488f34840bba516f7920f91676b8681d0dd833b4ce14468e0810b255f9b6ea46"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "01eccef768a79859f824a1d3c3e35e131184e2940c3fca9a4c9b307741f65363"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "148605be54585773b44ba87e79265149ae444c4cc37cb1f8db8c08482fba293b"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_8) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "found differ bulb shadow wrist blue bind vessel deposit tip pelican " - "action surprise weapon check fiction muscle this", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 198); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0xBB9ACA00); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "6fb22a4531ad79e828c4907c5fff3ecf686c16cb195f81243f1f0330173380e4"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "a0baa34e4e24f0500ed6e5e90ab41984b965b7464b0b28640528778dd8a6b854"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "170e0d3b65ba8d71f27a6db60d0ac26dcb16e52e08cc259db72066f206b258d5"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "3dae0c06d87db618d73ee808425898cdd882f9eb43bf139c6b3a4760551ee89f"), - 32); -} -END_TEST - -START_TEST(test_bip32_cardano_hdnode_vector_9) { - HDNode node; - - uint8_t mnemonic_bits[66]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - int mnemonic_bits_len = mnemonic_to_bits( - "balance exotic ranch knife glory slow tape favorite yard gym awake " - "ill exist useless parent aim pig stay effort into square gasp credit " - "butter", - mnemonic_bits); - ck_assert_int_eq(mnemonic_bits_len, 264); - secret_from_entropy_cardano_icarus((const uint8_t *)"", 0, mnemonic_bits, - mnemonic_bits_len / 8, cardano_secret, - NULL); - hdnode_from_secret_cardano(cardano_secret, &node); - - hdnode_private_ckd(&node, 0x80000000); - hdnode_private_ckd(&node, 0x80000001); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0x80000002); - hdnode_private_ckd(&node, 0xBB9ACA00); - - ck_assert_mem_eq( - node.chain_code, - fromhex( - "9b226add79f90086ea18b260da633089fe121db758aa31284ad1affaf3c9bb68"), - 32); - ck_assert_mem_eq( - node.private_key, - fromhex( - "38eb2a79486e516cb6658700503a3e2c870c03e9d1aec731f780aa6fb7f7de44"), - 32); - ck_assert_mem_eq( - node.private_key_extension, - fromhex( - "80d2c677638e5dbd4395cdec279bf2a42077f2797c9e887949d37cdb317fce6a"), - 32); - ck_assert_int_eq(hdnode_fill_public_key(&node), 0); - ck_assert_mem_eq( - node.public_key + 1, - fromhex( - "115a365b2aad1d8eba7d379de518f1fa8553855110af24e5695011c32ce9a300"), - 32); -} -END_TEST - -START_TEST(test_cardano_ledger_vector_1) { - uint8_t seed[512 / 8]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - - const char *mnemonic = - "recall grace sport punch exhibit mad harbor stand obey " - "short width stem awkward used stairs wool ugly " - "trap season stove worth toward congress jaguar"; - - mnemonic_to_seed(mnemonic, "", seed, NULL); - const int res = - secret_from_seed_cardano_ledger(seed, sizeof(seed), cardano_secret); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - cardano_secret, - fromhex( - "a08cf85b564ecf3b947d8d4321fb96d70ee7bb760877e371899b14e2ccf88658" - "104b884682b57efd97decbb318a45c05a527b9cc5c2f64f7352935a049ceea60" - "680d52308194ccef2a18e6812b452a5815fbd7f5babc083856919aaf668fe7e4"), - CARDANO_SECRET_LENGTH); -} -END_TEST - -START_TEST(test_cardano_ledger_vector_2) { - uint8_t seed[512 / 8]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - - const char *mnemonic = - "correct cherry mammal bubble want mandate polar hazard " - "crater better craft exotic choice fun tourist census " - "gap lottery neglect address glow carry old business"; - - mnemonic_to_seed(mnemonic, "", seed, NULL); - const int res = - secret_from_seed_cardano_ledger(seed, sizeof(seed), cardano_secret); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - cardano_secret, - fromhex( - "587c6774357ecbf840d4db6404ff7af016dace0400769751ad2abfc77b9a3844" - "cc71702520ef1a4d1b68b91187787a9b8faab0a9bb6b160de541b6ee62469901" - "fc0beda0975fe4763beabd83b7051a5fd5cbce5b88e82c4bbaca265014e524bd"), - CARDANO_SECRET_LENGTH); -} -END_TEST - -START_TEST(test_cardano_ledger_vector_3) { - uint8_t seed[512 / 8]; - uint8_t cardano_secret[CARDANO_SECRET_LENGTH]; - - const char *mnemonic = - "abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon abandon " - "abandon abandon abandon abandon abandon abandon abandon art"; - - mnemonic_to_seed(mnemonic, "foo", seed, NULL); - const int res = - secret_from_seed_cardano_ledger(seed, sizeof(seed), cardano_secret); - ck_assert_int_eq(res, 1); - ck_assert_mem_eq( - cardano_secret, - fromhex( - "f053a1e752de5c26197b60f032a4809f08bb3e5d90484fe42024be31efcba757" - "8d914d3ff992e21652fee6a4d99f6091006938fac2c0c0f9d2de0ba64b754e92" - "a4f3723f23472077aa4cd4dd8a8a175dba07ea1852dad1cf268c61a2679c3890"), - CARDANO_SECRET_LENGTH); -} -END_TEST diff --git a/trezor-crypto/crypto/tests/test_check_cashaddr.h b/trezor-crypto/crypto/tests/test_check_cashaddr.h deleted file mode 100644 index 4b60067f275..00000000000 --- a/trezor-crypto/crypto/tests/test_check_cashaddr.h +++ /dev/null @@ -1,68 +0,0 @@ -#include - -const char* valid_cashchecksum[] = { - "prefix:x64nx6hz", - "p:gpf8m4h7", - "bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn", - "bchtest:testnetaddress4d6njnut", - "bchreg:555555555555555555555555555555555555555555555udxmlmrz", -}; - -struct valid_cashaddr_data { - const char* legacy; - const char* cashaddress; -}; - -struct valid_cashaddr_data valid_cashaddr[] = { - {"1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu", - "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"}, - {"1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR", - "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"}, - {"16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb", - "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"}, - {"3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC", - "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"}, - {"3LDsS579y7sruadqu11beEJoTjdFiFCdX4", - "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"}, - {"31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw", - "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"}}; - -START_TEST(test_cashaddr) { - size_t i; - for (i = 0; i < sizeof(valid_cashchecksum) / sizeof(valid_cashchecksum[0]); - ++i) { - uint8_t data[82]; - char rebuild[92]; - char hrp[84]; - size_t data_len; - int res = cash_decode(hrp, data, &data_len, valid_cashchecksum[i]); - ck_assert_int_eq(res, 1); - res = cash_encode(rebuild, hrp, data, data_len); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(my_strncasecmp(rebuild, valid_cashchecksum[i], 92), 0); - } - for (i = 0; i < sizeof(valid_cashaddr) / sizeof(valid_cashaddr[0]); ++i) { - uint8_t prog[65]; - size_t prog_len; - const char* hrp = "bitcoincash"; - uint8_t rawdata[65]; - size_t rawdata_len; - char rebuild[93]; - int ret = - cash_addr_decode(prog, &prog_len, hrp, valid_cashaddr[i].cashaddress); - ck_assert_int_eq(ret, 1); - ck_assert_int_eq(prog_len, 21); - rawdata_len = base58_decode_check(valid_cashaddr[i].legacy, HASHER_SHA2D, - rawdata, sizeof(rawdata)); - ck_assert_int_eq(rawdata_len, 21); - ck_assert_int_eq(prog[0], rawdata[0] == 0 ? 0x00 - : rawdata[0] == 5 ? 0x08 - : -1); - ck_assert_int_eq(memcmp(rawdata + 1, prog + 1, 20), 0); - ret = cash_addr_encode(rebuild, hrp, prog, 21); - ck_assert_int_eq(ret, 1); - ck_assert_int_eq(my_strncasecmp(rebuild, valid_cashaddr[i].cashaddress, 92), - 0); - } -} -END_TEST diff --git a/trezor-crypto/crypto/tests/test_check_monero.h b/trezor-crypto/crypto/tests/test_check_monero.h deleted file mode 100644 index bba546f5050..00000000000 --- a/trezor-crypto/crypto/tests/test_check_monero.h +++ /dev/null @@ -1,1182 +0,0 @@ -#if USE_MONERO -#include "../monero/base58.h" - -START_TEST(test_xmr_base58) { - const struct { - uint64_t tag; - char *v1; - char *v2; - } tests[] = { - {0x12, - "3bec484c5d7f0246af520aab550452b5b6013733feabebd681c4a60d457b7fc12d5918e" - "31d3c003da3c778592c07b398ad6f961a67082a75fd49394d51e69bbe", - "43tpGG9PKbwCpjRvNLn1jwXPpnacw2uVUcszAtgmDiVcZK4VgHwjJT9BJz1WGF9eMxSYASp" - "8yNMkuLjeQfWqJn3CNWdWfzV"}, - {0x12, - "639050436fa36c8288706771412c5972461578d564188cd7fc6f81d6973d064fa461afe" - "66fb23879936d7225051bebbf7f3ae0c801a90bb99fbb346b2fd4d702", - "45PwgoUKaDHNqLL8o3okzLL7biv7GqPVmd8LTcTrYVrMEKdSYwFcyJfMLSRpfU3nh8Z2m81" - "FJD4sUY3nXCdGe61k1HAp8T1"}, - {53, - "5a10cca900ee47a7f412cd661b29f5ab356d6a1951884593bb170b5ec8b6f2e83b1da41" - "1527d062c9fedeb2dad669f2f5585a00a88462b8c95c809a630e5734c", - "9vacMKaj8JJV6MnwDzh2oNVdwTLJfTDyNRiB6NzV9TT7fqvzLivH2dB8Tv7VYR3ncn8vCb3" - "KdNMJzQWrPAF1otYJ9cPKpkr"}, - }; - - uint8_t rawn[512]; - char strn[512]; - int r; - uint64_t tag; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - const char *raw = tests[i].v1; - const char *str = tests[i].v2; - const size_t len = strlen(raw) / 2; - - memcpy(rawn, fromhex(raw), len); - - r = xmr_base58_addr_encode_check(tests[i].tag, rawn, len, strn, - sizeof(strn)); - ck_assert_int_eq((size_t)r, strlen(str)); - ck_assert_mem_eq(strn, str, r); - - r = xmr_base58_addr_decode_check(strn, r, &tag, rawn, len); - ck_assert_int_eq(r, len); - ck_assert_mem_eq(rawn, fromhex(raw), len); - } -} -END_TEST - -START_TEST(test_xmr_getset256_modm) { - const struct { - uint64_t val; - int r; - char *a; - } tests[] = { - {0x0, 1, - "0000000000000000000000000000000000000000000000000000000000000000"}, - {0x7fffffffULL, 1, - "ffffff7f00000000000000000000000000000000000000000000000000000000"}, - {0x7fffffffffffffffULL, 1, - "ffffffffffffff7f000000000000000000000000000000000000000000000000"}, - {0xdeadc0deULL, 1, - "dec0adde00000000000000000000000000000000000000000000000000000000"}, - {0x0, 0, - "dec0adde000000000000000000000000000000000000000000000000000000ff"}, - {0x0, 0, - "ffffffffffffffffff0000000000000000000000000000000000000000000000"}, - }; - - uint8_t rawn[32]; - uint64_t v1; - bignum256modm a1 = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - int get_res = tests[i].r; - if (get_res) { - set256_modm(a1, tests[i].val); - ck_assert_int_eq(get256_modm(&v1, a1), 1); - ck_assert(v1 == tests[i].val); - - contract256_modm(rawn, a1); - ck_assert_mem_eq(rawn, fromhex(tests[i].a), 32); - - } else { - expand256_modm(a1, fromhex(tests[i].a), 32); - ck_assert_int_eq(get256_modm(&v1, a1), 0); - } - } -} -END_TEST - -START_TEST(test_xmr_cmp256_modm) { - const struct { - char *a; - char *b; - int res_eq; - int res_cmp; - int res_is_zero_a; - } tests[] = { - {"0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", 1, 0, - 1}, - {"0000000000000000000000000000000000000000000000000000000000000000", - "0100000000000000000000000000000000000000000000000000000000000000", 0, - -1, 1}, - {"dec0adde00000000000000000000000000000000000000000000000000000000", - "dec0adde00000000000000000000000000000000000000000000000000000000", 1, 0, - 0}, - {"863346d8863c461cde2ec7c2759352c2b952228f33a86ca06bb79574bbe5c30d", - "3ddbd65a6d3ba5e2ab120603685a353a27ce3fd21dfdbea7952d2dd26f1ca00a", 0, 1, - 0}, - {"f7667f392edbea6e224b1aa9fbf2a3b238b4f977fb4a8f39130cc45f49b5c40a", - "b41b9b1e7e80be71cf290ed4bded58924086b8ac6bdfa1faa0c80c255f074d07", 0, 1, - 0}, - {"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27501", - "0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", 0, - -1, 0}, - {"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", - "0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", 1, 0, - 0}, - {"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", - "0e4005c7826de8f9978749903f41efd140e4ae6d3bed09e558fcce8367b27504", 0, - -1, 0}, - }; - - bignum256modm a1 = {0}, a2 = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a1, fromhex(tests[i].a), 32); - expand256_modm(a2, fromhex(tests[i].b), 32); - - ck_assert_int_eq(eq256_modm(a1, a2), tests[i].res_eq); - ck_assert_int_eq(cmp256_modm(a1, a2), tests[i].res_cmp); - ck_assert_int_eq(iszero256_modm(a1), tests[i].res_is_zero_a); - } -} -END_TEST - -START_TEST(test_xmr_copy_check_modm) { - const struct { - int check; - char *a; - } tests[] = { - {0, "0000000000000000000000000000000000000000000000000000000000000000"}, - {1, "ffffff7f00000000000000000000000000000000000000000000000000000000"}, - {1, "ffffffffffffff7f000000000000000000000000000000000000000000000000"}, - {1, "dec0adde00000000000000000000000000000000000000000000000000000000"}, - {0, "dec0adde000000000000000000000fffffffffffffffffffffffffffffffffff"}, - }; - - bignum256modm a1 = {0}, a2 = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand_raw256_modm(a1, fromhex(tests[i].a)); - copy256_modm(a2, a1); - ck_assert_int_eq(eq256_modm(a1, a2), 1); - ck_assert_int_eq(check256_modm(a1), tests[i].check); - } -} -END_TEST - -START_TEST(test_xmr_mulsub256_modm) { - const struct { - char *a; - char *b; - char *c; - char *r; - } tests[] = { - { - "713c199348cf7d14b67ae6265ea49c02c8647f07afcbcb6f8d3254b3db972e02", - "4e48a7b7a03ab1106fdfa9441a03c97c644395a12ac4b8effac7344e0719c200", - "1a5711b8c43bcab0161a620368d82727e1d027dc248f420d9bb4db2486c16405", - "6edcc08aa6ec3a5b3d333b5f826be7de9c268be8aaf9521586fbcccbed3b1c0c", - }, - { - "d4ade2c62d34af8cfd9daec6f46bf7e57962a8aa46935cb11fab64fa599b4700", - "22ea7989a9f4d34cd8c9442e03b5062dfe8493757cd18a63411cb1a25e44960f", - "772053e613f0859387badcefeb7fbe551a05b00b9337539c8d72661de5929806", - "a5063258df4520b33e97c0a46d80feeace5c251fc7ef7a938d160b8f25795106", - }, - { - "01fd2ef25c8221277a2b6daf1f1642bacb8d6ac0dd4f62731cdd73e26eb77900", - "0611b9357530aa638428002769ce0ad553421e971bea1f10d7009bf26d9af805", - "dfece232068b2f8059ca569f345baaed13ab464eb3bebb99de5625dc90a8cf03", - "85752e62bd8085c7c02d5edeb74969d22f1a5bb34349258d2e96de300176bb07", - }, - }; - - bignum256modm a = {0}, b = {0}, c = {0}, r = {0}, r2 = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i].a), 32); - expand256_modm(b, fromhex(tests[i].b), 32); - expand256_modm(c, fromhex(tests[i].c), 32); - expand256_modm(r, fromhex(tests[i].r), 32); - mulsub256_modm(r2, a, b, c); - ck_assert_int_eq(eq256_modm(r, r2), 1); - } -} -END_TEST - -START_TEST(test_xmr_muladd256_modm) { - const struct { - char *a; - char *b; - char *c; - char *r; - } tests[] = { - { - "7c3fd8abfbe2be3739d91679ac8dbda086961b941e0d4a00561f758927d8aa09", - "ac2d8d37e4f344aa4040d0f0fc29d45423ab7e69ecacb94ca9fc36819e0e990e", - "2f03f1bac09bc7d002848b68be069dc98b2db028390ae37e13a5166fcae08105", - "dce113add3392f08e3b38b7d31e237eba5066e5a95a1fdbf755b92d05e1ec70b", - }, - { - "6979b70f6198d043f4b14e2069f7b89cc9f09e3465e71d472946443989e0e80c", - "8dd5177bc8d7c5bd58c0be74b336952a73ac259ebb812ac8cd755773c6aab807", - "d7658e508a7454ccfb29e2890d6156ac10e18ebe6e00cc5a2d2d87a5080c7f06", - "51b33f6263772781cdbab26ef48870eaf94899894a437dac39496f15b9d0ae00", - }, - { - "ebfdb4eabedb1fb9a45b3204735b0511871e20358392fa16a851c519e3a29b09", - "59d98831e9f9e24260158986c4d4035438de9b8876cc11bdcf4c364c75f72908", - "93bce4764eee97dc67f2e37da40bc5641f2cdc637285d273287a3d4383b68f02", - "21547ca6855c85d5adcd673b9d801d0cb0f10dced8f8b68a8c2f74163defde0e", - }, - }; - - bignum256modm a = {0}, b = {0}, c = {0}, r = {0}, r2 = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i].a), 32); - expand256_modm(b, fromhex(tests[i].b), 32); - expand256_modm(c, fromhex(tests[i].c), 32); - expand256_modm(r, fromhex(tests[i].r), 32); - muladd256_modm(r2, a, b, c); - ck_assert_int_eq(eq256_modm(r, r2), 1); - } -} -END_TEST - -START_TEST(test_xmr_curve25519_set) { - const struct { - uint32_t val; - char *a; - } tests[] = { - {0x0, "0000000000000000000000000000000000000000000000000000000000000000"}, - {0x1, "0100000000000000000000000000000000000000000000000000000000000000"}, - {0xdeadc0deUL, - "dec0adde00000000000000000000000000000000000000000000000000000000"}, - }; - - unsigned char buff[32]; - bignum25519 a = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - curve25519_set(a, tests[i].val); - curve25519_contract(buff, a); - ck_assert_mem_eq(buff, fromhex(tests[i].a), 32); - } -} -END_TEST - -START_TEST(test_xmr_curve25519_consts) { - char *d = "a3785913ca4deb75abd841414d0a700098e879777940c78c73fe6f2bee6c0352"; - char *d2 = "59f1b226949bd6eb56b183829a14e00030d1f3eef2808e19e7fcdf56dcd90624"; - char *sqrtneg1 = - "b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b"; - - unsigned char buff[32]; - bignum25519 a = {0}; - - curve25519_set_d(a); - curve25519_contract(buff, a); - ck_assert_mem_eq(buff, fromhex(d), 32); - - curve25519_set_2d(a); - curve25519_contract(buff, a); - ck_assert_mem_eq(buff, fromhex(d2), 32); - - curve25519_set_sqrtneg1(a); - curve25519_contract(buff, a); - ck_assert_mem_eq(buff, fromhex(sqrtneg1), 32); -} -END_TEST - -START_TEST(test_xmr_curve25519_tests) { - const struct { - char *a; - int res_neg; - int res_nonzero; - } tests[] = { - { - "0000000000000000000000000000000000000000000000000000000000000000", - 0, - 0, - }, - { - "0100000000000000000000000000000000000000000000000000000000000000", - 1, - 1, - }, - { - "05737aa6100ee54283dc0d483b8e39e61846f6b3736908243d0c824d250b3139", - 1, - 1, - }, - { - "95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15", - 1, - 1, - }, - { - "02587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15", - 0, - 1, - }, - }; - - bignum25519 a = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - curve25519_expand(a, fromhex(tests[i].a)); - ck_assert_int_eq(curve25519_isnegative(a), tests[i].res_neg); - ck_assert_int_eq(curve25519_isnonzero(a), tests[i].res_nonzero); - } -} -END_TEST - -START_TEST(test_xmr_curve25519_expand_reduce) { - const struct { - char *a; - char *b; - } tests[] = { - {"dec0adde00000000000000000000000000000000000000000000000000000000", - "dec0adde00000000000000000000000000000000000000000000000000000000"}, - {"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15", - "95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15"}, - {"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bcff", - "a8587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc7f"}, - {"95587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bcff", - "a8587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bc7f"}, - }; - - unsigned char buff[32]; - bignum25519 a = {0}; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - curve25519_expand_reduce(a, fromhex(tests[i].a)); - curve25519_contract(buff, a); - ck_assert_mem_eq(buff, fromhex(tests[i].b), 32); - } -} -END_TEST - -START_TEST(test_xmr_ge25519_base) { - unsigned char buff[32]; - char *base = - "5866666666666666666666666666666666666666666666666666666666666666"; - ge25519 b; - ge25519_set_base(&b); - ge25519_pack(buff, &b); - ck_assert_mem_eq(buff, fromhex(base), 32); -} -END_TEST - -START_TEST(test_xmr_ge25519_check) { - const struct { - char *x; - char *y; - char *z; - char *t; - int r; - } tests[] = { - {"4ff97748221f954414f836d84e8e7e207786bcd20eb67044756dca307e792c60", - "2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7f63", - "0100000000000000000000000000000000000000000000000000000000000000", - "3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 1}, - {"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c", - "ca48045f790145a1eec3946dfd73747fde0fdb4238607e0a203f8ef5bef90e0e", - "0100000000000000000000000000000000000000000000000000000000000000", - "6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 1}, - {"4ff97748221f954414f836d84e8e7e207786bcd20eb6704475ffca307e792c60", - "2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7f63", - "0100000000000000000000000000000000000000000000000000000000000000", - "3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 0}, - {"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c", - "ca48045f790145a1eec3946dfd73747fdfffdb4238607e0a203f8ef5bef90e0e", - "0100000000000000000000000000000000000000000000000000000000000000", - "6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0}, - {"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c", - "ca48045f790145a1eec3946dfd73747fdfffdb4238607e0a203f8ef5bef90e0e", - "0100000000000000000000000000000000000000000000000000000000000000", - "6c5e5ffae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0}, - }; - - struct ge25519_t p; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - curve25519_expand_reduce(p.x, fromhex(tests[i].x)); - curve25519_expand_reduce(p.y, fromhex(tests[i].y)); - curve25519_expand_reduce(p.z, fromhex(tests[i].z)); - curve25519_expand_reduce(p.t, fromhex(tests[i].t)); - ck_assert_int_eq(ge25519_check(&p), tests[i].r); - } -} -END_TEST - -START_TEST(test_xmr_ge25519_scalarmult_base_wrapper) { - const struct { - char *sc; - char *pt; - } tests[] = { - { - "40be740e26bd1c84f5a8fec737c0ed30e87bd45adfcd91e320f8dfb68b1a870e", - "b7a8b2f3dbfd41b38d20aec733a316dbfc2633503799cd36f38570cafc8ea887", - }, - { - "1b3746add992215d427e43a58354c11ff9e6dfa1c187250938f7f9334fa41d05", - "e2a1bfbe38a9749fe6ede79d923b778fa4c89393473d633bec01fa68617d0828", - }, - { - "69af25c54090a9746d3f6043348452429ffd53c1530fa114fd0055b70d61020f", - "6bf1783b0a7495d5f6c36605dca95e723ca120a306c255084787f09b12771124", - }, - { - "0000000000000000000000000000000000000000000000000000000000000000", - "0100000000000000000000000000000000000000000000000000000000000000", - }, - { - "0100000000000000000000000000000000000000000000000000000000000000", - "5866666666666666666666666666666666666666666666666666666666666666", - }, - { - "0800000000000000000000000000000000000000000000000000000000000000", - "b4b937fca95b2f1e93e41e62fc3c78818ff38a66096fad6e7973e5c90006d321", - }, - { - "ffffffffffffffff000000000000000000000000000000000000000000000000", - "e185757a3fdc6519a6e7bebd97aa52bdc999e4c87d5c3aad0d995763ab6c6985", - }, - }; - - ge25519 pt, pt2; - bignum256modm sc; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(sc, fromhex(tests[i].sc), 32); - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - ge25519_scalarmult_base_wrapper(&pt2, sc); - ck_assert_int_eq(ge25519_eq(&pt, &pt2), 1); - } -} -END_TEST - -START_TEST(test_xmr_ge25519_scalarmult) { - const struct { - char *sc; - char *pt; - char *pt2; - } tests[] = { - { - "0000000000000000000000000000000000000000000000000000000000000000", - "5cbb3b2784c16f0e7eb4f2a7f93288552bb24ec51c5e01504c1e6885cfbca6d0", - "0100000000000000000000000000000000000000000000000000000000000000", - }, - { - "0100000000000000000000000000000000000000000000000000000000000000", - "f39b6770008d069acb92eb95329dec2cb0054da024e437a1bdf1ae06527deff6", - "f39b6770008d069acb92eb95329dec2cb0054da024e437a1bdf1ae06527deff6", - }, - { - "3930000000000000000000000000000000000000000000000000000000000000", - "2835b3983e3cc01a640fd188bf6bbbafbf997a3344d800eed22e4e82a412941c", - "2fe8b2dd0f23e02fca6989e170135584d684583c0a44f6a7d3ebd964685d36c7", - }, - { - "ffffffffffffffff000000000000000000000000000000000000000000000000", - "bb8af7a53a8f1b477c810e833a84cdc789a6b81a6b6417be4f97ffd9ae0fe0b8", - "3a5c9a7dacca9dd8827881f38c36aad7d402a5efc2cab58c7553b903876e1491", - }, - { - "864203a09e1c788a482685c739af07355ebb2c840b7de6af87eff5f19ee3b807", - "d404a9bbf351e7320ea6d11cdeeccaf505f706731cb5e5d839b950edb7ba6286", - "11e09c89e0be7663e0e2d4a01fb05d6a3fd84a78a6fa4fd7daaacf2d19311a38", - }, - { - "3e01f05920a238e33766814d10f0c3a3e975072399ad90a823d4808db1d85209", - "52a2d35798a0ac209b8fa194fe398b869aba5f20d80ee3d8ca77759a8e0bae0d", - "4256addc2f036150f3fdc0a7905f01285239d6dd4eecc4be8e3b134eef4639fe", - }, - { - "ad63d591716a9e89a024a074bc6ce661268d1bb3665f91e8b981f189b1a49507", - "3928bde7a92e1341c3dfee35a66fa5639204f5b9747963278af430145028648d", - "9c959003ba91004956df98800a5024d94031db5ac659675b26350657d93c34f9", - }, - }; - - ge25519 pt, pt2, pt3; - bignum256modm sc; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(sc, fromhex(tests[i].sc), 32); - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - ge25519_unpack_vartime(&pt2, fromhex(tests[i].pt2)); - ge25519_scalarmult(&pt3, &pt, sc); - ck_assert_int_eq(ge25519_eq(&pt3, &pt2), 1); - } -} -END_TEST - -START_TEST(test_xmr_ge25519_ops) { - int tests[] = {1, 2, 7, 8, 637, 9912, 12345}; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - struct ge25519_t a, b, c, d; - bignum256modm s1 = {0}, s2 = {0}, s3 = {0}, s4 = {0}; - - set256_modm(s1, tests[i]); - set256_modm(s2, 8 * tests[i]); - set256_modm(s3, 8); - set256_modm(s4, 2); - - ge25519_scalarmult_base_niels(&a, ge25519_niels_base_multiples, s1); - ge25519_scalarmult_base_niels(&b, ge25519_niels_base_multiples, s2); - ge25519_scalarmult(&c, &a, s4); - ge25519_scalarmult(&c, &c, s4); - ge25519_scalarmult(&c, &c, s4); - ck_assert_int_eq(ge25519_eq(&c, &b), 1); - ck_assert_int_eq(ge25519_eq(&a, &b), 0); - - ge25519_scalarmult_base_wrapper(&a, s1); - ge25519_mul8(&b, &a); - ge25519_scalarmult_base_wrapper(&c, s2); - ck_assert_int_eq(ge25519_eq(&b, &c), 1); - - ge25519_scalarmult(&d, &a, s3); - ck_assert_int_eq(ge25519_eq(&d, &c), 1); - - ge25519_copy(&a, &b); - ge25519_neg_full(&b); - ck_assert_int_eq(ge25519_eq(&b, &c), 0); - - ge25519_add(&c, &a, &b, 0); - set256_modm(s2, 0); - ge25519_scalarmult_base_wrapper(&a, s2); - ck_assert_int_eq(ge25519_eq(&a, &c), 1); - } -} -END_TEST - -START_TEST(test_xmr_check_point) { - const struct { - char *p; - bool on; - } tests[] = { - {"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608", - true}, - {"54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5", - true}, - {"bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808", - true}, - {"00000000000000c60073ec000000000000ff0000000000000000000000000080", - false}, - {"00000000000000004e0000000000000000000000000000000000000000000000", - false}, - {"0000008b0000000000000000b200000000000000000000000000000000000080", - false}, - {"a0953eebe2f676256c37af4f6f84f32d397aaf3b73606e96c5ddfcecbb1ceec8", - false}, - {"a82cd837efee505ec8425769ea925bee869ec3c78a57708c64c2ef2bd6ad3b88", - false}, - {"031c56cfc99758f6f025630e77c6dea0b853c3ab0bf6cf8c8dab03d1a4618178", - false}, - }; - - ge25519 tmp; - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - int res = ge25519_unpack_negative_vartime(&tmp, fromhex(tests[i].p)); - ck_assert_int_eq(ge25519_check(&tmp), tests[i].on); - ck_assert_int_eq(res, tests[i].on); - } -} -END_TEST - -START_TEST(test_xmr_h) { - char *H = "8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94"; - ge25519 H2, Z; - ge25519_p1p1 P_11; - ge25519_pniels P_ni; - uint8_t buff[32] = {0}; - - ge25519_pack(buff, &xmr_h); - ck_assert_mem_eq(buff, fromhex(H), 32); - - int res = ge25519_unpack_vartime(&H2, buff); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(ge25519_eq(&xmr_h, &xmr_h), 1); - ck_assert_int_eq(ge25519_eq(&H2, &xmr_h), 1); - - res = ge25519_unpack_negative_vartime(&H2, buff); - ck_assert_int_eq(res, 1); - ck_assert_int_eq(ge25519_eq(&H2, &xmr_h), 0); - ge25519_neg_full(&H2); - ck_assert_int_eq(ge25519_eq(&H2, &xmr_h), 1); - - ge25519_full_to_pniels(&P_ni, &xmr_h); - ge25519_pnielsadd_p1p1(&P_11, &H2, &P_ni, 1); - ge25519_p1p1_to_full(&H2, &P_11); - ge25519_set_neutral(&Z); - ck_assert_int_eq(ge25519_eq(&Z, &H2), 1); -} -END_TEST - -START_TEST(test_xmr_fast_hash) { - uint8_t hash[32]; - char tests[][2][65] = { - {"", "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"}, - {"00", - "bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a"}, - {"000102", - "f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"}, - {"000102030405", - "51e8babe8b42352100dffa7f7b3843c95245d3d545c6cbf5052e80258ae80627"}, - {"000102030406", - "74e7a0111ee2390dc68269a549a76dcfb553ca1260035eae982d669ff6494f32"}, - {"000102030407", - "3a81c5d02a87786343f88414aae150a09f6933b1d3bb660d0a9ac54e12e5cd86"}, - {"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64", - "7fb4d1c8e32f7414fe8c7b2774ec05bff6845e4278565d17f95559513a244da2"}, - {"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", - "2998fe52f8b9883149babd9c546912c3edfbd3cd98896a0e57b1b5929fa5ff7b"}, - }; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - xmr_fast_hash(hash, fromhex(tests[i][0]), strlen(tests[i][0]) / 2); - ck_assert_mem_eq(hash, fromhex(tests[i][1]), 32); - } -} -END_TEST - -START_TEST(test_xmr_hasher) { - Hasher hasher; - uint8_t hash[32]; - - const struct { - char *chunk[3]; - char *hash; - } tests[] = { - {{"00", "01", "02"}, - "f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"}, - {{"001122334455667788", "00", ""}, - "72a228ee8d0d01c815f112ce315cfc215a0594abcec24162304ae0ffda139d9e"}, - {{"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608", "", - "00112233445566"}, - "c3deafd96ff10cc190c6024548c344f6401cfe5151ab2fcd40df7cc501147e01"}, - }; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - xmr_hasher_init(&hasher); - for (int j = 0; j < 3; j++) { - xmr_hasher_update(&hasher, fromhex(tests[i].chunk[j]), - strlen(tests[i].chunk[j]) / 2); - } - xmr_hasher_final(&hasher, hash); - ck_assert_mem_eq(hash, fromhex(tests[i].hash), 32); - } -} -END_TEST - -START_TEST(test_xmr_hash_to_scalar) { - bignum256modm a1; - unsigned char out[32]; - char tests[][2][65] = { - {"", "4a078e76cd41a3d3b534b83dc6f2ea2de500b653ca82273b7bfad8045d85a400"}, - {"00", - "5497c9b6a7059553835f85118dc089d66512f7b477d66591ff96a9e064bcc90a"}, - {"000102", - "5727ca206dbafa2e099b022ed528f5bdf7874e3ec09c8f012159dfeeaab2b106"}, - {"000102030405", - "7740cf04577c107153a50b3abe44859f5245d3d545c6cbf5052e80258ae80607"}, - {"000102030406", - "ad6bbffaceb8020543ac82bcadb9d090b553ca1260035eae982d669ff6494f02"}, - {"000102030407", - "d2e116e9576ee5a29011c8fcb41259f99e6933b1d3bb660d0a9ac54e12e5cd06"}, - {"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64", - "3d6d3727dc50bca39e6ccfc9c12950eef5845e4278565d17f95559513a244d02"}, - {"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", - "aecc45c83f0408c96c70f8273e94f930edfbd3cd98896a0e57b1b5929fa5ff0b"}, - }; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - xmr_hash_to_scalar(a1, fromhex(tests[i][0]), strlen(tests[i][0]) / 2); - contract256_modm(out, a1); - ck_assert_mem_eq(out, fromhex(tests[i][1]), 32); - } -} -END_TEST - -START_TEST(test_xmr_hash_to_ec) { - ge25519 p1; - unsigned char out[32]; - char tests[][2][65] = { - {"", "d6d7d783ab18e1be65586adb7902a4175b737ef0b902875e1d1d5c5cf0478c0b"}, - {"00", - "8e2fecb36320bc4e192e10ef54afc7c83fbeb0c38b7debd4fea51301f0bd4f3d"}, - {"000102", - "73b233e2e75d81b9657a857e38e7ab2bc3600e5c56622b9fe4b976ff312220fa"}, - {"000102030405", - "bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808"}, - {"000102030406", - "525567a6a40a94f2d916bc1efea234bbd3b9162403ec2faba871a90f8d0d487e"}, - {"000102030407", - "99b1be2a92cbd22b24b48fb7a9daadd4d13a56915c4f6ed696f271ad5bdbc149"}, - {"42f6835bf83114a1f5f6076fe79bdfa0bd67c74b88f127d54572d3910dd09201", - "54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5"}, - {"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", - "001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608"}, - }; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - xmr_hash_to_ec(&p1, fromhex(tests[i][0]), strlen(tests[i][0]) / 2); - ge25519_pack(out, &p1); - ck_assert_mem_eq(out, fromhex(tests[i][1]), 32); - } -} -END_TEST - -START_TEST(test_xmr_derivation_to_scalar) { - const struct { - char *pt; - uint32_t idx; - char *sc; - } tests[] = { - { - "c655b2d9d2670a1c9f26f7586b6d6b1ec5173b8b33bca64c3d305a42d66738b1", - 0, - "ca7ce31b273dd1ac00dc3553e654fb66036804800e27c826bd2b78649243900b", - }, - { - "2b1dbd7a007dcc4d729fa8359705595599737fcef60afb36b379fe033095dca7", - 1, - "60afd5a63b14845d3b92d16eac386713e4ff617fdc5c1a07c3212098c1f5610c", - }, - { - "a48ed3797225dab4b4316b5e40107b6bd63e5f4dc517ba602774d703576ec771", - 24, - "fe81804091e50a5c2233faa6277360fbe1948ea15dddbae62c1d40bbd1918606", - }, - { - "fa27b5b39741f5341b4e89269e3a05ff7e76ec7739843872468fc4bec8475410", - 65537, - "1ba36841f57aa8b799c4dd02b39d53e5fb7780d3f09f91a57a86dcb418d8d506", - }, - }; - - ge25519 pt; - bignum256modm sc, sc2; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(sc, fromhex(tests[i].sc), 32); - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - - xmr_derivation_to_scalar(sc2, &pt, tests[i].idx); - ck_assert_int_eq(eq256_modm(sc, sc2), 1); - - xmr_derivation_to_scalar(sc2, &pt, tests[i].idx + 1); - ck_assert_int_eq(eq256_modm(sc, sc2), 0); - } -} -END_TEST - -START_TEST(test_xmr_generate_key_derivation) { - const struct { - char *pt; - char *sc; - char *r; - } tests[] = { - { - "38f94f27c8037aff025e365275ed1029fd636dda5f69e5f98fdcf92e0a28f31a", - "8f1c73ee5327a43264a7b60b9e7882312b582f33e89846a8694dbf094bb3a90a", - "1fbfe4dcc8c824c274649545f297fa320cd4c1689b1d0ff4887567c4d4a75649", - }, - { - "26785c3941a32f194228eb659c5ee305e63868896defc50ee6c4e0e92d1e246a", - "dbbffec4686ba8ab25e2f1b04c0e7ae51c5143c91353bfb5998430ebe365a609", - "cca34db8dd682ec164d8973b555253934596b77849ef7709d9321121c25aba02", - }, - { - "43505a8ce7248f70d3aae4f57fb59c254ce2b2a0cc2bcf50f2344e51d59b36b3", - "19a802e35f6ff94efe96ec016effe04e635bbd9c1ce2612d5ba2ee4659456b06", - "fc6c93a93f77ff89c18b9abf95b28ec8591ab97eee8e4afee93aa766a4bd3934", - }, - }; - - ge25519 pt, pt2, pt3; - bignum256modm sc; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(sc, fromhex(tests[i].sc), 32); - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - ge25519_unpack_vartime(&pt2, fromhex(tests[i].r)); - xmr_generate_key_derivation(&pt3, &pt, sc); - ck_assert_int_eq(ge25519_eq(&pt3, &pt2), 1); - ck_assert_int_eq(ge25519_eq(&pt3, &pt), 0); - } -} -END_TEST - -START_TEST(test_xmr_derive_private_key) { - const struct { - char *pt; - uint32_t idx; - char *base; - char *r; - } tests[] = { - { - "0541d8f069e5e80a892e39bbf1944ef578008cf9ecf1d100760a05858c1b709e", - 0, - "76967eeb0a3d181bb0b384be71c680a4287599f27b2ddbd07f8e06ab6f2c880e", - "45728c5cb658e470790f124a01699d2126832b7e5c6b7760b6f11119b96ad603", - }, - { - "fc6e0bd785a84e62c9ac8a97e0e604a79494bc2cf7b3b38ef8af7791c87b5bb8", - 1, - "32fbe149562b7ccb34bc4105b87b2a834024799336c8eea5e94df77f1ae9a807", - "64508e83bbadf63f8ecfae4d9dcdd39a4ba23508a545e1a37026f0fa2539d601", - }, - { - "f6bd7a72dc9444dc7e09a0eb4d312d36fe173693d6405b132a5b090297a04ea9", - 65537, - "333a8fcce6726457e4222a87b9b475c1fcf985f756c2029fcb39184c0a5c4804", - "37c16a22da4c0082ebf4bf807403b169f75142a9bd8560ed45f3f9347218260e", - }, - }; - - ge25519 pt; - bignum256modm base, res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(base, fromhex(tests[i].base), 32); - expand256_modm(res_exp, fromhex(tests[i].r), 32); - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - - xmr_derive_private_key(res, &pt, tests[i].idx, base); - ck_assert_int_eq(eq256_modm(res, res_exp), 1); - ck_assert_int_eq(eq256_modm(res, base), 0); - } -} -END_TEST - -START_TEST(test_xmr_derive_public_key) { - const struct { - char *pt; - uint32_t idx; - char *base; - char *r; - } tests[] = { - { - "653f03e7766d472826aa49793bc0cfde698e6745ae5e4217980ba307739f2ed9", - 0, - "2a393f0858732970ac8dea003b17e1ce9371f0a045bd9b7af0d998262739f4cc", - "f7a3db27c45f265f6a68a30137ca44289a6cf1a6db2cf482c59ebfb0142ad419", - }, - { - "338e93f61e6470a5cc71c07b8caedd1a9a28da037aab65c1ca5538501b012c81", - 1, - "af3a1d39397d778731c4510110fd117dc02f756e390713d58f94a06203ce39eb", - "779e2a043c881f06aba1952741fd753098615c4fafa8f62748467ab9bac43241", - }, - { - "7735e9476440927b89b18d7a1e0645b218a1a6d28c642aebb16c1dba0926d5e4", - 65537, - "62c3eed062bd602f7f2164c69ad0b5a8eb3ea560c930f6b41abfc1c4839ea432", - "6da4ebd29498d16c4e813abb3e328c83f9b01a7ba1da6e818071f8ec563626c8", - }, - }; - - ge25519 pt, base, res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - ge25519_unpack_vartime(&pt, fromhex(tests[i].pt)); - ge25519_unpack_vartime(&base, fromhex(tests[i].base)); - ge25519_unpack_vartime(&res_exp, fromhex(tests[i].r)); - - xmr_derive_public_key(&res, &pt, tests[i].idx, &base); - - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - ck_assert_int_eq(ge25519_eq(&res, &base), 0); - } -} -END_TEST - -START_TEST(test_xmr_add_keys2) { - const struct { - char *a; - char *b; - char *B; - char *r; - } tests[] = { - { - "631238da9578d7cb8db16fc4322671bfcb251cc5228b060664800ec1895be608", - "f9a73fca0be058415a148f9e2871be59e1fc7ae6f6193199125237e0d7c1630f", - "ef5ca4fc90f330e825adcdc953da0b3becd853aa819219842790bb39775f2255", - "06623fd0e7a3d787a4d224f6ca2fdab2dcd9d1221578515974b9c4dee65fdcf5", - }, - { - "dac2e629e5c75c312253b19d1d3a0a423158fdd9cdcf4c7a7bf2717d0b748602", - "0483d98d750d4977b499cefd558a0a61580823a37da2b011501e24718e6c7f0a", - "51fd3cd2f1a603ec7be3b35da9c105d91c4304e6a63facf48d7730712cedc0ee", - "f7a5d645ba01a5b7ccbe9636d14422bb587fc529317b23761f0e39222b783b87", - }, - { - "817c4d2fd3e841d860bdab6b7ccf098f3e637eca468d0a3825c50b71f61d0e0c", - "1f6c4795d7fb0d53b5775874ac4c0963607d2b7bd11a7c5d10735badc4a27207", - "bef0e0ed09d602bbe1dd38358b5f8fca27fcad60a69440f104441c3fc68df9c7", - "bc0fc824d74eca0e10eacd0bc2f3322e0bcb02a44ce53f2f5f1fc472f99be8d2", - }, - }; - - bignum256modm a, b; - ge25519 B, res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i].a), 32); - expand256_modm(b, fromhex(tests[i].b), 32); - ge25519_unpack_vartime(&B, fromhex(tests[i].B)); - ge25519_unpack_vartime(&res_exp, fromhex(tests[i].r)); - - xmr_add_keys2(&res, a, b, &B); - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - ck_assert_int_eq(ge25519_eq(&res, &B), 0); - - xmr_add_keys2_vartime(&res, a, b, &B); - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - ck_assert_int_eq(ge25519_eq(&res, &B), 0); - } -} -END_TEST - -START_TEST(test_xmr_add_keys3) { - const struct { - char *a; - char *A; - char *b; - char *B; - char *r; - } tests[] = { - { - "7048b8c4603ae194c502fa458b0e11a4c7a330852bbef66b7c1d67e9f919f509", - "9167c5b182758699baeb421e7f1200272fc775e4c7c7c183cc47261dccbb569f", - "c2cb2bc0249fc7be8eb9b3bed7d37aa6f2c3f433abb3a4a00b13bed64b61f30b", - "b3ec53b07a1be70ac8d0fa365b86f0d6d4cbf98641e7704b3d684558e2ea59ef", - "4dc016d702d599bde5eaeb2bf0c2d0d3f6b9cede961bc539bcb369c3b3086358", - }, - { - "e9794a6652940474958936f07f3904d514228553247633cfb7ae8ffa9fa0f406", - "0e51cea6df2f6f56a9935689364f0d295a7c89f51d40efb2518c17d1b9db792b", - "c132e7be08afdd93984c52c6e1c596edc6b8fc8f1faed95f55e2f819ee806706", - "1a0e03c6858f6cf1b43f4b8456c03144af553bbbd050e152834fd1615b577cb3", - "088f19c6727f8704373d391a36c230395d386f69edb4151ecf8afcd27793fff5", - }, - { - "88920b0c96b15cc04e879f53a76f85f3c7a2a5f275b2772b5b74ee83372aea00", - "e95731ab61a98fedcded475cf21b4ecf2ef9f1adecefba8fdc476a5bb1cf60f9", - "c86026b66c1045fb69e4f24ff6c15d4fad4d565e646938a2ffb7db37ccb4100d", - "d80cbf2986c12e4c7ebac1e55abbdfc4212c00aec8bc90c965becf863262a074", - "047cebaeb3ec2132e7386ba52531b04070206ba1106565c0fbd7d7280694568a", - }, - }; - - bignum256modm a, b; - ge25519 A, B, res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i].a), 32); - expand256_modm(b, fromhex(tests[i].b), 32); - ge25519_unpack_vartime(&A, fromhex(tests[i].A)); - ge25519_unpack_vartime(&B, fromhex(tests[i].B)); - ge25519_unpack_vartime(&res_exp, fromhex(tests[i].r)); - - xmr_add_keys3(&res, a, &A, b, &B); - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - ck_assert_int_eq(ge25519_eq(&res, &B), 0); - - xmr_add_keys3_vartime(&res, a, &A, b, &B); - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - ck_assert_int_eq(ge25519_eq(&res, &B), 0); - } -} -END_TEST - -START_TEST(test_xmr_get_subaddress_secret_key) { - const struct { - uint32_t major, minor; - char *m; - char *r; - } tests[] = { - { - 0, - 0, - "36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207", - "8a510a9fe1824b49abbae05958084f9c9098775f29e15427309177882471cf01", - }, - { - 0, - 1, - "36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207", - "2bbc9366c04abb0523e2b2d6e709670ffe6645bacedfee968d9c6bc8eefe9c0f", - }, - { - 100, - 100, - "36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207", - "c3837d41fedeaed126cf4fc1a5ea47b8b7f38f6a64aa534e3dd45a3c93f37600", - }, - }; - - bignum256modm m, res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(m, fromhex(tests[i].m), 32); - expand256_modm(res_exp, fromhex(tests[i].r), 32); - xmr_get_subaddress_secret_key(res, tests[i].major, tests[i].minor, m); - - ck_assert_int_eq(eq256_modm(res, res_exp), 1); - ck_assert_int_eq(eq256_modm(res, m), 0); - } -} -END_TEST - -START_TEST(test_xmr_gen_c) { - const struct { - char *a; - uint64_t amount; - char *r; - } tests[] = { - { - "e3e6558c291bbb98aa691d068b67d59dc520afb23fdd51bf65283626fc2ad903", - 0, - "ef19d73bdf3749240b80ee7695f53ad7c2fc2cf868a93209799f41212d099750", - }, - { - "6788c9579c377f3228680bd0e6d01b1ee0c763b35ed39d36fa2146cc2ee16e0e", - 1, - "4913b9af4f2725d87a4404c22cf366597d1c1e6a1f510ae14081d8b7c5a9de77", - }, - { - "ad9e89d67012935540427c241756d6a9d260c5e134603c41d31e24f8651bef08", - 65537, - "f005721da08f24e68314abed3ddfd94165e4be3813398fb126e3f366820b9c90", - }, - { - "fdbb70ff07be24d98de3bffa0a33756646497224318fb7fe136f0e7789d12607", - 0xffffffffffffffffULL, - "a9c38927f299c5f14c98a1a9c9981e59c606ff597274b9b709e1356f12e1498c", - }, - }; - - bignum256modm a; - ge25519 res, res_exp; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - expand256_modm(a, fromhex(tests[i].a), 32); - ge25519_unpack_vartime(&res_exp, fromhex(tests[i].r)); - xmr_gen_c(&res, a, tests[i].amount); - - ck_assert_int_eq(ge25519_eq(&res, &res_exp), 1); - } -} -END_TEST - -START_TEST(test_xmr_varint) { - const struct { - uint64_t x; - char *r; - } tests[] = { - { - 0, - "00", - }, - { - 24, - "18", - }, - { - 65535, - "ffff03", - }, - { - 65537, - "818004", - }, - { - 0x7fffffffULL, - "ffffffff07", - }, - { - 0xffffffffULL, - "ffffffff0f", - }, - { - 0xffffffffffffffffULL, - "ffffffffffffffffff01", - }, - { - 0xdeadc0deULL, - "de81b7f50d", - }, - }; - - uint64_t val; - unsigned char buff[64]; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - int s1 = xmr_size_varint(tests[i].x); - int written = 0; - int read = 0; - - ck_assert_int_eq(s1, strlen(tests[i].r) / 2); - written = xmr_write_varint(buff, sizeof(buff), tests[i].x); - ck_assert_int_eq(s1, written); - ck_assert_mem_eq(buff, fromhex(tests[i].r), strlen(tests[i].r) / 2); - - read = xmr_read_varint(buff, sizeof(buff), &val); - ck_assert_int_eq(read, written); - ck_assert(tests[i].x == val); - } -} -END_TEST - -START_TEST(test_xmr_gen_range_sig) { - uint64_t tests[] = { - 0, 1, 65535, 65537, 0xffffffffffffffffULL, 0xdeadc0deULL, - }; - - unsigned char buff[32]; - xmr_range_sig_t sig; - ge25519 C, Ctmp, Cb, Ch, P1, P2, LL; - bignum256modm mask, hsh, ee, s, ee_comp; - Hasher hasher; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - xmr_gen_range_sig(&sig, &C, mask, tests[i], NULL); - - ge25519_set_neutral(&Ctmp); - for (int j = 0; j < XMR_ATOMS; j++) { - ge25519_unpack_vartime(&Cb, sig.Ci[j]); - ge25519_add(&Ctmp, &Ctmp, &Cb, 0); - } - - ck_assert_int_eq(ge25519_eq(&C, &Ctmp), 1); - - xmr_hasher_init(&hasher); - ge25519_set_xmr_h(&Ch); - expand256_modm(ee, sig.asig.ee, 32); - - for (int j = 0; j < XMR_ATOMS; j++) { - ge25519_unpack_vartime(&P1, sig.Ci[j]); - ge25519_add(&P2, &P1, &Ch, 1); - expand256_modm(s, sig.asig.s0[j], 32); - - xmr_add_keys2(&LL, s, ee, &P1); - ge25519_pack(buff, &LL); - xmr_hash_to_scalar(hsh, buff, 32); - - expand256_modm(s, sig.asig.s1[j], 32); - xmr_add_keys2(&LL, s, hsh, &P2); - - ge25519_pack(buff, &LL); - xmr_hasher_update(&hasher, buff, 32); - - ge25519_double(&Ch, &Ch); - } - - xmr_hasher_final(&hasher, buff); - expand256_modm(ee_comp, buff, 32); - ck_assert_int_eq(eq256_modm(ee, ee_comp), 1); - } -} -END_TEST -#endif diff --git a/trezor-crypto/crypto/tests/test_check_nano.h b/trezor-crypto/crypto/tests/test_check_nano.h deleted file mode 100644 index 104af4c6440..00000000000 --- a/trezor-crypto/crypto/tests/test_check_nano.h +++ /dev/null @@ -1,107 +0,0 @@ -START_TEST(test_bip32_nano_vector_1) -{ - const char *mnemonic = "edge defense waste choose enrich upon flee junk siren film clown finish luggage leader kid quick brick print evidence swap drill paddle truly occur"; - const char *password = "some password"; - - uint8_t seed[64]; - mnemonic_to_seed(mnemonic, password, seed, NULL); - - HDNode node; - hdnode_from_seed(seed, sizeof(seed), ED25519_BLAKE2B_NANO_NAME, &node); - hdnode_private_ckd_prime(&node, 44); - hdnode_private_ckd_prime(&node, 165); - hdnode_private_ckd_prime(&node, 0); - hdnode_fill_public_key(&node); - - ck_assert_mem_eq(node.private_key, fromhex("3be4fc2ef3f3b7374e6fc4fb6e7bb153f8a2998b3b3dab50853eabe128024143"), 32); - ck_assert_mem_eq(node.public_key+1, fromhex("5b65b0e8173ee0802c2c3e6c9080d1a16b06de1176c938a924f58670904e82c4"), 32); -} -END_TEST - -START_TEST(test_base32_nano) -{ - const char *in_hex = "0000005114aad86a390897d2a91b33b931b3a59a7df9e63eb3694f9430122f5622ae505c6ff6b58e"; - const char *out = "11111nanode8ngaakzbck8smq6ru9bethqwyehomf79sae1k7xd47dkidjqzffeg"; - - uint8_t in[40]; - memcpy(in, fromhex(in_hex), sizeof(in)); - - char buffer[96]; - - ck_assert(base32_encode(in, sizeof(in), buffer, sizeof(buffer), BASE32_ALPHABET_NANO) != NULL); - ck_assert_str_eq(buffer, out); - - ck_assert(base32_decode(out, strlen(out), (uint8_t *)buffer, sizeof(buffer), BASE32_ALPHABET_NANO) != NULL); - ck_assert_mem_eq(buffer, in, sizeof(in)); -} -END_TEST - -START_TEST(test_nano_get_address) -{ - const char *prefix = "nano_"; - - struct { - const char *pk_hex; - const char *address; - } tests[] = { - /* 1 */ { "5114aad86a390897d2a91b33b931b3a59a7df9e63eb3694f9430122f5622ae50", - "nano_1nanode8ngaakzbck8smq6ru9bethqwyehomf79sae1k7xd47dkidjqzffeg" }, - /* 2 */ { "ea6f44048f04bf1f7083f5ad115a9f4e62ecb61b89a83e8bc68ad1e4d9575469", - "nano_3tmhai4ay37z5xra9xff47fbymm4xku3q4fa9t7wf4pjwmeogo5ba8wyccku" }, - /* 3 */ { "0000000000000000000000000000000000000000000000000000000000000000", - "nano_1111111111111111111111111111111111111111111111111111hifc8npp" }, - /* 4 */ { "e89208dd038fbb269987689621d52292ae9c35941a7484756ecced92a65093ba", - "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3" }, - }; - - for (int i = 0; i < 4; i++) { - ed25519_public_key public_key; - memcpy(public_key, fromhex(tests[i].pk_hex), sizeof(public_key)); - - char buffer[96]; - size_t count; - count = nano_get_address( - public_key, - prefix, strlen(prefix), - buffer, sizeof(buffer) - ); - ck_assert_int_eq(count, 66); - ck_assert_str_eq(buffer, tests[i].address); - } -} - -END_TEST -START_TEST(test_nano_validate_address) -{ - const char *prefix = "nano_"; - - struct { - const char *address; - const char *pk_hex; - } tests[] = { - /* 1 */ { "nano_1nanode8ngaakzbck8smq6ru9bethqwyehomf79sae1k7xd47dkidjqzffeg", - "5114aad86a390897d2a91b33b931b3a59a7df9e63eb3694f9430122f5622ae50" }, - /* 2 */ { "xrb_1nanode8ngaakzbck8smq6ru9bethqwyehomf79sae1k7xd47dkidjqzffeg", - NULL }, - /* 3 */ { "nano_1nanode7ngaakzbck8smq6ru9bethqwyehomf79sae1k7xd47dkidjqzffeg", - NULL }, - }; - - for (int i = 0; i < 3; i++) { - ed25519_public_key public_key; - bool is_valid; - is_valid = nano_validate_address( - prefix, strlen(prefix), - tests[i].address, strlen(tests[i].address), - public_key - ); - if (tests[i].pk_hex == NULL) { - ck_assert(is_valid == false); - } else { - ck_assert(is_valid == true); - ck_assert_mem_eq(public_key, fromhex(tests[i].pk_hex), sizeof(public_key)); - } - } -} - -END_TEST \ No newline at end of file diff --git a/trezor-crypto/crypto/tests/test_check_zilliqa.h b/trezor-crypto/crypto/tests/test_check_zilliqa.h deleted file mode 100644 index b8b16824b51..00000000000 --- a/trezor-crypto/crypto/tests/test_check_zilliqa.h +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include - -START_TEST(test_zil_schnorr_sign_verify) { - static struct { - const char *message; - const char *priv_key; - const char *k_hex; - const char *s_hex; - const char *r_hex; - } test_cases[] = { - { - "123", - "3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6", - "669301F724C555D7BB1185C04909E9CACA3EC7A292B3A1C92DDCCD5A5A7DDDD3", - "FFD72C290B98C93A4BCEDC0EDCDF040C35579BE962FE83E6821D4F3CB4B795D2", - "74AAE9C3E069E2806E1B0D890970BE387AEBED8040F37991AACAD70B27895E39", - }, - { - "1234", - "51a2758eed776c40b367364909c8a9c98cc969104f69ff316f7a287495c37c9b", - "A0A1A9B3570AAE963535B8D4376C58A61646C18182C9FDDA5FB13703F88D4D1E", - "99A0CB942C81571B77C682F79CD3CB663CE9E1C55BB425BA24B9F11A0DE84FE2", - "C3C10363E38158BBA20556A36DE9358DFD81A31C180ABC9E7617C1CC1CAF03B3", - }, - { - "12345", - "2685adffdbb4b2c515054cffc25cfcbfe2e462df65bbe82fb50f71e1e68dd285", - "38DE7B3315F201433D271E91FBE62966576CA05CBFEC1770B77D7EC9D6A01D6D", - "28982FA6C2B620CBC550F7EF9EAB605F409C584FBE5A765678877B79AB517086", - "9A0788E5B0947DEDEDE386DF57A006CF3FE43919A74D9CA630F8A1A9D97B4650", - }, - { - "fun", - "7457dc574d927e5dae84b05264a5b637b5a68e34a85b3965084ed6fed5b7f12d", - "E005ABD242C7C602AB5EED080C5083C7C5F8DAEC6D046A54F384A8B8CDECF740", - "51070ABCA039DAC294F6BA3BFC8C36CFC66020EDF66D1ACF1A9B545B0BF09F52", - "330A924525EF722FA20E8E25CB6E8BD7DF4394886FA4414E4A0B6812AA25BBC0", - }, - { - "funny", - "52c395a6d304de1a959e73e4604e32c5ad3f2bf01c8f730af426b38d7d5dd908", - "0CF28B5C40A8830F3195BB99A9F0E2808F576105F41D16ABCF596AC5A8CFE88A", - "3D60FB4664C994AD956378B9402BC68F7B4799D74F4783A6199C0D74865EA2B6", - "5ED5EDEE0314DFFBEE39EE4E9C76DE8BC3EB8CB891AEC32B83957514284B205B", - }, - { - "What is great in man is that he is a bridge and not a goal", - "52c395a6d304de1a959e73e4604e32c5ad3f2bf01c8f730af426b38d7d5dd908", - "000000000000000000000000000000000000000000000000000000000000007B", - "546F70AA1FEE3718C95508240CDC073B9FEFED05959C5319DD8E2BF07A1DD028", - "B8667BE5E10B113608BFE5327C44E9F0462BE26F789177E10DCE53019AA33DAA", - }, - { - "123456789147258369qwertyuiopasdfghjklzxcvbnm,", - "2685adffdbb4b2c515054cffc25cfcbfe2e462df65bbe82fb50f71e1e68dd285", - "1D0CB70310C4D793A4561FE592B7C156771E3E26283B28AB588E968243B52DD0", - "54D7A435E5E3F2811AA542F8895C20CCB760F2713DBDDB7291DAB6DA4E4F927E", - "20A3BDABFFF2C1BF8E2AF709F6CDCAFE70DA9A1DBC22305B6332E36844092984", - }, - { - "11111111111111111111111111111111111111111111111111111111111111111" - "11111111111111111111111111111111111111111111111111111111111111111" - "111111111111111111", - "3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6", - "A669F372B3C2EEA351210082CAEC3B96767A7B222D19FF2EE3D814860F0D703A", - "4890F9AC3A8D102EE3A2A473930C01CAD29DCE3860ACB7A5DADAEF16FE808991", - "979F088E58F1814D5E462CB9F935D2924ABD8D32211D8F02DD7E0991726DF573", - }, - { - "qwertyuiop[]asdfghjkl;'zxcvbnm,./1234567890-=", - "7457dc574d927e5dae84b05264a5b637b5a68e34a85b3965084ed6fed5b7f12d", - "000000000000000000000000000000000000000000000000000000000000007C", - "0AA595A649E517133D3448CA657424DD07BBED289030F0C0AA6738D26AB9A910", - "83812632F1443A70B198D112D075D886BE7BBC6EC6275AE52661E52B7358BB8B", - }, - }; - - const ecdsa_curve *curve = &secp256k1; - bignum256 k; - uint8_t priv_key[32]; - uint8_t pub_key[33]; - uint8_t buf_raw[32]; - schnorr_sign_pair result; - schnorr_sign_pair expected; - int res; - - for (size_t i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) { - memcpy(priv_key, fromhex(test_cases[i].priv_key), 32); - memcpy(&buf_raw, fromhex(test_cases[i].k_hex), 32); - bn_read_be(buf_raw, &k); - zil_schnorr_sign_k(curve, priv_key, &k, (const uint8_t *)test_cases[i].message, - strlen(test_cases[i].message), &result); - - memcpy(&expected.s, fromhex(test_cases[i].s_hex), 32); - memcpy(&expected.r, fromhex(test_cases[i].r_hex), 32); - - ck_assert_mem_eq(&expected.r, &result.r, 32); - ck_assert_mem_eq(&expected.s, &result.s, 32); - - ecdsa_get_public_key33(curve, priv_key, pub_key); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_cases[i].message, - strlen(test_cases[i].message), &result); - ck_assert_int_eq(res, 0); - } -} -END_TEST - -START_TEST(test_zil_schnorr_fail_verify) { - static struct { - const char *message; - const char *priv_key; - const char *k_hex; - const char *s_hex; - const char *r_hex; - } test_case = { - "123", - "3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6", - "669301F724C555D7BB1185C04909E9CACA3EC7A292B3A1C92DDCCD5A5A7DDDD3", - "FFD72C290B98C93A4BCEDC0EDCDF040C35579BE962FE83E6821D4F3CB4B795D2", - "74AAE9C3E069E2806E1B0D890970BE387AEBED8040F37991AACAD70B27895E39", - }; - - const ecdsa_curve *curve = &secp256k1; - bignum256 k; - bignum256 bn_temp; - uint8_t priv_key[32]; - uint8_t pub_key[33]; - uint8_t buf_raw[32]; - schnorr_sign_pair result; - schnorr_sign_pair bad_result; - int res; - - memcpy(priv_key, fromhex(test_case.priv_key), 32); - memcpy(&buf_raw, fromhex(test_case.k_hex), 32); - bn_read_be(buf_raw, &k); - - zil_schnorr_sign_k(curve, priv_key, &k, (const uint8_t *)test_case.message, - strlen(test_case.message), &result); - - ecdsa_get_public_key33(curve, priv_key, pub_key); - - // Test result = 0 (OK) - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &result); - ck_assert_int_eq(res, 0); - - // Test result = 1 (empty message) - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, 0, - &result); - ck_assert_int_eq(res, 1); - - // Test result = 2 (r = 0) - bn_zero(&bn_temp); - bn_write_be(&bn_temp, bad_result.r); - memcpy(bad_result.s, result.s, 32); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 2); - - // Test result = 3 (s = 0) - memcpy(bad_result.r, result.r, 32); - bn_zero(&bn_temp); - bn_write_be(&bn_temp, bad_result.s); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 3); - - // Test result = 4 (curve->order < r) - bn_copy(&curve->order, &bn_temp); - bn_addi(&bn_temp, 1); - bn_write_be(&bn_temp, bad_result.r); - memcpy(bad_result.s, result.s, 32); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 4); - - // Test result = 5 (curve->order < s) - memcpy(bad_result.r, result.r, 32); - bn_copy(&curve->order, &bn_temp); - bn_addi(&bn_temp, 1); - bn_write_be(&bn_temp, bad_result.s); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 5); - - // Test result = 6 (curve->order = r) - bn_copy(&curve->order, &bn_temp); - bn_write_be(&bn_temp, bad_result.r); - memcpy(bad_result.s, result.s, 32); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 6); - - // Test result = 7 (curve->order = s) - memcpy(bad_result.r, result.r, 32); - bn_copy(&curve->order, &bn_temp); - bn_write_be(&bn_temp, bad_result.s); - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 7); - - // Test result = 8 (failed ecdsa_read_pubkey) - // TBD - - // Test result = 10 (r != r') - memcpy(bad_result.r, result.r, 32); - memcpy(bad_result.s, result.s, 32); - test_case.message = "12"; - res = zil_schnorr_verify_pair(curve, pub_key, (const uint8_t *)test_case.message, - strlen(test_case.message), &bad_result); - ck_assert_int_eq(res, 10); -} -END_TEST diff --git a/trezor-crypto/crypto/tests/test_curves.py b/trezor-crypto/crypto/tests/test_curves.py deleted file mode 100755 index 6897cea8707..00000000000 --- a/trezor-crypto/crypto/tests/test_curves.py +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/py.test -import binascii -import ctypes as c -import hashlib -import os -import random - -import curve25519 -import ecdsa -import pytest - - -def bytes2num(s): - res = 0 - for i, b in enumerate(reversed(bytearray(s))): - res += b << (i * 8) - return res - - -curves = {"nist256p1": ecdsa.curves.NIST256p, "secp256k1": ecdsa.curves.SECP256k1} - - -class Point: - def __init__(self, name, x, y): - self.curve = name - self.x = x - self.y = y - - -points = [ - Point( - "secp256k1", - 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, - 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, - ), - Point( - "secp256k1", - 0x1, - 0x4218F20AE6C646B363DB68605822FB14264CA8D2587FDD6FBC750D587E76A7EE, - ), - Point( - "secp256k1", - 0x2, - 0x66FBE727B2BA09E09F5A98D70A5EFCE8424C5FA425BBDA1C511F860657B8535E, - ), - Point( - "secp256k1", - 0x1B, - 0x1ADCEA1CF831B0AD1653E769D1A229091D0CC68D4B0328691B9CAACC76E37C90, - ), - Point( - "nist256p1", - 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296, - 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5, - ), - Point( - "nist256p1", - 0x0, - 0x66485C780E2F83D72433BD5D84A06BB6541C2AF31DAE871728BF856A174F93F4, - ), - Point( - "nist256p1", - 0x0, - 0x99B7A386F1D07C29DBCC42A27B5F9449ABE3D50DE25178E8D7407A95E8B06C0B, - ), - Point( - "nist256p1", - 0xAF8BBDFE8CDD5577ACBF345B543D28CF402F4E94D3865B97EA0787F2D3AA5D22, - 0x35802B8B376B995265918B078BC109C21A535176585C40F519ACA52D6AFC147C, - ), - Point( - "nist256p1", - 0x80000, - 0x580610071F440F0DCC14A22E2D5D5AFC1224C0CD11A3B4B51B8ECD2224EE1CE2, - ), -] - -random_iters = int(os.environ.get("ITERS", 1)) - -DIR = os.path.abspath(os.path.dirname(__file__)) -lib = c.cdll.LoadLibrary(os.path.join(DIR, "libtrezor-crypto.so")) - -BIGNUM = c.c_uint32 * 9 - - -class curve_info(c.Structure): - _fields_ = [("bip32_name", c.c_char_p), ("params", c.c_void_p)] - - -class curve_point(c.Structure): - _fields_ = [("x", BIGNUM), ("y", BIGNUM)] - - -class ecdsa_curve(c.Structure): - _fields_ = [ - ("prime", BIGNUM), - ("G", curve_point), - ("order", BIGNUM), - ("order_half", BIGNUM), - ("a", c.c_int), - ("b", BIGNUM), - ] - - -lib.get_curve_by_name.restype = c.POINTER(curve_info) - - -class Random(random.Random): - def randbytes(self, n): - buf = (c.c_uint8 * n)() - for i in range(n): - buf[i] = self.randrange(0, 256) - return buf - - def randpoint(self, curve): - k = self.randrange(0, curve.order) - return k * curve.generator - - -def int2bn(x, bn_type=BIGNUM): - b = bn_type() - b._int = x - for i in range(len(b)): - b[i] = x % (1 << 29) - x = x >> 29 - return b - - -def bn2int(b): - x = 0 - for i in range(len(b)): - x += b[i] << (29 * i) - return x - - -@pytest.fixture(params=range(random_iters)) -def r(request): - seed = request.param - return Random(seed + int(os.environ.get("SEED", 0))) - - -@pytest.fixture(params=list(sorted(curves))) -def curve(request): - name = request.param - curve_ptr = lib.get_curve_by_name(bytes(name, "ascii")).contents.params - assert curve_ptr, "curve {} not found".format(name) - curve_obj = curves[name] - curve_obj.ptr = c.cast(curve_ptr, c.POINTER(ecdsa_curve)) - curve_obj.p = curve_obj.curve.p() # shorthand - return curve_obj - - -@pytest.fixture(params=points) -def point(request): - name = request.param.curve - curve_ptr = lib.get_curve_by_name(bytes(name, "ascii")).contents.params - assert curve_ptr, "curve {} not found".format(name) - curve_obj = curves[name] - curve_obj.ptr = c.c_void_p(curve_ptr) - curve_obj.p = ecdsa.ellipticcurve.Point( - curve_obj.curve, request.param.x, request.param.y - ) - return curve_obj - - -POINT = BIGNUM * 2 - - -def to_POINT(p): - return POINT(int2bn(p.x()), int2bn(p.y())) - - -def from_POINT(p): - return (bn2int(p[0]), bn2int(p[1])) - - -JACOBIAN = BIGNUM * 3 - - -def to_JACOBIAN(jp): - return JACOBIAN(int2bn(jp[0]), int2bn(jp[1]), int2bn(jp[2])) - - -def from_JACOBIAN(p): - return (bn2int(p[0]), bn2int(p[1]), bn2int(p[2])) - - -def test_curve_parameters(curve): - assert curve.curve.p() == bn2int(curve.ptr.contents.prime) - assert curve.generator.x() == bn2int(curve.ptr.contents.G.x) - assert curve.generator.y() == bn2int(curve.ptr.contents.G.y) - assert curve.order == bn2int(curve.ptr.contents.order) - assert curve.order // 2 == bn2int(curve.ptr.contents.order_half) - assert curve.curve.a() == curve.ptr.contents.a - assert curve.curve.b() == bn2int(curve.ptr.contents.b) - - -def test_point_multiply(curve, r): - p = r.randpoint(curve) - k = r.randrange(0, 2 ** 256) - kp = k * p - res = POINT(int2bn(0), int2bn(0)) - lib.point_multiply(curve.ptr, int2bn(k), to_POINT(p), res) - res = from_POINT(res) - assert res == (kp.x(), kp.y()) - - -def test_point_add(curve, r): - p1 = r.randpoint(curve) - p2 = r.randpoint(curve) - # print '-' * 80 - q = p1 + p2 - q1 = to_POINT(p1) - q2 = to_POINT(p2) - lib.point_add(curve.ptr, q1, q2) - q_ = from_POINT(q2) - assert q_ == (q.x(), q.y()) - - -def test_point_double(curve, r): - p = r.randpoint(curve) - q = p.double() - q_ = to_POINT(p) - lib.point_double(curve.ptr, q_) - q_ = from_POINT(q_) - assert q_ == (q.x(), q.y()) - - -def test_point_to_jacobian(curve, r): - p = r.randpoint(curve) - jp = JACOBIAN() - lib.curve_to_jacobian(to_POINT(p), jp, int2bn(curve.p)) - jx, jy, jz = from_JACOBIAN(jp) - assert jx % curve.p == (p.x() * jz ** 2) % curve.p - assert jy % curve.p == (p.y() * jz ** 3) % curve.p - - q = POINT() - lib.jacobian_to_curve(jp, q, int2bn(curve.p)) - q = from_POINT(q) - assert q == (p.x(), p.y()) - - -def test_jacobian_add(curve, r): - p1 = r.randpoint(curve) - p2 = r.randpoint(curve) - prime = int2bn(curve.p) - q = POINT() - jp2 = JACOBIAN() - lib.curve_to_jacobian(to_POINT(p2), jp2, prime) - lib.point_jacobian_add(to_POINT(p1), jp2, curve.ptr) - lib.jacobian_to_curve(jp2, q, prime) - q = from_POINT(q) - p_ = p1 + p2 - assert (p_.x(), p_.y()) == q - - -def test_jacobian_add_double(curve, r): - p1 = r.randpoint(curve) - p2 = p1 - prime = int2bn(curve.p) - q = POINT() - jp2 = JACOBIAN() - lib.curve_to_jacobian(to_POINT(p2), jp2, prime) - lib.point_jacobian_add(to_POINT(p1), jp2, curve.ptr) - lib.jacobian_to_curve(jp2, q, prime) - q = from_POINT(q) - p_ = p1 + p2 - assert (p_.x(), p_.y()) == q - - -def test_jacobian_double(curve, r): - p = r.randpoint(curve) - p2 = p.double() - prime = int2bn(curve.p) - q = POINT() - jp = JACOBIAN() - lib.curve_to_jacobian(to_POINT(p), jp, prime) - lib.point_jacobian_double(jp, curve.ptr) - lib.jacobian_to_curve(jp, q, prime) - q = from_POINT(q) - assert (p2.x(), p2.y()) == q - - -def sigdecode(sig, _): - return map(bytes2num, [sig[:32], sig[32:]]) - - -def test_sign(curve, r): - priv = r.randbytes(32) - digest = r.randbytes(32) - sig = r.randbytes(64) - - lib.ecdsa_sign_digest(curve.ptr, priv, digest, sig, c.c_void_p(0), c.c_void_p(0)) - - exp = bytes2num(priv) - sk = ecdsa.SigningKey.from_secret_exponent(exp, curve, hashfunc=hashlib.sha256) - vk = sk.get_verifying_key() - - sig_ref = sk.sign_digest_deterministic( - digest, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_string_canonize - ) - assert binascii.hexlify(sig) == binascii.hexlify(sig_ref) - - assert vk.verify_digest(sig, digest, sigdecode) - - -def test_validate_pubkey(curve, r): - p = r.randpoint(curve) - assert lib.ecdsa_validate_pubkey(curve.ptr, to_POINT(p)) - - -def test_validate_pubkey_direct(point): - assert lib.ecdsa_validate_pubkey(point.ptr, to_POINT(point.p)) - - -def test_curve25519(r): - sec1 = bytes(bytearray(r.randbytes(32))) - sec2 = bytes(bytearray(r.randbytes(32))) - pub1 = curve25519.Private(sec1).get_public() - pub2 = curve25519.Private(sec2).get_public() - - session1 = r.randbytes(32) - lib.curve25519_scalarmult(session1, sec2, pub1.public) - session2 = r.randbytes(32) - lib.curve25519_scalarmult(session2, sec1, pub2.public) - assert bytearray(session1) == bytearray(session2) - - shared1 = curve25519.Private(sec2).get_shared_key(pub1, hashfunc=lambda x: x) - shared2 = curve25519.Private(sec1).get_shared_key(pub2, hashfunc=lambda x: x) - assert shared1 == shared2 - assert bytearray(session1) == shared1 - assert bytearray(session2) == shared2 - - -def test_curve25519_pubkey(r): - sec = bytes(bytearray(r.randbytes(32))) - pub = curve25519.Private(sec).get_public() - res = r.randbytes(32) - lib.curve25519_scalarmult_basepoint(res, sec) - assert bytearray(res) == pub.public - - -def test_curve25519_scalarmult_from_gpg(r): - sec = binascii.unhexlify( - "4a1e76f133afb29dbc7860bcbc16d0e829009cc15c2f81ed26de1179b1d9c938" - ) - pub = binascii.unhexlify( - "5d6fc75c016e85b17f54e0128a216d5f9229f25bac1ec85cecab8daf48621b31" - ) - res = r.randbytes(32) - lib.curve25519_scalarmult(res, sec[::-1], pub[::-1]) - expected = "a93dbdb23e5c99da743e203bd391af79f2b83fb8d0fd6ec813371c71f08f2d4d" - assert binascii.hexlify(bytearray(res)) == bytes(expected, "ascii") diff --git a/trezor-crypto/crypto/tests/test_openssl.c b/trezor-crypto/crypto/tests/test_openssl.c deleted file mode 100644 index b9390846cb9..00000000000 --- a/trezor-crypto/crypto/tests/test_openssl.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * 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. - */ - -/* OpenSSL's SHA256_CTX/SHA512_CTX conflicts with our own */ -#define SHA256_CTX _openssl_SHA256_CTX -#define SHA512_CTX _openssl_SHA512_CTX -#include -#include -#include -#include -#include -#undef SHA256_CTX -#undef SHA512_CTX - -#include -#include -#include - -#include "ecdsa.h" -#include "hasher.h" -#include "rand.h" - -#include "nist256p1.h" -#include - -#include - -void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve) { - uint8_t sig[64], pub_key33[33], pub_key65[65], priv_key[32], msg[256], - hash[32]; - struct SHA256state_st sha256; - EC_GROUP *ecgroup; - - ecgroup = EC_GROUP_new_by_curve_name(nid); - - for (unsigned int iter = 0; iter < iterations; iter++) { - // random message len between 1 and 256 - int msg_len = (random32() & 0xFF) + 1; - // create random message - random_buffer(msg, msg_len); - - // new ECDSA key - EC_KEY *eckey = EC_KEY_new(); - EC_KEY_set_group(eckey, ecgroup); - - // generate the key - EC_KEY_generate_key(eckey); - // copy key to buffer - const BIGNUM *K = EC_KEY_get0_private_key(eckey); - int bn_off = sizeof(priv_key) - BN_num_bytes(K); - memzero(priv_key, bn_off); - BN_bn2bin(K, priv_key + bn_off); - - // use our ECDSA signer to sign the message with the key - if (ecdsa_sign(curve, HASHER_SHA2, priv_key, msg, msg_len, sig, NULL, - NULL) != 0) { - printf("trezor-crypto signing failed\n"); - return; - } - - // generate public key from private key - if (ecdsa_get_public_key33(curve, priv_key, pub_key33) != 0) { - printf("ecdsa_get_public_key33 failed\n"); - return; - } - - if (ecdsa_get_public_key65(curve, priv_key, pub_key65) != 0) { - printf("ecdsa_get_public_key65 failed\n"); - return; - } - - // use our ECDSA verifier to verify the message signature - if (ecdsa_verify(curve, HASHER_SHA2, pub_key65, sig, msg, msg_len) != 0) { - printf("trezor-crypto verification failed (pub_key_len = 65)\n"); - return; - } - if (ecdsa_verify(curve, HASHER_SHA2, pub_key33, sig, msg, msg_len) != 0) { - printf("trezor-crypto verification failed (pub_key_len = 33)\n"); - return; - } - - // copy signature to the OpenSSL struct - ECDSA_SIG *signature = ECDSA_SIG_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - BN_bin2bn(sig, 32, signature->r); - BN_bin2bn(sig + 32, 32, signature->s); -#else - BIGNUM *R = BN_bin2bn(sig, 32, NULL); - BIGNUM *S = BN_bin2bn(sig + 32, 32, NULL); - ECDSA_SIG_set0(signature, R, S); -#endif - - // compute the digest of the message - // note: these are OpenSSL functions, not our own - SHA256_Init(&sha256); - SHA256_Update(&sha256, msg, msg_len); - SHA256_Final(hash, &sha256); - - // verify all went well, i.e. we can decrypt our signature with OpenSSL - int v = ECDSA_do_verify(hash, 32, signature, eckey); - if (v != 1) { - printf("OpenSSL verification failed (%d)\n", v); - return; - } - - ECDSA_SIG_free(signature); - EC_KEY_free(eckey); - if (((iter + 1) % 100) == 0) printf("Passed ... %d\n", iter + 1); - } - EC_GROUP_free(ecgroup); - printf("All OK\n"); -} - -int main(int argc, char *argv[]) { - if (argc != 2) { - printf("Usage: test_openssl iterations\n"); - return 1; - } - - unsigned int iterations; - sscanf(argv[1], "%u", &iterations); - - printf("Testing secp256k1:\n"); - openssl_check(iterations, NID_secp256k1, &secp256k1); - - printf("Testing nist256p1:\n"); - openssl_check(iterations, NID_X9_62_prime256v1, &nist256p1); - - return 0; -} diff --git a/trezor-crypto/crypto/tests/test_speed.c b/trezor-crypto/crypto/tests/test_speed.c deleted file mode 100644 index a82f67f3e65..00000000000 --- a/trezor-crypto/crypto/tests/test_speed.c +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include -#include -#include -#include -#include "bip32.h" -#include -#include "ecdsa.h" -#include - -static uint8_t msg[256]; - -void prepare_msg(void) { - for (size_t i = 0; i < sizeof(msg); i++) { - msg[i] = i * 1103515245; - } -} - -void bench_sign_secp256k1(int iterations) { - uint8_t sig[64], priv[32], pby; - - const ecdsa_curve *curve = &secp256k1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - - for (int i = 0; i < iterations; i++) { - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - } -} - -void bench_sign_nist256p1(int iterations) { - uint8_t sig[64], priv[32], pby; - - const ecdsa_curve *curve = &nist256p1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - - for (int i = 0; i < iterations; i++) { - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - } -} - -void bench_sign_ed25519(int iterations) { - ed25519_secret_key sk; - ed25519_signature sig; - - memcpy(sk, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - - for (int i = 0; i < iterations; i++) { - ed25519_sign(msg, sizeof(msg), sk, sig); - } -} - -void bench_verify_secp256k1_33(int iterations) { - uint8_t sig[64], pub[33], priv[32], pby; - - const ecdsa_curve *curve = &secp256k1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - ecdsa_get_public_key33(curve, priv, pub); - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - - for (int i = 0; i < iterations; i++) { - ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); - } -} - -void bench_verify_secp256k1_65(int iterations) { - uint8_t sig[64], pub[65], priv[32], pby; - - const ecdsa_curve *curve = &secp256k1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - ecdsa_get_public_key65(curve, priv, pub); - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - - for (int i = 0; i < iterations; i++) { - ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); - } -} - -void bench_verify_nist256p1_33(int iterations) { - uint8_t sig[64], pub[33], priv[32], pby; - - const ecdsa_curve *curve = &nist256p1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - ecdsa_get_public_key33(curve, priv, pub); - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - - for (int i = 0; i < iterations; i++) { - ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); - } -} - -void bench_verify_nist256p1_65(int iterations) { - uint8_t sig[64], pub[65], priv[32], pby; - - const ecdsa_curve *curve = &nist256p1; - - memcpy(priv, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - ecdsa_get_public_key65(curve, priv, pub); - ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL); - - for (int i = 0; i < iterations; i++) { - ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg)); - } -} - -void bench_verify_ed25519(int iterations) { - ed25519_public_key pk; - ed25519_secret_key sk; - ed25519_signature sig; - - memcpy(sk, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - ed25519_publickey(sk, pk); - ed25519_sign(msg, sizeof(msg), sk, sig); - - for (int i = 0; i < iterations; i++) { - ed25519_sign_open(msg, sizeof(msg), pk, sig); - } -} - -void bench_multiply_curve25519(int iterations) { - uint8_t result[32]; - uint8_t secret[32]; - uint8_t basepoint[32]; - - memcpy(secret, - "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3" - "\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", - 32); - memcpy(basepoint, - "\x96\x47\xda\xbe\x1e\xea\xaf\x25\x47\x1e\x68\x0b\x4d\x7c\x6f\xd1\x14" - "\x38\x76\xbb\x77\x59\xd8\x3d\x0f\xf7\xa2\x49\x08\xfd\xda\xbc", - 32); - - for (int i = 0; i < iterations; i++) { - curve25519_scalarmult(result, secret, basepoint); - } -} - -static HDNode root; - -void prepare_node(void) { - hdnode_from_seed((uint8_t *)"NothingToSeeHere", 16, SECP256K1_NAME, &root); - hdnode_fill_public_key(&root); -} - -void bench_ckd_normal(int iterations) { - char addr[MAX_ADDR_SIZE]; - HDNode node; - for (int i = 0; i < iterations; i++) { - memcpy(&node, &root, sizeof(HDNode)); - hdnode_public_ckd(&node, i); - hdnode_fill_public_key(&node); - ecdsa_get_address(node.public_key, HASHER_SHA2, HASHER_SHA2D, 0, addr, - sizeof(addr)); - } -} - -void bench_ckd_optimized(int iterations) { - char addr[MAX_ADDR_SIZE]; - curve_point pub; - ecdsa_read_pubkey(&secp256k1, root.public_key, &pub); - for (int i = 0; i < iterations; i++) { - hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0, - HASHER_SHA2, HASHER_SHA2D, addr, - sizeof(addr), false); - } -} - -void bench(void (*func)(int), const char *name, int iterations) { - clock_t t = clock(); - func(iterations); - float speed = iterations / ((float)(clock() - t) / CLOCKS_PER_SEC); - printf("%25s: %8.2f ops/s\n", name, speed); -} - -#define BENCH(FUNC, ITER) bench(FUNC, #FUNC, ITER) - -int main(void) { - prepare_msg(); - - BENCH(bench_sign_secp256k1, 500); - BENCH(bench_verify_secp256k1_33, 500); - BENCH(bench_verify_secp256k1_65, 500); - - BENCH(bench_sign_nist256p1, 500); - BENCH(bench_verify_nist256p1_33, 500); - BENCH(bench_verify_nist256p1_65, 500); - - BENCH(bench_sign_ed25519, 4000); - BENCH(bench_verify_ed25519, 4000); - - BENCH(bench_multiply_curve25519, 4000); - - prepare_node(); - - BENCH(bench_ckd_normal, 1000); - BENCH(bench_ckd_optimized, 1000); - - return 0; -} diff --git a/trezor-crypto/crypto/tests/test_wycheproof.py b/trezor-crypto/crypto/tests/test_wycheproof.py deleted file mode 100755 index c449b29c8a7..00000000000 --- a/trezor-crypto/crypto/tests/test_wycheproof.py +++ /dev/null @@ -1,721 +0,0 @@ -#!/usr/bin/env python -import ctypes -import json -import os -from binascii import hexlify, unhexlify - -import pytest -from pyasn1.codec.ber.decoder import decode as ber_decode -from pyasn1.codec.der.decoder import decode as der_decode -from pyasn1.codec.der.encoder import encode as der_encode -from pyasn1.type import namedtype, univ - - -class EcSignature(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType("r", univ.Integer()), - namedtype.NamedType("s", univ.Integer()), - ) - - -class EcKeyInfo(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType("key_type", univ.ObjectIdentifier()), - namedtype.NamedType("curve_name", univ.ObjectIdentifier()), - ) - - -class EcPublicKey(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType("key_info", EcKeyInfo()), - namedtype.NamedType("public_key", univ.BitString()), - ) - - -class EdKeyInfo(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType("key_type", univ.ObjectIdentifier()) - ) - - -class EdPublicKey(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType("key_info", EdKeyInfo()), - namedtype.NamedType("public_key", univ.BitString()), - ) - - -class ParseError(Exception): - pass - - -class NotSupported(Exception): - pass - - -class DataError(Exception): - pass - - -class curve_info(ctypes.Structure): - _fields_ = [("bip32_name", ctypes.c_char_p), ("params", ctypes.c_void_p)] - - -def keys_in_dict(dictionary, keys): - return keys <= set(dictionary.keys()) - - -def parse_eddsa_signature(signature): - if len(signature) != 64: - raise ParseError("Not a valid EdDSA signature") - return signature - - -def parse_ecdh256_privkey(private_key): - if private_key < 0 or private_key.bit_length() > 256: - raise ParseError("Not a valid 256 bit ECDH private key") - return private_key.to_bytes(32, byteorder="big") - - -def parse_signed_hex(string): - if len(string) % 2 == 1: - string = "0" + string - number = int(string, 16) - if int(string[0], 16) & 8: - return -number - else: - return number - - -def parse_result(result): - if result == "valid": - return True - elif result == "invalid": - return False - elif result == "acceptable": - return None - else: - raise DataError() - - -def is_valid_der(data): - try: - structure, _ = der_decode(data) - return data == der_encode(structure) - except Exception: - return False - - -def parse_ed_pubkey(public_key): - try: - public_key, _ = ber_decode(public_key, asn1Spec=EdPublicKey()) - except Exception: - raise ParseError("Not a BER encoded Edwards curve public key") - - if not public_key["key_info"]["key_type"] == univ.ObjectIdentifier("1.3.101.112"): - raise ParseError("Not a BER encoded Edwards curve public key") - - public_key = bytes(public_key["public_key"].asOctets()) - - return public_key - - -def parse_ec_pubkey(public_key): - try: - public_key, _ = ber_decode(public_key, asn1Spec=EcPublicKey()) - except Exception: - raise ParseError("Not a BER encoded named elliptic curve public key") - - if not public_key["key_info"]["key_type"] == univ.ObjectIdentifier( - "1.2.840.10045.2.1" - ): - raise ParseError("Not a BER encoded named elliptic curve public key") - curve_identifier = public_key["key_info"]["curve_name"] - curve_name = get_curve_name_by_identifier(curve_identifier) - - if curve_name is None: - raise NotSupported( - "Unsupported named elliptic curve: {}".format(curve_identifier) - ) - - try: - public_key = bytes(public_key["public_key"].asOctets()) - except Exception: - raise ParseError("Not a BER encoded named elliptic curve public key") - - return curve_name, public_key - - -def parse_ecdsa256_signature(signature): - s = signature - if not is_valid_der(signature): - raise ParseError("Not a valid DER") - try: - signature, _ = der_decode(signature, asn1Spec=EcSignature()) - except Exception: - raise ParseError("Not a valid DER encoded ECDSA signature") - try: - r = int(signature["r"]).to_bytes(32, byteorder="big") - s = int(signature["s"]).to_bytes(32, byteorder="big") - signature = r + s - except Exception: - raise ParseError("Not a valid DER encoded 256 bit ECDSA signature") - return signature - - -def parse_digest(name): - if name == "SHA-256": - return 0 - else: - raise NotSupported("Unsupported hash function: {}".format(name)) - - -def get_curve_by_name(name): - lib.get_curve_by_name.restype = ctypes.c_void_p - curve = lib.get_curve_by_name(bytes(name, "ascii")) - if curve is None: - return None - curve = ctypes.cast(curve, ctypes.POINTER(curve_info)) - return ctypes.c_void_p(curve.contents.params) - - -def parse_curve_name(name): - if name == "secp256r1": - return "nist256p1" - elif name == "secp256k1": - return "secp256k1" - elif name == "curve25519": - return "curve25519" - else: - return None - - -def get_curve_name_by_identifier(identifier): - if identifier == univ.ObjectIdentifier("1.3.132.0.10"): - return "secp256k1" - elif identifier == univ.ObjectIdentifier("1.2.840.10045.3.1.7"): - return "nist256p1" - else: - return None - - -def chacha_poly_encrypt(key, iv, associated_data, plaintext): - context = bytes(context_structure_length) - tag = bytes(16) - ciphertext = bytes(len(plaintext)) - lib.rfc7539_init(context, key, iv) - lib.rfc7539_auth(context, associated_data, len(associated_data)) - lib.chacha20poly1305_encrypt(context, plaintext, ciphertext, len(plaintext)) - lib.rfc7539_finish(context, len(associated_data), len(plaintext), tag) - return ciphertext, tag - - -def chacha_poly_decrypt(key, iv, associated_data, ciphertext, tag): - context = bytes(context_structure_length) - computed_tag = bytes(16) - plaintext = bytes(len(ciphertext)) - lib.rfc7539_init(context, key, iv) - lib.rfc7539_auth(context, associated_data, len(associated_data)) - lib.chacha20poly1305_decrypt(context, ciphertext, plaintext, len(ciphertext)) - lib.rfc7539_finish(context, len(associated_data), len(ciphertext), computed_tag) - return plaintext if tag == computed_tag else False - - -def add_pkcs_padding(data): - padding_length = 16 - len(data) % 16 - return data + bytes([padding_length] * padding_length) - - -def remove_pkcs_padding(data): - padding_length = data[-1] - if not ( - 0 < padding_length <= 16 - and data[-padding_length:] == bytes([padding_length] * padding_length) - ): - return False - else: - return data[:-padding_length] - - -def aes_encrypt_initialise(key, context): - if len(key) == (128 / 8): - lib.aes_encrypt_key128(key, context) - elif len(key) == (192 / 8): - lib.aes_encrypt_key192(key, context) - elif len(key) == (256 / 8): - lib.aes_encrypt_key256(key, context) - else: - raise NotSupported("Unsupported key length: {}".format(len(key) * 8)) - - -def aes_cbc_encrypt(key, iv, plaintext): - plaintext = add_pkcs_padding(plaintext) - context = bytes(context_structure_length) - ciphertext = bytes(len(plaintext)) - aes_encrypt_initialise(key, context) - lib.aes_cbc_encrypt( - plaintext, ciphertext, len(plaintext), bytes(bytearray(iv)), context - ) - return ciphertext - - -def aes_decrypt_initialise(key, context): - if len(key) == (128 / 8): - lib.aes_decrypt_key128(key, context) - elif len(key) == (192 / 8): - lib.aes_decrypt_key192(key, context) - elif len(key) == (256 / 8): - lib.aes_decrypt_key256(key, context) - else: - raise NotSupported("Unsupported AES key length: {}".format(len(key) * 8)) - - -def aes_cbc_decrypt(key, iv, ciphertext): - context = bytes(context_structure_length) - plaintext = bytes(len(ciphertext)) - aes_decrypt_initialise(key, context) - lib.aes_cbc_decrypt(ciphertext, plaintext, len(ciphertext), iv, context) - return remove_pkcs_padding(plaintext) - - -def load_json_testvectors(filename): - try: - result = json.loads(open(os.path.join(testvectors_directory, filename)).read()) - except Exception: - raise DataError() - return result - - -def generate_aes(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "AES-CBC-PKCS5": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests"}): - raise DataError() - - for test in test_group["tests"]: - if not keys_in_dict(test, {"key", "iv", "msg", "ct", "result"}): - raise DataError() - try: - key = unhexlify(test["key"]) - iv = unhexlify(test["iv"]) - plaintext = unhexlify(test["msg"]) - ciphertext = unhexlify(test["ct"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - if len(key) not in [128 / 8, 192 / 8, 256 / 8]: - continue - - if result is None: - continue - - vectors.append( - ( - hexlify(key), - hexlify(iv), - hexlify(plaintext), - hexlify(ciphertext), - result, - ) - ) - return vectors - - -def generate_chacha_poly(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "CHACHA20-POLY1305": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests"}): - raise DataError() - - for test in test_group["tests"]: - if not keys_in_dict( - test, {"key", "iv", "aad", "msg", "ct", "tag", "result"} - ): - raise DataError() - try: - key = unhexlify(test["key"]) - iv = unhexlify(test["iv"]) - associated_data = unhexlify(test["aad"]) - plaintext = unhexlify(test["msg"]) - ciphertext = unhexlify(test["ct"]) - tag = unhexlify(test["tag"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - if result is None: - continue - - vectors.append( - ( - hexlify(key), - hexlify(iv), - hexlify(associated_data), - hexlify(plaintext), - hexlify(ciphertext), - hexlify(tag), - result, - ) - ) - return vectors - - -def generate_curve25519_dh(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "X25519": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests"}): - raise DataError() - - for test in test_group["tests"]: - if not keys_in_dict( - test, {"public", "private", "shared", "result", "curve"} - ): - raise DataError() - - try: - public_key = unhexlify(test["public"]) - curve_name = parse_curve_name(test["curve"]) - private_key = unhexlify(test["private"]) - shared = unhexlify(test["shared"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - if curve_name != "curve25519": - continue - if result is None: - continue - - vectors.append( - (hexlify(public_key), hexlify(private_key), hexlify(shared), result) - ) - - return vectors - - -def generate_ecdh(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "ECDH": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests"}): - raise DataError() - - for test in test_group["tests"]: - if not keys_in_dict( - test, {"public", "private", "shared", "result", "curve"} - ): - raise DataError() - - try: - public_key = unhexlify(test["public"]) - curve_name = parse_curve_name(test["curve"]) - private_key = parse_signed_hex(test["private"]) - shared = unhexlify(test["shared"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - try: - private_key = parse_ecdh256_privkey(private_key) - except ParseError: - continue - - try: - key_curve_name, public_key = parse_ec_pubkey(public_key) - except NotSupported: - continue - except ParseError: - continue - - if key_curve_name != curve_name: - continue - if result is None: - continue - - vectors.append( - ( - curve_name, - hexlify(public_key), - hexlify(private_key), - hexlify(shared), - result, - ) - ) - - return vectors - - -def generate_ecdsa(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "ECDSA": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests", "keyDer", "sha"}): - raise DataError() - - try: - public_key = unhexlify(test_group["keyDer"]) - except Exception: - raise DataError() - - try: - curve_name, public_key = parse_ec_pubkey(public_key) - except NotSupported: - continue - except ParseError: - continue - - try: - hasher = parse_digest(test_group["sha"]) - except NotSupported: - continue - - for test in test_group["tests"]: - if not keys_in_dict(test, {"sig", "msg", "result"}): - raise DataError() - - try: - signature = unhexlify(test["sig"]) - message = unhexlify(test["msg"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - if result is None: - continue - - try: - signature = parse_ecdsa256_signature(signature) - except ParseError: - continue - - vectors.append( - ( - curve_name, - hexlify(public_key), - hasher, - hexlify(message), - hexlify(signature), - result, - ) - ) - - return vectors - - -def generate_eddsa(filename): - vectors = [] - - data = load_json_testvectors(filename) - - if not keys_in_dict(data, {"algorithm", "testGroups"}): - raise DataError() - - if data["algorithm"] != "EDDSA": - raise DataError() - - for test_group in data["testGroups"]: - if not keys_in_dict(test_group, {"tests", "keyDer"}): - raise DataError() - - try: - public_key = unhexlify(test_group["keyDer"]) - except Exception: - raise DataError() - - try: - public_key = parse_ed_pubkey(public_key) - except ParseError: - continue - - for test in test_group["tests"]: - if not keys_in_dict(test, {"sig", "msg", "result"}): - raise DataError() - - try: - signature = unhexlify(test["sig"]) - message = unhexlify(test["msg"]) - result = parse_result(test["result"]) - except Exception: - raise DataError() - - if result is None: - continue - - try: - signature = parse_eddsa_signature(signature) - except ParseError: - continue - - vectors.append( - (hexlify(public_key), hexlify(message), hexlify(signature), result) - ) - - return vectors - - -dir = os.path.abspath(os.path.dirname(__file__)) -lib = ctypes.cdll.LoadLibrary(os.path.join(dir, "libtrezor-crypto.so")) -testvectors_directory = os.path.join(dir, "wycheproof/testvectors") -context_structure_length = 1024 - -ecdh_vectors = generate_ecdh("ecdh_test.json") -curve25519_dh_vectors = generate_curve25519_dh("x25519_test.json") -eddsa_vectors = generate_eddsa("eddsa_test.json") -ecdsa_vectors = ( - generate_ecdsa("ecdsa_test.json") - + generate_ecdsa("ecdsa_secp256k1_sha256_test.json") - + generate_ecdsa("ecdsa_secp256r1_sha256_test.json") -) -ecdh_vectors = ( - generate_ecdh("ecdh_test.json") - + generate_ecdh("ecdh_secp256k1_test.json") - + generate_ecdh("ecdh_secp256r1_test.json") -) -chacha_poly_vectors = generate_chacha_poly("chacha20_poly1305_test.json") -aes_vectors = generate_aes("aes_cbc_pkcs5_test.json") - - -@pytest.mark.parametrize("public_key, message, signature, result", eddsa_vectors) -def test_eddsa(public_key, message, signature, result): - public_key = unhexlify(public_key) - signature = unhexlify(signature) - message = unhexlify(message) - - computed_result = ( - lib.ed25519_sign_open(message, len(message), public_key, signature) == 0 - ) - assert result == computed_result - - -@pytest.mark.parametrize( - "curve_name, public_key, hasher, message, signature, result", ecdsa_vectors -) -def test_ecdsa(curve_name, public_key, hasher, message, signature, result): - curve = get_curve_by_name(curve_name) - if curve is None: - raise NotSupported("Curve not supported: {}".format(curve_name)) - - public_key = unhexlify(public_key) - signature = unhexlify(signature) - message = unhexlify(message) - - computed_result = ( - lib.ecdsa_verify(curve, hasher, public_key, signature, message, len(message)) - == 0 - ) - assert result == computed_result - - -@pytest.mark.parametrize( - "public_key, private_key, shared, result", curve25519_dh_vectors -) -def test_curve25519_dh(public_key, private_key, shared, result): - public_key = unhexlify(public_key) - private_key = unhexlify(private_key) - shared = unhexlify(shared) - - computed_shared = bytes([0] * 32) - lib.curve25519_scalarmult(computed_shared, private_key, public_key) - computed_result = shared == computed_shared - assert result == computed_result - - -@pytest.mark.parametrize( - "curve_name, public_key, private_key, shared, result", ecdh_vectors -) -def test_ecdh(curve_name, public_key, private_key, shared, result): - curve = get_curve_by_name(curve_name) - if curve is None: - raise NotSupported("Curve not supported: {}".format(curve_name)) - - public_key = unhexlify(public_key) - private_key = unhexlify(private_key) - shared = unhexlify(shared) - - computed_shared = bytes([0] * 2 * 32) - lib.ecdh_multiply(curve, private_key, public_key, computed_shared) - computed_shared = computed_shared[1:33] - computed_result = shared == computed_shared - assert result == computed_result - - -@pytest.mark.parametrize( - "key, iv, associated_data, plaintext, ciphertext, tag, result", chacha_poly_vectors -) -def test_chacha_poly(key, iv, associated_data, plaintext, ciphertext, tag, result): - key = unhexlify(key) - iv = unhexlify(iv) - associated_data = unhexlify(associated_data) - plaintext = unhexlify(plaintext) - ciphertext = unhexlify(ciphertext) - tag = unhexlify(tag) - - computed_ciphertext, computed_tag = chacha_poly_encrypt( - key, iv, associated_data, plaintext - ) - computed_result = ciphertext == computed_ciphertext and tag == computed_tag - assert result == computed_result - - computed_plaintext = chacha_poly_decrypt(key, iv, associated_data, ciphertext, tag) - computed_result = plaintext == computed_plaintext - assert result == computed_result - - -@pytest.mark.parametrize("key, iv, plaintext, ciphertext, result", aes_vectors) -def test_aes(key, iv, plaintext, ciphertext, result): - key = unhexlify(key) - iv = unhexlify(iv) - plaintext = unhexlify(plaintext) - ciphertext = unhexlify(ciphertext) - - computed_ciphertext = aes_cbc_encrypt(key, iv, plaintext) - computed_result = ciphertext == computed_ciphertext - assert result == computed_result - - computed_plaintext = aes_cbc_decrypt(key, bytes(iv), ciphertext) - computed_result = plaintext == computed_plaintext - assert result == computed_result diff --git a/trezor-crypto/crypto/tools/.gitignore b/trezor-crypto/crypto/tools/.gitignore deleted file mode 100644 index da1bc3702be..00000000000 --- a/trezor-crypto/crypto/tools/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -xpubaddrgen -mktable -bip39bruteforce diff --git a/trezor-crypto/crypto/tools/README.md b/trezor-crypto/crypto/tools/README.md deleted file mode 100644 index 7786244def8..00000000000 --- a/trezor-crypto/crypto/tools/README.md +++ /dev/null @@ -1,54 +0,0 @@ -trezor-crypto tools -=================== - -Set of small utilities using the trezor-crypto library. - -xpubaddrgen ------------ - -xpubaddrgen reads job specification from stdin in format: - -``` - -``` - -and prints the results to stdout in format: - -``` -
-``` - -Example input: - -``` -23 xpub6BcjTvRCYD4VvFQ8whztSXhbNyhS56eTd5P3g9Zvd3zPEeUeL5CUqBYX8NSd1b6Thitr8bZcSnesmXZH7KerMcc4tUkenBShYCtQ1L8ebVe 0 0 5 -42 xpub6AT2YrLinU4Be5UWUxMaUz3zTA99CSGvXt1jt2Lgym8PqXbTzmpQ8MHjoLnx8YJiMMUP5iEfR97YQVmgF6B2tAhbCZrXqn65ur526NkZ6ey 1 1000 1005 -``` - -Example output: - -``` -23 0 14vb5Cws75p2i5rmSiF5CKMyezUX4hxSb9 -23 1 1Lf4ciA36dsi1niF6smVcpCiHcpj2skaPq -23 2 1LraByp7gQAipvHnFS1gTSzixBtYaVyQGp -23 3 1Hy6n56qZj1EefLVfDAeEpmveNteY9jpiG -23 4 183Nn4mrUjPizM3xu8C6SrmViaWrk8YyRS -42 1000 12eAFGAqGUtszc9R7euRqk7DUcQNXvQZSg -42 1001 1BrLbFCD3MNYedJaz92U9iqy9ukHrtQ1A6 -42 1002 1Jhv33bJy229ThM7HKxUa92cMK5gi7DyPC -42 1003 13LxbTjQPByisj4F4sZEivUBdnJwigzg6R -42 1004 1BWBpSWkPwcKxVr2WDyUqQbmvk5SGihcx9 -``` - -It will print ``` error``` when there was an error processing job jobid. - -It will print ```error``` when it encountered a malformed line. - - -mktable ------------ - -mktable computes the points of the form `(2*j+1)*16^i*G` and prints them in the format to be included in `secp256k1.c` and `nist256p1.c`. -These points are used by the fast ECC multiplication. - -It is only meant to be run if the `scalar_mult` algorithm changes. diff --git a/trezor-crypto/crypto/tools/bip39bruteforce.c b/trezor-crypto/crypto/tools/bip39bruteforce.c deleted file mode 100644 index cee7e24b473..00000000000 --- a/trezor-crypto/crypto/tools/bip39bruteforce.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include "bip32.h" -#include "bip39.h" -#include "curves.h" -#include "ecdsa.h" -#include - -char iter[256]; -uint8_t seed[512 / 8]; -char addr[MAX_ADDR_SIZE]; -int count = 0, found = 0; -HDNode node; -clock_t start; - -#define ACCOUNT_LEGACY 0 - -// around 280 tries per second - -// testing data: -// -// mnemonic: "all all all all all all all all all all all all" -// address: legacy: "1JAd7XCBzGudGpJQSDSfpmJhiygtLQWaGL" -// segwit: "3L6TyTisPBmrDAj6RoKmDzNnj4eQi54gD2" -// passphrase: "" -// -// mnemonic: "all all all all all all all all all all all all" -// address: legacy: "1N3uJ5AU3FTYQ1ZQgTMtYmgSvMBmQiGVBS" -// segwit: "3NcXPfbDP4UHSbuHASALJEBtDeAcWYMMcS" -// passphrase: "testing" - -int main(int argc, char **argv) { - if (argc != 2 && argc != 3) { - fprintf(stderr, "Usage: bip39bruteforce address [mnemonic]\n"); - return 1; - } - const char *address = argv[1]; - const char *mnemonic, *item; - if (argc == 3) { - mnemonic = argv[2]; - item = "passphrase"; - } else { - mnemonic = NULL; - item = "mnemonic"; - } - if (mnemonic && !mnemonic_check(mnemonic)) { - fprintf(stderr, "\"%s\" is not a valid mnemonic\n", mnemonic); - return 2; - } - printf("Reading %ss from stdin ...\n", item); - start = clock(); - for (;;) { - if (fgets(iter, 256, stdin) == NULL) break; - int len = strlen(iter); - if (len <= 0) { - continue; - } - count++; - iter[len - 1] = 0; - if (mnemonic) { - mnemonic_to_seed(mnemonic, iter, seed, NULL); - } else { - mnemonic_to_seed(iter, "", seed, NULL); - } - hdnode_from_seed(seed, 512 / 8, SECP256K1_NAME, &node); -#if ACCOUNT_LEGACY - hdnode_private_ckd_prime(&node, 44); -#else - hdnode_private_ckd_prime(&node, 49); -#endif - hdnode_private_ckd_prime(&node, 0); - hdnode_private_ckd_prime(&node, 0); - hdnode_private_ckd(&node, 0); - hdnode_private_ckd(&node, 0); - hdnode_fill_public_key(&node); -#if ACCOUNT_LEGACY - // Legacy address - ecdsa_get_address(node.public_key, 0, HASHER_SHA2_RIPEMD, HASHER_SHA2D, - addr, sizeof(addr)); -#else - // Segwit-in-P2SH - ecdsa_get_address_segwit_p2sh(node.public_key, 5, HASHER_SHA2_RIPEMD, - HASHER_SHA2D, addr, sizeof(addr)); -#endif - if (strcmp(address, addr) == 0) { - found = 1; - break; - } - } - float dur = (float)(clock() - start) / CLOCKS_PER_SEC; - printf("Tried %d %ss in %f seconds = %f tries/second\n", count, item, dur, - (float)count / dur); - if (found) { - printf("Correct %s found! :-)\n\"%s\"\n", item, iter); - return 0; - } - printf("Correct %s not found. :-(\n", item); - return 4; -} diff --git a/trezor-crypto/crypto/tools/mktable.c b/trezor-crypto/crypto/tools/mktable.c deleted file mode 100644 index 9d9f5850719..00000000000 --- a/trezor-crypto/crypto/tools/mktable.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include "bip32.h" -#include "ecdsa.h" -#include "rand.h" - -/* - * This program prints the contents of the ecdsa_curve.cp array. - * The entry cp[i][j] contains the number (2*j+1)*16^i*G, - * where G is the generator of the specified elliptic curve. - */ -int main(int argc, char **argv) { - int i, j, k; - if (argc != 2) { - printf("Usage: %s CURVE_NAME\n", argv[0]); - return 1; - } - const char *name = argv[1]; - const curve_info *info = get_curve_by_name(name); - const ecdsa_curve *curve = info->params; - if (curve == 0) { - printf("Unknown curve '%s'\n", name); - return 1; - } - - curve_point ng = curve->G; - curve_point pow2ig = curve->G; - for (i = 0; i < 64; i++) { - // invariants: - // pow2ig = 16^i * G - // ng = pow2ig - printf("\t{\n"); - for (j = 0; j < 8; j++) { - // invariants: - // pow2ig = 16^i * G - // ng = (2*j+1) * 16^i * G -#ifndef NDEBUG - curve_point checkresult; - bignum256 a; - bn_zero(&a); - a.val[(4 * i) / BN_BITS_PER_LIMB] = ((uint32_t)2 * j + 1) - << ((4 * i) % BN_BITS_PER_LIMB); - bn_normalize(&a); - point_multiply(curve, &a, &curve->G, &checkresult); - assert(point_is_equal(&checkresult, &ng)); -#endif - printf("\t\t/* %2d*16^%d*G: */\n\t\t{{{", 2 * j + 1, i); - // print x coordinate - for (k = 0; k < 9; k++) { - printf((k < 8 ? "0x%08x, " : "0x%04x"), ng.x.val[k]); - } - printf("}},\n\t\t {{"); - // print y coordinate - for (k = 0; k < 9; k++) { - printf((k < 8 ? "0x%08x, " : "0x%04x"), ng.y.val[k]); - } - if (j == 7) { - printf("}}}\n\t},\n"); - } else { - printf("}}},\n"); - point_add(curve, &pow2ig, &ng); - } - point_add(curve, &pow2ig, &ng); - } - pow2ig = ng; - } - return 0; -} diff --git a/trezor-crypto/crypto/tools/nem_test_vectors.erb b/trezor-crypto/crypto/tools/nem_test_vectors.erb deleted file mode 100644 index 0e7ed946ec4..00000000000 --- a/trezor-crypto/crypto/tools/nem_test_vectors.erb +++ /dev/null @@ -1,18 +0,0 @@ -// test vectors from <%= source_url %> -START_TEST(<%= test_name %>) -{ - static const struct { -<% fields.each do |(name, type)| -%> - <%= if type.nil? then 'const char *' else "#{type} " end %><%= name %>; -<% end -%> - } tests[] = { -<% data.each do |values| -%> - { <% values.each do |value| %><%= value %>, <% end %>}, -<% end -%> - }; - - for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - // TODO: Implement test - } -} -END_TEST diff --git a/trezor-crypto/crypto/tools/nem_test_vectors.rb b/trezor-crypto/crypto/tools/nem_test_vectors.rb deleted file mode 100755 index 9bb4879275b..00000000000 --- a/trezor-crypto/crypto/tools/nem_test_vectors.rb +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env ruby -require 'highline' -require 'open-uri' - -TEMPLATE_NAME = (Pathname.new(__FILE__).sub_ext '.erb').to_s.freeze - -@terminal = HighLine.new($stdin, $stderr) - -def github_files - require 'octokit' - - @github_files ||= Octokit.contents('NemProject/nem-test-vectors') - .select do |file| - file.name.end_with? '.dat' - end -end - -def choose_data_file - @terminal.choose do |menu| - github_files.each do |file| - menu.choice(file.name) { file.download_url } - end - - menu.prompt = 'Which file? ' - - menu.index = :none - menu.select_by = :name - end -end - -def load_header(line) - line = line.dup - abort 'Header is not a comment' unless line.slice!(0) == '#' - - header = line.split(':').each(&:strip!) - header.shift if header.first.empty? - - header -end - -def parse_field_answer(answer) - if answer.empty? - nil - elsif /^(?:(?\w+) )?(?\w+)$/ =~ answer - [identifier, type] - else - raise NotValidQuestionError - end -end - -def ask_fields(header) - header.map do |name| - @terminal.ask "Field for `#{name}'? " do |question| - question.answer_type = lambda(&method(:parse_field_answer)) - end - end -end - -def load_data_line(line) - abort 'Line does not begin with colon' unless line.slice!(0) == ':' - - line.strip! - line.chomp!(',') - - values = line.split(':').each(&:strip!) - values.pop if values.last.empty? - - values -end - -def load_data(file, count) - file.each_line.lazy.reject { |line| line.start_with? '#' } - .take(count) - .map(&method(:load_data_line)) - .to_a -end - -def remove_skipped_fields(fields, data) - data.each do |values| - abort 'Line does not match header' unless values.size == fields.size - - values.reject!.each_with_index { |_, index| fields[index].nil? } - end - - fields.compact! -end - -def format_data_fields(fields, data) - data.each do |values| - fields.each_with_index do |(_, type), index| - values[index] = values[index].dump if type.nil? - end - end -end - -def template(source_url, fields, data) - test_name = @terminal.ask('Name for test? ') do |question| - question.validate = /./ - end - - erb = ERB.new(File.read(TEMPLATE_NAME), nil, '-') - erb.filename = TEMPLATE_NAME - - erb.result(binding) -end - -download_url = choose_data_file - -source_code = open download_url do |file| - line = file.readline - - header = load_header(line) - @terminal.say line - - count = @terminal.ask('How many vectors to import? ', Integer) - - fields = ask_fields(header) - data = load_data(file, count) - - remove_skipped_fields(fields, data) - format_data_fields(fields, data) - - template(download_url, fields, data) -end - -puts source_code diff --git a/trezor-crypto/crypto/tools/xpubaddrgen.c b/trezor-crypto/crypto/tools/xpubaddrgen.c deleted file mode 100644 index cce472923fe..00000000000 --- a/trezor-crypto/crypto/tools/xpubaddrgen.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include "bip32.h" -#include "curves.h" -#include "ecdsa.h" - -#define VERSION_PUBLIC 0x0488b21e - -void process_job(uint32_t jobid, const char *xpub, uint32_t change, - uint32_t from, uint32_t to) { - HDNode node, child; - if (change > 1 || to <= from || - hdnode_deserialize_public(xpub, VERSION_PUBLIC, SECP256K1_NAME, &node, - NULL) != 0) { - printf("%d error\n", jobid); - return; - } - hdnode_public_ckd(&node, change); - uint32_t i; - char address[36]; - for (i = from; i < to; i++) { - memcpy(&child, &node, sizeof(HDNode)); - hdnode_public_ckd(&child, i); - ecdsa_get_address(child.public_key, 0, HASHER_SHA2, HASHER_SHA2D, address, - sizeof(address)); - printf("%d %d %s\n", jobid, i, address); - } -} - -int main(void) { - char line[1024], xpub[1024]; - uint32_t jobid, change, from, to; - int r; - for (;;) { - if (!fgets(line, sizeof(line), stdin)) break; - r = sscanf(line, "%u %s %u %u %u\n", &jobid, xpub, &change, &from, &to); - if (r < 1) { - printf("error\n"); - } else if (r != 5) { - printf("%d error\n", jobid); - } else { - process_job(jobid, xpub, change, from, to); - } - } - return 0; -} diff --git a/trezor-crypto/crypto/zilliqa.c b/trezor-crypto/crypto/zilliqa.c deleted file mode 100644 index 5d30b56bf6c..00000000000 --- a/trezor-crypto/crypto/zilliqa.c +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright (c) 2019 Anatolii Kurotych - * - * 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 -#include -#include -#include - -int zil_schnorr_sign(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *msg, const uint32_t msg_len, uint8_t *sig) -{ - int i; - bignum256 k; - - uint8_t hash[32]; - sha256_Raw(msg, msg_len, hash); - - rfc6979_state rng; - init_rfc6979(priv_key, hash, curve, &rng); - - for (i = 0; i < 10000; i++) { - // generate K deterministically - generate_k_rfc6979(&k, &rng); - // if k is too big or too small, we don't like it - if (bn_is_zero(&k) || !bn_is_less(&k, &curve->order)) { - continue; - } - - schnorr_sign_pair sign; - if (zil_schnorr_sign_k(curve, priv_key, &k, msg, msg_len, &sign) != 0) { - continue; - } - - // we're done - memcpy(sig, sign.r, 32); - memcpy(sig + 32, sign.s, 32); - - memzero(&k, sizeof(k)); - memzero(&rng, sizeof(rng)); - memzero(&sign, sizeof(sign)); - return 0; - } - - // Too many retries without a valid signature - // -> fail with an error - memzero(&k, sizeof(k)); - memzero(&rng, sizeof(rng)); - return -1; -} - -// r = H(Q, kpub, m) -static void calc_r(const curve_point *Q, const uint8_t pub_key[33], - const uint8_t *msg, const uint32_t msg_len, bignum256 *r) { - uint8_t Q_compress[33]; - compress_coords(Q, Q_compress); - - SHA256_CTX ctx; - uint8_t digest[SHA256_DIGEST_LENGTH]; - sha256_Init(&ctx); - sha256_Update(&ctx, Q_compress, 33); - sha256_Update(&ctx, pub_key, 33); - sha256_Update(&ctx, msg, msg_len); - sha256_Final(&ctx, digest); - - // Convert the raw bigendian 256 bit value to a normalized, partly reduced bignum - bn_read_be(digest, r); -} - -// Returns 0 if signing succeeded -int zil_schnorr_sign_k(const ecdsa_curve *curve, const uint8_t *priv_key, - const bignum256 *k, const uint8_t *msg, const uint32_t msg_len, - schnorr_sign_pair *result) { - uint8_t pub_key[33]; - curve_point Q; - bignum256 private_key_scalar; - bignum256 r_temp; - bignum256 s_temp; - bignum256 r_kpriv_result; - - bn_read_be(priv_key, &private_key_scalar); - ecdsa_get_public_key33(curve, priv_key, pub_key); - - // Compute commitment Q = kG - point_multiply(curve, k, &curve->G, &Q); - - // Compute challenge r = H(Q, kpub, m) - calc_r(&Q, pub_key, msg, msg_len, &r_temp); - - // Fully reduce the bignum - bn_mod(&r_temp, &curve->order); - - // Convert the normalized, fully reduced bignum to a raw bigendian 256 bit value - bn_write_be(&r_temp, result->r); - - // Compute s = k - r*kpriv - bn_copy(&r_temp, &r_kpriv_result); - - // r*kpriv result is partly reduced - bn_multiply(&private_key_scalar, &r_kpriv_result, &curve->order); - - // k - r*kpriv result is normalized but not reduced - bn_subtractmod(k, &r_kpriv_result, &s_temp, &curve->order); - - // Partly reduce the result - bn_fast_mod(&s_temp, &curve->order); - - // Fully reduce the result - bn_mod(&s_temp, &curve->order); - - // Convert the normalized, fully reduced bignum to a raw bigendian 256 bit value - bn_write_be(&s_temp, result->s); - - if (bn_is_zero(&r_temp) || bn_is_zero(&s_temp)) return 1; - - return 0; -} - -int zil_schnorr_verify(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, const uint32_t msg_len) -{ - schnorr_sign_pair sign; - - memcpy(sign.r, sig, 32); - memcpy(sign.s, sig + 32, 32); - - return zil_schnorr_verify_pair(curve, pub_key, msg, msg_len, &sign); -} - -// Returns 0 if verification succeeded -int zil_schnorr_verify_pair(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *msg, const uint32_t msg_len, - const schnorr_sign_pair *sign) { - curve_point pub_key_point; - curve_point sG, Q; - bignum256 r_temp; - bignum256 s_temp; - bignum256 r_computed; - - if (msg_len == 0) return 1; - - // Convert the raw bigendian 256 bit values to normalized, partly reduced bignums - bn_read_be(sign->r, &r_temp); - bn_read_be(sign->s, &s_temp); - - // Check if r,s are in [1, ..., order-1] - if (bn_is_zero(&r_temp)) return 2; - if (bn_is_zero(&s_temp)) return 3; - if (bn_is_less(&curve->order, &r_temp)) return 4; - if (bn_is_less(&curve->order, &s_temp)) return 5; - if (bn_is_equal(&curve->order, &r_temp)) return 6; - if (bn_is_equal(&curve->order, &s_temp)) return 7; - - if (!ecdsa_read_pubkey(curve, pub_key, &pub_key_point)) { - return 8; - } - - // Compute Q = sG + r*kpub - point_multiply(curve, &s_temp, &curve->G, &sG); - point_multiply(curve, &r_temp, &pub_key_point, &Q); - point_add(curve, &sG, &Q); - - // Compute r' = H(Q, kpub, m) - calc_r(&Q, pub_key, msg, msg_len, &r_computed); - - // Fully reduce the bignum - bn_mod(&r_computed, &curve->order); - - // Check r == r' - if (bn_is_equal(&r_temp, &r_computed)) return 0; // success - - return 10; -} diff --git a/trezor-crypto/include/TrezorCrypto/TrezorCrypto.h b/trezor-crypto/include/TrezorCrypto/TrezorCrypto.h deleted file mode 100644 index 10910c17b2c..00000000000 --- a/trezor-crypto/include/TrezorCrypto/TrezorCrypto.h +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -#include -#include -#include -#include -#include -#include -#include diff --git a/trezor-crypto/include/TrezorCrypto/address.h b/trezor-crypto/include/TrezorCrypto/address.h deleted file mode 100644 index 009f61789e6..00000000000 --- a/trezor-crypto/include/TrezorCrypto/address.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * 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 -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/aes.h b/trezor-crypto/include/TrezorCrypto/aes.h deleted file mode 100644 index 615f19db0da..00000000000 --- a/trezor-crypto/include/TrezorCrypto/aes.h +++ /dev/null @@ -1,228 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 - -#include -#include - -#define VOID_RETURN void -#define INT_RETURN int -#define ALIGN_OFFSET(x,n) (((intptr_t)(x)) & ((n) - 1)) -#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((intptr_t)(x)) & ((n) - 1))) -#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((intptr_t)(x)) & ((n) - 1))) - -#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 diff --git a/trezor-crypto/include/TrezorCrypto/aes/aesopt.h b/trezor-crypto/include/TrezorCrypto/aes/aesopt.h deleted file mode 100644 index 5e8763fa545..00000000000 --- a/trezor-crypto/include/TrezorCrypto/aes/aesopt.h +++ /dev/null @@ -1,784 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 -#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 systems 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 Microsoft 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 diff --git a/trezor-crypto/include/TrezorCrypto/aes/aestab.h b/trezor-crypto/include/TrezorCrypto/aes/aestab.h deleted file mode 100644 index 8fe32d1800d..00000000000 --- a/trezor-crypto/include/TrezorCrypto/aes/aestab.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ---------------------------------------------------------------------------- -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 diff --git a/trezor-crypto/include/TrezorCrypto/base32.h b/trezor-crypto/include/TrezorCrypto/base32.h deleted file mode 100644 index 0144df13a5f..00000000000 --- a/trezor-crypto/include/TrezorCrypto/base32.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * 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 -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/base58.h b/trezor-crypto/include/TrezorCrypto/base58.h deleted file mode 100644 index 1b9c07e822d..00000000000 --- a/trezor-crypto/include/TrezorCrypto/base58.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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 -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/bignum.h b/trezor-crypto/include/TrezorCrypto/bignum.h deleted file mode 100644 index fca969c02c3..00000000000 --- a/trezor-crypto/include/TrezorCrypto/bignum.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * 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 -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BN_LIMBS 9 -#define BN_BITS_PER_LIMB 29 -#define BN_BASE (1u << BN_BITS_PER_LIMB) -#define BN_LIMB_MASK ((1u << BN_BITS_PER_LIMB) - 1) -#define BN_EXTRA_BITS (32 - BN_BITS_PER_LIMB) -#define BN_BITS_LAST_LIMB (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB) - -// Represents the number sum([val[i] * 2**(29*i) for i in range(9)) -typedef struct { - uint32_t val[BN_LIMBS]; -} bignum256; - -static inline uint32_t read_be(const uint8_t *data) { - return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | - (((uint32_t)data[2]) << 8) | (((uint32_t)data[3])); -} - -static inline void write_be(uint8_t *data, uint32_t x) { - data[0] = x >> 24; - data[1] = x >> 16; - data[2] = x >> 8; - data[3] = x; -} - -static inline uint32_t read_le(const uint8_t *data) { - return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) | - (((uint32_t)data[1]) << 8) | (((uint32_t)data[0])); -} - -static inline void write_le(uint8_t *data, uint32_t x) { - data[3] = x >> 24; - data[2] = x >> 16; - data[1] = x >> 8; - data[0] = x; -} - -void bn_read_be(const uint8_t *in_number, bignum256 *out_number); -void bn_write_be(const bignum256 *in_number, uint8_t *out_number); -void bn_read_le(const uint8_t *in_number, bignum256 *out_number); -void bn_write_le(const bignum256 *in_number, uint8_t *out_number); -void bn_read_uint32(uint32_t in_number, bignum256 *out_number); -void bn_read_uint64(uint64_t in_number, bignum256 *out_number); -int bn_bitcount(const bignum256 *x); -unsigned int bn_digitcount(const bignum256 *x); -void bn_zero(bignum256 *x); -void bn_one(bignum256 *x); -int bn_is_zero(const bignum256 *x); -int bn_is_one(const bignum256 *x); -int bn_is_less(const bignum256 *x, const bignum256 *y); -int bn_is_equal(const bignum256 *x, const bignum256 *y); -void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase, - const bignum256 *falsecase); -void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime); -void bn_lshift(bignum256 *x); -void bn_rshift(bignum256 *x); -void bn_setbit(bignum256 *x, uint16_t i); -void bn_clearbit(bignum256 *x, uint16_t i); -uint32_t bn_testbit(const bignum256 *x, uint16_t i); -void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y); -void bn_mult_half(bignum256 *x, const bignum256 *prime); -void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime); -void bn_mod(bignum256 *x, const bignum256 *prime); -void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime); -void bn_fast_mod_old(bignum256 *x, const bignum256 *prime); -void bn_fast_mod(bignum256 *x, const bignum256 *prime); -void bn_power_mod(const bignum256 *x, const bignum256 *e, - const bignum256 *prime, bignum256 *res); -void bn_sqrt(bignum256 *x, const bignum256 *prime); -uint32_t inverse_mod_power_two(uint32_t a, uint32_t n); -void bn_divide_base(bignum256 *x, const bignum256 *prime); -void bn_inverse_slow(bignum256 *x, const bignum256 *prime); -void bn_inverse_fast_1(bignum256 *x, const bignum256 *prime); -void bn_inverse_fast_2(bignum256 *x, const bignum256 *prime); -void bn_inverse_fast_3(bignum256 *x, const bignum256 *prime); -void bn_inverse_old(bignum256 *x, const bignum256 *prime); -void bn_normalize(bignum256 *x); -void bn_add(bignum256 *x, const bignum256 *y); -void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime); -void bn_addi(bignum256 *x, uint32_t y); -void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime); -void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res, - const bignum256 *prime); -void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res); -void bn_long_division(bignum256 *x, uint32_t d, bignum256 *q, uint32_t *r); -void bn_divmod58(bignum256 *x, uint32_t *r); -void bn_divmod1000(bignum256 *x, uint32_t *r); -void bn_inverse(bignum256 *x, const bignum256 *prime); -size_t bn_format(const bignum256 *amount, const char *prefix, - const char *suffix, unsigned int decimals, int exponent, - bool trailing, char *output, size_t output_length); - -// Returns (uint32_t) in_number -// Assumes in_number < 2**32 -// Assumes in_number is normalized -static inline uint32_t bn_write_uint32(const bignum256 *in_number) { - return in_number->val[0] | (in_number->val[1] << BN_BITS_PER_LIMB); -} - -// Returns (uint64_t) in_number -// Assumes in_number < 2**64 -// Assumes in_number is normalized -static inline uint64_t bn_write_uint64(const bignum256 *in_number) { - uint64_t acc; - acc = in_number->val[2]; - acc <<= BN_BITS_PER_LIMB; - acc |= in_number->val[1]; - acc <<= BN_BITS_PER_LIMB; - acc |= in_number->val[0]; - return acc; -} - -// y = x -static inline void bn_copy(const bignum256 *x, bignum256 *y) { *y = *x; } - -// Returns x % 2 == 0 -static inline int bn_is_even(const bignum256 *x) { - return (x->val[0] & 1) == 0; -} - -// Returns x % 2 == 0 -static inline int bn_is_odd(const bignum256 *x) { return (x->val[0] & 1) == 1; } - -static inline size_t bn_format_uint64(uint64_t amount, const char *prefix, - const char *suffix, unsigned int decimals, - int exponent, bool trailing, char *output, - size_t output_length) { - bignum256 bn_amount; - bn_read_uint64(amount, &bn_amount); - - return bn_format(&bn_amount, prefix, suffix, decimals, exponent, trailing, - output, output_length); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif -#if USE_BN_PRINT -void bn_print(const bignum256 *x); -void bn_print_raw(const bignum256 *x); -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/bip32.h b/trezor-crypto/include/TrezorCrypto/bip32.h deleted file mode 100644 index 4b698bcc600..00000000000 --- a/trezor-crypto/include/TrezorCrypto/bip32.h +++ /dev/null @@ -1,157 +0,0 @@ -/** - * 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 -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Maximum length of a Base58Check-encoded extended public or private key. -#define XPUB_MAXLEN 112 - -// Maximum length of a Base58Check-encoded address. -#define ADDRESS_MAXLEN 39 - -typedef struct { - const char *bip32_name; // string for generating BIP32 xprv from seed - const ecdsa_curve *params; // ecdsa curve parameters, null for ed25519 - - 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); - -int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, - const uint8_t *parent_chain_code, uint32_t i, - curve_point *child, uint8_t *child_chain_code); - -int hdnode_public_ckd(HDNode *inout, uint32_t i); - -void hdnode_public_ckd_address_optimized(const curve_point *pub, - const uint8_t *chain_code, uint32_t i, - uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize, int addrformat); - -#if USE_BIP32_CACHE -void bip32_cache_clear(void); -int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, - uint32_t *fingerprint); -#endif - -uint32_t hdnode_fingerprint(HDNode *node); - -int 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_public(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint); - -int hdnode_deserialize_private(const char *str, uint32_t version, - const char *curve, HDNode *node, - uint32_t *fingerprint); - -int hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw); -int hdnode_get_address(HDNode *node, uint32_t version, char *addr, - int addrsize); - -const curve_info *get_curve_by_name(const char *curve_name); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/bip39.h b/trezor-crypto/include/TrezorCrypto/bip39.h deleted file mode 100644 index 46ec5b0229c..00000000000 --- a/trezor-crypto/include/TrezorCrypto/bip39.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 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__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include - -#define BIP39_WORD_COUNT 2048 -#define BIP39_PBKDF2_ROUNDS 2048 - -#if USE_BIP39_CACHE -void bip39_cache_clear(void); -#endif - -// [wallet-core] -#define BIP39_MAX_WORDS 24 -#define BIP39_MAX_WORD_LENGTH 9 - -// [wallet-core] Added output buffer -const char *mnemonic_generate(int strength, char *buf, int buflen); // strength in bits -const char *mnemonic_from_data(const uint8_t *data, int datalen, char *buf, int buflen); -void mnemonic_clear(void); - -int mnemonic_check(const char *mnemonic); - -int mnemonic_to_bits(const char *mnemonic, uint8_t *bits); - -// passphrase must be at most 256 characters otherwise it would be truncated -void mnemonic_to_seed(const char *mnemonic, const char *passphrase, - uint8_t seed[512 / 8], - void (*progress_callback)(uint32_t current, - uint32_t total)); - -int mnemonic_find_word(const char *word); -const char *mnemonic_complete_word(const char *prefix, int len); -const char *mnemonic_get_word(int index); -uint32_t mnemonic_word_completion_mask(const char *prefix, int len); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/bip39_english.h b/trezor-crypto/include/TrezorCrypto/bip39_english.h deleted file mode 100644 index 0eeacd6c9bc..00000000000 --- a/trezor-crypto/include/TrezorCrypto/bip39_english.h +++ /dev/null @@ -1,367 +0,0 @@ -/** - * 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. - */ - -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, -}; diff --git a/trezor-crypto/include/TrezorCrypto/blake256.h b/trezor-crypto/include/TrezorCrypto/blake256.h deleted file mode 100644 index 56c84a96929..00000000000 --- a/trezor-crypto/include/TrezorCrypto/blake256.h +++ /dev/null @@ -1,61 +0,0 @@ -// 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 -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#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 *); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __BLAKE256_H__ */ diff --git a/trezor-crypto/include/TrezorCrypto/blake2_common.h b/trezor-crypto/include/TrezorCrypto/blake2_common.h deleted file mode 100644 index 0a7a3ad9188..00000000000 --- a/trezor-crypto/include/TrezorCrypto/blake2_common.h +++ /dev/null @@ -1,25 +0,0 @@ -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)); -} diff --git a/trezor-crypto/include/TrezorCrypto/blake2b.h b/trezor-crypto/include/TrezorCrypto/blake2b.h deleted file mode 100644 index c4e20bb7c34..00000000000 --- a/trezor-crypto/include/TrezorCrypto/blake2b.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __BLAKE2B_H__ -#define __BLAKE2B_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 tc_blake2b_Init(blake2b_state *S, size_t outlen); -int tc_blake2b_InitKey(blake2b_state *S, size_t outlen, const void *key, size_t keylen); -int tc_blake2b_InitPersonal(blake2b_state *S, size_t outlen, const void *personal, size_t personal_len); -int tc_blake2b_Update(blake2b_state *S, const void *pin, size_t inlen); -int tc_blake2b_Final(blake2b_state *S, void *out, size_t outlen); - -int tc_blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen); -// [wallet-core] -int tc_blake2b_Personal(const uint8_t *msg, uint32_t msg_len, const void *personal, size_t personal_len, void *out, size_t outlen); -int tc_blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/blake2s.h b/trezor-crypto/include/TrezorCrypto/blake2s.h deleted file mode 100644 index 06f10f1a8eb..00000000000 --- a/trezor-crypto/include/TrezorCrypto/blake2s.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __BLAKE2S_H__ -#define __BLAKE2S_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/cardano.h b/trezor-crypto/include/TrezorCrypto/cardano.h deleted file mode 100644 index 3e9986c52bd..00000000000 --- a/trezor-crypto/include/TrezorCrypto/cardano.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2013-2021 SatoshiLabs - * - * 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 __CARDANO_H__ -#define __CARDANO_H__ - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#include -#include -#include -#include - -#if USE_CARDANO - -#define CARDANO_SECRET_LENGTH 96 -#define CARDANO_ICARUS_PBKDF2_ROUNDS 4096 - -extern const curve_info ed25519_cardano_info; - -int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i); - -int secret_from_entropy_cardano_icarus( - const uint8_t *pass, int pass_len, const uint8_t *entropy, int entropy_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH], - void (*progress_callback)(uint32_t current, uint32_t total)); -int secret_from_seed_cardano_ledger(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]); -int secret_from_seed_cardano_slip23(const uint8_t *seed, int seed_len, - uint8_t secret_out[CARDANO_SECRET_LENGTH]); - -int hdnode_from_secret_cardano(const uint8_t secret[CARDANO_SECRET_LENGTH], - HDNode *out); - -#endif // USE_CARDANO - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // __CARDANO_H__ diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/chacha20poly1305.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/chacha20poly1305.h deleted file mode 100644 index f881b93a9f3..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/chacha20poly1305.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CHACHA20POLY1305_H -#define CHACHA20POLY1305_H - -#include -#include -#include - -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 diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-config.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-config.h deleted file mode 100644 index 0749df73083..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-config.h +++ /dev/null @@ -1,316 +0,0 @@ -/* 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 - -/* --- 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 -#define MAXT __m128 - -#elif defined(__MMX__) - -#include -#define MAXT __m64 - -#elif defined(__ALTIVEC__) - -#define MAXT __vector int - -#else - -#define MAXT long - -#endif - -/* ------------------------------------------------------------------------- */ - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-machine.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-machine.h deleted file mode 100644 index d006bedec16..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-machine.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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 - -#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 - -/* ------------------------------------------------------------------------- */ diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-portable.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-portable.h deleted file mode 100644 index e5276d846b9..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-portable.h +++ /dev/null @@ -1,275 +0,0 @@ -/* ecrypt-portable.h */ - -/* - * WARNING: the conversions defined below are implemented as macros, - * and should be used carefully. They should NOT be used with - * parameters which perform some action. E.g., the following two lines - * are not equivalent: - * - * 1) ++x; y = ROTL32(x, n); - * 2) y = ROTL32(++x, n); - */ - -/* - * *** Please do not edit this file. *** - * - * The default macros can be overridden for specific architectures by - * editing 'ecrypt-machine.h'. - */ - -#ifndef ECRYPT_PORTABLE -#define ECRYPT_PORTABLE - -#include "ecrypt-config.h" -#include "ecrypt-types.h" - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros are used to obtain exact-width results. - */ - -#define U8V(v) ((u8)(v) & U8C(0xFF)) -#define U16V(v) ((u16)(v) & U16C(0xFFFF)) -#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) -#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros return words with their bits rotated over n - * positions to the left/right. - */ - -#define ECRYPT_DEFAULT_ROT - -#define ROTL8(v, n) \ - (U8V((v) << (n)) | ((v) >> (8 - (n)))) - -#define ROTL16(v, n) \ - (U16V((v) << (n)) | ((v) >> (16 - (n)))) - -#define ROTL32(v, n) \ - (U32V((v) << (n)) | ((v) >> (32 - (n)))) - -#define ROTL64(v, n) \ - (U64V((v) << (n)) | ((v) >> (64 - (n)))) - -#define ROTR8(v, n) ROTL8(v, 8 - (n)) -#define ROTR16(v, n) ROTL16(v, 16 - (n)) -#define ROTR32(v, n) ROTL32(v, 32 - (n)) -#define ROTR64(v, n) ROTL64(v, 64 - (n)) - -#include "ecrypt-machine.h" - -/* ------------------------------------------------------------------------- */ - -/* - * The following macros return a word with bytes in reverse order. - */ - -#define ECRYPT_DEFAULT_SWAP - -#define SWAP16(v) \ - ROTL16(v, 8) - -#define SWAP32(v) \ - ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ - (ROTL32(v, 24) & U32C(0xFF00FF00))) - -#ifdef ECRYPT_NATIVE64 -#define SWAP64(v) \ - ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ - (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ - (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ - (ROTL64(v, 56) & U64C(0xFF000000FF000000))) -#else -#define SWAP64(v) \ - (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) -#endif - -#include "ecrypt-machine.h" - -#define ECRYPT_DEFAULT_WTOW - -#ifdef ECRYPT_LITTLE_ENDIAN -#define U16TO16_LITTLE(v) (v) -#define U32TO32_LITTLE(v) (v) -#define U64TO64_LITTLE(v) (v) - -#define U16TO16_BIG(v) SWAP16(v) -#define U32TO32_BIG(v) SWAP32(v) -#define U64TO64_BIG(v) SWAP64(v) -#endif - -#ifdef ECRYPT_BIG_ENDIAN -#define U16TO16_LITTLE(v) SWAP16(v) -#define U32TO32_LITTLE(v) SWAP32(v) -#define U64TO64_LITTLE(v) SWAP64(v) - -#define U16TO16_BIG(v) (v) -#define U32TO32_BIG(v) (v) -#define U64TO64_BIG(v) (v) -#endif - -#include "ecrypt-machine.h" - -/* - * The following macros load words from an array of bytes with - * different types of endianness, and vice versa. - */ - -#define ECRYPT_DEFAULT_BTOW - -#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) - -#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) -#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) -#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) - -#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) -#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) -#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) - -#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) -#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) -#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) - -#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) -#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) -#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) - -#else - -#define U8TO16_LITTLE(p) \ - (((u16)((p)[0]) ) | \ - ((u16)((p)[1]) << 8)) - -#define U8TO32_LITTLE(p) \ - (((u32)((p)[0]) ) | \ - ((u32)((p)[1]) << 8) | \ - ((u32)((p)[2]) << 16) | \ - ((u32)((p)[3]) << 24)) - -#ifdef ECRYPT_NATIVE64 -#define U8TO64_LITTLE(p) \ - (((u64)((p)[0]) ) | \ - ((u64)((p)[1]) << 8) | \ - ((u64)((p)[2]) << 16) | \ - ((u64)((p)[3]) << 24) | \ - ((u64)((p)[4]) << 32) | \ - ((u64)((p)[5]) << 40) | \ - ((u64)((p)[6]) << 48) | \ - ((u64)((p)[7]) << 56)) -#else -#define U8TO64_LITTLE(p) \ - ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) -#endif - -#define U8TO16_BIG(p) \ - (((u16)((p)[0]) << 8) | \ - ((u16)((p)[1]) )) - -#define U8TO32_BIG(p) \ - (((u32)((p)[0]) << 24) | \ - ((u32)((p)[1]) << 16) | \ - ((u32)((p)[2]) << 8) | \ - ((u32)((p)[3]) )) - -#ifdef ECRYPT_NATIVE64 -#define U8TO64_BIG(p) \ - (((u64)((p)[0]) << 56) | \ - ((u64)((p)[1]) << 48) | \ - ((u64)((p)[2]) << 40) | \ - ((u64)((p)[3]) << 32) | \ - ((u64)((p)[4]) << 24) | \ - ((u64)((p)[5]) << 16) | \ - ((u64)((p)[6]) << 8) | \ - ((u64)((p)[7]) )) -#else -#define U8TO64_BIG(p) \ - (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) -#endif - -#define U16TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - } while (0) - -#define U32TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - } while (0) - -#ifdef ECRYPT_NATIVE64 -#define U64TO8_LITTLE(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - (p)[2] = U8V((v) >> 16); \ - (p)[3] = U8V((v) >> 24); \ - (p)[4] = U8V((v) >> 32); \ - (p)[5] = U8V((v) >> 40); \ - (p)[6] = U8V((v) >> 48); \ - (p)[7] = U8V((v) >> 56); \ - } while (0) -#else -#define U64TO8_LITTLE(p, v) \ - do { \ - U32TO8_LITTLE((p), U32V((v) )); \ - U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ - } while (0) -#endif - -#define U16TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) ); \ - (p)[1] = U8V((v) >> 8); \ - } while (0) - -#define U32TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) >> 24); \ - (p)[1] = U8V((v) >> 16); \ - (p)[2] = U8V((v) >> 8); \ - (p)[3] = U8V((v) ); \ - } while (0) - -#ifdef ECRYPT_NATIVE64 -#define U64TO8_BIG(p, v) \ - do { \ - (p)[0] = U8V((v) >> 56); \ - (p)[1] = U8V((v) >> 48); \ - (p)[2] = U8V((v) >> 40); \ - (p)[3] = U8V((v) >> 32); \ - (p)[4] = U8V((v) >> 24); \ - (p)[5] = U8V((v) >> 16); \ - (p)[6] = U8V((v) >> 8); \ - (p)[7] = U8V((v) ); \ - } while (0) -#else -#define U64TO8_BIG(p, v) \ - do { \ - U32TO8_BIG((p), U32V((v) >> 32)); \ - U32TO8_BIG((p) + 4, U32V((v) )); \ - } while (0) -#endif - -#endif - -#include "ecrypt-machine.h" - -/* ------------------------------------------------------------------------- */ - -#define AT_LEAST_ONE(n) (((n) < 1) ? 1 : (n)) - -#define ALIGN(t, v, n) \ - union { t b[n]; MAXT l[AT_LEAST_ONE(n * sizeof(t) / sizeof(MAXT))]; } v - -/* ------------------------------------------------------------------------- */ - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-sync.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-sync.h deleted file mode 100644 index efce9dde273..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-sync.h +++ /dev/null @@ -1,290 +0,0 @@ -#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. ECRYPT_ivsetup() also sets block counter to zero. - */ -void ECRYPT_ivsetup( - ECRYPT_ctx* ctx, - const u8* iv); - -/* - * Block counter setup. It is used only for special purposes, - * since block counter is usually initialized with ECRYPT_ivsetup. - * ECRYPT_ctrsetup has to be called after ECRYPT_ivsetup. - */ -void ECRYPT_ctrsetup( - ECRYPT_ctx* ctx, - const u8* ctr); - -/* - * 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 diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-types.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-types.h deleted file mode 100644 index e608e220a00..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/ecrypt-types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* 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 diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna-32.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna-32.h deleted file mode 100644 index 6a570f06e1b..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna-32.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication and 64 bit addition -*/ - -#if defined(_MSC_VER) - #define POLY1305_NOINLINE __declspec(noinline) -#elif defined(__GNUC__) - #define POLY1305_NOINLINE __attribute__((noinline)) -#else - #define POLY1305_NOINLINE -#endif - -#define poly1305_block_size 16 - -/* 17 + sizeof(size_t) + 14*sizeof(unsigned long) */ -typedef struct poly1305_state_internal_t { - unsigned long r[5]; - unsigned long h[5]; - unsigned long pad[4]; - size_t leftover; - unsigned char buffer[poly1305_block_size]; - unsigned char final; -} poly1305_state_internal_t; - -/* interpret four 8 bit unsigned integers as a 32 bit unsigned integer in little endian */ -static unsigned long -U8TO32(const unsigned char *p) { - return - (((unsigned long)(p[0] & 0xff) ) | - ((unsigned long)(p[1] & 0xff) << 8) | - ((unsigned long)(p[2] & 0xff) << 16) | - ((unsigned long)(p[3] & 0xff) << 24)); -} - -/* store a 32 bit unsigned integer as four 8 bit unsigned integers in little endian */ -static void -U32TO8(unsigned char *p, unsigned long v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; -} - -void -poly1305_init(poly1305_context *ctx, const unsigned char key[32]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - st->r[0] = (U8TO32(&key[ 0]) ) & 0x3ffffff; - st->r[1] = (U8TO32(&key[ 3]) >> 2) & 0x3ffff03; - st->r[2] = (U8TO32(&key[ 6]) >> 4) & 0x3ffc0ff; - st->r[3] = (U8TO32(&key[ 9]) >> 6) & 0x3f03fff; - st->r[4] = (U8TO32(&key[12]) >> 8) & 0x00fffff; - - /* h = 0 */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; - - /* save pad for later */ - st->pad[0] = U8TO32(&key[16]); - st->pad[1] = U8TO32(&key[20]); - st->pad[2] = U8TO32(&key[24]); - st->pad[3] = U8TO32(&key[28]); - - st->leftover = 0; - st->final = 0; -} - -static void -poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) { - const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ - unsigned long r0,r1,r2,r3,r4; - unsigned long s1,s2,s3,s4; - unsigned long h0,h1,h2,h3,h4; - unsigned long long d0,d1,d2,d3,d4; - unsigned long c; - - r0 = st->r[0]; - r1 = st->r[1]; - r2 = st->r[2]; - r3 = st->r[3]; - r4 = st->r[4]; - - s1 = r1 * 5; - s2 = r2 * 5; - s3 = r3 * 5; - s4 = r4 * 5; - - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; - - while (bytes >= poly1305_block_size) { - /* h += m[i] */ - h0 += (U8TO32(m+ 0) ) & 0x3ffffff; - h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; - h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; - h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; - h4 += (U8TO32(m+12) >> 8) | hibit; - - /* h *= r */ - d0 = ((unsigned long long)h0 * r0) + ((unsigned long long)h1 * s4) + ((unsigned long long)h2 * s3) + ((unsigned long long)h3 * s2) + ((unsigned long long)h4 * s1); - d1 = ((unsigned long long)h0 * r1) + ((unsigned long long)h1 * r0) + ((unsigned long long)h2 * s4) + ((unsigned long long)h3 * s3) + ((unsigned long long)h4 * s2); - d2 = ((unsigned long long)h0 * r2) + ((unsigned long long)h1 * r1) + ((unsigned long long)h2 * r0) + ((unsigned long long)h3 * s4) + ((unsigned long long)h4 * s3); - d3 = ((unsigned long long)h0 * r3) + ((unsigned long long)h1 * r2) + ((unsigned long long)h2 * r1) + ((unsigned long long)h3 * r0) + ((unsigned long long)h4 * s4); - d4 = ((unsigned long long)h0 * r4) + ((unsigned long long)h1 * r3) + ((unsigned long long)h2 * r2) + ((unsigned long long)h3 * r1) + ((unsigned long long)h4 * r0); - - /* (partial) h %= p */ - c = (unsigned long)(d0 >> 26); h0 = (unsigned long)d0 & 0x3ffffff; - d1 += c; c = (unsigned long)(d1 >> 26); h1 = (unsigned long)d1 & 0x3ffffff; - d2 += c; c = (unsigned long)(d2 >> 26); h2 = (unsigned long)d2 & 0x3ffffff; - d3 += c; c = (unsigned long)(d3 >> 26); h3 = (unsigned long)d3 & 0x3ffffff; - d4 += c; c = (unsigned long)(d4 >> 26); h4 = (unsigned long)d4 & 0x3ffffff; - h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; - h1 += c; - - m += poly1305_block_size; - bytes -= poly1305_block_size; - } - - st->h[0] = h0; - st->h[1] = h1; - st->h[2] = h2; - st->h[3] = h3; - st->h[4] = h4; -} - -POLY1305_NOINLINE void -poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) { - poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; - unsigned long h0,h1,h2,h3,h4,c; - unsigned long g0,g1,g2,g3,g4; - unsigned long long f; - unsigned long mask; - - /* process the remaining block */ - if (st->leftover) { - size_t i = st->leftover; - st->buffer[i++] = 1; - for (; i < poly1305_block_size; i++) - st->buffer[i] = 0; - st->final = 1; - poly1305_blocks(st, st->buffer, poly1305_block_size); - } - - /* fully carry h */ - h0 = st->h[0]; - h1 = st->h[1]; - h2 = st->h[2]; - h3 = st->h[3]; - h4 = st->h[4]; - - c = h1 >> 26; h1 = h1 & 0x3ffffff; - h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; - h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; - h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; - h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; - h1 += c; - - /* compute h + -p */ - g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; - g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; - g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; - g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; - g4 = h4 + c - (1UL << 26); - - /* select h if h < p, or h + -p if h >= p */ - mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; - g0 &= mask; - g1 &= mask; - g2 &= mask; - g3 &= mask; - g4 &= mask; - mask = ~mask; - h0 = (h0 & mask) | g0; - h1 = (h1 & mask) | g1; - h2 = (h2 & mask) | g2; - h3 = (h3 & mask) | g3; - h4 = (h4 & mask) | g4; - - /* h = h % (2^128) */ - h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; - h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; - h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; - h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; - - /* mac = (h + pad) % (2^128) */ - f = (unsigned long long)h0 + st->pad[0] ; h0 = (unsigned long)f; - f = (unsigned long long)h1 + st->pad[1] + (f >> 32); h1 = (unsigned long)f; - f = (unsigned long long)h2 + st->pad[2] + (f >> 32); h2 = (unsigned long)f; - f = (unsigned long long)h3 + st->pad[3] + (f >> 32); h3 = (unsigned long)f; - - U32TO8(mac + 0, h0); - U32TO8(mac + 4, h1); - U32TO8(mac + 8, h2); - U32TO8(mac + 12, h3); - - /* zero out the state */ - st->h[0] = 0; - st->h[1] = 0; - st->h[2] = 0; - st->h[3] = 0; - st->h[4] = 0; - st->r[0] = 0; - st->r[1] = 0; - st->r[2] = 0; - st->r[3] = 0; - st->r[4] = 0; - st->pad[0] = 0; - st->pad[1] = 0; - st->pad[2] = 0; - st->pad[3] = 0; -} - diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna.h deleted file mode 100644 index 94e23533f21..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/poly1305-donna.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef POLY1305_DONNA_H -#define POLY1305_DONNA_H - -#include - -typedef struct poly1305_context { - size_t aligner; - unsigned char opaque[136]; -} poly1305_context; - -void poly1305_init(poly1305_context *ctx, const unsigned char key[32]); -void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes); -void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]); -void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]); - -int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]); -int poly1305_power_on_self_test(void); - -#endif /* POLY1305_DONNA_H */ - diff --git a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/rfc7539.h b/trezor-crypto/include/TrezorCrypto/chacha20poly1305/rfc7539.h deleted file mode 100644 index d94c777138b..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha20poly1305/rfc7539.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef RFC7539_H -#define RFC7539_H - -#include - -void rfc7539_init(chacha20poly1305_ctx *ctx, const uint8_t key[32], const uint8_t nonce[12]); -void rfc7539_auth(chacha20poly1305_ctx *ctx, const uint8_t *in, size_t n); -void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16]); - -#endif // RFC7539_H diff --git a/trezor-crypto/include/TrezorCrypto/chacha_drbg.h b/trezor-crypto/include/TrezorCrypto/chacha_drbg.h deleted file mode 100644 index 0676d126cd3..00000000000 --- a/trezor-crypto/include/TrezorCrypto/chacha_drbg.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of the Trezor project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CHACHA_DRBG__ -#define __CHACHA_DRBG__ - -#include -#include - -// A very fast deterministic random bit generator based on CTR_DRBG in NIST SP -// 800-90A. Chacha is used instead of a block cipher in the counter mode, SHA256 -// is used as a derivation function. The highest supported security strength is -// at least 256 bits. Reseeding is left up to caller. - -// Length of inputs of chacha_drbg_init (entropy and nonce) or -// chacha_drbg_reseed (entropy and additional_input) that fill exactly -// block_count blocks of hash function in derivation_function. There is no need -// the input to have this length, it's just an optimalization. -#define CHACHA_DRBG_OPTIMAL_RESEED_LENGTH(block_count) \ - ((block_count)*SHA256_BLOCK_LENGTH - 1 - 4 - 9) -// 1 = sizeof(counter), 4 = sizeof(output_length) in -// derivation_function, 9 is length of SHA256 padding of message -// aligned to bytes - -typedef struct _CHACHA_DRBG_CTX { - ECRYPT_ctx chacha_ctx; - uint32_t reseed_counter; -} CHACHA_DRBG_CTX; - -void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *nonce, - size_t nonce_length); -void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, - size_t output_length); -void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, const uint8_t *entropy, - size_t entropy_length, const uint8_t *additional_input, - size_t additional_input_length); -#endif // __CHACHA_DRBG__ diff --git a/trezor-crypto/include/TrezorCrypto/check_mem.h b/trezor-crypto/include/TrezorCrypto/check_mem.h deleted file mode 100644 index cc174563b25..00000000000 --- a/trezor-crypto/include/TrezorCrypto/check_mem.h +++ /dev/null @@ -1,30 +0,0 @@ -#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]; \ - 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 diff --git a/trezor-crypto/include/TrezorCrypto/curves.h b/trezor-crypto/include/TrezorCrypto/curves.h deleted file mode 100644 index d8d423563c6..00000000000 --- a/trezor-crypto/include/TrezorCrypto/curves.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * 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__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -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_SEED_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[]; - -extern const char ED25519_BLAKE2B_NANO_NAME[]; // [wallet-core] - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ecdsa.h b/trezor-crypto/include/TrezorCrypto/ecdsa.h deleted file mode 100644 index 48033642325..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ecdsa.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - * 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 -#include "bignum.h" -#include "hasher.h" -#include - -#if defined(__cplusplus) -extern "C" -{ -#endif - -// 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); -int point_multiply(const ecdsa_curve *curve, const bignum256 *k, - const curve_point *p, curve_point *res); -void point_set_infinity(curve_point *p); -int point_is_infinity(const curve_point *p); -int point_is_equal(const curve_point *p, const curve_point *q); -int point_is_negative_of(const curve_point *p, const curve_point *q); -int scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, - curve_point *res); -int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *pub_key, uint8_t *session_key); -void compress_coords(const curve_point *cp, uint8_t *compressed); -void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, - const bignum256 *x, bignum256 *y); -int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - uint8_t *uncompressed); - -int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, - uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])); -int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *digest, uint8_t *sig, uint8_t *pby, - int (*is_canonical)(uint8_t by, uint8_t sig[64])); -int ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key); -int ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, - uint8_t *pub_key); -void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, - uint8_t *pubkeyhash); -void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, uint8_t *addr_raw); -void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, HasherType hasher_base58, - char *addr, int addrsize); -void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - uint8_t *addr_raw); -void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, - HasherType hasher_pubkey, - HasherType hasher_base58, char *addr, - int addrsize); -void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, - HasherType hasher_base58, char *wif, int wifsize); - -int ecdsa_address_decode(const char *addr, uint32_t version, - HasherType hasher_base58, uint8_t *out); -int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, - curve_point *pub); -int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub); -int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, - const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, - uint32_t msg_len); -int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest); -int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key, - const uint8_t *sig, const uint8_t *digest, - int recid); -int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der); -int ecdsa_sig_from_der(const uint8_t *der, size_t der_len, uint8_t sig[64]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-32bit.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-32bit.h deleted file mode 100644 index 7e38795305b..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-32bit.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - 32 bit integer curve25519 implementation -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -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]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-helpers.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-helpers.h deleted file mode 100644 index 72b0556a6a8..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-helpers.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Public domain by Andrew M. - See: https://github.com/floodyberry/curve25519-donna - - Curve25519 implementation agnostic helpers -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * 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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-scalarmult-base.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-scalarmult-base.h deleted file mode 100644 index 9f3d7989568..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/curve25519-donna-scalarmult-base.h +++ /dev/null @@ -1,8 +0,0 @@ -/* 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); diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-blake2b.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-blake2b.h deleted file mode 100644 index f9bd619e93c..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-blake2b.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ED25519_BLAKE2B_H -#define ED25519_BLAKE2B_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -void ed25519_publickey_blake2b(const ed25519_secret_key sk, ed25519_public_key pk); - -int ed25519_sign_open_blake2b(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign_blake2b(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); - -int ed25519_scalarmult_blake2b(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_BLAKE2B_H diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-32bit-tables.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-32bit-tables.h deleted file mode 100644 index c2300d0cfe4..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-32bit-tables.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -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]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-basepoint-table.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-basepoint-table.h deleted file mode 100644 index 7cdd79af914..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-basepoint-table.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ -extern const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96]; - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-impl-base.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-impl-base.h deleted file mode 100644 index c17e7ef6ded..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-impl-base.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* - 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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-portable.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-portable.h deleted file mode 100644 index 1c89c4957ed..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna-portable.h +++ /dev/null @@ -1,32 +0,0 @@ -#define mul32x32_64(a,b) (((uint64_t)(a))*(b)) - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#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)); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna.h deleted file mode 100644 index 717157bcbaf..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-donna.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Public domain by Andrew M. - 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 - -#include - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 - -#include - -#include - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-blake2b.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-blake2b.h deleted file mode 100644 index 68706f37795..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-blake2b.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 - -#define ed25519_hash_context BLAKE2B_CTX -#define ed25519_hash_init(ctx) tc_blake2b_Init(ctx, 64) -#define ed25519_hash_update(ctx, in, inlen) tc_blake2b_Update((ctx), (in), (inlen)) -#define ed25519_hash_final(ctx, hash) tc_blake2b_Final((ctx), (hash), 64) -#define ed25519_hash(hash, in, inlen) tc_blake2b((in), (inlen), (hash), 64) - -#endif // ED25519_HASH_CUSTOM diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-keccak.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-keccak.h deleted file mode 100644 index 2ebfb3d2cd8..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-keccak.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 - -#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 diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-sha3.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-sha3.h deleted file mode 100644 index a3c2f6dc341..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom-sha3.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 - -#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 diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom.h deleted file mode 100644 index c945e6e9b13..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-hash-custom.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 - -#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 diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-keccak.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-keccak.h deleted file mode 100644 index 58fd8355ae4..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-keccak.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ED25519_KECCAK_H -#define ED25519_KECCAK_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -void ed25519_publickey_keccak(const ed25519_secret_key sk, ed25519_public_key pk); - -int ed25519_sign_open_keccak(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign_keccak(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); - -int ed25519_scalarmult_keccak(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_KECCAK_H diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-sha3.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-sha3.h deleted file mode 100644 index 3adcf84891f..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/ed25519-sha3.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ED25519_SHA3_H -#define ED25519_SHA3_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -void ed25519_publickey_sha3(const ed25519_secret_key sk, ed25519_public_key pk); - -int ed25519_sign_open_sha3(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign_sha3(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); - -int ed25519_scalarmult_sha3(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_SHA3_H diff --git a/trezor-crypto/include/TrezorCrypto/ed25519-donna/modm-donna-32bit.h b/trezor-crypto/include/TrezorCrypto/ed25519-donna/modm-donna-32bit.h deleted file mode 100644 index 953e0204a29..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519-donna/modm-donna-32bit.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Public domain by Andrew M. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - 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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ed25519.h b/trezor-crypto/include/TrezorCrypto/ed25519.h deleted file mode 100644 index 6b4c098b963..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ed25519.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef ED25519_H -#define ED25519_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -typedef unsigned char ed25519_signature[64]; -typedef unsigned char ed25519_public_key[32]; -typedef unsigned char ed25519_secret_key[32]; - -typedef unsigned char curve25519_key[32]; - -typedef unsigned char ed25519_cosi_signature[32]; - -void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); -void ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk); - -int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); -void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS); -void ed25519_sign_ext(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_signature RS); - -int ed25519_scalarmult(ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk); - -void curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint); -void curve25519_scalarmult_basepoint(curve25519_key mypublic, const curve25519_key secret); - -#if !defined(__GNUC__) || __GNUC__ > 4 -#define CONST const -#else -#define CONST -#endif - -int ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n); -void ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n); -void ed25519_cosi_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key key, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig); - -#if defined(__cplusplus) -} -#endif - -#endif // ED25519_H diff --git a/trezor-crypto/include/TrezorCrypto/endian.h b/trezor-crypto/include/TrezorCrypto/endian.h deleted file mode 100644 index e456cf945cd..00000000000 --- a/trezor-crypto/include/TrezorCrypto/endian.h +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * Copyright 2007-2009 Colin Percival - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * This file was originally written by Colin Percival as part of the Tarsnap - * online backup system. - */ -#ifndef _ENDIAN_H_ -#define _ENDIAN_H_ - - -#include -#ifdef _MSC_VER - #define INLINE __inline -#else - #define INLINE inline -#endif - -static INLINE uint32_t -be32dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + - ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); -} - -static INLINE void -be32enc(void *pp, uint32_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[3] = x & 0xff; - p[2] = (x >> 8) & 0xff; - p[1] = (x >> 16) & 0xff; - p[0] = (x >> 24) & 0xff; -} - -static INLINE uint64_t -be64dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + - ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + - ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + - ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); -} - -static INLINE void -be64enc(void *pp, uint64_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[7] = x & 0xff; - p[6] = (x >> 8) & 0xff; - p[5] = (x >> 16) & 0xff; - p[4] = (x >> 24) & 0xff; - p[3] = (x >> 32) & 0xff; - p[2] = (x >> 40) & 0xff; - p[1] = (x >> 48) & 0xff; - p[0] = (x >> 56) & 0xff; -} - -static INLINE uint32_t -le32dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + - ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); -} - -static INLINE void -le32enc(void *pp, uint32_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; -} - -static INLINE uint64_t -le64dec(const void *pp) -{ - const uint8_t *p = (uint8_t const *)pp; - - return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + - ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + - ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + - ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); -} - -static INLINE void -le64enc(void *pp, uint64_t x) -{ - uint8_t * p = (uint8_t *)pp; - - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; - p[4] = (x >> 32) & 0xff; - p[5] = (x >> 40) & 0xff; - p[6] = (x >> 48) & 0xff; - p[7] = (x >> 56) & 0xff; -} - -#endif /* !_ENDIAN_H_ */ diff --git a/trezor-crypto/include/TrezorCrypto/groestl.h b/trezor-crypto/include/TrezorCrypto/groestl.h deleted file mode 100644 index 8335abf46a1..00000000000 --- a/trezor-crypto/include/TrezorCrypto/groestl.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Groestl hash from https://github.com/Groestlcoin/vanitygen - * Trezor adaptation by Yura Pakhuchiy . */ -/** - * 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 - */ - -#ifndef GROESTL_H__ -#define GROESTL_H__ - -#include - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/** - * 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 - * memcpy()). - */ -typedef struct { - unsigned char buf[128]; /* first field, for alignment */ - size_t ptr; - union { - uint64_t wide[16]; - uint32_t narrow[32]; - } state; - uint64_t count; -} 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 - * GROESTL512_CTX) - */ -void groestl512_Init(void *cc); - -/** - * Process some data bytes. It is acceptable that len 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 - * accommodate 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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/groestl_internal.h b/trezor-crypto/include/TrezorCrypto/groestl_internal.h deleted file mode 100644 index 73d0156c379..00000000000 --- a/trezor-crypto/include/TrezorCrypto/groestl_internal.h +++ /dev/null @@ -1,510 +0,0 @@ -/* Groestl hash from https://github.com/Groestlcoin/vanitygen - * Trezor adaptation by Yura Pakhuchiy . */ -/** - * 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 unsigned char 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 - */ - -#ifndef GROESTL_INTERNAL_H__ -#define GROESTL_INTERNAL_H__ - -#include - -/* - * 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 - -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 - -/* - * ARM64, little-endian. - */ -#elif defined __aarch64__ - -#define SPH_DETECT_LITTLE_ENDIAN 1 -#define SPH_DETECT_BIG_ENDIAN 0 - -#endif - -#define SPH_LITTLE_ENDIAN 1 // [wallet-core] - -#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 diff --git a/trezor-crypto/include/TrezorCrypto/hasher.h b/trezor-crypto/include/TrezorCrypto/hasher.h deleted file mode 100644 index e0d70934b7c..00000000000 --- a/trezor-crypto/include/TrezorCrypto/hasher.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * 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 -#include - -#include "blake256.h" -#include "blake2b.h" -#include "groestl.h" -#include -#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 diff --git a/trezor-crypto/include/TrezorCrypto/hmac.h b/trezor-crypto/include/TrezorCrypto/hmac.h deleted file mode 100644 index b7919ae599b..00000000000 --- a/trezor-crypto/include/TrezorCrypto/hmac.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * 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 -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/hmac_drbg.h b/trezor-crypto/include/TrezorCrypto/hmac_drbg.h deleted file mode 100644 index 3316e56c14f..00000000000 --- a/trezor-crypto/include/TrezorCrypto/hmac_drbg.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2019 Andrew R. Kozlik - * - * 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 __HMAC_DRBG_H__ -#define __HMAC_DRBG_H__ - -#include -#include - -// HMAC based Deterministic Random Bit Generator with SHA-256 - -typedef struct _HMAC_DRBG_CTX { - uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t v[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; -} HMAC_DRBG_CTX; - -void hmac_drbg_init(HMAC_DRBG_CTX *ctx, const uint8_t *buf, size_t len, - const uint8_t *nonce, size_t nonce_len); -void hmac_drbg_reseed(HMAC_DRBG_CTX *ctx, const uint8_t *buf, size_t len, - const uint8_t *addin, size_t addin_len); -void hmac_drbg_generate(HMAC_DRBG_CTX *ctx, uint8_t *buf, size_t len); - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/monero/xmr.h b/trezor-crypto/include/TrezorCrypto/monero/xmr.h deleted file mode 100644 index 579c530c4ee..00000000000 --- a/trezor-crypto/include/TrezorCrypto/monero/xmr.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// Created by Dusan Klinec on 10/05/2018. -// - -#ifndef TREZOR_CRYPTO_XMR_H -#define TREZOR_CRYPTO_XMR_H - -#include -#include - -extern const ge25519 ALIGN(16) xmr_h; - -typedef unsigned char xmr_key_t[32]; - -typedef struct xmr_ctkey { - xmr_key_t dest; - xmr_key_t mask; -} xmr_ctkey_t; - -/* sets H point to r */ -void ge25519_set_xmr_h(ge25519 *r); - -/* random scalar value */ -void xmr_random_scalar(bignum256modm m); - -/* cn_fast_hash */ -void xmr_fast_hash(uint8_t * hash, const void *data, size_t length); - -/* incremental hashing wrappers */ -void xmr_hasher_init(Hasher * hasher); -void xmr_hasher_update(Hasher * hasher, const void *data, size_t length); -void xmr_hasher_final(Hasher * hasher, uint8_t * hash); -void xmr_hasher_copy(Hasher * dst, const Hasher * src); - -/* H_s(buffer) */ -void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length); - -/* H_p(buffer) */ -void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length); - -/* derivation to scalar value */ -void xmr_derivation_to_scalar(bignum256modm s, const ge25519 * p, uint32_t output_index); - -/* derivation */ -void xmr_generate_key_derivation(ge25519 * r, const ge25519 * A, const bignum256modm b); - -/* H_s(derivation || varint(output_index)) + base */ -void xmr_derive_private_key(bignum256modm s, const ge25519 * deriv, uint32_t idx, const bignum256modm base); - -/* H_s(derivation || varint(output_index))G + base */ -void xmr_derive_public_key(ge25519 * r, const ge25519 * deriv, uint32_t idx, const ge25519 * base); - -/* aG + bB, G is basepoint */ -void xmr_add_keys2(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B); -void xmr_add_keys2_vartime(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B); - -/* aA + bB */ -void xmr_add_keys3(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B); -void xmr_add_keys3_vartime(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B); - -/* subaddress secret */ -void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, uint32_t minor, const bignum256modm m); - -/* Generates Pedersen commitment C = aG + bH */ -void xmr_gen_c(ge25519 * r, const bignum256modm a, uint64_t amount); - -#endif //TREZOR_CRYPTO_XMR_H diff --git a/trezor-crypto/include/TrezorCrypto/nano.h b/trezor-crypto/include/TrezorCrypto/nano.h deleted file mode 100644 index 72a9e15306b..00000000000 --- a/trezor-crypto/include/TrezorCrypto/nano.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (c) 2019 Mart Roosmaa - * - * 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 __NANO_H__ -#define __NANO_H__ - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char *BASE32_ALPHABET_NANO; - -size_t nano_get_address( - const ed25519_public_key public_key, - const char *prefix, - const size_t prefix_len, - char *out, - size_t out_len); - -bool nano_validate_address( - const char *prefix, - const size_t prefix_len, - const char *address, - const size_t address_len, - ed25519_public_key out_public_key); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif \ No newline at end of file diff --git a/trezor-crypto/include/TrezorCrypto/nem.h b/trezor-crypto/include/TrezorCrypto/nem.h deleted file mode 100644 index 574c67aaa8d..00000000000 --- a/trezor-crypto/include/TrezorCrypto/nem.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * 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 __NEM_H__ -#define __NEM_H__ - -#include -#include -#include - -#include "bip32.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define NEM_LEVY_PERCENTILE_DIVISOR 4 -#define NEM_MAX_DIVISIBILITY 6 -#define NEM_MAX_SUPPLY 9000000000 - -#define NEM_NETWORK_MAINNET 0x68 -#define NEM_NETWORK_TESTNET 0x98 -#define NEM_NETWORK_MIJIN 0x60 - -#define NEM_ADDRESS_SIZE 40 -#define NEM_ADDRESS_SIZE_RAW 25 - -#define NEM_TRANSACTION_TYPE_TRANSFER 0x0101 -#define NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER 0x0801 -#define NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION 0x1001 -#define NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE 0x1002 -#define NEM_TRANSACTION_TYPE_MULTISIG 0x1004 -#define NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE 0x2001 -#define NEM_TRANSACTION_TYPE_MOSAIC_CREATION 0x4001 -#define NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE 0x4002 - -#define NEM_SALT_SIZE sizeof(ed25519_public_key) - -#define NEM_ENCRYPTED_SIZE(size) \ - (((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE) -#define NEM_ENCRYPTED_PAYLOAD_SIZE(size) \ - (AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size)) - -#define _NEM_PADDING_SIZE(buffer, size) ((buffer)[(size)-1]) -#define NEM_PADDING_SIZE(buffer, size) \ - (_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) \ - : _NEM_PADDING_SIZE(buffer, size)) - -#define NEM_DECRYPTED_SIZE(buffer, size) ((size)-NEM_PADDING_SIZE(buffer, size)) - -typedef struct { - ed25519_public_key public_key; - uint8_t *buffer; - size_t offset; - size_t size; -} nem_transaction_ctx; - -const char *nem_network_name(uint8_t network); - -void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, - uint8_t *address); -bool nem_get_address(const ed25519_public_key public_key, uint8_t version, - char *address); - -bool nem_validate_address_raw(const uint8_t *address, uint8_t network); -bool nem_validate_address(const char *address, uint8_t network); - -void nem_transaction_start(nem_transaction_ctx *ctx, - const ed25519_public_key public_key, uint8_t *buffer, - size_t size); -size_t nem_transaction_end(nem_transaction_ctx *ctx, - const ed25519_secret_key private_key, - ed25519_signature signature); - -bool nem_transaction_write_common(nem_transaction_ctx *context, uint32_t type, - uint32_t version, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, - uint32_t deadline); - -bool nem_transaction_create_transfer(nem_transaction_ctx *context, - uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const char *recipient, uint64_t amount, - const uint8_t *payload, uint32_t length, - bool encrypted, uint32_t mosaics); - -bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx, - const char *namespace, const char *mosaic, - uint64_t quantity); - -bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network, - uint32_t timestamp, - const ed25519_public_key signer, - uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner); - -bool nem_transaction_create_multisig_signature( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const nem_transaction_ctx *inner); - -bool nem_transaction_create_provision_namespace( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *parent, const char *rental_sink, - uint64_t rental_fee); - -bool nem_transaction_create_mosaic_creation( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, const char *description, - uint32_t divisibility, uint64_t supply, bool mutable_supply, - bool transferable, uint32_t levy_type, uint64_t levy_fee, - const char *levy_address, const char *levy_namespace, - const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee); - -bool nem_transaction_create_mosaic_supply_change( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - const char *namespace, const char *mosaic, uint32_t type, uint64_t delta); - -bool nem_transaction_create_aggregate_modification( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t modifications, bool relative_change); - -bool nem_transaction_write_cosignatory_modification( - nem_transaction_ctx *ctx, uint32_t type, - const ed25519_public_key cosignatory); - -bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx, - int32_t relative_change); - -bool nem_transaction_create_importance_transfer( - nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp, - const ed25519_public_key signer, uint64_t fee, uint32_t deadline, - uint32_t mode, const ed25519_public_key remote); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/nist256p1.h b/trezor-crypto/include/TrezorCrypto/nist256p1.h deleted file mode 100644 index 02d04025ade..00000000000 --- a/trezor-crypto/include/TrezorCrypto/nist256p1.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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 __NIST256P1_H__ -#define __NIST256P1_H__ - -#include - -#include "bip32.h" -#include "ecdsa.h" - -extern const ecdsa_curve nist256p1; -extern const curve_info nist256p1_info; - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/options.h b/trezor-crypto/include/TrezorCrypto/options.h deleted file mode 100644 index ce72d886604..00000000000 --- a/trezor-crypto/include/TrezorCrypto/options.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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 __OPTIONS_H__ -#define __OPTIONS_H__ - -#ifndef AES_128 -#define AES_128 1 // [wallet-core] -#endif - -#ifndef AES_VAR -#define AES_VAR 1 // [wallet-core] -#endif - -// use precomputed Curve Points (some scalar multiples of curve base point G) -#ifndef USE_PRECOMPUTED_CP -#define USE_PRECOMPUTED_CP 1 -#endif - -// use fast inverse method -#ifndef USE_INVERSE_FAST -#define USE_INVERSE_FAST 1 -#endif - -// support for printing bignum256 structures via printf -#ifndef USE_BN_PRINT -#define USE_BN_PRINT 0 -#endif - -// use deterministic signatures -#ifndef USE_RFC6979 -#define USE_RFC6979 1 -#endif - -// implement BIP32 caching -#ifndef USE_BIP32_CACHE -#define USE_BIP32_CACHE 0 // [wallet-core] -#define BIP32_CACHE_SIZE 10 -#define BIP32_CACHE_MAXDEPTH 8 -#endif - -// support constructing BIP32 nodes from ed25519 and curve25519 curves. -#ifndef USE_BIP32_25519_CURVES -#define USE_BIP32_25519_CURVES 1 -#endif - -// implement BIP39 caching -#ifndef USE_BIP39_CACHE -#define USE_BIP39_CACHE 1 -#define BIP39_CACHE_SIZE 4 -#endif - -// support Ethereum operations -#ifndef USE_ETHEREUM -#define USE_ETHEREUM 0 -#endif - -// support Graphene operations (STEEM, BitShares) -#ifndef USE_GRAPHENE -#define USE_GRAPHENE 0 -#endif - -// support NEM operations -#ifndef USE_NEM -#define USE_NEM 0 -#endif - -// support MONERO operations -#ifndef USE_MONERO -#define USE_MONERO 0 -#endif - -// support CARDANO operations -#ifndef USE_CARDANO -#define USE_CARDANO 1 // [wallet-core] -#endif - -// support Keccak hashing -#ifndef USE_KECCAK -#define USE_KECCAK 1 -#endif - -// add way how to mark confidential data -#ifndef CONFIDENTIAL -#define CONFIDENTIAL -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/pbkdf2.h b/trezor-crypto/include/TrezorCrypto/pbkdf2.h deleted file mode 100644 index d34e80191f0..00000000000 --- a/trezor-crypto/include/TrezorCrypto/pbkdf2.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * 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 __PBKDF2_H__ -#define __PBKDF2_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _PBKDF2_HMAC_SHA256_CTX { - uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t f[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)]; - char first; -} PBKDF2_HMAC_SHA256_CTX; - -typedef struct _PBKDF2_HMAC_SHA512_CTX { - uint64_t odig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; - uint64_t idig[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; - uint64_t f[SHA512_DIGEST_LENGTH / sizeof(uint64_t)]; - uint64_t g[SHA512_BLOCK_LENGTH / sizeof(uint64_t)]; - char first; -} PBKDF2_HMAC_SHA512_CTX; - -void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, - int passlen, const uint8_t *salt, int saltlen, - uint32_t blocknr); -void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, - uint32_t iterations); -void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key); -void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen); - -void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, - int passlen, const uint8_t *salt, int saltlen, - uint32_t blocknr); -void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, - uint32_t iterations); -void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key); -void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, - int saltlen, uint32_t iterations, uint8_t *key, - int keylen); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/rc4.h b/trezor-crypto/include/TrezorCrypto/rc4.h deleted file mode 100644 index 8ba8a9b25a0..00000000000 --- a/trezor-crypto/include/TrezorCrypto/rc4.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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 __RC4_H__ -#define __RC4_H__ - -#include -#include - -typedef struct { - uint8_t S[256]; - uint8_t i, j; -} RC4_CTX; - -void rc4_init(RC4_CTX *ctx, const uint8_t *key, size_t length); -void rc4_encrypt(RC4_CTX *ctx, uint8_t *buffer, size_t length); - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/rfc6979.h b/trezor-crypto/include/TrezorCrypto/rfc6979.h deleted file mode 100644 index e4cb9ff049f..00000000000 --- a/trezor-crypto/include/TrezorCrypto/rfc6979.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * Copyright (c) 2015-2017 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 __RFC6979_H__ -#define __RFC6979_H__ - -#include -#include "bignum.h" -#include "ecdsa.h" -#include "hmac_drbg.h" - -// rfc6979 pseudo random number generator state -typedef HMAC_DRBG_CTX rfc6979_state; - -void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, - const ecdsa_curve *curve, rfc6979_state *rng); -void generate_rfc6979(uint8_t rnd[32], rfc6979_state *rng); -void generate_k_rfc6979(bignum256 *k, rfc6979_state *rng); - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/ripemd160.h b/trezor-crypto/include/TrezorCrypto/ripemd160.h deleted file mode 100644 index 78c9ed751f9..00000000000 --- a/trezor-crypto/include/TrezorCrypto/ripemd160.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __RIPEMD160_H__ -#define __RIPEMD160_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define RIPEMD160_BLOCK_LENGTH 64 -#define RIPEMD160_DIGEST_LENGTH 20 - -typedef struct _RIPEMD160_CTX { - uint32_t total[2]; /*!< number of bytes processed */ - uint32_t state[5]; /*!< intermediate digest state */ - uint8_t buffer[RIPEMD160_BLOCK_LENGTH]; /*!< data block being processed */ -} RIPEMD160_CTX; - -void ripemd160_Init(RIPEMD160_CTX *ctx); -void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen); -void ripemd160_Final(RIPEMD160_CTX *ctx, - uint8_t output[RIPEMD160_DIGEST_LENGTH]); -void ripemd160(const uint8_t *msg, uint32_t msg_len, - uint8_t hash[RIPEMD160_DIGEST_LENGTH]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/script.h b/trezor-crypto/include/TrezorCrypto/script.h deleted file mode 100644 index c9cc003b866..00000000000 --- a/trezor-crypto/include/TrezorCrypto/script.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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 __SCRIPT_H__ -#define __SCRIPT_H__ - -#include - -int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, - int addrsize); - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/scrypt.h b/trezor-crypto/include/TrezorCrypto/scrypt.h deleted file mode 100644 index 7140bc2e255..00000000000 --- a/trezor-crypto/include/TrezorCrypto/scrypt.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright 2009 Colin Percival - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * This file was originally written by Colin Percival as part of the Tarsnap - * online backup system. - */ - -#ifndef _SCRYPT_H_ -#define _SCRYPT_H_ - - -#include -#include -#ifdef __cplusplus -extern "C"{ -#endif - -/** - * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): - * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, - * p, buflen) and write the result into buf. The parameters r, p, and buflen - * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N - * must be a power of 2 greater than 1. - * - * scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): - * password; duh - * N: CPU AND RAM cost (first modifier) - * r: RAM Cost - * p: CPU cost (parallelisation) - * In short, N is your main performance modifier. Values of r = 8, p = 1 are - * standard unless you want to modify the CPU/RAM ratio. - * Return 0 on success; or -1 on error. - */ -int scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, - uint32_t, uint32_t, /*@out@*/ uint8_t *, size_t); - -#ifdef __cplusplus -} -#endif - -/* Sane default values */ -#define SCRYPT_N 16384 -#define SCRYPT_r 8 -#define SCRYPT_p 16 - -#endif /* !_SCRYPT_H_ */ diff --git a/trezor-crypto/include/TrezorCrypto/secp256k1.h b/trezor-crypto/include/TrezorCrypto/secp256k1.h deleted file mode 100644 index 516ae391d89..00000000000 --- a/trezor-crypto/include/TrezorCrypto/secp256k1.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __SECP256K1_H__ -#define __SECP256K1_H__ - -#include - -#include "bip32.h" -#include "ecdsa.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ecdsa_curve secp256k1; -extern const curve_info secp256k1_info; -extern const curve_info secp256k1_decred_info; -extern const curve_info secp256k1_groestl_info; -extern const curve_info secp256k1_smart_info; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/sha2.h b/trezor-crypto/include/TrezorCrypto/sha2.h deleted file mode 100644 index 76bb2bcf3bc..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sha2.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (c) 2000-2001 Aaron D. Gifford - * Copyright (c) 2013-2014 Pavol Rusnak - * 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 contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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. - */ - -#ifndef __SHA2_H__ -#define __SHA2_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SHA1_BLOCK_LENGTH 64 -#define SHA1_DIGEST_LENGTH 20 -#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) - -typedef struct _SHA1_CTX { - uint32_t state[5]; - uint64_t bitcount; - uint32_t buffer[SHA1_BLOCK_LENGTH/sizeof(uint32_t)]; -} SHA1_CTX; -typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint32_t buffer[SHA256_BLOCK_LENGTH/sizeof(uint32_t)]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint64_t buffer[SHA512_BLOCK_LENGTH/sizeof(uint64_t)]; -} SHA512_CTX; - -/*** ENDIAN REVERSAL MACROS *******************************************/ -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#define BIG_ENDIAN 4321 -#endif - -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -#define REVERSE32(w,x) { \ - uint32_t tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ -} -#define REVERSE64(w,x) { \ - uint64_t tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ -} -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -extern const uint32_t sha256_initial_hash_value[8]; -extern const uint64_t sha512_initial_hash_value[8]; - -void sha1_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); -void sha1_Init(SHA1_CTX *); -void sha1_Update(SHA1_CTX*, const uint8_t*, size_t); -void sha1_Final(SHA1_CTX*, uint8_t[SHA1_DIGEST_LENGTH]); -char* sha1_End(SHA1_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); -void sha1_Raw(const uint8_t*, size_t, uint8_t[SHA1_DIGEST_LENGTH]); -char* sha1_Data(const uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); - -void sha256_Transform(const uint32_t* state_in, const uint32_t* data, uint32_t* state_out); -void sha256_Init(SHA256_CTX *); -void sha256_Update(SHA256_CTX*, const uint8_t*, size_t); -void sha256_Final(SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]); -char* sha256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -void sha256_Raw(const uint8_t*, size_t, uint8_t[SHA256_DIGEST_LENGTH]); -char* sha256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); - -void sha512_Transform(const uint64_t* state_in, const uint64_t* data, uint64_t* state_out); -void sha512_Init(SHA512_CTX*); -void sha512_Update(SHA512_CTX*, const uint8_t*, size_t); -void sha512_Final(SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]); -char* sha512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -void sha512_Raw(const uint8_t*, size_t, uint8_t[SHA512_DIGEST_LENGTH]); -// [wallet-core] -void sha512_256_Raw(const uint8_t*, size_t, uint8_t[SHA256_DIGEST_LENGTH]); -char* sha512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/sha3.h b/trezor-crypto/include/TrezorCrypto/sha3.h deleted file mode 100644 index be4bea05135..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sha3.h +++ /dev/null @@ -1,89 +0,0 @@ -/* sha3.h - an implementation of Secure Hash Algorithm 3 (Keccak). - * based on the - * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 - * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche - * - * Copyright: 2013 Aleksey Kravchenko - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! - */ - -#ifndef __SHA3_H__ -#define __SHA3_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define sha3_224_hash_size 28 -#define sha3_256_hash_size 32 -#define sha3_384_hash_size 48 -#define sha3_512_hash_size 64 -#define sha3_max_permutation_size 25 -#define sha3_max_rate_in_qwords 24 - -#define SHA3_224_BLOCK_LENGTH 144 -#define SHA3_256_BLOCK_LENGTH 136 -#define SHA3_384_BLOCK_LENGTH 104 -#define SHA3_512_BLOCK_LENGTH 72 - -#define SHA3_224_DIGEST_LENGTH sha3_224_hash_size -#define SHA3_256_DIGEST_LENGTH sha3_256_hash_size -#define SHA3_384_DIGEST_LENGTH sha3_384_hash_size -#define SHA3_512_DIGEST_LENGTH sha3_512_hash_size - -/** - * SHA3 Algorithm context. - */ -typedef struct SHA3_CTX -{ - /* 1600 bits algorithm hashing state */ - uint64_t hash[sha3_max_permutation_size]; - /* 1536-bit buffer for leftovers */ - uint64_t message[sha3_max_rate_in_qwords]; - /* count of bytes in the message[] buffer */ - unsigned rest; - /* size of a message block processed at once */ - unsigned block_size; -} SHA3_CTX; - -/* methods for calculating the hash function */ - -void sha3_224_Init(SHA3_CTX *ctx); -void sha3_256_Init(SHA3_CTX *ctx); -void sha3_384_Init(SHA3_CTX *ctx); -void sha3_512_Init(SHA3_CTX *ctx); -void sha3_Update(SHA3_CTX *ctx, const unsigned char* msg, size_t size); -void sha3_Final(SHA3_CTX *ctx, unsigned char* result); - -#if USE_KECCAK -#define keccak_224_Init sha3_224_Init -#define keccak_256_Init sha3_256_Init -#define keccak_384_Init sha3_384_Init -#define keccak_512_Init sha3_512_Init -#define keccak_Update sha3_Update -void keccak_Final(SHA3_CTX *ctx, unsigned char* result); -void keccak_256(const unsigned char* data, size_t len, unsigned char* digest); -void keccak_512(const unsigned char* data, size_t len, unsigned char* digest); -#endif - -void sha3_256(const unsigned char* data, size_t len, unsigned char* digest); -void sha3_512(const unsigned char* data, size_t len, unsigned char* digest); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __SHA3_H__ */ diff --git a/trezor-crypto/include/TrezorCrypto/shamir.h b/trezor-crypto/include/TrezorCrypto/shamir.h deleted file mode 100644 index ef04a30636a..00000000000 --- a/trezor-crypto/include/TrezorCrypto/shamir.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Low level API for Daan Sprenkels' Shamir secret sharing library - * Copyright (c) 2017 Daan Sprenkels - * Copyright (c) 2019 SatoshiLabs - * - * 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. - * - * Usage of this API is hazardous and is only reserved for beings with a - * good understanding of the Shamir secret sharing scheme and who know how - * crypto code is implemented. If you are unsure about this, use the - * intermediate level API. You have been warned! - */ - -#ifndef __SHAMIR_H__ -#define __SHAMIR_H__ - -#include -#include -#include - -#define SHAMIR_MAX_LEN 32 - -/* - * Computes f(x) given the Shamir shares (x_1, f(x_1)), ... , (x_m, f(x_m)). - * The x coordinates of the shares must be pairwise distinct. Returns true on - * success, otherwise false. - * result: Array of length len where the evaluations of the polynomials in x - * will be written. - * result_index: The x coordinate of the result. - * share_indices: Points to the array of integers x_1, ... , x_m. - * share_values: Points to the array of y_1, ... , y_m, where each y_i is an - * array of bytes of length len representing the evaluations of the - * polynomials in x_i. - * share_count: The number of shares m. - * len: The length of the result array and of each of the y_1, ... , y_m arrays. - * - * The number of shares used to compute the result may be larger than the - * required threshold. - * - * This function does *not* do *any* checking for integrity. If any of the - * shares are not original, this will result in an invalid restored value. - * All values written to `result` should be treated as secret. Even if some of - * the shares that were provided as input were incorrect, the result *still* - * allows an attacker to gain information about the correct result. - * - * This function treats `shares_values`, `share_indices` and `result` as secret - * values. `share_count` is treated as a public value (for performance reasons). - */ -bool shamir_interpolate(uint8_t *result, uint8_t result_index, - const uint8_t *share_indices, - const uint8_t **share_values, uint8_t share_count, - size_t len); - -#endif /* __SHAMIR_H__ */ diff --git a/trezor-crypto/include/TrezorCrypto/slip39.h b/trezor-crypto/include/TrezorCrypto/slip39.h deleted file mode 100644 index 08883edf2b5..00000000000 --- a/trezor-crypto/include/TrezorCrypto/slip39.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * This file is part of the TREZOR project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * 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 __SLIP39_H__ -#define __SLIP39_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -const char* get_word(uint16_t index); - -bool word_index(uint16_t* index, const char* word, uint8_t word_length); - -uint16_t slip39_word_completion_mask(uint16_t prefix); - -const char* button_sequence_to_word(uint16_t prefix); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/slip39_wordlist.h b/trezor-crypto/include/TrezorCrypto/slip39_wordlist.h deleted file mode 100644 index 3464aae9412..00000000000 --- a/trezor-crypto/include/TrezorCrypto/slip39_wordlist.h +++ /dev/null @@ -1,1246 +0,0 @@ -/** - * This file is part of the TREZOR project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * 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 __SLIP39_WORDLIST_H__ -#define __SLIP39_WORDLIST_H__ - -#include - -#define WORDS_COUNT 1024 - -static const char* const slip39_wordlist[WORDS_COUNT] = { - "academic", "acid", "acne", "acquire", "acrobat", "activity", - "actress", "adapt", "adequate", "adjust", "admit", "adorn", - "adult", "advance", "advocate", "afraid", "again", "agency", - "agree", "aide", "aircraft", "airline", "airport", "ajar", - "alarm", "album", "alcohol", "alien", "alive", "alpha", - "already", "alto", "aluminum", "always", "amazing", "ambition", - "amount", "amuse", "analysis", "anatomy", "ancestor", "ancient", - "angel", "angry", "animal", "answer", "antenna", "anxiety", - "apart", "aquatic", "arcade", "arena", "argue", "armed", - "artist", "artwork", "aspect", "auction", "august", "aunt", - "average", "aviation", "avoid", "award", "away", "axis", - "axle", "beam", "beard", "beaver", "become", "bedroom", - "behavior", "being", "believe", "belong", "benefit", "best", - "beyond", "bike", "biology", "birthday", "bishop", "black", - "blanket", "blessing", "blimp", "blind", "blue", "body", - "bolt", "boring", "born", "both", "boundary", "bracelet", - "branch", "brave", "breathe", "briefing", "broken", "brother", - "browser", "bucket", "budget", "building", "bulb", "bulge", - "bumpy", "bundle", "burden", "burning", "busy", "buyer", - "cage", "calcium", "camera", "campus", "canyon", "capacity", - "capital", "capture", "carbon", "cards", "careful", "cargo", - "carpet", "carve", "category", "cause", "ceiling", "center", - "ceramic", "champion", "change", "charity", "check", "chemical", - "chest", "chew", "chubby", "cinema", "civil", "class", - "clay", "cleanup", "client", "climate", "clinic", "clock", - "clogs", "closet", "clothes", "club", "cluster", "coal", - "coastal", "coding", "column", "company", "corner", "costume", - "counter", "course", "cover", "cowboy", "cradle", "craft", - "crazy", "credit", "cricket", "criminal", "crisis", "critical", - "crowd", "crucial", "crunch", "crush", "crystal", "cubic", - "cultural", "curious", "curly", "custody", "cylinder", "daisy", - "damage", "dance", "darkness", "database", "daughter", "deadline", - "deal", "debris", "debut", "decent", "decision", "declare", - "decorate", "decrease", "deliver", "demand", "density", "deny", - "depart", "depend", "depict", "deploy", "describe", "desert", - "desire", "desktop", "destroy", "detailed", "detect", "device", - "devote", "diagnose", "dictate", "diet", "dilemma", "diminish", - "dining", "diploma", "disaster", "discuss", "disease", "dish", - "dismiss", "display", "distance", "dive", "divorce", "document", - "domain", "domestic", "dominant", "dough", "downtown", "dragon", - "dramatic", "dream", "dress", "drift", "drink", "drove", - "drug", "dryer", "duckling", "duke", "duration", "dwarf", - "dynamic", "early", "earth", "easel", "easy", "echo", - "eclipse", "ecology", "edge", "editor", "educate", "either", - "elbow", "elder", "election", "elegant", "element", "elephant", - "elevator", "elite", "else", "email", "emerald", "emission", - "emperor", "emphasis", "employer", "empty", "ending", "endless", - "endorse", "enemy", "energy", "enforce", "engage", "enjoy", - "enlarge", "entrance", "envelope", "envy", "epidemic", "episode", - "equation", "equip", "eraser", "erode", "escape", "estate", - "estimate", "evaluate", "evening", "evidence", "evil", "evoke", - "exact", "example", "exceed", "exchange", "exclude", "excuse", - "execute", "exercise", "exhaust", "exotic", "expand", "expect", - "explain", "express", "extend", "extra", "eyebrow", "facility", - "fact", "failure", "faint", "fake", "false", "family", - "famous", "fancy", "fangs", "fantasy", "fatal", "fatigue", - "favorite", "fawn", "fiber", "fiction", "filter", "finance", - "findings", "finger", "firefly", "firm", "fiscal", "fishing", - "fitness", "flame", "flash", "flavor", "flea", "flexible", - "flip", "float", "floral", "fluff", "focus", "forbid", - "force", "forecast", "forget", "formal", "fortune", "forward", - "founder", "fraction", "fragment", "frequent", "freshman", "friar", - "fridge", "friendly", "frost", "froth", "frozen", "fumes", - "funding", "furl", "fused", "galaxy", "game", "garbage", - "garden", "garlic", "gasoline", "gather", "general", "genius", - "genre", "genuine", "geology", "gesture", "glad", "glance", - "glasses", "glen", "glimpse", "goat", "golden", "graduate", - "grant", "grasp", "gravity", "gray", "greatest", "grief", - "grill", "grin", "grocery", "gross", "group", "grownup", - "grumpy", "guard", "guest", "guilt", "guitar", "gums", - "hairy", "hamster", "hand", "hanger", "harvest", "have", - "havoc", "hawk", "hazard", "headset", "health", "hearing", - "heat", "helpful", "herald", "herd", "hesitate", "hobo", - "holiday", "holy", "home", "hormone", "hospital", "hour", - "huge", "human", "humidity", "hunting", "husband", "hush", - "husky", "hybrid", "idea", "identify", "idle", "image", - "impact", "imply", "improve", "impulse", "include", "income", - "increase", "index", "indicate", "industry", "infant", "inform", - "inherit", "injury", "inmate", "insect", "inside", "install", - "intend", "intimate", "invasion", "involve", "iris", "island", - "isolate", "item", "ivory", "jacket", "jerky", "jewelry", - "join", "judicial", "juice", "jump", "junction", "junior", - "junk", "jury", "justice", "kernel", "keyboard", "kidney", - "kind", "kitchen", "knife", "knit", "laden", "ladle", - "ladybug", "lair", "lamp", "language", "large", "laser", - "laundry", "lawsuit", "leader", "leaf", "learn", "leaves", - "lecture", "legal", "legend", "legs", "lend", "length", - "level", "liberty", "library", "license", "lift", "likely", - "lilac", "lily", "lips", "liquid", "listen", "literary", - "living", "lizard", "loan", "lobe", "location", "losing", - "loud", "loyalty", "luck", "lunar", "lunch", "lungs", - "luxury", "lying", "lyrics", "machine", "magazine", "maiden", - "mailman", "main", "makeup", "making", "mama", "manager", - "mandate", "mansion", "manual", "marathon", "march", "market", - "marvel", "mason", "material", "math", "maximum", "mayor", - "meaning", "medal", "medical", "member", "memory", "mental", - "merchant", "merit", "method", "metric", "midst", "mild", - "military", "mineral", "minister", "miracle", "mixed", "mixture", - "mobile", "modern", "modify", "moisture", "moment", "morning", - "mortgage", "mother", "mountain", "mouse", "move", "much", - "mule", "multiple", "muscle", "museum", "music", "mustang", - "nail", "national", "necklace", "negative", "nervous", "network", - "news", "nuclear", "numb", "numerous", "nylon", "oasis", - "obesity", "object", "observe", "obtain", "ocean", "often", - "olympic", "omit", "oral", "orange", "orbit", "order", - "ordinary", "organize", "ounce", "oven", "overall", "owner", - "paces", "pacific", "package", "paid", "painting", "pajamas", - "pancake", "pants", "papa", "paper", "parcel", "parking", - "party", "patent", "patrol", "payment", "payroll", "peaceful", - "peanut", "peasant", "pecan", "penalty", "pencil", "percent", - "perfect", "permit", "petition", "phantom", "pharmacy", "photo", - "phrase", "physics", "pickup", "picture", "piece", "pile", - "pink", "pipeline", "pistol", "pitch", "plains", "plan", - "plastic", "platform", "playoff", "pleasure", "plot", "plunge", - "practice", "prayer", "preach", "predator", "pregnant", "premium", - "prepare", "presence", "prevent", "priest", "primary", "priority", - "prisoner", "privacy", "prize", "problem", "process", "profile", - "program", "promise", "prospect", "provide", "prune", "public", - "pulse", "pumps", "punish", "puny", "pupal", "purchase", - "purple", "python", "quantity", "quarter", "quick", "quiet", - "race", "racism", "radar", "railroad", "rainbow", "raisin", - "random", "ranked", "rapids", "raspy", "reaction", "realize", - "rebound", "rebuild", "recall", "receiver", "recover", "regret", - "regular", "reject", "relate", "remember", "remind", "remove", - "render", "repair", "repeat", "replace", "require", "rescue", - "research", "resident", "response", "result", "retailer", "retreat", - "reunion", "revenue", "review", "reward", "rhyme", "rhythm", - "rich", "rival", "river", "robin", "rocky", "romantic", - "romp", "roster", "round", "royal", "ruin", "ruler", - "rumor", "sack", "safari", "salary", "salon", "salt", - "satisfy", "satoshi", "saver", "says", "scandal", "scared", - "scatter", "scene", "scholar", "science", "scout", "scramble", - "screw", "script", "scroll", "seafood", "season", "secret", - "security", "segment", "senior", "shadow", "shaft", "shame", - "shaped", "sharp", "shelter", "sheriff", "short", "should", - "shrimp", "sidewalk", "silent", "silver", "similar", "simple", - "single", "sister", "skin", "skunk", "slap", "slavery", - "sled", "slice", "slim", "slow", "slush", "smart", - "smear", "smell", "smirk", "smith", "smoking", "smug", - "snake", "snapshot", "sniff", "society", "software", "soldier", - "solution", "soul", "source", "space", "spark", "speak", - "species", "spelling", "spend", "spew", "spider", "spill", - "spine", "spirit", "spit", "spray", "sprinkle", "square", - "squeeze", "stadium", "staff", "standard", "starting", "station", - "stay", "steady", "step", "stick", "stilt", "story", - "strategy", "strike", "style", "subject", "submit", "sugar", - "suitable", "sunlight", "superior", "surface", "surprise", "survive", - "sweater", "swimming", "swing", "switch", "symbolic", "sympathy", - "syndrome", "system", "tackle", "tactics", "tadpole", "talent", - "task", "taste", "taught", "taxi", "teacher", "teammate", - "teaspoon", "temple", "tenant", "tendency", "tension", "terminal", - "testify", "texture", "thank", "that", "theater", "theory", - "therapy", "thorn", "threaten", "thumb", "thunder", "ticket", - "tidy", "timber", "timely", "ting", "tofu", "together", - "tolerate", "total", "toxic", "tracks", "traffic", "training", - "transfer", "trash", "traveler", "treat", "trend", "trial", - "tricycle", "trip", "triumph", "trouble", "true", "trust", - "twice", "twin", "type", "typical", "ugly", "ultimate", - "umbrella", "uncover", "undergo", "unfair", "unfold", "unhappy", - "union", "universe", "unkind", "unknown", "unusual", "unwrap", - "upgrade", "upstairs", "username", "usher", "usual", "valid", - "valuable", "vampire", "vanish", "various", "vegan", "velvet", - "venture", "verdict", "verify", "very", "veteran", "vexed", - "victim", "video", "view", "vintage", "violence", "viral", - "visitor", "visual", "vitamins", "vocal", "voice", "volume", - "voter", "voting", "walnut", "warmth", "warn", "watch", - "wavy", "wealthy", "weapon", "webcam", "welcome", "welfare", - "western", "width", "wildlife", "window", "wine", "wireless", - "wisdom", "withdraw", "wits", "wolf", "woman", "work", - "worthy", "wrap", "wrist", "writing", "wrote", "year", - "yelp", "yield", "yoga", "zero", -}; - -/** - * This array contains number representations of SLIP-39 words. - * These numbers are determined how the words were entered on a - * T9 keyboard with the following layout: - * ab (1) cd (2) ef (3) - * ghij (4) klm (5) nopq (6) - * rs (7) tuv (8) wxyz (9) - * - * Each word is uniquely defined by four buttons. - */ -static const struct { - uint16_t sequence; - uint16_t index; -} words_button_seq[WORDS_COUNT] = { - {1212, 0}, // academic - {1216, 7}, // adapt - {1236, 8}, // adequate - {1242, 1}, // acid - {1248, 9}, // adjust - {1254, 10}, // admit - {1263, 2}, // acne - {1267, 11}, // adorn - {1268, 3}, // acquire - {1276, 4}, // acrobat - {1281, 13}, // advance - {1284, 5}, // activity - {1285, 12}, // adult - {1286, 14}, // advocate - {1287, 6}, // actress - {1315, 67}, // beam - {1317, 68}, // beard - {1318, 69}, // beaver - {1326, 70}, // become - {1327, 71}, // bedroom - {1341, 72}, // behavior - {1346, 73}, // being - {1354, 74}, // believe - {1356, 75}, // belong - {1363, 76}, // benefit - {1371, 15}, // afraid - {1378, 77}, // best - {1396, 78}, // beyond - {1414, 16}, // again - {1417, 23}, // ajar - {1423, 19}, // aide - {1436, 17}, // agency - {1453, 79}, // bike - {1465, 80}, // biology - {1472, 20}, // aircraft - {1473, 18}, // agree - {1474, 82}, // bishop - {1475, 21}, // airline - {1476, 22}, // airport - {1478, 81}, // birthday - {1512, 83}, // black - {1514, 35}, // ambition - {1516, 84}, // blanket - {1517, 24}, // alarm - {1518, 25}, // album - {1519, 34}, // amazing - {1526, 26}, // alcohol - {1537, 85}, // blessing - {1543, 27}, // alien - {1545, 86}, // blimp - {1546, 87}, // blind - {1548, 28}, // alive - {1564, 29}, // alpha - {1568, 36}, // amount - {1573, 30}, // already - {1583, 88}, // blue - {1585, 32}, // aluminum - {1586, 31}, // alto - {1587, 37}, // amuse - {1591, 33}, // always - {1615, 38}, // analysis - {1617, 48}, // apart - {1618, 39}, // anatomy - {1623, 40}, // ancestor - {1624, 41}, // ancient - {1629, 89}, // body - {1643, 42}, // angel - {1645, 44}, // animal - {1647, 43}, // angry - {1658, 90}, // bolt - {1674, 91}, // boring - {1676, 92}, // born - {1679, 45}, // answer - {1681, 49}, // aquatic - {1683, 46}, // antenna - {1684, 93}, // both - {1686, 94}, // boundary - {1694, 47}, // anxiety - {1712, 95}, // bracelet - {1716, 96}, // branch - {1718, 97}, // brave - {1721, 50}, // arcade - {1731, 98}, // breathe - {1736, 51}, // arena - {1743, 99}, // briefing - {1748, 52}, // argue - {1753, 53}, // armed - {1763, 56}, // aspect - {1765, 100}, // broken - {1768, 101}, // brother - {1769, 102}, // browser - {1784, 54}, // artist - {1789, 55}, // artwork - {1824, 104}, // budget - {1825, 103}, // bucket - {1828, 57}, // auction - {1837, 60}, // average - {1841, 61}, // aviation - {1845, 105}, // building - {1848, 58}, // august - {1851, 106}, // bulb - {1854, 107}, // bulge - {1856, 108}, // bumpy - {1862, 109}, // bundle - {1864, 62}, // avoid - {1868, 59}, // aunt - {1872, 110}, // burden - {1876, 111}, // burning - {1879, 112}, // busy - {1893, 113}, // buyer - {1917, 63}, // award - {1919, 64}, // away - {1947, 65}, // axis - {1953, 66}, // axle - {2143, 114}, // cage - {2147, 185}, // daisy - {2151, 186}, // damage - {2152, 115}, // calcium - {2153, 116}, // camera - {2156, 117}, // campus - {2161, 119}, // capacity - {2162, 187}, // dance - {2164, 120}, // capital - {2168, 121}, // capture - {2169, 118}, // canyon - {2171, 122}, // carbon - {2172, 123}, // cards - {2173, 124}, // careful - {2174, 125}, // cargo - {2175, 188}, // darkness - {2176, 126}, // carpet - {2178, 127}, // carve - {2181, 189}, // database - {2183, 128}, // category - {2184, 190}, // daughter - {2187, 129}, // cause - {2312, 191}, // deadline - {2315, 192}, // deal - {2317, 193}, // debris - {2318, 194}, // debut - {2323, 195}, // decent - {2324, 196}, // decision - {2325, 197}, // declare - {2326, 198}, // decorate - {2327, 199}, // decrease - {2345, 130}, // ceiling - {2351, 201}, // demand - {2354, 200}, // deliver - {2361, 204}, // depart - {2363, 205}, // depend - {2364, 206}, // depict - {2365, 207}, // deploy - {2367, 202}, // density - {2368, 131}, // center - {2369, 203}, // deny - {2371, 132}, // ceramic - {2372, 208}, // describe - {2373, 209}, // desert - {2374, 210}, // desire - {2375, 211}, // desktop - {2378, 212}, // destroy - {2381, 213}, // detailed - {2383, 214}, // detect - {2384, 215}, // device - {2386, 216}, // devote - {2414, 217}, // diagnose - {2415, 133}, // champion - {2416, 134}, // change - {2417, 135}, // charity - {2428, 218}, // dictate - {2432, 136}, // check - {2435, 137}, // chemical - {2437, 138}, // chest - {2438, 219}, // diet - {2439, 139}, // chew - {2453, 220}, // dilemma - {2454, 221}, // diminish - {2463, 141}, // cinema - {2464, 222}, // dining - {2465, 223}, // diploma - {2471, 224}, // disaster - {2472, 225}, // discuss - {2473, 226}, // disease - {2474, 227}, // dish - {2475, 228}, // dismiss - {2476, 229}, // display - {2478, 230}, // distance - {2481, 140}, // chubby - {2483, 231}, // dive - {2484, 142}, // civil - {2486, 232}, // divorce - {2517, 143}, // class - {2519, 144}, // clay - {2531, 145}, // cleanup - {2543, 146}, // client - {2545, 147}, // climate - {2546, 148}, // clinic - {2562, 149}, // clock - {2564, 150}, // clogs - {2567, 151}, // closet - {2568, 152}, // clothes - {2581, 153}, // club - {2587, 154}, // cluster - {2615, 155}, // coal - {2617, 156}, // coastal - {2624, 157}, // coding - {2628, 233}, // document - {2651, 234}, // domain - {2653, 235}, // domestic - {2654, 236}, // dominant - {2656, 159}, // company - {2658, 158}, // column - {2676, 160}, // corner - {2678, 161}, // costume - {2683, 164}, // cover - {2684, 237}, // dough - {2686, 162}, // counter - {2687, 163}, // course - {2691, 165}, // cowboy - {2696, 238}, // downtown - {2712, 166}, // cradle - {2713, 167}, // craft - {2714, 239}, // dragon - {2715, 240}, // dramatic - {2719, 168}, // crazy - {2731, 241}, // dream - {2732, 169}, // credit - {2737, 242}, // dress - {2742, 170}, // cricket - {2743, 243}, // drift - {2745, 171}, // criminal - {2746, 244}, // drink - {2747, 172}, // crisis - {2748, 173}, // critical - {2768, 245}, // drove - {2769, 174}, // crowd - {2782, 175}, // crucial - {2784, 246}, // drug - {2786, 176}, // crunch - {2787, 177}, // crush - {2793, 247}, // dryer - {2797, 178}, // crystal - {2814, 179}, // cubic - {2825, 248}, // duckling - {2853, 249}, // duke - {2858, 180}, // cultural - {2871, 250}, // duration - {2874, 181}, // curious - {2875, 182}, // curly - {2878, 183}, // custody - {2917, 251}, // dwarf - {2954, 184}, // cylinder - {2961, 252}, // dynamic - {3124, 323}, // facility - {3128, 324}, // fact - {3145, 325}, // failure - {3146, 326}, // faint - {3153, 327}, // fake - {3154, 329}, // family - {3156, 330}, // famous - {3157, 328}, // false - {3162, 331}, // fancy - {3164, 332}, // fangs - {3168, 333}, // fantasy - {3173, 255}, // easel - {3175, 253}, // early - {3178, 254}, // earth - {3179, 256}, // easy - {3181, 334}, // fatal - {3184, 335}, // fatigue - {3186, 336}, // favorite - {3196, 337}, // fawn - {3243, 260}, // edge - {3246, 257}, // echo - {3248, 261}, // editor - {3254, 258}, // eclipse - {3265, 259}, // ecology - {3282, 262}, // educate - {3413, 338}, // fiber - {3428, 339}, // fiction - {3458, 340}, // filter - {3461, 341}, // finance - {3462, 342}, // findings - {3464, 343}, // finger - {3472, 346}, // fiscal - {3473, 344}, // firefly - {3474, 347}, // fishing - {3475, 345}, // firm - {3484, 263}, // either - {3486, 348}, // fitness - {3514, 273}, // email - {3515, 349}, // flame - {3516, 264}, // elbow - {3517, 350}, // flash - {3518, 351}, // flavor - {3523, 265}, // elder - {3531, 352}, // flea - {3532, 266}, // election - {3534, 267}, // elegant - {3535, 268}, // element - {3536, 269}, // elephant - {3537, 274}, // emerald - {3538, 270}, // elevator - {3539, 353}, // flexible - {3546, 354}, // flip - {3547, 275}, // emission - {3548, 271}, // elite - {3561, 355}, // float - {3563, 276}, // emperor - {3564, 277}, // emphasis - {3565, 278}, // employer - {3567, 356}, // floral - {3568, 279}, // empty - {3573, 272}, // else - {3583, 357}, // fluff - {3624, 280}, // ending - {3625, 281}, // endless - {3626, 282}, // endorse - {3628, 358}, // focus - {3635, 283}, // enemy - {3636, 285}, // enforce - {3637, 284}, // energy - {3641, 286}, // engage - {3642, 292}, // epidemic - {3646, 287}, // enjoy - {3647, 293}, // episode - {3651, 288}, // enlarge - {3671, 359}, // forbid - {3672, 360}, // force - {3673, 361}, // forecast - {3674, 362}, // forget - {3675, 363}, // formal - {3678, 364}, // fortune - {3679, 365}, // forward - {3681, 294}, // equation - {3683, 290}, // envelope - {3684, 295}, // equip - {3686, 366}, // founder - {3687, 289}, // entrance - {3689, 291}, // envy - {3712, 367}, // fraction - {3714, 368}, // fragment - {3717, 296}, // eraser - {3721, 298}, // escape - {3736, 369}, // frequent - {3737, 370}, // freshman - {3741, 371}, // friar - {3742, 372}, // fridge - {3743, 373}, // friendly - {3762, 297}, // erode - {3767, 374}, // frost - {3768, 375}, // froth - {3769, 376}, // frozen - {3781, 299}, // estate - {3784, 300}, // estimate - {3815, 301}, // evaluate - {3836, 302}, // evening - {3842, 303}, // evidence - {3845, 304}, // evil - {3853, 377}, // fumes - {3862, 378}, // funding - {3865, 305}, // evoke - {3873, 380}, // fused - {3875, 379}, // furl - {3912, 306}, // exact - {3915, 307}, // example - {3923, 308}, // exceed - {3924, 309}, // exchange - {3925, 310}, // exclude - {3928, 311}, // excuse - {3931, 322}, // eyebrow - {3932, 312}, // execute - {3937, 313}, // exercise - {3941, 314}, // exhaust - {3961, 316}, // expand - {3963, 317}, // expect - {3965, 318}, // explain - {3967, 319}, // express - {3968, 315}, // exotic - {3983, 320}, // extend - {3987, 321}, // extra - {4125, 483}, // jacket - {4147, 420}, // hairy - {4151, 381}, // galaxy - {4153, 382}, // game - {4157, 421}, // hamster - {4162, 422}, // hand - {4164, 423}, // hanger - {4171, 383}, // garbage - {4172, 384}, // garden - {4175, 385}, // garlic - {4176, 386}, // gasoline - {4178, 424}, // harvest - {4183, 425}, // have - {4184, 387}, // gather - {4186, 426}, // havoc - {4191, 428}, // hazard - {4195, 427}, // hawk - {4231, 452}, // idea - {4236, 453}, // identify - {4253, 454}, // idle - {4312, 429}, // headset - {4315, 430}, // health - {4317, 431}, // hearing - {4318, 432}, // heat - {4356, 433}, // helpful - {4363, 388}, // general - {4364, 389}, // genius - {4365, 392}, // geology - {4367, 390}, // genre - {4368, 391}, // genuine - {4371, 434}, // herald - {4372, 435}, // herd - {4374, 436}, // hesitate - {4375, 484}, // jerky - {4378, 393}, // gesture - {4393, 485}, // jewelry - {4512, 394}, // glad - {4514, 455}, // image - {4516, 395}, // glance - {4517, 396}, // glasses - {4536, 397}, // glen - {4545, 398}, // glimpse - {4561, 456}, // impact - {4565, 457}, // imply - {4567, 458}, // improve - {4568, 459}, // impulse - {4616, 437}, // hobo - {4618, 399}, // goat - {4623, 463}, // index - {4624, 464}, // indicate - {4625, 460}, // include - {4626, 461}, // income - {4627, 462}, // increase - {4628, 465}, // industry - {4631, 466}, // infant - {4636, 467}, // inform - {4643, 468}, // inherit - {4646, 486}, // join - {4648, 469}, // injury - {4651, 470}, // inmate - {4652, 400}, // golden - {4653, 440}, // home - {4654, 438}, // holiday - {4659, 439}, // holy - {4673, 471}, // insect - {4674, 472}, // inside - {4675, 441}, // hormone - {4676, 442}, // hospital - {4678, 473}, // install - {4681, 476}, // invasion - {4683, 474}, // intend - {4684, 475}, // intimate - {4686, 477}, // involve - {4687, 443}, // hour - {4712, 401}, // graduate - {4716, 402}, // grant - {4717, 403}, // grasp - {4718, 404}, // gravity - {4719, 405}, // gray - {4731, 406}, // greatest - {4743, 407}, // grief - {4745, 408}, // grill - {4746, 409}, // grin - {4747, 478}, // iris - {4751, 479}, // island - {4762, 410}, // grocery - {4765, 480}, // isolate - {4767, 411}, // gross - {4768, 412}, // group - {4769, 413}, // grownup - {4785, 414}, // grumpy - {4817, 415}, // guard - {4824, 487}, // judicial - {4835, 481}, // item - {4837, 416}, // guest - {4842, 488}, // juice - {4843, 444}, // huge - {4845, 417}, // guilt - {4848, 418}, // guitar - {4851, 445}, // human - {4854, 446}, // humidity - {4856, 489}, // jump - {4857, 419}, // gums - {4862, 490}, // junction - {4864, 491}, // junior - {4865, 492}, // junk - {4867, 482}, // ivory - {4868, 447}, // hunting - {4871, 448}, // husband - {4874, 449}, // hush - {4875, 450}, // husky - {4878, 494}, // justice - {4879, 493}, // jury - {4917, 451}, // hybrid - {5123, 502}, // laden - {5124, 549}, // machine - {5125, 503}, // ladle - {5129, 504}, // ladybug - {5141, 550}, // magazine - {5142, 551}, // maiden - {5145, 552}, // mailman - {5146, 553}, // main - {5147, 505}, // lair - {5151, 556}, // mama - {5153, 554}, // makeup - {5154, 555}, // making - {5156, 506}, // lamp - {5161, 557}, // manager - {5162, 558}, // mandate - {5164, 507}, // language - {5167, 559}, // mansion - {5168, 560}, // manual - {5171, 561}, // marathon - {5172, 562}, // march - {5173, 509}, // laser - {5174, 508}, // large - {5175, 563}, // market - {5176, 565}, // mason - {5178, 564}, // marvel - {5183, 566}, // material - {5184, 567}, // math - {5186, 510}, // laundry - {5194, 568}, // maximum - {5196, 569}, // mayor - {5197, 511}, // lawsuit - {5312, 512}, // leader - {5313, 513}, // leaf - {5316, 570}, // meaning - {5317, 514}, // learn - {5318, 515}, // leaves - {5321, 571}, // medal - {5324, 572}, // medical - {5328, 516}, // lecture - {5341, 517}, // legal - {5343, 518}, // legend - {5347, 519}, // legs - {5351, 573}, // member - {5356, 574}, // memory - {5362, 520}, // lend - {5364, 521}, // length - {5368, 575}, // mental - {5372, 576}, // merchant - {5374, 577}, // merit - {5376, 495}, // kernel - {5383, 522}, // level - {5384, 578}, // method - {5387, 579}, // metric - {5391, 496}, // keyboard - {5413, 523}, // liberty - {5417, 524}, // library - {5423, 525}, // license - {5426, 497}, // kidney - {5427, 580}, // midst - {5438, 526}, // lift - {5451, 528}, // lilac - {5452, 581}, // mild - {5453, 527}, // likely - {5454, 582}, // military - {5459, 529}, // lily - {5462, 498}, // kind - {5463, 583}, // mineral - {5464, 584}, // minister - {5467, 530}, // lips - {5468, 531}, // liquid - {5471, 585}, // miracle - {5478, 532}, // listen - {5482, 499}, // kitchen - {5483, 533}, // literary - {5484, 534}, // living - {5491, 535}, // lizard - {5493, 586}, // mixed - {5498, 587}, // mixture - {5613, 537}, // lobe - {5614, 588}, // mobile - {5616, 536}, // loan - {5621, 538}, // location - {5623, 589}, // modern - {5624, 590}, // modify - {5643, 500}, // knife - {5647, 591}, // moisture - {5648, 501}, // knit - {5653, 592}, // moment - {5674, 539}, // losing - {5676, 593}, // morning - {5678, 594}, // mortgage - {5682, 540}, // loud - {5683, 598}, // move - {5684, 595}, // mother - {5686, 596}, // mountain - {5687, 597}, // mouse - {5691, 541}, // loyalty - {5824, 599}, // much - {5825, 542}, // luck - {5853, 600}, // mule - {5858, 601}, // multiple - {5861, 543}, // lunar - {5862, 544}, // lunch - {5864, 545}, // lungs - {5872, 602}, // muscle - {5873, 603}, // museum - {5874, 604}, // music - {5878, 605}, // mustang - {5898, 546}, // luxury - {5946, 547}, // lying - {5974, 548}, // lyrics - {6123, 636}, // paces - {6124, 637}, // pacific - {6125, 638}, // package - {6137, 618}, // obesity - {6141, 641}, // pajamas - {6142, 639}, // paid - {6143, 619}, // object - {6145, 606}, // nail - {6146, 640}, // painting - {6161, 644}, // papa - {6162, 642}, // pancake - {6163, 645}, // paper - {6168, 643}, // pants - {6172, 646}, // parcel - {6173, 620}, // observe - {6174, 617}, // oasis - {6175, 647}, // parking - {6178, 648}, // party - {6181, 621}, // obtain - {6183, 649}, // patent - {6184, 607}, // national - {6187, 650}, // patrol - {6195, 651}, // payment - {6197, 652}, // payroll - {6231, 622}, // ocean - {6312, 653}, // peaceful - {6316, 654}, // peanut - {6317, 655}, // peasant - {6321, 656}, // pecan - {6325, 608}, // necklace - {6341, 609}, // negative - {6361, 657}, // penalty - {6362, 658}, // pencil - {6372, 659}, // percent - {6373, 660}, // perfect - {6375, 661}, // permit - {6378, 610}, // nervous - {6383, 623}, // often - {6384, 662}, // petition - {6389, 611}, // network - {6397, 612}, // news - {6416, 663}, // phantom - {6417, 664}, // pharmacy - {6425, 668}, // pickup - {6428, 669}, // picture - {6432, 670}, // piece - {6453, 671}, // pile - {6463, 673}, // pipeline - {6465, 672}, // pink - {6468, 665}, // photo - {6471, 666}, // phrase - {6478, 674}, // pistol - {6482, 675}, // pitch - {6497, 667}, // physics - {6514, 676}, // plains - {6516, 677}, // plan - {6517, 678}, // plastic - {6518, 679}, // platform - {6519, 680}, // playoff - {6531, 681}, // pleasure - {6548, 625}, // omit - {6568, 682}, // plot - {6586, 683}, // plunge - {6595, 624}, // olympic - {6712, 684}, // practice - {6714, 628}, // orbit - {6715, 626}, // oral - {6716, 627}, // orange - {6719, 685}, // prayer - {6723, 629}, // order - {6724, 630}, // ordinary - {6731, 686}, // preach - {6732, 687}, // predator - {6734, 688}, // pregnant - {6735, 689}, // premium - {6736, 690}, // prepare - {6737, 691}, // presence - {6738, 692}, // prevent - {6741, 631}, // organize - {6743, 693}, // priest - {6745, 694}, // primary - {6746, 695}, // priority - {6747, 696}, // prisoner - {6748, 697}, // privacy - {6749, 698}, // prize - {6761, 699}, // problem - {6762, 700}, // process - {6763, 701}, // profile - {6764, 702}, // program - {6765, 703}, // promise - {6767, 704}, // prospect - {6768, 705}, // provide - {6786, 706}, // prune - {6815, 707}, // public - {6816, 716}, // quantity - {6817, 717}, // quarter - {6825, 613}, // nuclear - {6836, 633}, // oven - {6837, 634}, // overall - {6842, 718}, // quick - {6843, 719}, // quiet - {6851, 614}, // numb - {6853, 615}, // numerous - {6856, 709}, // pumps - {6857, 708}, // pulse - {6861, 712}, // pupal - {6862, 632}, // ounce - {6864, 710}, // punish - {6869, 711}, // puny - {6872, 713}, // purchase - {6876, 714}, // purple - {6956, 616}, // nylon - {6963, 635}, // owner - {6984, 715}, // python - {7121, 722}, // radar - {7123, 720}, // race - {7124, 721}, // racism - {7125, 775}, // sack - {7131, 776}, // safari - {7145, 723}, // railroad - {7146, 724}, // rainbow - {7147, 725}, // raisin - {7151, 777}, // salary - {7156, 778}, // salon - {7158, 779}, // salt - {7162, 726}, // random - {7164, 728}, // rapids - {7165, 727}, // ranked - {7176, 729}, // raspy - {7183, 782}, // saver - {7184, 780}, // satisfy - {7186, 781}, // satoshi - {7197, 783}, // says - {7216, 784}, // scandal - {7217, 785}, // scared - {7218, 786}, // scatter - {7236, 787}, // scene - {7243, 789}, // science - {7246, 788}, // scholar - {7268, 790}, // scout - {7271, 791}, // scramble - {7273, 792}, // screw - {7274, 793}, // script - {7276, 794}, // scroll - {7312, 730}, // reaction - {7313, 795}, // seafood - {7315, 731}, // realize - {7316, 732}, // rebound - {7317, 796}, // season - {7318, 733}, // rebuild - {7321, 734}, // recall - {7323, 735}, // receiver - {7326, 736}, // recover - {7327, 797}, // secret - {7328, 798}, // security - {7343, 739}, // reject - {7345, 799}, // segment - {7347, 737}, // regret - {7348, 738}, // regular - {7351, 740}, // relate - {7353, 741}, // remember - {7354, 742}, // remind - {7356, 743}, // remove - {7361, 745}, // repair - {7362, 744}, // render - {7363, 746}, // repeat - {7364, 800}, // senior - {7365, 747}, // replace - {7368, 748}, // require - {7372, 749}, // rescue - {7373, 750}, // research - {7374, 751}, // resident - {7376, 752}, // response - {7378, 753}, // result - {7381, 754}, // retailer - {7383, 757}, // revenue - {7384, 758}, // review - {7386, 756}, // reunion - {7387, 755}, // retreat - {7391, 759}, // reward - {7412, 801}, // shadow - {7413, 802}, // shaft - {7415, 803}, // shame - {7416, 804}, // shaped - {7417, 805}, // sharp - {7423, 811}, // sidewalk - {7424, 762}, // rich - {7435, 806}, // shelter - {7437, 807}, // sheriff - {7453, 812}, // silent - {7454, 814}, // similar - {7456, 815}, // simple - {7458, 813}, // silver - {7464, 816}, // single - {7467, 808}, // short - {7468, 809}, // should - {7474, 810}, // shrimp - {7478, 817}, // sister - {7481, 763}, // rival - {7483, 764}, // river - {7495, 760}, // rhyme - {7498, 761}, // rhythm - {7516, 820}, // slap - {7517, 827}, // smart - {7518, 821}, // slavery - {7531, 828}, // smear - {7532, 822}, // sled - {7535, 829}, // smell - {7542, 823}, // slice - {7545, 824}, // slim - {7546, 818}, // skin - {7547, 830}, // smirk - {7548, 831}, // smith - {7565, 832}, // smoking - {7569, 825}, // slow - {7584, 833}, // smug - {7586, 819}, // skunk - {7587, 826}, // slush - {7612, 843}, // space - {7614, 765}, // robin - {7615, 834}, // snake - {7616, 835}, // snapshot - {7617, 844}, // spark - {7624, 837}, // society - {7625, 766}, // rocky - {7631, 845}, // speak - {7632, 846}, // species - {7635, 847}, // spelling - {7636, 848}, // spend - {7638, 838}, // software - {7639, 849}, // spew - {7642, 850}, // spider - {7643, 836}, // sniff - {7645, 851}, // spill - {7646, 852}, // spine - {7647, 853}, // spirit - {7648, 854}, // spit - {7651, 767}, // romantic - {7652, 839}, // soldier - {7656, 768}, // romp - {7658, 840}, // solution - {7671, 855}, // spray - {7674, 856}, // sprinkle - {7678, 769}, // roster - {7681, 857}, // square - {7683, 858}, // squeeze - {7685, 841}, // soul - {7686, 770}, // round - {7687, 842}, // source - {7691, 771}, // royal - {7812, 859}, // stadium - {7813, 860}, // staff - {7814, 873}, // subject - {7815, 874}, // submit - {7816, 861}, // standard - {7817, 862}, // starting - {7818, 863}, // station - {7819, 864}, // stay - {7831, 865}, // steady - {7836, 866}, // step - {7841, 875}, // sugar - {7842, 867}, // stick - {7845, 868}, // stilt - {7846, 772}, // ruin - {7848, 876}, // suitable - {7853, 773}, // ruler - {7856, 774}, // rumor - {7863, 878}, // superior - {7865, 877}, // sunlight - {7867, 869}, // story - {7871, 870}, // strategy - {7873, 879}, // surface - {7874, 871}, // strike - {7876, 880}, // surprise - {7878, 881}, // survive - {7895, 872}, // style - {7931, 882}, // sweater - {7945, 883}, // swimming - {7946, 884}, // swing - {7948, 885}, // switch - {7951, 886}, // symbolic - {7956, 887}, // sympathy - {7962, 888}, // syndrome - {7978, 889}, // system - {8125, 890}, // tackle - {8126, 892}, // tadpole - {8128, 891}, // tactics - {8153, 893}, // talent - {8154, 965}, // valid - {8156, 967}, // vampire - {8158, 966}, // valuable - {8164, 968}, // vanish - {8174, 969}, // various - {8175, 894}, // task - {8178, 895}, // taste - {8184, 896}, // taught - {8194, 897}, // taxi - {8312, 898}, // teacher - {8315, 899}, // teammate - {8317, 900}, // teaspoon - {8341, 970}, // vegan - {8356, 901}, // temple - {8358, 971}, // velvet - {8361, 902}, // tenant - {8362, 903}, // tendency - {8367, 904}, // tension - {8368, 972}, // venture - {8372, 973}, // verdict - {8374, 974}, // verify - {8375, 905}, // terminal - {8378, 906}, // testify - {8379, 975}, // very - {8383, 976}, // veteran - {8393, 977}, // vexed - {8398, 907}, // texture - {8416, 908}, // thank - {8418, 909}, // that - {8423, 979}, // video - {8425, 917}, // ticket - {8428, 978}, // victim - {8429, 918}, // tidy - {8431, 910}, // theater - {8436, 911}, // theory - {8437, 912}, // therapy - {8439, 980}, // view - {8451, 919}, // timber - {8453, 920}, // timely - {8459, 946}, // ugly - {8464, 921}, // ting - {8465, 982}, // violence - {8467, 913}, // thorn - {8468, 981}, // vintage - {8471, 983}, // viral - {8473, 914}, // threaten - {8474, 984}, // visitor - {8478, 985}, // visual - {8481, 986}, // vitamins - {8485, 915}, // thumb - {8486, 916}, // thunder - {8517, 948}, // umbrella - {8584, 947}, // ultimate - {8621, 987}, // vocal - {8623, 950}, // undergo - {8626, 949}, // uncover - {8631, 951}, // unfair - {8636, 952}, // unfold - {8638, 922}, // tofu - {8641, 953}, // unhappy - {8642, 988}, // voice - {8643, 923}, // together - {8646, 954}, // union - {8647, 960}, // upgrade - {8648, 955}, // universe - {8653, 924}, // tolerate - {8654, 956}, // unkind - {8656, 957}, // unknown - {8658, 989}, // volume - {8678, 961}, // upstairs - {8681, 925}, // total - {8683, 990}, // voter - {8684, 991}, // voting - {8687, 958}, // unusual - {8694, 926}, // toxic - {8697, 959}, // unwrap - {8712, 927}, // tracks - {8713, 928}, // traffic - {8714, 929}, // training - {8716, 930}, // transfer - {8717, 931}, // trash - {8718, 932}, // traveler - {8731, 933}, // treat - {8736, 934}, // trend - {8737, 962}, // username - {8741, 935}, // trial - {8742, 936}, // tricycle - {8743, 963}, // usher - {8746, 937}, // trip - {8748, 938}, // triumph - {8768, 939}, // trouble - {8781, 964}, // usual - {8783, 940}, // true - {8787, 941}, // trust - {8942, 942}, // twice - {8946, 943}, // twin - {8963, 944}, // type - {8964, 945}, // typical - {9156, 992}, // walnut - {9175, 993}, // warmth - {9176, 994}, // warn - {9182, 995}, // watch - {9189, 996}, // wavy - {9312, 999}, // webcam - {9315, 997}, // wealthy - {9316, 998}, // weapon - {9317, 1019}, // year - {9352, 1000}, // welcome - {9353, 1001}, // welfare - {9356, 1020}, // yelp - {9376, 1023}, // zero - {9378, 1002}, // western - {9428, 1003}, // width - {9435, 1021}, // yield - {9452, 1004}, // wildlife - {9462, 1005}, // window - {9463, 1006}, // wine - {9472, 1008}, // wisdom - {9473, 1007}, // wireless - {9484, 1009}, // withdraw - {9487, 1010}, // wits - {9641, 1022}, // yoga - {9651, 1012}, // woman - {9653, 1011}, // wolf - {9675, 1013}, // work - {9678, 1014}, // worthy - {9716, 1015}, // wrap - {9747, 1016}, // wrist - {9748, 1017}, // writing - {9768, 1018}, // wrote -}; - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/sodium/keypair.h b/trezor-crypto/include/TrezorCrypto/sodium/keypair.h deleted file mode 100644 index 2f5b02513ad..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sodium/keypair.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __KEYPAIR_H__ -#define __KEYPAIR_H__ - -#include - -#include "private/ed25519_ref10.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int ed25519_pk_to_curve25519(unsigned char *curve25519_pk, const unsigned char *ed25519_pk); - -int curve25519_pk_to_ed25519(unsigned char *ed25519_pk, const unsigned char *curve25519_pk); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif \ No newline at end of file diff --git a/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10.h b/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10.h deleted file mode 100644 index 5441c06ef14..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef __ED25519_REF10_H__ -#define __ED25519_REF10_H__ - -#include -#include - -#include -#include "fe_25_5/fe.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void fe25519_invert(fe25519 out, const fe25519 z); - -/* - ge means group element. - - Here the group is the set of pairs (x,y) of field elements - satisfying -x^2 + y^2 = 1 + d x^2y^2 - where d = -121665/121666. - - Representations: - ge25519_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z - ge25519_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT - ge25519_p1p1_1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T - ge25519_precomp (Duif): (y+x,y-x,2dxy) - */ - -typedef struct { - fe25519 X; - fe25519 Y; - fe25519 Z; -} ge25519_p2; - -typedef struct { - fe25519 X; - fe25519 Y; - fe25519 Z; - fe25519 T; -} ge25519_p3; - -typedef struct { - fe25519 X; - fe25519 Y; - fe25519 Z; - fe25519 T; -} ge25519_p1p1_1; - -typedef struct { - fe25519 yplusx; - fe25519 yminusx; - fe25519 xy2d; -} ge25519_precomp; - -typedef struct { - fe25519 YplusX; - fe25519 YminusX; - fe25519 Z; - fe25519 T2d; -} ge25519_cached; - -void ge25519_tobytes(unsigned char *s, const ge25519_p2 *h); - -void ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h); - -int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s); - -void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p); - -void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1_1 *p); - -void ge25519_add2(ge25519_p1p1_1 *r, const ge25519_p3 *p, const ge25519_cached *q); - -void ge25519_sub(ge25519_p1p1_1 *r, const ge25519_p3 *p, const ge25519_cached *q); - -int ge25519_is_on_main_subgroup(const ge25519_p3 *p); - -int ge25519_has_small_order(const unsigned char s[32]); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10_fe_25_5.h b/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10_fe_25_5.h deleted file mode 100644 index 44b9a299584..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sodium/private/ed25519_ref10_fe_25_5.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __ED25519_REF10_FE_25_H__ -#define __ED25519_REF10_FE_25_H__ - -#include - -#include -#include "fe_25_5/fe.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void fe25519_0(fe25519 h); - -void fe25519_1(fe25519 h); - -void fe25519_add(fe25519 h, const fe25519 f, const fe25519 g); - -void fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g); - -void fe25519_neg(fe25519 h, const fe25519 f); - -void fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b); - -void fe25519_copy(fe25519 h, const fe25519 f); - -int fe25519_isnegative(const fe25519 f); - -int sodium_is_zero(const unsigned char *n, const size_t nlen); - -int fe25519_iszero(const fe25519 f); - -void fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g); - -void fe25519_sq(fe25519 h, const fe25519 f); - -void fe25519_sq2(fe25519 h, const fe25519 f); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif \ No newline at end of file diff --git a/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/constants.h b/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/constants.h deleted file mode 100644 index ee408f5ad11..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/constants.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __CONSTANTS_H__ -#define __CONSTANTS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ -const fe25519 d = {-10913610, 13857413, -15372611, 6949391, 114729, - -8787816, -6275908, -3247719, -18696448, -12055116}; - -/* 2 * d = - * 16295367250680780974490674513165176452449235426866156013048779062215315747161 - */ -const fe25519 d2 = {-21827239, -5839606, -30745221, 13898782, 229458, - 15978800, -12551817, -6495438, 29715968, 9444199}; - -/* sqrt(-1) */ -const fe25519 sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472, - -272473, -25146209, -2005654, 326686, 11406482}; - -/* A = 486662 */ -const fe25519 curve25519_A = {486662, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif \ No newline at end of file diff --git a/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/fe.h b/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/fe.h deleted file mode 100644 index fd3080a9305..00000000000 --- a/trezor-crypto/include/TrezorCrypto/sodium/private/fe_25_5/fe.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __FE_H__ -#define __FE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - fe means field element. - Here the field is \Z/(2^255-19). - */ - -typedef int32_t fe25519[10]; - -void fe25519_frombytes(fe25519 h, const unsigned char *s); - -void fe25519_tobytes(unsigned char *s, const fe25519 h); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif \ No newline at end of file diff --git a/trezor-crypto/include/TrezorCrypto/zilliqa.h b/trezor-crypto/include/TrezorCrypto/zilliqa.h deleted file mode 100644 index 46ada660b06..00000000000 --- a/trezor-crypto/include/TrezorCrypto/zilliqa.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2019 Anatolii Kurotych - * - * 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 __ZILLIQA_H__ -#define __ZILLIQA_H__ - -#include - -#if defined(__cplusplus) -extern "C" -{ -#endif - -// result of sign operation -typedef struct { - uint8_t r[32]; - uint8_t s[32]; -} schnorr_sign_pair; - -// sign/verify returns 0 if operation succeeded - -int zil_schnorr_sign(const ecdsa_curve *curve, const uint8_t *priv_key, - const uint8_t *msg, const uint32_t msg_len, uint8_t *sig); -int zil_schnorr_verify(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *sig, const uint8_t *msg, const uint32_t msg_len); - -// k is a random from [1, ..., order-1] -int zil_schnorr_sign_k(const ecdsa_curve *curve, const uint8_t *priv_key, - const bignum256 *k, const uint8_t *msg, const uint32_t msg_len, - schnorr_sign_pair *result); -int zil_schnorr_verify_pair(const ecdsa_curve *curve, const uint8_t *pub_key, - const uint8_t *msg, const uint32_t msg_len, - const schnorr_sign_pair *sign); -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/trezor-crypto/setup_from_upstream.sh b/trezor-crypto/setup_from_upstream.sh deleted file mode 100755 index a2b808db424..00000000000 --- a/trezor-crypto/setup_from_upstream.sh +++ /dev/null @@ -1,26 +0,0 @@ -# Steps to update TrezorCrypto lib to a newer version: -# - start with a clean wallet-core repo -# - clone fresh version of https://github.com/trezor/trezor-firmware -# - Copy contents of trezor-firmware/crypto to trezor-crypto/crypto -# - Run this script (or below commands) from trezor-crypto folder, to move over header files to include folder -# - Try compiling TrezorCrypto lib, wallet-core lib, TrezorCrypto tests, wallet-core tests -# - Execute tests -# - Do fixes as needed -# - Review changes (changed files, new files, removed files) -# - Things to watch out for: -# -- changes in #include's due to different location of header files -# -- wallet-core-specific changes, marked [wallet-core] -# -- static variables - -TARGET=include/TrezorCrypto - -mkdir -p $TARGET -mv crypto/*.h $TARGET -mv crypto/aes/aes.h $TARGET -mkdir -p $TARGET/aes -mv crypto/aes/*.h $TARGET/aes -mv crypto/ed25519-donna/ed25519.h $TARGET -mkdir -p $TARGET/ed25519-donna -mv crypto/ed25519-donna/*.h $TARGET/ed25519-donna -mkdir -p $TARGET/chacha20poly1305 -mv crypto/chacha20poly1305/*.h $TARGET/chacha20poly1305 diff --git a/trezor-crypto/version b/trezor-crypto/version deleted file mode 100644 index 3784c9db248..00000000000 --- a/trezor-crypto/version +++ /dev/null @@ -1 +0,0 @@ -ffa96205fb5e22b43e7b08a3dbc3cdeee0931de3 diff --git a/wallet_core.srctrlprj b/wallet_core.srctrlprj index 2b28f31167f..50ee02a5d1f 100644 --- a/wallet_core.srctrlprj +++ b/wallet_core.srctrlprj @@ -14,7 +14,6 @@ include - trezor-crypto/include build/local/include C++ Source Group diff --git a/walletconsole/CMakeLists.txt b/walletconsole/CMakeLists.txt index f5c8c08ff31..346e5c55a63 100644 --- a/walletconsole/CMakeLists.txt +++ b/walletconsole/CMakeLists.txt @@ -5,7 +5,7 @@ # walletconsole executable file(GLOB walletconsole_sources *.cpp) add_executable(walletconsole ${walletconsole_sources}) -target_link_libraries(walletconsole walletconsolelib TrezorCrypto TrustWalletCore protobuf Boost::boost) +target_link_libraries(walletconsole walletconsolelib TrustWalletCore protobuf Boost::boost) target_include_directories(walletconsole PRIVATE ${CMAKE_SOURCE_DIR}/walletconsole/lib ${CMAKE_SOURCE_DIR}/src) INSTALL(TARGETS walletconsole DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/walletconsole/lib/CMakeLists.txt b/walletconsole/lib/CMakeLists.txt index dc3453b0112..89512d3f8c5 100644 --- a/walletconsole/lib/CMakeLists.txt +++ b/walletconsole/lib/CMakeLists.txt @@ -5,6 +5,6 @@ # walletconsolelib library file(GLOB_RECURSE walletconsolelib_sources *.cpp) add_library(walletconsolelib ${walletconsolelib_sources}) -#target_link_libraries(tests gtest_main TrezorCrypto TrustWalletCore protobuf Boost::boost) -target_link_libraries(walletconsolelib TrezorCrypto TrustWalletCore protobuf Boost::boost) +#target_link_libraries(tests gtest_main TrustWalletCore protobuf Boost::boost) +target_link_libraries(walletconsolelib TrustWalletCore protobuf Boost::boost) target_include_directories(walletconsolelib PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src) diff --git a/wasm/CMakeLists.txt b/wasm/CMakeLists.txt index 1b4017a7ea4..cdfbc5b707c 100644 --- a/wasm/CMakeLists.txt +++ b/wasm/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(${TARGET_NAME} ${wasm_sources} ${wasm_headers}) target_link_libraries(${TARGET_NAME} TrustWalletCore) -target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/trezor-crypto/include) +target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src) target_compile_options(${TARGET_NAME} PRIVATE "-Wall") set_target_properties(${TARGET_NAME} diff --git a/wasm/tests/Blockchain/Aptos.test.ts b/wasm/tests/Blockchain/Aptos.test.ts index 98ccaf9ce27..3b5eab56e33 100644 --- a/wasm/tests/Blockchain/Aptos.test.ts +++ b/wasm/tests/Blockchain/Aptos.test.ts @@ -10,7 +10,7 @@ import Long = require("long"); describe("Aptos", () => { it("test sign aptos", () => { - const { PrivateKey, HexCoding, AnySigner, AnyAddress, CoinType } = globalThis.core; + const { PrivateKey, HexCoding, AnySigner, AnyAddress, CoinType, CoinTypeExt } = globalThis.core; const txDataInput = TW.Aptos.Proto.SigningInput.create({ chainId: 33, sender: "0x07968dab936c1bad187c60ce4082f307d030d780e91e694ae03aef16aba73f30", @@ -26,6 +26,7 @@ describe("Aptos", () => { HexCoding.decode( "0x5d996aa76b3212142792d9130796cd2e11e3c445a93118c08414df4f66bc60ec", ), + CoinTypeExt.curve(CoinType.aptos) ).data(), }); const input = TW.Aptos.Proto.SigningInput.encode(txDataInput).finish(); diff --git a/wasm/tests/Blockchain/Bitcoin.test.ts b/wasm/tests/Blockchain/Bitcoin.test.ts index f839f31b8f3..81be2ab5656 100644 --- a/wasm/tests/Blockchain/Bitcoin.test.ts +++ b/wasm/tests/Blockchain/Bitcoin.test.ts @@ -16,14 +16,14 @@ describe("Bitcoin", () => { // Transfer from P2TR to P2WPKH address. // Successfully broadcasted: https://mempool.space/tx/a9c63dfe54f6ff462155d966a54226c456b3e43b52a9abe55d7fa87d6564c6e4 it("test Bitcoin sign P2TR", () => { - const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType } = globalThis.core; + const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType, CoinTypeExt } = globalThis.core; const Proto = TW.BitcoinV2.Proto; const privateKeyData = HexCoding.decode("7fa638b0df495b2968ae6dc7011c4db08c86df16c91aa71a77ee6a222954e5bb"); const dustAmount = new Long(546); const utxoTxId = HexCoding.decode("75ed78f0ae2bad924065d2357ef01184ceee2181c44e03337746512be9371a82").reverse(); - const privateKey = PrivateKey.createWithData(privateKeyData); + const privateKey = PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.bitcoin)); const publicKey = privateKey.getPublicKeySecp256k1(true); const utxo0 = Proto.Input.create({ @@ -94,7 +94,7 @@ describe("Bitcoin", () => { // Successfully broadcasted: https://www.blockchain.com/explorer/transactions/btc/3e3576eb02667fac284a5ecfcb25768969680cc4c597784602d0a33ba7c654b7 it("test Bitcoin sign BRC20 Transfer", () => { - const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType } = globalThis.core; + const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType, CoinTypeExt } = globalThis.core; const Proto = TW.BitcoinV2.Proto; const privateKeyData = HexCoding.decode("e253373989199da27c48680e3a3fc0f648d50f9a727ef17a7fe6a4dc3b159129"); @@ -102,7 +102,7 @@ describe("Bitcoin", () => { const txIdInscription = HexCoding.decode("7046dc2689a27e143ea2ad1039710885147e9485ab6453fa7e87464aa7dd3eca").reverse(); const txIdForFees = HexCoding.decode("797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1").reverse(); - const privateKey = PrivateKey.createWithData(privateKeyData); + const privateKey = PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.bitcoin)); const publicKey = privateKey.getPublicKeySecp256k1(true); const bobAddress = "bc1qazgc2zhu2kmy42py0vs8d7yff67l3zgpwfzlpk"; @@ -188,14 +188,14 @@ describe("Bitcoin", () => { // Successfully broadcasted: https://www.blockchain.com/explorer/transactions/btc/797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1 it("test Bitcoin sign BRC20 Commit", () => { - const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType } = globalThis.core; + const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType, CoinTypeExt } = globalThis.core; const Proto = TW.BitcoinV2.Proto; const privateKeyData = HexCoding.decode("e253373989199da27c48680e3a3fc0f648d50f9a727ef17a7fe6a4dc3b159129"); const dustAmount = new Long(546); const txId = HexCoding.decode("8ec895b4d30adb01e38471ca1019bfc8c3e5fbd1f28d9e7b5653260d89989008").reverse(); - const privateKey = PrivateKey.createWithData(privateKeyData); + const privateKey = PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.bitcoin)); const publicKey = privateKey.getPublicKeySecp256k1(true); const utxo0 = Proto.Input.create({ @@ -270,14 +270,14 @@ describe("Bitcoin", () => { // Successfully broadcasted: https://www.blockchain.com/explorer/transactions/btc/7046dc2689a27e143ea2ad1039710885147e9485ab6453fa7e87464aa7dd3eca it("test Bitcoin sign BRC20 Reveal", () => { - const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType } = globalThis.core; + const { AnySigner, BitcoinSigHashType, PrivateKey, HexCoding, CoinType, CoinTypeExt } = globalThis.core; const Proto = TW.BitcoinV2.Proto; const privateKeyData = HexCoding.decode("e253373989199da27c48680e3a3fc0f648d50f9a727ef17a7fe6a4dc3b159129"); const dustAmount = new Long(546); const txIdCommit = HexCoding.decode("797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1").reverse(); - const privateKey = PrivateKey.createWithData(privateKeyData); + const privateKey = PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.bitcoin)); const publicKey = privateKey.getPublicKeySecp256k1(true); // Now spend just created `797d17d47ae66e598341f9dfdea020b04d4017dcf9cc33f0e51f7a6082171fb1` commit output. diff --git a/wasm/tests/Blockchain/Ethereum.test.ts b/wasm/tests/Blockchain/Ethereum.test.ts index 357e8d306f3..381b3279c0a 100644 --- a/wasm/tests/Blockchain/Ethereum.test.ts +++ b/wasm/tests/Blockchain/Ethereum.test.ts @@ -16,7 +16,7 @@ describe("Ethereum", () => { assert.isTrue(PrivateKey.isValid(data, Curve.secp256k1)); - const key = PrivateKey.createWithData(data); + const key = PrivateKey.createWithData(data, Curve.secp256k1); const pubKey = key.getPublicKeySecp256k1(false); assert.equal( @@ -104,9 +104,9 @@ describe("Ethereum", () => { assert.equal(HexCoding.encode(hash), "0x1da44b586eb0729ff70a73c326926f6ed5a25f5b056e7f47fbc6e58d86871655"); - var key = PrivateKey.createWithData(HexCoding.decode("1fcb84974220eb76e619d7208e1446ae9c0f755e97fb220a8f61c7dc03a0dfce")); + var key = PrivateKey.createWithData(HexCoding.decode("1fcb84974220eb76e619d7208e1446ae9c0f755e97fb220a8f61c7dc03a0dfce"), Curve.secp256k1); - const signature = key.sign(hash, Curve.secp256k1); + const signature = key.sign(hash); assert.equal(HexCoding.encode(signature), "0x58156c371347613642e94b66abc4ced8e36011fb3233f5372371aa5ad321671b1a10c0b88f47ce543fd4c455761f5fbf8f61d050f57dcba986640011da794a9000"); @@ -116,7 +116,7 @@ describe("Ethereum", () => { it("test signing EIP712 message", () => { const { EthereumAbi, HexCoding, Hash, PrivateKey, Curve } = globalThis.core;; - const key = PrivateKey.createWithData(Hash.keccak256(Buffer.from("cow"))); + const key = PrivateKey.createWithData(Hash.keccak256(Buffer.from("cow")), Curve.secp256k1); const message = { types: { EIP712Domain: [ @@ -156,7 +156,7 @@ describe("Ethereum", () => { }; const hash = EthereumAbi.encodeTyped(JSON.stringify(message)); - const signature = key.sign(hash, Curve.secp256k1); + const signature = key.sign(hash); assert.equal(HexCoding.encode(hash), "0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"); assert.equal(HexCoding.encode(signature), "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b9156201"); diff --git a/wasm/tests/Blockchain/Hedera.test.ts b/wasm/tests/Blockchain/Hedera.test.ts index e9dbbe0c881..11efc80bef4 100644 --- a/wasm/tests/Blockchain/Hedera.test.ts +++ b/wasm/tests/Blockchain/Hedera.test.ts @@ -20,7 +20,7 @@ describe("Hedera", () => { }); it("test sign simple transfer Hedera", () => { - const { PrivateKey, HexCoding, AnySigner, AnyAddress, CoinType } = globalThis.core; + const { PrivateKey, HexCoding, AnySigner, AnyAddress, CoinType, CoinTypeExt } = globalThis.core; const transferMsg = TW.Hedera.Proto.TransferMessage.create({ from: "0.0.48694347", to: "0.0.48462050", @@ -49,6 +49,7 @@ describe("Hedera", () => { HexCoding.decode( "0xe87a5584c0173263e138db689fdb2a7389025aaae7cb1a18a1017d76012130e8", ), + CoinTypeExt.curve(CoinType.hedera) ).data(), body: transactionBody }); diff --git a/wasm/tests/Blockchain/InternetComputer.test.ts b/wasm/tests/Blockchain/InternetComputer.test.ts index 210a06961e0..abb1a3da1d7 100644 --- a/wasm/tests/Blockchain/InternetComputer.test.ts +++ b/wasm/tests/Blockchain/InternetComputer.test.ts @@ -11,12 +11,12 @@ import Long = require("long"); describe("InternetComputer", () => { it("test address", () => { - const { PrivateKey, HexCoding, AnyAddress, CoinType, Curve } = globalThis.core; + const { PrivateKey, HexCoding, AnyAddress, CoinType, Curve, CoinTypeExt } = globalThis.core; const privateKeyBytes = HexCoding.decode("ee42eaada903e20ef6e5069f0428d552475c1ea7ed940842da6448f6ef9d48e7"); assert.isTrue(PrivateKey.isValid(privateKeyBytes, Curve.secp256k1)); - const privateKey = PrivateKey.createWithData(privateKeyBytes); + const privateKey = PrivateKey.createWithData(privateKeyBytes, CoinTypeExt.curve(CoinType.hedera)); const publicKey = privateKey.getPublicKeySecp256k1(false); assert.equal( diff --git a/wasm/tests/Blockchain/Ripple.test.ts b/wasm/tests/Blockchain/Ripple.test.ts index 323ae28dd1e..20a069344ae 100644 --- a/wasm/tests/Blockchain/Ripple.test.ts +++ b/wasm/tests/Blockchain/Ripple.test.ts @@ -9,10 +9,11 @@ import Long = require("long"); describe("Ripple", () => { it("test sign XRP payment", () => { - const {PrivateKey, HexCoding, AnySigner, CoinType} = globalThis.core; + const {PrivateKey, HexCoding, AnySigner, CoinType, CoinTypeExt} = globalThis.core; const privateKey = PrivateKey.createWithData( - HexCoding.decode("0xa5576c0f63da10e584568c8d134569ff44017b0a249eb70657127ae04f38cc77") + HexCoding.decode("0xa5576c0f63da10e584568c8d134569ff44017b0a249eb70657127ae04f38cc77"), + CoinTypeExt.curve(CoinType.xrp) ); const txDataInput = TW.Ripple.Proto.SigningInput.create({ fee: new Long(10), diff --git a/wasm/tests/Blockchain/TheOpenNetwork.test.ts b/wasm/tests/Blockchain/TheOpenNetwork.test.ts index b96cb551675..bc06e3291fa 100644 --- a/wasm/tests/Blockchain/TheOpenNetwork.test.ts +++ b/wasm/tests/Blockchain/TheOpenNetwork.test.ts @@ -10,9 +10,9 @@ import Long = require("long"); describe("TheOpenNetwork", () => { it("test address from private key TheOpenNetwork", () => { - const { PrivateKey, HexCoding, AnyAddress, CoinType, Curve } = globalThis.core; + const { PrivateKey, HexCoding, AnyAddress, CoinType, Curve, CoinTypeExt } = globalThis.core; let data = HexCoding.decode("63474e5fe9511f1526a50567ce142befc343e71a49b865ac3908f58667319cb8"); - let privateKey = PrivateKey.createWithData(data); + let privateKey = PrivateKey.createWithData(data, CoinTypeExt.curve(CoinType.ton)); assert.isTrue(PrivateKey.isValid(data, Curve.ed25519)); @@ -66,7 +66,7 @@ describe("TheOpenNetwork", () => { }); it("test sign TheOpenNetwork", () => { - const { PrivateKey, HexCoding, CoinType, AnySigner } = globalThis.core; + const { PrivateKey, HexCoding, CoinType, AnySigner, CoinTypeExt } = globalThis.core; let privateKeyData = HexCoding.decode("c38f49de2fb13223a9e7d37d5d0ffbdd89a5eb7c8b0ee4d1c299f2cefe7dc4a0"); @@ -79,7 +79,7 @@ describe("TheOpenNetwork", () => { let input = TW.TheOpenNetwork.Proto.SigningInput.create({ messages: [transfer], - privateKey: PrivateKey.createWithData(privateKeyData).data(), + privateKey: PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.ton)).data(), sequenceNumber: 6, expireAt: 1671132440, walletVersion: TW.TheOpenNetwork.Proto.WalletVersion.WALLET_V4_R2, @@ -96,7 +96,7 @@ describe("TheOpenNetwork", () => { }); it("test jetton transfer TheOpenNetwork", () => { - const { PrivateKey, HexCoding, CoinType, AnySigner } = globalThis.core; + const { PrivateKey, HexCoding, CoinType, AnySigner, CoinTypeExt } = globalThis.core; let privateKeyData = HexCoding.decode("c054900a527538c1b4325688a421c0469b171c29f23a62da216e90b0df2412ee"); @@ -118,7 +118,7 @@ describe("TheOpenNetwork", () => { let input = TW.TheOpenNetwork.Proto.SigningInput.create({ messages: [transfer], - privateKey: PrivateKey.createWithData(privateKeyData).data(), + privateKey: PrivateKey.createWithData(privateKeyData, CoinTypeExt.curve(CoinType.ton)).data(), sequenceNumber: 1, expireAt: 1787693046, walletVersion: TW.TheOpenNetwork.Proto.WalletVersion.WALLET_V4_R2, diff --git a/wasm/tests/CoinType.test.ts b/wasm/tests/CoinType.test.ts index 75a0bed0408..a0b593afbcd 100644 --- a/wasm/tests/CoinType.test.ts +++ b/wasm/tests/CoinType.test.ts @@ -33,7 +33,7 @@ describe("CoinType", () => { const { CoinType, CoinTypeExt, PrivateKey, HexCoding } = globalThis.core; const data = HexCoding.decode("8778cc93c6596387e751d2dc693bbd93e434bd233bc5b68a826c56131821cb63"); - const key = PrivateKey.createWithData(data); + const key = PrivateKey.createWithData(data, CoinTypeExt.curve(CoinType.solana)); const addr = CoinTypeExt.deriveAddress(CoinType.solana, key); assert.equal(addr, "7v91N7iZ9mNicL8WfG6cgSCKyRXydQjLh6UYBWwm6y1Q") }); diff --git a/wasm/tests/PrivateKey.test.ts b/wasm/tests/PrivateKey.test.ts new file mode 100644 index 00000000000..67e15295a03 --- /dev/null +++ b/wasm/tests/PrivateKey.test.ts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +import "mocha"; +import { assert } from "chai"; + +describe("PrivateKey", () => { + + it("test sign without curve", () => { + const { PrivateKey, HexCoding, Curve } = globalThis.core; + + const data = HexCoding.decode("0139fe4d6f02e666e86a6f58e65060f115cd3c185bd9e98bd829636931458f79"); + + const key = PrivateKey.createWithData(data, Curve.starkex); + const digest = HexCoding.decode("06fea80189363a786037ed3e7ba546dad0ef7de49fccae0e31eb658b7dd4ea76"); + const signature = key.sign(digest); + + assert.equal( + HexCoding.encode(signature), + "0x061ec782f76a66f6984efc3a1b6d152a124c701c00abdd2bf76641b4135c770f04e44e759cea02c23568bb4d8a09929bbca8768ab68270d50c18d214166ccd9a" + ); + + key.delete(); + }); +});