From 2581c92f92e704890e9348cbc2160252af080974 Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Tue, 9 Feb 2021 11:48:00 +0200 Subject: [PATCH 1/6] add "com.ionspin.kotlin:bignum-jvm" dependency to all submodules --- build.gradle.kts | 1 + buildSrc/src/main/kotlin/Versions.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 61fafe91..c85a2cb4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,6 +40,7 @@ subprojects { dependencies { "implementation"("org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}") + "implementation"("com.ionspin.kotlin:bignum-jvm:${Versions.bignum}") "testImplementation"("org.assertj:assertj-core:3.19.0") "testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.jupiter}") diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 96a9d677..87b116d5 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -12,4 +12,5 @@ object Versions { const val threetenbp = "1.5.0" const val okio = "2.4.0" const val base58 = "0.2" + const val bignum = "0.2.7" } \ No newline at end of file From 44d90ae121d5d1f6cb704ccdb8f129c4c8e029e7 Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Tue, 9 Feb 2021 11:50:48 +0200 Subject: [PATCH 2/6] replaced all usages of java's BigInteger/BigDecimal with a multiplatform implementation (except for java crypto implementations) --- .../main/kotlin/org/kethereum/bip32/BIP32.kt | 5 +-- .../kotlin/org/kethereum/bip32/Converter.kt | 7 ++-- .../org/kethereum/bip32/model/ExtendedKey.kt | 2 +- .../kethereum/blockscout/Blockscout.kt | 15 +++++---- .../org/kethereum/bloomfilter/BloomFilter.kt | 9 +++--- .../kotlin/org/kethereum/crypto/Converters.kt | 5 +-- .../main/kotlin/org/kethereum/crypto/Sign.kt | 3 +- .../kotlin/org/kethereum/crypto/Signatures.kt | 2 +- .../kotlin/org/kethereum/crypto/SignTest.kt | 5 +-- .../org/kethereum/crypto/TheSignatures.kt | 3 +- .../org/kethereum/crypto/api/ec/Curve.kt | 2 +- .../org/kethereum/crypto/api/ec/CurvePoint.kt | 2 +- .../kethereum/crypto/api/ec/ECDSASignature.kt | 2 +- .../org/kethereum/crypto/api/ec/Signer.kt | 2 +- .../org/kethereum/crypto/impl/BigInteger.kt | 12 +++++++ .../kethereum/crypto/impl/ec/EllipticCurve.kt | 8 +++-- .../impl/ec/EllipticCurveKeyPairGenerator.kt | 8 +++-- .../crypto/impl/ec/EllipticCurvePoint.kt | 10 +++--- .../crypto/impl/ec/EllipticCurveSigner.kt | 32 +++++++++++-------- .../crypto/impl/ec/EllipticCurveUtils.kt | 5 +-- .../kethereum/crypto/impl/ec/EllipticCurve.kt | 8 +++-- .../impl/ec/EllipticCurveKeyPairGenerator.kt | 8 +++-- .../crypto/impl/ec/EllipticCurvePoint.kt | 10 +++--- .../crypto/impl/ec/EllipticCurveSigner.kt | 32 +++++++++++-------- .../crypto/impl/ec/EllipticCurveUtils.kt | 5 +-- .../kotlin/org/kethereum/eip155/EIP155.kt | 14 ++++---- .../kotlin/org/kethereum/eip155/TheEIP155.kt | 20 ++++++------ .../org/kethereum/erc1328/ERC1328Parser.kt | 2 +- .../main/kotlin/org/kethereum/erc67/ERC67.kt | 6 ++-- .../kotlin/org/kethereum/erc67/TheERC67.kt | 12 +++---- .../kotlin/org/kethereum/erc681/ERC681.kt | 2 +- .../org/kethereum/erc681/ERC681Parser.kt | 8 ++--- .../kethereum/erc681/TheERC681Generator.kt | 8 ++--- .../org/kethereum/erc681/TheERC681Parsing.kt | 30 ++++++++--------- .../walleth/kethereum/etherscan/EtherScan.kt | 12 +++---- .../org/kethereum/extensions/BigInteger.kt | 13 ++++---- .../extensions/TheBigIntegerExtensions.kt | 8 +++-- .../extensions/transactions/TransactionFun.kt | 4 +-- .../transactions/TheTransactionDecoder.kt | 4 +-- .../transactions/TheTransactionEncoder.kt | 4 +-- .../transactions/TheTransactionFun.kt | 4 +-- .../kotlin/org/kethereum/flows/BlockFlow.kt | 4 +-- .../org/kethereum/abi/TheUserdocResolver.kt | 2 +- .../org/kethereum/abi/TheMetaDataRepo.kt | 4 +-- .../methodsignatures/TheSignatureFun.kt | 2 +- model/src/main/kotlin/org/kethereum/Values.kt | 9 +++--- .../kotlin/org/kethereum/model/ChainId.kt | 4 +-- .../kotlin/org/kethereum/model/Constants.kt | 2 +- .../kotlin/org/kethereum/model/ECKeyPair.kt | 2 +- .../org/kethereum/model/SignatureData.kt | 4 +-- .../kotlin/org/kethereum/model/Transaction.kt | 2 +- .../kotlin/org/kethereum/rlp/RLPDecoder.kt | 5 +-- .../org/kethereum/rlp/RLPTypeConverter.kt | 7 ++-- .../org/kethereum/rlp/TheRLPTypeConverter.kt | 12 ++++--- .../org/kethereum/rpc/BaseEthereumRPC.kt | 2 +- .../kotlin/org/kethereum/rpc/EthereumRPC.kt | 2 +- .../kethereum/rpc/model/BigIntegerAdapter.kt | 4 +-- .../kethereum/rpc/model/BlockInformation.kt | 2 +- .../test/kotlin/org/kethereum/TheConverter.kt | 10 +++--- .../org/kethereum/rpc/TheEthereumRPC.kt | 10 +++--- .../kotlin/org/kethereum/rpc/min3/MIN3.kt | 2 +- .../kethereum/crypto/test_data/TestData.kt | 30 +++++++++-------- .../abi/types/StringToTypeConverter.kt | 2 +- .../contract/abi/types/TypeEncoder.kt | 6 ++-- .../model/types/DynamicSizedBytesETHType.kt | 9 +++--- .../abi/types/model/types/IntETHType.kt | 16 ++++++---- .../abi/types/model/types/UIntETHType.kt | 13 ++++---- .../contract/abi/types/TheDecoder.kt | 12 +++---- .../abi/types/TheUINTypeConstraints.kt | 6 ++-- .../kethereum/uri/common/CommonURIParser.kt | 4 +-- 70 files changed, 298 insertions(+), 244 deletions(-) create mode 100644 crypto_api/src/main/kotlin/org/kethereum/crypto/impl/BigInteger.kt diff --git a/bip32/src/main/kotlin/org/kethereum/bip32/BIP32.kt b/bip32/src/main/kotlin/org/kethereum/bip32/BIP32.kt index dd94bcbc..673c7b94 100644 --- a/bip32/src/main/kotlin/org/kethereum/bip32/BIP32.kt +++ b/bip32/src/main/kotlin/org/kethereum/bip32/BIP32.kt @@ -2,6 +2,8 @@ package org.kethereum.bip32 +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.bip32.model.CHAINCODE_SIZE import org.kethereum.bip32.model.ExtendedKey import org.kethereum.bip32.model.Seed @@ -14,7 +16,6 @@ import org.komputing.kbip44.BIP44 import org.komputing.kbip44.BIP44Element import org.komputing.khash.ripemd160.extensions.digestRipemd160 import org.komputing.khash.sha256.extensions.sha256 -import java.math.BigInteger import java.nio.ByteBuffer import java.nio.ByteOrder import java.security.InvalidKeyException @@ -76,7 +77,7 @@ fun ExtendedKey.generateChildKey(element: BIP44Element): ExtendedKey { val l = lr.copyOfRange(0, PRIVATE_KEY_SIZE) val r = lr.copyOfRange(PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE + CHAINCODE_SIZE) - val m = BigInteger(1, l) + val m = BigInteger.fromByteArray(l, Sign.POSITIVE) if (m >= CURVE.n) { throw KeyException("Child key derivation resulted in a key with higher modulus. Suggest deriving the next increment.") } diff --git a/bip32/src/main/kotlin/org/kethereum/bip32/Converter.kt b/bip32/src/main/kotlin/org/kethereum/bip32/Converter.kt index 54544290..64949d07 100644 --- a/bip32/src/main/kotlin/org/kethereum/bip32/Converter.kt +++ b/bip32/src/main/kotlin/org/kethereum/bip32/Converter.kt @@ -1,5 +1,7 @@ package org.kethereum.bip32 +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.bip32.model.* import org.kethereum.crypto.CURVE import org.kethereum.crypto.CryptoAPI @@ -10,7 +12,6 @@ import org.kethereum.model.PRIVATE_KEY_SIZE import org.kethereum.model.PrivateKey import org.kethereum.model.PublicKey import org.komputing.kbase58.decodeBase58WithChecksum -import java.math.BigInteger import java.nio.ByteBuffer import java.nio.ByteOrder import java.security.InvalidKeyException @@ -23,7 +24,7 @@ fun Seed.toExtendedKey(publicKeyOnly: Boolean = false, testnet: Boolean = false) val lr = CryptoAPI.hmac.init(BITCOIN_SEED).generate(seed) val l = lr.copyOfRange(0, PRIVATE_KEY_SIZE) val r = lr.copyOfRange(PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE + CHAINCODE_SIZE) - val m = BigInteger(1, l) + val m = BigInteger.fromByteArray(l, Sign.POSITIVE) if (m >= CURVE.n) { throw KeyException("Master key creation resulted in a key with higher modulus. Suggest deriving the next increment.") } @@ -83,7 +84,7 @@ fun XPriv.toExtendedKey(): ExtendedKey { val uncompressedPublicBytes = decompressKey(compressedPublicBytes) ECKeyPair( PrivateKey(BigInteger.ZERO), - PublicKey(BigInteger(1, uncompressedPublicBytes)) + PublicKey(BigInteger.fromByteArray(uncompressedPublicBytes, Sign.POSITIVE)) ) } return ExtendedKey(keyPair, chainCode, depth, parent, sequence, versionBytes) diff --git a/bip32/src/main/kotlin/org/kethereum/bip32/model/ExtendedKey.kt b/bip32/src/main/kotlin/org/kethereum/bip32/model/ExtendedKey.kt index 8c88f0e6..b31aeae8 100644 --- a/bip32/src/main/kotlin/org/kethereum/bip32/model/ExtendedKey.kt +++ b/bip32/src/main/kotlin/org/kethereum/bip32/model/ExtendedKey.kt @@ -1,12 +1,12 @@ package org.kethereum.bip32.model +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.crypto.getCompressedPublicKey import org.kethereum.extensions.toBytesPadded import org.kethereum.model.ECKeyPair import org.kethereum.model.PRIVATE_KEY_SIZE import org.komputing.kbase58.encodeToBase58WithChecksum import java.io.IOException -import java.math.BigInteger import java.nio.ByteBuffer import java.security.KeyException import java.util.* diff --git a/blockscout/src/main/kotlin/org/walleth/kethereum/blockscout/Blockscout.kt b/blockscout/src/main/kotlin/org/walleth/kethereum/blockscout/Blockscout.kt index 114f7292..d8ef1118 100644 --- a/blockscout/src/main/kotlin/org/walleth/kethereum/blockscout/Blockscout.kt +++ b/blockscout/src/main/kotlin/org/walleth/kethereum/blockscout/Blockscout.kt @@ -1,18 +1,19 @@ package org.walleth.kethereum.blockscout +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.ChainId private const val BLOCKSCOUTCOM_BASE_URL = "https://blockscout.com" private val BLOCKSCOUT_URLS = mapOf( - 1L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/eth/mainnet", - 42L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/eth/kovan", - 61L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/etc/mainnet", - 77L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/poa/sokol", - 99L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/poa/core", - 100L.toBigInteger() to "$BLOCKSCOUTCOM_BASE_URL/poa/xdai", + BigInteger(1L) to "$BLOCKSCOUTCOM_BASE_URL/eth/mainnet", + BigInteger(42L) to "$BLOCKSCOUTCOM_BASE_URL/eth/kovan", + BigInteger(61L) to "$BLOCKSCOUTCOM_BASE_URL/etc/mainnet", + BigInteger(77L) to "$BLOCKSCOUTCOM_BASE_URL/poa/sokol", + BigInteger(99L) to "$BLOCKSCOUTCOM_BASE_URL/poa/core", + BigInteger(100L) to "$BLOCKSCOUTCOM_BASE_URL/poa/xdai", - 43110L.toBigInteger() to "http://athexplorer.ava.network" + BigInteger(43110L) to "http://athexplorer.ava.network" ) val ALL_BLOCKSCOUT_SUPPORTED_NETWORKS = BLOCKSCOUT_URLS.map { it.key }.toSet() diff --git a/bloomfilter/src/main/kotlin/org/kethereum/bloomfilter/BloomFilter.kt b/bloomfilter/src/main/kotlin/org/kethereum/bloomfilter/BloomFilter.kt index f508cdad..ccf2b478 100644 --- a/bloomfilter/src/main/kotlin/org/kethereum/bloomfilter/BloomFilter.kt +++ b/bloomfilter/src/main/kotlin/org/kethereum/bloomfilter/BloomFilter.kt @@ -1,7 +1,8 @@ package org.kethereum.bloomfilter +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.komputing.khash.sha256.extensions.sha256 -import java.math.BigInteger import java.util.* import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read @@ -31,7 +32,7 @@ class BloomFilter(private val size: Int) { } private fun hashing(filterSize: Int, seed: Int, value: ByteArray) = - BigInteger(1, value.plus(seed.toByte()).sha256()) - .remainder(BigInteger.valueOf(filterSize.toLong())) - .toInt() + BigInteger.fromByteArray(value.plus(seed.toByte()).sha256(), Sign.POSITIVE) + .remainder(BigInteger(filterSize.toLong())) + .intValue() } diff --git a/crypto/src/main/kotlin/org/kethereum/crypto/Converters.kt b/crypto/src/main/kotlin/org/kethereum/crypto/Converters.kt index 470a8112..20e27f7e 100644 --- a/crypto/src/main/kotlin/org/kethereum/crypto/Converters.kt +++ b/crypto/src/main/kotlin/org/kethereum/crypto/Converters.kt @@ -1,5 +1,7 @@ package org.kethereum.crypto +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.crypto.api.ec.CurvePoint import org.kethereum.extensions.toHexStringZeroPadded import org.kethereum.keccakshortcut.keccak @@ -7,7 +9,6 @@ import org.kethereum.model.* import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.extensions.toHexString import org.komputing.khex.model.HexString -import java.math.BigInteger fun PublicKey.toAddress() : Address { val publicKeyHexString = HexString(key.toHexStringZeroPadded(PUBLIC_KEY_LENGTH_IN_HEX, false)) @@ -28,5 +29,5 @@ fun PrivateKey.toECKeyPair() = ECKeyPair(this, publicKeyFromPrivate(this)) * Decodes an uncompressed public key (without 0x04 prefix) given an ECPoint */ fun CurvePoint.toPublicKey() = encoded().let { encoded -> - PublicKey(BigInteger(1, encoded.copyOfRange(1, encoded.size))) + PublicKey(BigInteger.fromByteArray(encoded.copyOfRange(1, encoded.size), Sign.POSITIVE)) } diff --git a/crypto/src/main/kotlin/org/kethereum/crypto/Sign.kt b/crypto/src/main/kotlin/org/kethereum/crypto/Sign.kt index 7a36b222..147d992e 100644 --- a/crypto/src/main/kotlin/org/kethereum/crypto/Sign.kt +++ b/crypto/src/main/kotlin/org/kethereum/crypto/Sign.kt @@ -1,5 +1,6 @@ package org.kethereum.crypto +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.crypto.api.ec.Curve import org.kethereum.crypto.api.ec.ECDSASignature import org.kethereum.keccakshortcut.keccak @@ -47,7 +48,7 @@ fun signMessageHash(messageHash: ByteArray, keyPair: ECKeyPair, toCanonical: Boo val headerByte = recId + 27 - return SignatureData(signature.r, signature.s, headerByte.toBigInteger()) + return SignatureData(signature.r, signature.s, BigInteger(headerByte)) } fun ECDSASignature.determineRecId(messageHash: ByteArray, publicKey: PublicKey): Int { diff --git a/crypto/src/main/kotlin/org/kethereum/crypto/Signatures.kt b/crypto/src/main/kotlin/org/kethereum/crypto/Signatures.kt index 93d18afa..c220e173 100644 --- a/crypto/src/main/kotlin/org/kethereum/crypto/Signatures.kt +++ b/crypto/src/main/kotlin/org/kethereum/crypto/Signatures.kt @@ -1,9 +1,9 @@ package org.kethereum.crypto +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.extensions.toHexStringNoPrefix import org.kethereum.extensions.toHexStringZeroPadded import org.kethereum.model.SignatureData -import java.math.BigInteger fun SignatureData.toHex() = r.to64BytePaddedHex() + s.to64BytePaddedHex() + v.toHexStringNoPrefix() diff --git a/crypto/src/test/kotlin/org/kethereum/crypto/SignTest.kt b/crypto/src/test/kotlin/org/kethereum/crypto/SignTest.kt index b1464311..16ed549b 100644 --- a/crypto/src/test/kotlin/org/kethereum/crypto/SignTest.kt +++ b/crypto/src/test/kotlin/org/kethereum/crypto/SignTest.kt @@ -1,5 +1,6 @@ package org.kethereum.crypto +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.crypto.test_data.KEY_PAIR @@ -22,7 +23,7 @@ class SignTest { val expected = SignatureData( HexString("0x9631f6d21dec448a213585a4a41a28ef3d4337548aa34734478b563036163786").hexToBigInteger(), HexString("0x2ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b").hexToBigInteger(), - 27.toBigInteger() + BigInteger(27) ) assertThat(signatureData).isEqualTo(expected) @@ -39,7 +40,7 @@ class SignTest { val expected = SignatureData( HexString("0x6bcd81446183af193ca4a172d5c5c26345903b24770d90b5d790f74a9dec1f68").hexToBigInteger(), HexString("0xe2b85b3c92c9b4f3cf58de46e7997d8efb6e14b2e532d13dfa22ee02f3a43d5d").hexToBigInteger(), - 28.toBigInteger() + BigInteger(28) ) assertThat(expected).isEqualTo(signatureData) diff --git a/crypto/src/test/kotlin/org/kethereum/crypto/TheSignatures.kt b/crypto/src/test/kotlin/org/kethereum/crypto/TheSignatures.kt index c0023110..13b50126 100644 --- a/crypto/src/test/kotlin/org/kethereum/crypto/TheSignatures.kt +++ b/crypto/src/test/kotlin/org/kethereum/crypto/TheSignatures.kt @@ -1,5 +1,6 @@ package org.kethereum.crypto +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.extensions.hexToBigInteger @@ -14,7 +15,7 @@ class TheSignatures { val signatureData = SignatureData( HexString("0x0031f6d21dec448a213585a4a41a28ef3d4337548aa34734478b563036163786").hexToBigInteger(), HexString("0x2ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b").hexToBigInteger(), - 27.toBigInteger() + BigInteger(27) ) assertThat(signatureData.toHex()).isEqualTo("0031f6d21dec448a213585a4a41a28ef3d4337548aa34734478b5630361637862ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b1b") diff --git a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Curve.kt b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Curve.kt index 1efbc743..14f0ce72 100644 --- a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Curve.kt +++ b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Curve.kt @@ -1,6 +1,6 @@ package org.kethereum.crypto.api.ec -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger interface Curve { val n: BigInteger diff --git a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/CurvePoint.kt b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/CurvePoint.kt index 59cfbabf..fb7b60e2 100644 --- a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/CurvePoint.kt +++ b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/CurvePoint.kt @@ -1,6 +1,6 @@ package org.kethereum.crypto.api.ec -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger interface CurvePoint { val x: BigInteger diff --git a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/ECDSASignature.kt b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/ECDSASignature.kt index 7eb5ea06..f0d0b79e 100644 --- a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/ECDSASignature.kt +++ b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/ECDSASignature.kt @@ -1,5 +1,5 @@ package org.kethereum.crypto.api.ec -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger data class ECDSASignature(val r: BigInteger, val s: BigInteger) diff --git a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Signer.kt b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Signer.kt index 6b417733..69fd78fd 100644 --- a/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Signer.kt +++ b/crypto_api/src/main/kotlin/org/kethereum/crypto/api/ec/Signer.kt @@ -1,6 +1,6 @@ package org.kethereum.crypto.api.ec -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger interface Signer { fun sign(transactionHash: ByteArray, privateKey: BigInteger, canonical: Boolean): ECDSASignature diff --git a/crypto_api/src/main/kotlin/org/kethereum/crypto/impl/BigInteger.kt b/crypto_api/src/main/kotlin/org/kethereum/crypto/impl/BigInteger.kt new file mode 100644 index 00000000..822e1246 --- /dev/null +++ b/crypto_api/src/main/kotlin/org/kethereum/crypto/impl/BigInteger.kt @@ -0,0 +1,12 @@ +package org.kethereum.crypto.impl + +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.util.fromTwosComplementByteArray +import com.ionspin.kotlin.bignum.integer.util.toTwosComplementByteArray +import java.math.BigInteger as JavaBigInteger + +fun JavaBigInteger.toKotlinBigInteger(): BigInteger = + BigInteger.fromTwosComplementByteArray(toByteArray()) + +fun BigInteger.toJavaBigInteger(): JavaBigInteger = + JavaBigInteger(toTwosComplementByteArray()) \ No newline at end of file diff --git a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt index 9205e3eb..ce50b538 100644 --- a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt +++ b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt @@ -1,10 +1,12 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger import org.bouncycastle.crypto.ec.CustomNamedCurves import org.bouncycastle.crypto.params.ECDomainParameters import org.kethereum.crypto.api.ec.Curve import org.kethereum.crypto.api.ec.CurvePoint -import java.math.BigInteger +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger internal val CURVE_PARAMS by lazy { CustomNamedCurves.getByName("secp256k1")!! } internal val DOMAIN_PARAMS = CURVE_PARAMS.run { ECDomainParameters(curve, g, n, h) } @@ -12,7 +14,7 @@ internal val DOMAIN_PARAMS = CURVE_PARAMS.run { ECDomainParameters(curve, g, n, class EllipticCurve : Curve { override val n: BigInteger - get() = CURVE_PARAMS.n + get() = CURVE_PARAMS.n.toKotlinBigInteger() override val g: CurvePoint get() = CURVE_PARAMS.g.toCurvePoint() @@ -21,5 +23,5 @@ class EllipticCurve : Curve { CURVE_PARAMS.curve.decodePoint(data).toCurvePoint() override fun createPoint(x: BigInteger, y: BigInteger): CurvePoint = - CURVE_PARAMS.curve.createPoint(x, y).toCurvePoint() + CURVE_PARAMS.curve.createPoint(x.toJavaBigInteger(), y.toJavaBigInteger()).toCurvePoint() } diff --git a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt index e14b3ff4..334b1520 100644 --- a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt +++ b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt @@ -1,23 +1,25 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.bouncycastle.crypto.generators.ECKeyPairGenerator import org.bouncycastle.crypto.params.ECKeyGenerationParameters import org.bouncycastle.crypto.params.ECPrivateKeyParameters import org.bouncycastle.crypto.params.ECPublicKeyParameters import org.kethereum.crypto.api.ec.KeyPairGenerator +import org.kethereum.crypto.impl.toKotlinBigInteger import org.kethereum.model.ECKeyPair import org.kethereum.model.PrivateKey import org.kethereum.model.PublicKey -import java.math.BigInteger import java.util.* class EllipticCurveKeyPairGenerator : KeyPairGenerator { override fun generate() = ECKeyPairGenerator().run { init(ECKeyGenerationParameters(DOMAIN_PARAMS, null)) generateKeyPair().run { - val privateKeyValue = (private as ECPrivateKeyParameters).d + val privateKeyValue = (private as ECPrivateKeyParameters).d.toKotlinBigInteger() val publicKeyBytes = (public as ECPublicKeyParameters).q.getEncoded(false) - val publicKeyValue = BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.size)) + val publicKeyValue = BigInteger.fromByteArray(Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.size), Sign.POSITIVE) ECKeyPair(PrivateKey(privateKeyValue), PublicKey(publicKeyValue)) } } diff --git a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt index 7611f5e3..60b33bb1 100644 --- a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt +++ b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt @@ -1,17 +1,19 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger import org.bouncycastle.math.ec.ECPoint import org.kethereum.crypto.api.ec.CurvePoint -import java.math.BigInteger +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger class EllipticCurvePoint(private val ecPoint: ECPoint) : CurvePoint { override val x: BigInteger - get() = ecPoint.xCoord.toBigInteger() + get() = ecPoint.xCoord.toBigInteger().toKotlinBigInteger() override val y: BigInteger - get() = ecPoint.yCoord.toBigInteger() + get() = ecPoint.yCoord.toBigInteger().toKotlinBigInteger() override fun mul(n: BigInteger): CurvePoint = - ecPoint.multiply(n).toCurvePoint() + ecPoint.multiply(n.toJavaBigInteger()).toCurvePoint() override fun add(p: CurvePoint): CurvePoint = (p as? EllipticCurvePoint)?.let { diff --git a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt index a3be6279..67d5493b 100644 --- a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt +++ b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt @@ -1,5 +1,7 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.bouncycastle.asn1.x9.X9IntegerConverter import org.bouncycastle.crypto.digests.SHA256Digest import org.bouncycastle.crypto.params.ECPrivateKeyParameters @@ -11,7 +13,9 @@ import org.bouncycastle.math.ec.FixedPointCombMultiplier import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve import org.kethereum.crypto.api.ec.ECDSASignature import org.kethereum.crypto.api.ec.Signer -import java.math.BigInteger +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger +import java.math.BigInteger as JavaBigInteger import java.util.* class EllipticCurveSigner : Signer { @@ -19,9 +23,9 @@ class EllipticCurveSigner : Signer { override fun sign(transactionHash: ByteArray, privateKey: BigInteger, canonical: Boolean): ECDSASignature { val signer = ECDSASigner(HMacDSAKCalculator(SHA256Digest())) - val ecPrivateKeyParameters = ECPrivateKeyParameters(privateKey, DOMAIN_PARAMS) + val ecPrivateKeyParameters = ECPrivateKeyParameters(privateKey.toJavaBigInteger(), DOMAIN_PARAMS) signer.init(true, ecPrivateKeyParameters) - val components = signer.generateSignature(transactionHash) + val components = signer.generateSignature(transactionHash).map { it.toKotlinBigInteger() } return ECDSASignature(components[0], components[1]).let { if (canonical) { @@ -68,8 +72,8 @@ class EllipticCurveSigner : Signer { // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn val n = CURVE_PARAMS.n // Curve order. - val i = BigInteger.valueOf(recId.toLong() / 2) - val x = sig.r.add(i.multiply(n)) + val i = JavaBigInteger.valueOf(recId.toLong() / 2) + val x = sig.r.toJavaBigInteger().add(i.multiply(n)) // 1.2. Convert the integer x to an octet string X of length mlen using the conversion // routine specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R @@ -91,7 +95,7 @@ class EllipticCurveSigner : Signer { return null } // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. - val e = BigInteger(1, message) + val e = JavaBigInteger(1, message) // 1.6. For k from 1 to 2 do the following. (loop is outside this function via // iterating recId) // 1.6.1. Compute a candidate public key as: @@ -106,19 +110,19 @@ class EllipticCurveSigner : Signer { // We can find the additive inverse by subtracting e from zero then taking the mod. For // example the additive inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and // -3 mod 11 = 8. - val eInv = BigInteger.ZERO.subtract(e).mod(n) - val rInv = sig.r.modInverse(n) - val srInv = rInv.multiply(sig.s).mod(n) + val eInv = JavaBigInteger.ZERO.subtract(e).mod(n) + val rInv = sig.r.toJavaBigInteger().modInverse(n) + val srInv = rInv.multiply(sig.s.toJavaBigInteger()).mod(n) val eInvrInv = rInv.multiply(eInv).mod(n) val q = ECAlgorithms.sumOfTwoMultiplies(CURVE_PARAMS.g, eInvrInv, r, srInv) val qBytes = q.getEncoded(false) // We remove the prefix - return BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.size)) + return BigInteger.fromByteArray(Arrays.copyOfRange(qBytes, 1, qBytes.size), Sign.POSITIVE) } /** Decompress a compressed public key (x co-ord and low-bit of y-coord). */ - private fun decompressKey(xBN: BigInteger, yBit: Boolean): ECPoint { + private fun decompressKey(xBN: JavaBigInteger, yBit: Boolean): ECPoint { val x9 = X9IntegerConverter() val compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE_PARAMS.curve)) compEnc[0] = (if (yBit) 0x03 else 0x02).toByte() @@ -127,16 +131,16 @@ class EllipticCurveSigner : Signer { override fun publicFromPrivate(privateKey: BigInteger): BigInteger { - val point = publicPointFromPrivate(privateKey) + val point = publicPointFromPrivate(privateKey.toJavaBigInteger()) val encoded = point.getEncoded(false) - return BigInteger(1, Arrays.copyOfRange(encoded, 1, encoded.size)) + return BigInteger.fromByteArray(Arrays.copyOfRange(encoded, 1, encoded.size), Sign.POSITIVE) } /** * Returns public key point from the given private key. */ - private fun publicPointFromPrivate(privateKey: BigInteger): ECPoint { + private fun publicPointFromPrivate(privateKey: JavaBigInteger): ECPoint { /* * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group * order, but that could change in future versions. diff --git a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt index 3533cad5..3ee309f5 100644 --- a/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt +++ b/crypto_impl_bouncycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt @@ -1,8 +1,9 @@ package org.kethereum.crypto.impl.ec import org.kethereum.crypto.api.ec.ECDSASignature +import org.kethereum.crypto.impl.toKotlinBigInteger -private val HALF_CURVE_ORDER = CURVE_PARAMS.n.shiftRight(1) +private val HALF_CURVE_ORDER = CURVE_PARAMS.n.shiftRight(1).toKotlinBigInteger() /** * Returns true if the S component is "low", that means it is below * [HALF_CURVE_ORDER]. See @@ -27,5 +28,5 @@ fun ECDSASignature.canonicalise() = if (isCanonical()) { // N = 10 // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. // 10 - 8 == 2, giving us always the latter solution, which is canonical. - ECDSASignature(r, CURVE_PARAMS.n.subtract(s)) + ECDSASignature(r, CURVE_PARAMS.n.toKotlinBigInteger().subtract(s)) } diff --git a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt index f0177042..fc591045 100644 --- a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt +++ b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurve.kt @@ -1,10 +1,12 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.crypto.api.ec.Curve import org.kethereum.crypto.api.ec.CurvePoint +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger import org.spongycastle.crypto.ec.CustomNamedCurves import org.spongycastle.crypto.params.ECDomainParameters -import java.math.BigInteger internal val CURVE_PARAMS by lazy { CustomNamedCurves.getByName("secp256k1")!! } internal val DOMAIN_PARAMS = CURVE_PARAMS.run { ECDomainParameters(curve, g, n, h) } @@ -12,7 +14,7 @@ internal val DOMAIN_PARAMS = CURVE_PARAMS.run { ECDomainParameters(curve, g, n, class EllipticCurve : Curve { override val n: BigInteger - get() = CURVE_PARAMS.n + get() = CURVE_PARAMS.n.toKotlinBigInteger() override val g: CurvePoint get() = CURVE_PARAMS.g.toCurvePoint() @@ -21,5 +23,5 @@ class EllipticCurve : Curve { CURVE_PARAMS.curve.decodePoint(data).toCurvePoint() override fun createPoint(x: BigInteger, y: BigInteger): CurvePoint = - CURVE_PARAMS.curve.createPoint(x, y).toCurvePoint() + CURVE_PARAMS.curve.createPoint(x.toJavaBigInteger(), y.toJavaBigInteger()).toCurvePoint() } diff --git a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt index 35af2ace..28e66b33 100644 --- a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt +++ b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveKeyPairGenerator.kt @@ -1,6 +1,9 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.crypto.api.ec.KeyPairGenerator +import org.kethereum.crypto.impl.toKotlinBigInteger import org.kethereum.model.ECKeyPair import org.kethereum.model.PrivateKey import org.kethereum.model.PublicKey @@ -8,16 +11,15 @@ import org.spongycastle.crypto.generators.ECKeyPairGenerator import org.spongycastle.crypto.params.ECKeyGenerationParameters import org.spongycastle.crypto.params.ECPrivateKeyParameters import org.spongycastle.crypto.params.ECPublicKeyParameters -import java.math.BigInteger import java.util.* class EllipticCurveKeyPairGenerator : KeyPairGenerator { override fun generate() = ECKeyPairGenerator().run { init(ECKeyGenerationParameters(DOMAIN_PARAMS, null)) generateKeyPair().run { - val privateKeyValue = (private as ECPrivateKeyParameters).d + val privateKeyValue = (private as ECPrivateKeyParameters).d.toKotlinBigInteger() val publicKeyBytes = (public as ECPublicKeyParameters).q.getEncoded(false) - val publicKeyValue = BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.size)) + val publicKeyValue = BigInteger.fromByteArray(Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.size), Sign.POSITIVE) ECKeyPair(PrivateKey(privateKeyValue), PublicKey(publicKeyValue)) } } diff --git a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt index 2bd37781..5df23663 100644 --- a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt +++ b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurvePoint.kt @@ -1,17 +1,19 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.crypto.api.ec.CurvePoint +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger import org.spongycastle.math.ec.ECPoint -import java.math.BigInteger class EllipticCurvePoint(private val ecPoint: ECPoint) : CurvePoint { override val x: BigInteger - get() = ecPoint.xCoord.toBigInteger() + get() = ecPoint.xCoord.toBigInteger().toKotlinBigInteger() override val y: BigInteger - get() = ecPoint.yCoord.toBigInteger() + get() = ecPoint.yCoord.toBigInteger().toKotlinBigInteger() override fun mul(n: BigInteger): CurvePoint = - ecPoint.multiply(n).toCurvePoint() + ecPoint.multiply(n.toJavaBigInteger()).toCurvePoint() override fun add(p: CurvePoint): CurvePoint = (p as? EllipticCurvePoint)?.let { diff --git a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt index 91fe961b..2bcdbaa9 100644 --- a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt +++ b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveSigner.kt @@ -1,7 +1,11 @@ package org.kethereum.crypto.impl.ec +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.crypto.api.ec.ECDSASignature import org.kethereum.crypto.api.ec.Signer +import org.kethereum.crypto.impl.toJavaBigInteger +import org.kethereum.crypto.impl.toKotlinBigInteger import org.spongycastle.asn1.x9.X9IntegerConverter import org.spongycastle.crypto.digests.SHA256Digest import org.spongycastle.crypto.params.ECPrivateKeyParameters @@ -11,19 +15,19 @@ import org.spongycastle.math.ec.ECAlgorithms import org.spongycastle.math.ec.ECPoint import org.spongycastle.math.ec.FixedPointCombMultiplier import org.spongycastle.math.ec.custom.sec.SecP256K1Curve -import java.math.BigInteger import java.util.* +import java.math.BigInteger as JavaBigInteger class EllipticCurveSigner : Signer { override fun sign(transactionHash: ByteArray, privateKey: BigInteger, canonical: Boolean): ECDSASignature { val signer = ECDSASigner(HMacDSAKCalculator(SHA256Digest())) - val ecPrivateKeyParameters = ECPrivateKeyParameters(privateKey, DOMAIN_PARAMS) + val ecPrivateKeyParameters = ECPrivateKeyParameters(privateKey.toJavaBigInteger(), DOMAIN_PARAMS) signer.init(true, ecPrivateKeyParameters) val components = signer.generateSignature(transactionHash) - return ECDSASignature(components[0], components[1]).let { + return ECDSASignature(components[0].toKotlinBigInteger(), components[1].toKotlinBigInteger()).let { if (canonical) { it.canonicalise() } else { @@ -68,8 +72,8 @@ class EllipticCurveSigner : Signer { // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn val n = CURVE_PARAMS.n // Curve order. - val i = BigInteger.valueOf(recId.toLong() / 2) - val x = sig.r.add(i.multiply(n)) + val i = JavaBigInteger.valueOf(recId.toLong() / 2) + val x = sig.r.toJavaBigInteger().add(i.multiply(n)) // 1.2. Convert the integer x to an octet string X of length mlen using the conversion // routine specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R @@ -91,7 +95,7 @@ class EllipticCurveSigner : Signer { return null } // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. - val e = BigInteger(1, message) + val e = JavaBigInteger(1, message) // 1.6. For k from 1 to 2 do the following. (loop is outside this function via // iterating recId) // 1.6.1. Compute a candidate public key as: @@ -106,19 +110,19 @@ class EllipticCurveSigner : Signer { // We can find the additive inverse by subtracting e from zero then taking the mod. For // example the additive inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and // -3 mod 11 = 8. - val eInv = BigInteger.ZERO.subtract(e).mod(n) - val rInv = sig.r.modInverse(n) - val srInv = rInv.multiply(sig.s).mod(n) + val eInv = JavaBigInteger.ZERO.subtract(e).mod(n) + val rInv = sig.r.toJavaBigInteger().modInverse(n) + val srInv = rInv.multiply(sig.s.toJavaBigInteger()).mod(n) val eInvrInv = rInv.multiply(eInv).mod(n) val q = ECAlgorithms.sumOfTwoMultiplies(CURVE_PARAMS.g, eInvrInv, r, srInv) val qBytes = q.getEncoded(false) // We remove the prefix - return BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.size)) + return BigInteger.fromByteArray(Arrays.copyOfRange(qBytes, 1, qBytes.size), Sign.POSITIVE) } /** Decompress a compressed public key (x co-ord and low-bit of y-coord). */ - private fun decompressKey(xBN: BigInteger, yBit: Boolean): ECPoint { + private fun decompressKey(xBN: JavaBigInteger, yBit: Boolean): ECPoint { val x9 = X9IntegerConverter() val compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE_PARAMS.curve)) compEnc[0] = (if (yBit) 0x03 else 0x02).toByte() @@ -127,16 +131,16 @@ class EllipticCurveSigner : Signer { override fun publicFromPrivate(privateKey: BigInteger): BigInteger { - val point = publicPointFromPrivate(privateKey) + val point = publicPointFromPrivate(privateKey.toJavaBigInteger()) val encoded = point.getEncoded(false) - return BigInteger(1, Arrays.copyOfRange(encoded, 1, encoded.size)) + return BigInteger.fromByteArray(Arrays.copyOfRange(encoded, 1, encoded.size), Sign.POSITIVE) } /** * Returns public key point from the given private key. */ - private fun publicPointFromPrivate(privateKey: BigInteger): ECPoint { + private fun publicPointFromPrivate(privateKey: JavaBigInteger): ECPoint { /* * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group * order, but that could change in future versions. diff --git a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt index 3533cad5..3ee309f5 100644 --- a/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt +++ b/crypto_impl_spongycastle/src/main/kotlin/org/kethereum/crypto/impl/ec/EllipticCurveUtils.kt @@ -1,8 +1,9 @@ package org.kethereum.crypto.impl.ec import org.kethereum.crypto.api.ec.ECDSASignature +import org.kethereum.crypto.impl.toKotlinBigInteger -private val HALF_CURVE_ORDER = CURVE_PARAMS.n.shiftRight(1) +private val HALF_CURVE_ORDER = CURVE_PARAMS.n.shiftRight(1).toKotlinBigInteger() /** * Returns true if the S component is "low", that means it is below * [HALF_CURVE_ORDER]. See @@ -27,5 +28,5 @@ fun ECDSASignature.canonicalise() = if (isCanonical()) { // N = 10 // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. // 10 - 8 == 2, giving us always the latter solution, which is canonical. - ECDSASignature(r, CURVE_PARAMS.n.subtract(s)) + ECDSASignature(r, CURVE_PARAMS.n.toKotlinBigInteger().subtract(s)) } diff --git a/eip155/src/main/kotlin/org/kethereum/eip155/EIP155.kt b/eip155/src/main/kotlin/org/kethereum/eip155/EIP155.kt index 7ba55d13..de69b5b1 100644 --- a/eip155/src/main/kotlin/org/kethereum/eip155/EIP155.kt +++ b/eip155/src/main/kotlin/org/kethereum/eip155/EIP155.kt @@ -1,5 +1,7 @@ package org.kethereum.eip155 +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO import org.kethereum.crypto.signMessage import org.kethereum.crypto.signedMessageToKey import org.kethereum.crypto.toAddress @@ -8,9 +10,6 @@ import org.kethereum.model.ChainId import org.kethereum.model.ECKeyPair import org.kethereum.model.SignatureData import org.kethereum.model.Transaction -import java.math.BigInteger -import java.math.BigInteger.ZERO -import java.math.BigInteger.valueOf /* * @@ -27,7 +26,7 @@ import java.math.BigInteger.valueOf fun Transaction.signViaEIP155(key: ECKeyPair, chainId: ChainId): SignatureData { val signatureData = key.signMessage(encodeRLP(SignatureData().apply { v = chainId.value })) - return signatureData.copy(v = (signatureData.v.plus(chainId.value.shl(1)).plus(valueOf(8)))) + return signatureData.copy(v = signatureData.v + (chainId.value shl 1) + BigInteger(8)) } /** @@ -36,11 +35,12 @@ fun Transaction.signViaEIP155(key: ECKeyPair, chainId: ChainId): SignatureData { * @return ChainID or null when not EIP155 signed * */ -fun SignatureData.extractChainID() = if (v < BigInteger.valueOf(37)) { // not EIP 155 signed +fun SignatureData.extractChainID() = if (v < BigInteger(37)) { // not EIP 155 signed null } else { - (v - valueOf(35)).shr(1) + (v - BigInteger(35)).shr(1) } fun Transaction.extractFrom(eip155signatureData: SignatureData, chainId: ChainId) = - signedMessageToKey(encodeRLP(SignatureData(ZERO, ZERO, chainId.value)), eip155signatureData.copy(v = (eip155signatureData.v - valueOf(8) - (chainId.value * valueOf(2))))).toAddress() + signedMessageToKey(encodeRLP(SignatureData(ZERO, ZERO, chainId.value)), + eip155signatureData.copy(v = (eip155signatureData.v - BigInteger(8) - (chainId.value * BigInteger(2))))).toAddress() diff --git a/eip155/src/test/kotlin/org/kethereum/eip155/TheEIP155.kt b/eip155/src/test/kotlin/org/kethereum/eip155/TheEIP155.kt index c5c39f3e..f362baf3 100644 --- a/eip155/src/test/kotlin/org/kethereum/eip155/TheEIP155.kt +++ b/eip155/src/test/kotlin/org/kethereum/eip155/TheEIP155.kt @@ -1,5 +1,6 @@ package org.kethereum.eip155 +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.crypto.toECKeyPair @@ -12,7 +13,6 @@ import org.kethereum.rlp.decodeRLP import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.extensions.toHexString import org.komputing.khex.model.HexString -import java.math.BigInteger val privateKey = PrivateKey(HexString("4646464646464646464646464646464646464646464646464646464646464646")) @@ -22,21 +22,21 @@ class TheEIP155 { @Test fun canExtractChainIDs() { - assertThat(SignatureData().copy(v = BigInteger.valueOf(37)).extractChainID()).isEqualTo(1) - assertThat(SignatureData().copy(v = BigInteger.valueOf(38)).extractChainID()).isEqualTo(1) - assertThat(SignatureData().copy(v = BigInteger.valueOf(39)).extractChainID()).isEqualTo(2) - assertThat(SignatureData().copy(v = BigInteger.valueOf(40)).extractChainID()).isEqualTo(2) + assertThat(SignatureData().copy(v = BigInteger(37)).extractChainID()).isEqualTo(1) + assertThat(SignatureData().copy(v = BigInteger(38)).extractChainID()).isEqualTo(1) + assertThat(SignatureData().copy(v = BigInteger(39)).extractChainID()).isEqualTo(2) + assertThat(SignatureData().copy(v = BigInteger(40)).extractChainID()).isEqualTo(2) } @Test fun signTransaction() { val transaction = Transaction().apply { - nonce = BigInteger.valueOf(9) - gasPrice = BigInteger.valueOf(20000000000L) - gasLimit = BigInteger.valueOf(21000) + nonce = BigInteger(9) + gasPrice = BigInteger(20000000000L) + gasLimit = BigInteger(21000) to = Address("0x3535353535353535353535353535353535353535") - value = BigInteger.valueOf(1000000000000000000L) + value = BigInteger(1000000000000000000L) } val signatureData = transaction.signViaEIP155(KEY_PAIR, ChainId(1)) @@ -56,7 +56,5 @@ class TheEIP155 { val sig = (hex.hexToByteArray().decodeRLP() as RLPList).toTransactionSignatureData() assertThat(tx.extractFrom(sig, ChainId(4))).isEqualTo(Address("8a681d2b7400d67966eef4f585b31a7458f96dba")) - - } } \ No newline at end of file diff --git a/erc1328/src/main/kotlin/org/kethereum/erc1328/ERC1328Parser.kt b/erc1328/src/main/kotlin/org/kethereum/erc1328/ERC1328Parser.kt index 08d39c78..7ef86a62 100644 --- a/erc1328/src/main/kotlin/org/kethereum/erc1328/ERC1328Parser.kt +++ b/erc1328/src/main/kotlin/org/kethereum/erc1328/ERC1328Parser.kt @@ -9,7 +9,7 @@ fun EthereumURI.toERC1328() = ERC1328().apply { valid = commonURI.valid && commonURI.prefix == ERC1328_SCHEMA && commonURI.scheme == "ethereum" - version = commonURI.chainId?.value?.toLong() ?: 1L + version = commonURI.chainId?.value?.longValue() ?: 1L topic = commonURI.address val queryAsMap = commonURI.query.toMap() diff --git a/erc67/src/main/kotlin/org/kethereum/erc67/ERC67.kt b/erc67/src/main/kotlin/org/kethereum/erc67/ERC67.kt index 5a6d8115..da7e81dc 100644 --- a/erc67/src/main/kotlin/org/kethereum/erc67/ERC67.kt +++ b/erc67/src/main/kotlin/org/kethereum/erc67/ERC67.kt @@ -1,15 +1,15 @@ package org.kethereum.erc67 +import com.ionspin.kotlin.bignum.decimal.BigDecimal +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.ETH_IN_WEI import org.kethereum.model.Address -import java.math.BigDecimal -import java.math.BigInteger // https://github.com/ethereum/EIPs/issues/67 fun Address.toERC67String() = "ethereum:$hex" fun Address.toERC67String(valueInWei: BigInteger) = "ethereum:$hex?value=$valueInWei" -fun Address.toERC67String(valueInEther: BigDecimal) = toERC67String((valueInEther * BigDecimal(ETH_IN_WEI)).toBigInteger()) +fun Address.toERC67String(valueInEther: BigDecimal) = toERC67String((valueInEther * BigDecimal.fromBigInteger(ETH_IN_WEI)).toBigInteger()) fun String.isERC67String() = startsWith("ethereum:") diff --git a/erc67/src/test/kotlin/org/kethereum/erc67/TheERC67.kt b/erc67/src/test/kotlin/org/kethereum/erc67/TheERC67.kt index f0f530f0..2a344053 100644 --- a/erc67/src/test/kotlin/org/kethereum/erc67/TheERC67.kt +++ b/erc67/src/test/kotlin/org/kethereum/erc67/TheERC67.kt @@ -1,10 +1,10 @@ package org.kethereum.erc67 +import com.ionspin.kotlin.bignum.decimal.BigDecimal +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.model.Address -import java.math.BigDecimal -import java.math.BigInteger class TheERC67 { @@ -15,10 +15,10 @@ class TheERC67 { @Test fun toERC67WithValueWorks() { - assertThat(Address("0x00AB42").toERC67String(valueInWei = BigInteger("1"))).isEqualTo("ethereum:0x00AB42?value=1") - assertThat(Address("0x00AB42").toERC67String(valueInWei = BigInteger("2"))).isEqualTo("ethereum:0x00AB42?value=2") + assertThat(Address("0x00AB42").toERC67String(valueInWei = BigInteger.parseString("1"))).isEqualTo("ethereum:0x00AB42?value=1") + assertThat(Address("0x00AB42").toERC67String(valueInWei = BigInteger.parseString("2"))).isEqualTo("ethereum:0x00AB42?value=2") - assertThat(Address("0x00AB42").toERC67String(valueInEther = BigDecimal("0.42"))).isEqualTo("ethereum:0x00AB42?value=420000000000000000") + assertThat(Address("0x00AB42").toERC67String(valueInEther = BigDecimal.parseString("0.42"))).isEqualTo("ethereum:0x00AB42?value=420000000000000000") } @Test @@ -38,7 +38,7 @@ class TheERC67 { assertThat(ERC67("ethereum:0x00AB42?value=1").value).isEqualTo("1") (0..10).forEach { - val probe = ERC67(Address("0xAABB").toERC67String(valueInWei = BigInteger.valueOf(it.toLong()))) + val probe = ERC67(Address("0xAABB").toERC67String(valueInWei = BigInteger(it.toLong()))) assertThat(probe.value).isEqualTo(it.toString()) } } diff --git a/erc681/src/main/kotlin/org/kethereum/erc681/ERC681.kt b/erc681/src/main/kotlin/org/kethereum/erc681/ERC681.kt index 969245ab..b22f1bac 100644 --- a/erc681/src/main/kotlin/org/kethereum/erc681/ERC681.kt +++ b/erc681/src/main/kotlin/org/kethereum/erc681/ERC681.kt @@ -1,8 +1,8 @@ package org.kethereum.erc681 +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.ChainId import org.kethereum.model.EthereumFunctionCall -import java.math.BigInteger data class ERC681( var valid: Boolean = true, diff --git a/erc681/src/main/kotlin/org/kethereum/erc681/ERC681Parser.kt b/erc681/src/main/kotlin/org/kethereum/erc681/ERC681Parser.kt index eb6a9c35..c2366817 100644 --- a/erc681/src/main/kotlin/org/kethereum/erc681/ERC681Parser.kt +++ b/erc681/src/main/kotlin/org/kethereum/erc681/ERC681Parser.kt @@ -1,11 +1,11 @@ package org.kethereum.erc681 +import com.ionspin.kotlin.bignum.decimal.BigDecimal +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.erc831.ERC831 import org.kethereum.model.EthereumURI import org.kethereum.uri.common.CommonEthereumURIData import org.kethereum.uri.common.parseCommonURI -import java.math.BigDecimal -import java.math.BigInteger private val scientificNumberRegEx = Regex("^[0-9]+(\\.[0-9]+)?(e[0-9]+)?$") @@ -36,13 +36,13 @@ fun CommonEthereumURIData.toERC681() = let { commonURI -> return when { contains("e") -> { val split = split("e") - BigDecimal(split.first()).multiply(BigDecimal.TEN.pow(split[1].toIntOrNull() ?: 1)).toBigInteger() + BigDecimal.parseString(split.first()).multiply(BigDecimal.TEN.pow(split[1].toIntOrNull() ?: 1)).toBigInteger() } contains(".") -> { valid = false null } - else -> BigInteger(this) + else -> BigInteger.parseString(this) } } diff --git a/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Generator.kt b/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Generator.kt index 120b1d50..d5b45c1d 100644 --- a/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Generator.kt +++ b/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Generator.kt @@ -1,9 +1,9 @@ package org.kethereum.erc681 +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.model.ChainId -import java.math.BigInteger class TheERC681Generator { @@ -14,8 +14,8 @@ class TheERC681Generator { @Test fun toERC681WithValueWorks() { - assertThat(ERC681(address = "0x00AB42", value = BigInteger("1")).generateURL()).isEqualTo("ethereum:0x00AB42?value=1") - assertThat(ERC681(address = "0x00AB42", value = BigInteger("2")).generateURL()).isEqualTo("ethereum:0x00AB42?value=2") + assertThat(ERC681(address = "0x00AB42", value = BigInteger.parseString("1")).generateURL()).isEqualTo("ethereum:0x00AB42?value=1") + assertThat(ERC681(address = "0x00AB42", value = BigInteger.parseString("2")).generateURL()).isEqualTo("ethereum:0x00AB42?value=2") } @Test @@ -44,7 +44,7 @@ class TheERC681Generator { @Test fun toERC681Full() { - val highUsageERC681 = ERC681(address = "0x00AB42", prefix = "prefixFTW", chainId = ChainId(42), function = "funfun", value = BigInteger("100"), gasLimit = BigInteger("5"), + val highUsageERC681 = ERC681(address = "0x00AB42", prefix = "prefixFTW", chainId = ChainId(42), function = "funfun", value = BigInteger.parseString("100"), gasLimit = BigInteger.parseString("5"), functionParams = listOf("uint256" to "0", "address" to "0x0")) assertThat(highUsageERC681.generateURL()).isEqualTo("ethereum:prefixFTW-0x00AB42@42/funfun?uint256=0&address=0x0&gas=5&value=100") assertThat(highUsageERC681.copy(prefix = null).generateURL()).isEqualTo("ethereum:0x00AB42@42/funfun?uint256=0&address=0x0&gas=5&value=100") diff --git a/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Parsing.kt b/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Parsing.kt index f33d3ad3..f20741cd 100644 --- a/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Parsing.kt +++ b/erc681/src/test/kotlin/org/kethereum/erc681/TheERC681Parsing.kt @@ -1,10 +1,10 @@ package org.kethereum.erc681 +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.model.ChainId -import java.math.BigInteger class TheERC681Parsing { @@ -53,17 +53,17 @@ class TheERC681Parsing { @Test fun weCanParseScientificNotationForValue() { - Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?value=42e18").value).isEqualTo(BigInteger("42000000000000000000")) + Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?value=42e18").value).isEqualTo(BigInteger.parseString("42000000000000000000")) } @Test fun weCanParseScientificNotationWithDecimalsForValue() { - Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?value=42.123e18").value).isEqualTo(BigInteger("42123000000000000000")) + Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?value=42.123e18").value).isEqualTo(BigInteger.parseString("42123000000000000000")) } @Test fun weCanParseScientificNotationForGas() { - Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?gas=42e1").gasLimit).isEqualTo(BigInteger("420")) + Assertions.assertThat(parseERC681("ethereum:0x00AB42@23?gas=42e1").gasLimit).isEqualTo(BigInteger.parseString("420")) } @Test @@ -111,31 +111,31 @@ class TheERC681Parsing { Assertions.assertThat(parseERC681("ethereum:0x00AB42").value).isNull() Assertions.assertThat(parseERC681("ethereum:0x00AB42?value=1").valid).isEqualTo(true) - Assertions.assertThat(parseERC681("ethereum:0x00AB42?value=1").value).isEqualTo("1") + Assertions.assertThat(parseERC681("ethereum:0x00AB42?value=1").value).isEqualTo(BigInteger.ONE) (0..10).forEach { - val erC681 = ERC681(address = "0xAABB", value = BigInteger.valueOf(it.toLong())) + val erC681 = ERC681(address = "0xAABB", value = BigInteger(it.toLong())) val probe = parseERC681(erC681.generateURL()) - Assertions.assertThat(probe.value).isEqualTo(it.toString()) + Assertions.assertThat(probe.value).isEqualTo(BigInteger(it)) } } @Test fun parsingERC681WithGasValueWorks() { - Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=2").gasLimit).isEqualTo("2") - Assertions.assertThat(parseERC681("ethereum:0x00AB42?gasLimit=4").gasLimit).isEqualTo("4") - Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=42&value=3").gasLimit).isEqualTo("42") - Assertions.assertThat(parseERC681("ethereum:0x00AB42?value=1&gas=2").value).isEqualTo("1") - Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=2&value=1").gasLimit).isEqualTo("2") + Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=2").gasLimit).isEqualTo(BigInteger(2)) + Assertions.assertThat(parseERC681("ethereum:0x00AB42?gasLimit=4").gasLimit).isEqualTo(BigInteger(4)) + Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=42&value=3").gasLimit).isEqualTo(BigInteger(42)) + Assertions.assertThat(parseERC681("ethereum:0x00AB42?value=1&gas=2").value).isEqualTo(BigInteger.ONE) + Assertions.assertThat(parseERC681("ethereum:0x00AB42?gas=2&value=1").gasLimit).isEqualTo(BigInteger(2)) Assertions.assertThat(parseERC681("ethereum:0x00AB42?gasLimit=4").gasPrice).isNull() - Assertions.assertThat(parseERC681("ethereum:0x00AB42?gasPrice=42").gasPrice).isEqualTo("42") + Assertions.assertThat(parseERC681("ethereum:0x00AB42?gasPrice=42").gasPrice).isEqualTo(BigInteger(42)) } @Test fun canParseFullyFeaturedERC681URL() { Assertions.assertThat(parseERC681("ethereum:pay-0x00AB42@23?value=42&gas=3").prefix).isEqualTo("pay") - Assertions.assertThat(parseERC681("ethereum:pay-0x00AB42@23?value=42&gas=3").value).isEqualTo("42") - Assertions.assertThat(parseERC681("ethereum:pay-0x00AB42@23?value=42&gas=3").gasLimit).isEqualTo("3") + Assertions.assertThat(parseERC681("ethereum:pay-0x00AB42@23?value=42&gas=3").value).isEqualTo(BigInteger(42)) + Assertions.assertThat(parseERC681("ethereum:pay-0x00AB42@23?value=42&gas=3").gasLimit).isEqualTo(BigInteger(3)) } @Test diff --git a/etherscan/src/main/kotlin/org/walleth/kethereum/etherscan/EtherScan.kt b/etherscan/src/main/kotlin/org/walleth/kethereum/etherscan/EtherScan.kt index 40f3fa3c..c097e38f 100644 --- a/etherscan/src/main/kotlin/org/walleth/kethereum/etherscan/EtherScan.kt +++ b/etherscan/src/main/kotlin/org/walleth/kethereum/etherscan/EtherScan.kt @@ -1,15 +1,15 @@ package org.walleth.kethereum.etherscan +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.ChainId -import java.math.BigInteger private val ETHERSCAN_PREFIX_MAP = mapOf( - BigInteger.valueOf(1L) to "", - BigInteger.valueOf(3L) to "ropsten", - BigInteger.valueOf(4L) to "rinkeby", - BigInteger.valueOf(5L) to "goerli", - BigInteger.valueOf(42L) to "kovan" + BigInteger(1L) to "", + BigInteger(3L) to "ropsten", + BigInteger(4L) to "rinkeby", + BigInteger(5L) to "goerli", + BigInteger(42L) to "kovan" ) val ALL_ETHERSCAN_SUPPORTED_NETWORKS = ETHERSCAN_PREFIX_MAP.map { it.key }.toSet() diff --git a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt index abe3b1b0..1d881b9d 100644 --- a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt +++ b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt @@ -1,9 +1,10 @@ package org.kethereum.extensions +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import org.komputing.khex.extensions.clean0xPrefix import org.komputing.khex.extensions.has0xPrefix import org.komputing.khex.model.HexString -import java.math.BigInteger fun BigInteger.toBytesPadded(length: Int): ByteArray { val result = ByteArray(length) @@ -44,14 +45,14 @@ fun BigInteger.toHexStringZeroPadded(size: Int, withPrefix: Boolean = true): Str } } -fun HexString.hexToBigInteger() = BigInteger(clean0xPrefix().string, 16) +fun HexString.hexToBigInteger() = BigInteger.parseString(clean0xPrefix().string, 16) fun HexString.maybeHexToBigInteger() = if (has0xPrefix()) { - BigInteger(clean0xPrefix().string, 16) + BigInteger.parseString(clean0xPrefix().string, 16) } else { - BigInteger(string) + BigInteger.parseString(string) } -fun ByteArray.toBigInteger(offset: Int, length: Int) = BigInteger(1, copyOfRange(offset, offset + length)) -fun ByteArray.toBigInteger() = BigInteger(1, this) +fun ByteArray.toBigInteger(offset: Int, length: Int) = BigInteger.fromByteArray(copyOfRange(offset, offset + length), Sign.POSITIVE) +fun ByteArray.toBigInteger() = BigInteger.fromByteArray(this, Sign.POSITIVE) diff --git a/extensions_kotlin/src/test/kotlin/org/kethereum/extensions/TheBigIntegerExtensions.kt b/extensions_kotlin/src/test/kotlin/org/kethereum/extensions/TheBigIntegerExtensions.kt index 5a8f9221..ee123636 100644 --- a/extensions_kotlin/src/test/kotlin/org/kethereum/extensions/TheBigIntegerExtensions.kt +++ b/extensions_kotlin/src/test/kotlin/org/kethereum/extensions/TheBigIntegerExtensions.kt @@ -1,17 +1,19 @@ package org.kethereum.extensions +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.TEN import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test import org.komputing.khex.model.HexString -import java.math.BigInteger -import java.math.BigInteger.* class TheBigIntegerExtensions { @Test fun paddingWorks() { - assertThat(BigInteger("5").toBytesPadded(42).size).isEqualTo(42) + assertThat(BigInteger.parseString("5").toBytesPadded(42).size).isEqualTo(42) } @Test diff --git a/extensions_transactions/src/main/kotlin/org/kethereum/extensions/transactions/TransactionFun.kt b/extensions_transactions/src/main/kotlin/org/kethereum/extensions/transactions/TransactionFun.kt index 73754590..76978633 100644 --- a/extensions_transactions/src/main/kotlin/org/kethereum/extensions/transactions/TransactionFun.kt +++ b/extensions_transactions/src/main/kotlin/org/kethereum/extensions/transactions/TransactionFun.kt @@ -1,19 +1,19 @@ package org.kethereum.extensions.transactions +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.extensions.startsWith import org.kethereum.keccakshortcut.keccak import org.kethereum.model.Address import org.kethereum.model.Transaction import org.komputing.khex.extensions.toHexString import org.komputing.khex.extensions.toNoPrefixHexString -import java.math.BigInteger fun Transaction.calculateHash() = encodeRLP().keccak() val tokenTransferSignature = listOf(0xa9.toByte(), 0x05.toByte(), 0x9c.toByte(), 0xbb.toByte()) fun Transaction.isTokenTransfer() = input.toList().startsWith(tokenTransferSignature) -fun Transaction.getTokenTransferValue() = BigInteger(input.toList().subList(input.size - 32, input.size).toNoPrefixHexString(), 16) +fun Transaction.getTokenTransferValue() = BigInteger.parseString(input.toList().subList(input.size - 32, input.size).toNoPrefixHexString(), 16) fun Transaction.getTokenTransferTo() = Address(input.toList().subList(input.size - 32 - 20, input.size - 32).toHexString()) val tokenMintSignature = listOf(0x40.toByte(), 0xc1.toByte(), 0x0f.toByte(), 0x19.toByte()) diff --git a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionDecoder.kt b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionDecoder.kt index d967482d..27bd6b8a 100644 --- a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionDecoder.kt +++ b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionDecoder.kt @@ -2,6 +2,7 @@ package org.kethereum.extensions.transactions import com.beust.klaxon.JsonObject import com.beust.klaxon.Klaxon +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.rlp.RLPList @@ -10,9 +11,8 @@ import org.kethereum.model.Address import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString import transactionTestData -import java.math.BigInteger -private fun Any?.getBigInteger() = BigInteger((this as String).replace("0x", ""), 16) +private fun Any?.getBigInteger() = BigInteger.parseString((this as String).replace("0x", ""), 16) class TheTransactionDecoder { diff --git a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionEncoder.kt b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionEncoder.kt index bb688e61..a33ed24e 100644 --- a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionEncoder.kt +++ b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionEncoder.kt @@ -2,6 +2,7 @@ package org.kethereum.extensions.transactions import com.beust.klaxon.JsonObject import com.beust.klaxon.Klaxon +import com.ionspin.kotlin.bignum.integer.BigInteger import org.junit.jupiter.api.Test import org.kethereum.model.Address import org.kethereum.model.SignatureData @@ -10,7 +11,6 @@ import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.extensions.toHexString import org.komputing.khex.model.HexString import transactionTestData -import java.math.BigInteger class TheTransactionEncoder { @@ -46,5 +46,5 @@ class TheTransactionEncoder { } } - private fun Any?.getBigInteger() = BigInteger((this as String).replace("0x", ""), 16) + private fun Any?.getBigInteger() = BigInteger.parseString((this as String).replace("0x", ""), 16) } diff --git a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionFun.kt b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionFun.kt index 15c02fdc..5436e656 100644 --- a/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionFun.kt +++ b/extensions_transactions/src/test/kotlin/org/kethereum/extensions/transactions/TheTransactionFun.kt @@ -1,12 +1,12 @@ package org.kethereum.extensions.transactions +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.model.Address import org.kethereum.model.createEmptyTransaction import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString -import java.math.BigInteger class TheTransactionFun { @@ -14,7 +14,7 @@ class TheTransactionFun { @Test fun weCanParseTokenTransferValue() { - assertThat(createTokenTransferTransactionInput.getTokenTransferValue()).isEqualTo(BigInteger("420"+"0".repeat(18))) + assertThat(createTokenTransferTransactionInput.getTokenTransferValue()).isEqualTo(BigInteger.parseString("420"+"0".repeat(18))) } @Test diff --git a/flows/src/main/kotlin/org/kethereum/flows/BlockFlow.kt b/flows/src/main/kotlin/org/kethereum/flows/BlockFlow.kt index 2406804c..1a0cfca8 100644 --- a/flows/src/main/kotlin/org/kethereum/flows/BlockFlow.kt +++ b/flows/src/main/kotlin/org/kethereum/flows/BlockFlow.kt @@ -1,10 +1,10 @@ package org.kethereum.flows +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flow import org.kethereum.rpc.EthereumRPC -import java.math.BigInteger -import java.math.BigInteger.ONE fun getBlockFlow(rpc: EthereumRPC, delay_between_fetches: Long = 4200) = flow { var lastBlock: BigInteger? = null diff --git a/metadata/src/test/kotlin/org/kethereum/abi/TheUserdocResolver.kt b/metadata/src/test/kotlin/org/kethereum/abi/TheUserdocResolver.kt index 94fba592..1e9b120b 100644 --- a/metadata/src/test/kotlin/org/kethereum/abi/TheUserdocResolver.kt +++ b/metadata/src/test/kotlin/org/kethereum/abi/TheUserdocResolver.kt @@ -1,5 +1,6 @@ package org.kethereum.abi +import com.ionspin.kotlin.bignum.integer.BigInteger import kotlinx.coroutines.runBlocking import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -20,7 +21,6 @@ import org.kethereum.model.EthereumURI import org.kethereum.model.createEmptyTransaction import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString -import java.math.BigInteger class TheUserdocResolver { diff --git a/metadata_repo/src/test/kotlin/org/kethereum/abi/TheMetaDataRepo.kt b/metadata_repo/src/test/kotlin/org/kethereum/abi/TheMetaDataRepo.kt index a980869e..db852f16 100644 --- a/metadata_repo/src/test/kotlin/org/kethereum/abi/TheMetaDataRepo.kt +++ b/metadata_repo/src/test/kotlin/org/kethereum/abi/TheMetaDataRepo.kt @@ -1,5 +1,6 @@ package org.kethereum.abi +import com.ionspin.kotlin.bignum.integer.BigInteger import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.assertj.core.api.Assertions.assertThat @@ -13,7 +14,6 @@ import org.kethereum.metadata.repo.model.getMetaDataForTransaction import org.kethereum.model.ChainId import org.kethereum.model.createEmptyTransaction import java.io.File -import java.math.BigInteger.valueOf class TheMetaDataRepo { @@ -100,7 +100,7 @@ class TheMetaDataRepo { val tested = MetaDataRepoHttpWithCacheImpl(repoURL = mockWebServer.url("").toString()) mockWebServer.enqueue(MockResponse().setBody(testMetaDataJSON)) - val tx = createEmptyTransaction().copy(to = TEST_ADDRESSES.first(), chain = valueOf(5L)) + val tx = createEmptyTransaction().copy(to = TEST_ADDRESSES.first(), chain = BigInteger(5L)) assertThat(tested.getMetaDataForTransaction(tx)).isInstanceOf(MetaDataResolveResultOK::class.java) } diff --git a/method_signatures/src/test/kotlin/org/kethereum/methodsignatures/TheSignatureFun.kt b/method_signatures/src/test/kotlin/org/kethereum/methodsignatures/TheSignatureFun.kt index 6c56e11f..18ad3786 100644 --- a/method_signatures/src/test/kotlin/org/kethereum/methodsignatures/TheSignatureFun.kt +++ b/method_signatures/src/test/kotlin/org/kethereum/methodsignatures/TheSignatureFun.kt @@ -1,5 +1,6 @@ package org.kethereum.methodsignatures +import com.ionspin.kotlin.bignum.integer.BigInteger import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.crypto.test_data.TEST_ADDRESSES @@ -7,7 +8,6 @@ import org.kethereum.methodsignatures.model.TextMethodSignature import org.kethereum.model.createTransactionWithDefaults import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString -import java.math.BigInteger class TheSignatureFun { diff --git a/model/src/main/kotlin/org/kethereum/Values.kt b/model/src/main/kotlin/org/kethereum/Values.kt index 952d40a6..03c626ac 100644 --- a/model/src/main/kotlin/org/kethereum/Values.kt +++ b/model/src/main/kotlin/org/kethereum/Values.kt @@ -1,10 +1,11 @@ package org.kethereum -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger -val ETH_IN_WEI = BigInteger("1000000000000000000") -var DEFAULT_GAS_PRICE = BigInteger("20000000000") -var DEFAULT_GAS_LIMIT = BigInteger("21000") +val ETH_IN_WEI = BigInteger.parseString("1000000000000000000") + +var DEFAULT_GAS_PRICE = BigInteger.parseString("20000000000") +var DEFAULT_GAS_LIMIT = BigInteger.parseString("21000") const val DEFAULT_ETHEREUM_BIP44_PATH = "m/44'/60'/0'/0/0" \ No newline at end of file diff --git a/model/src/main/kotlin/org/kethereum/model/ChainId.kt b/model/src/main/kotlin/org/kethereum/model/ChainId.kt index 9aa3eb8e..dee72a0d 100644 --- a/model/src/main/kotlin/org/kethereum/model/ChainId.kt +++ b/model/src/main/kotlin/org/kethereum/model/ChainId.kt @@ -1,7 +1,7 @@ package org.kethereum.model -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger inline class ChainId(val value: BigInteger) { - constructor(longValue: Long) : this(BigInteger.valueOf(longValue)) + constructor(longValue: Long) : this(BigInteger(longValue)) } diff --git a/model/src/main/kotlin/org/kethereum/model/Constants.kt b/model/src/main/kotlin/org/kethereum/model/Constants.kt index 43713d14..35aad554 100644 --- a/model/src/main/kotlin/org/kethereum/model/Constants.kt +++ b/model/src/main/kotlin/org/kethereum/model/Constants.kt @@ -4,4 +4,4 @@ const val PRIVATE_KEY_SIZE = 32 const val PUBLIC_KEY_SIZE = 64 const val ADDRESS_LENGTH_IN_HEX = 40 -const val PUBLIC_KEY_LENGTH_IN_HEX = PUBLIC_KEY_SIZE shl 1 +const val PUBLIC_KEY_LENGTH_IN_HEX: Int = PUBLIC_KEY_SIZE shl 1 diff --git a/model/src/main/kotlin/org/kethereum/model/ECKeyPair.kt b/model/src/main/kotlin/org/kethereum/model/ECKeyPair.kt index 333044dd..d3fb78c0 100644 --- a/model/src/main/kotlin/org/kethereum/model/ECKeyPair.kt +++ b/model/src/main/kotlin/org/kethereum/model/ECKeyPair.kt @@ -1,9 +1,9 @@ package org.kethereum.model +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.extensions.hexToBigInteger import org.kethereum.extensions.toBigInteger import org.komputing.khex.model.HexString -import java.math.BigInteger inline class PrivateKey(val key: BigInteger) { constructor(privateKey: ByteArray) : this(privateKey.toBigInteger()) diff --git a/model/src/main/kotlin/org/kethereum/model/SignatureData.kt b/model/src/main/kotlin/org/kethereum/model/SignatureData.kt index e077be1a..3cd22822 100644 --- a/model/src/main/kotlin/org/kethereum/model/SignatureData.kt +++ b/model/src/main/kotlin/org/kethereum/model/SignatureData.kt @@ -1,7 +1,7 @@ package org.kethereum.model -import java.math.BigInteger -import java.math.BigInteger.ZERO +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO data class SignatureData(var r: BigInteger = ZERO, var s: BigInteger = ZERO, diff --git a/model/src/main/kotlin/org/kethereum/model/Transaction.kt b/model/src/main/kotlin/org/kethereum/model/Transaction.kt index d645b9f2..0faac29a 100644 --- a/model/src/main/kotlin/org/kethereum/model/Transaction.kt +++ b/model/src/main/kotlin/org/kethereum/model/Transaction.kt @@ -1,8 +1,8 @@ package org.kethereum.model +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.DEFAULT_GAS_LIMIT import org.kethereum.DEFAULT_GAS_PRICE -import java.math.BigInteger data class Transaction( var chain: BigInteger?, diff --git a/rlp/src/main/kotlin/org/kethereum/rlp/RLPDecoder.kt b/rlp/src/main/kotlin/org/kethereum/rlp/RLPDecoder.kt index 0c29d78d..b4639d17 100644 --- a/rlp/src/main/kotlin/org/kethereum/rlp/RLPDecoder.kt +++ b/rlp/src/main/kotlin/org/kethereum/rlp/RLPDecoder.kt @@ -1,6 +1,7 @@ package org.kethereum.rlp -import java.math.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign /** RLP as of Appendix B. Recursive Length Prefix at https://github.com/ethereum/yellowpaper @@ -44,6 +45,6 @@ private fun ByteArray.getLengthAndOffset(firstByte: Int, offset: Int) = if (firs LengthAndOffset(firstByte, offset + 1) } else { val size = firstByte - 54 - val length = BigInteger(1, copyOfRange(offset + 1, offset + size)).toInt() + val length = BigInteger.fromByteArray(copyOfRange(offset + 1, offset + size), Sign.POSITIVE).intValue() LengthAndOffset(length, offset + size) } diff --git a/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt b/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt index 279aed30..e9090d33 100644 --- a/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt +++ b/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt @@ -1,9 +1,10 @@ package org.kethereum.rlp +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO +import com.ionspin.kotlin.bignum.integer.Sign import org.kethereum.extensions.removeLeadingZero import org.kethereum.extensions.toMinimalByteArray -import java.math.BigInteger -import java.math.BigInteger.ZERO /** RLP as of Appendix B. Recursive Length Prefix at https://github.com/ethereum/yellowpaper @@ -27,7 +28,7 @@ fun RLPElement.toIntFromRLP() = if (bytes.isEmpty()) { .reduce { acc, i -> acc + i } } -fun RLPElement.toUnsignedBigIntegerFromRLP(): BigInteger = if (bytes.isEmpty()) ZERO else BigInteger(1, bytes) +fun RLPElement.toUnsignedBigIntegerFromRLP(): BigInteger = if (bytes.isEmpty()) ZERO else BigInteger.fromByteArray(bytes, Sign.POSITIVE) fun RLPElement.toByteFromRLP(): Byte { require(bytes.size == 1) { "trying to convert RLP with != 1 byte to Byte" } return bytes.first() diff --git a/rlp/src/test/kotlin/org/kethereum/rlp/TheRLPTypeConverter.kt b/rlp/src/test/kotlin/org/kethereum/rlp/TheRLPTypeConverter.kt index a2f0f355..c8bd39ae 100644 --- a/rlp/src/test/kotlin/org/kethereum/rlp/TheRLPTypeConverter.kt +++ b/rlp/src/test/kotlin/org/kethereum/rlp/TheRLPTypeConverter.kt @@ -1,17 +1,19 @@ package org.kethereum.rlp +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.TEN +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import java.math.BigInteger -import java.math.BigInteger.* val bigIntegerTestVectors = arrayOf( ZERO, ONE, TEN, - BigInteger.valueOf(70_000), - BigInteger.valueOf(Long.MAX_VALUE), - BigInteger.valueOf(54408193066555392L) + BigInteger(70_000), + BigInteger(Long.MAX_VALUE), + BigInteger(54408193066555392L) ) val integerTestVectors = arrayOf( diff --git a/rpc/src/main/kotlin/org/kethereum/rpc/BaseEthereumRPC.kt b/rpc/src/main/kotlin/org/kethereum/rpc/BaseEthereumRPC.kt index 6415bc98..e79b24ad 100644 --- a/rpc/src/main/kotlin/org/kethereum/rpc/BaseEthereumRPC.kt +++ b/rpc/src/main/kotlin/org/kethereum/rpc/BaseEthereumRPC.kt @@ -1,5 +1,6 @@ package org.kethereum.rpc +import com.ionspin.kotlin.bignum.integer.BigInteger import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import org.kethereum.extensions.hexToBigInteger @@ -13,7 +14,6 @@ import org.kethereum.rpc.model.StringResultResponse import org.kethereum.rpc.model.TransactionResponse import org.komputing.khex.model.HexString import java.io.IOException -import java.math.BigInteger class EthereumRPCException(override val message: String, val code: Int) : IOException(message) diff --git a/rpc/src/main/kotlin/org/kethereum/rpc/EthereumRPC.kt b/rpc/src/main/kotlin/org/kethereum/rpc/EthereumRPC.kt index 3c6a2bf7..aa3e443d 100644 --- a/rpc/src/main/kotlin/org/kethereum/rpc/EthereumRPC.kt +++ b/rpc/src/main/kotlin/org/kethereum/rpc/EthereumRPC.kt @@ -1,12 +1,12 @@ package org.kethereum.rpc +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.Address import org.kethereum.model.ChainId import org.kethereum.model.SignedTransaction import org.kethereum.model.Transaction import org.kethereum.rpc.model.BlockInformation import org.komputing.khex.model.HexString -import java.math.BigInteger interface EthereumRPC { diff --git a/rpc/src/main/kotlin/org/kethereum/rpc/model/BigIntegerAdapter.kt b/rpc/src/main/kotlin/org/kethereum/rpc/model/BigIntegerAdapter.kt index 45ce3ce6..bd346c53 100644 --- a/rpc/src/main/kotlin/org/kethereum/rpc/model/BigIntegerAdapter.kt +++ b/rpc/src/main/kotlin/org/kethereum/rpc/model/BigIntegerAdapter.kt @@ -1,8 +1,8 @@ package org.kethereum.rpc.model +import com.ionspin.kotlin.bignum.integer.BigInteger import com.squareup.moshi.FromJson import com.squareup.moshi.ToJson -import java.math.BigInteger internal class BigIntegerAdapter { @@ -11,6 +11,6 @@ internal class BigIntegerAdapter { fun toJson(card: BigInteger) = card.toString() @FromJson - fun fromJson(card: String) = BigInteger(card) + fun fromJson(card: String) = BigInteger.parseString(card) } \ No newline at end of file diff --git a/rpc/src/main/kotlin/org/kethereum/rpc/model/BlockInformation.kt b/rpc/src/main/kotlin/org/kethereum/rpc/model/BlockInformation.kt index e2eaaa89..6a354cf8 100644 --- a/rpc/src/main/kotlin/org/kethereum/rpc/model/BlockInformation.kt +++ b/rpc/src/main/kotlin/org/kethereum/rpc/model/BlockInformation.kt @@ -1,8 +1,8 @@ package org.kethereum.rpc.model +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.SignedTransaction import org.komputing.khex.model.HexString -import java.math.BigInteger data class BlockInformation( val number: BigInteger, diff --git a/rpc/src/test/kotlin/org/kethereum/TheConverter.kt b/rpc/src/test/kotlin/org/kethereum/TheConverter.kt index 870c4177..ea1fa652 100644 --- a/rpc/src/test/kotlin/org/kethereum/TheConverter.kt +++ b/rpc/src/test/kotlin/org/kethereum/TheConverter.kt @@ -1,5 +1,6 @@ package org.kethereum +import com.ionspin.kotlin.bignum.integer.BigInteger import com.squareup.moshi.Moshi import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -7,7 +8,6 @@ import org.kethereum.model.Address import org.kethereum.rpc.model.rpc.TransactionRPC import org.kethereum.rpc.toKethereumTransaction import org.komputing.khex.extensions.toHexString -import java.math.BigInteger class TheConverter { private val transactionRPCAdapter = Moshi.Builder().build().adapter(TransactionRPC::class.java) @@ -20,13 +20,13 @@ class TheConverter { val tested = transactionRPC.toKethereumTransaction().transaction - assertThat(tested.value).isEqualTo(BigInteger("11")) + assertThat(tested.value).isEqualTo(BigInteger.parseString("11")) assertThat(tested.input.toHexString()).isEqualTo("0x82ab890a00000000000000000000000000000000000000000000000000000000000027c1") assertThat(tested.from).isEqualTo(Address("0x9e3d69305da51f34ee29bfb52721e3a824d59e69")) assertThat(tested.to).isEqualTo(Address("0xaca0cc3a6bf9552f2866ccc67801d4e6aa6a70f2")) - assertThat(tested.gasLimit).isEqualTo(BigInteger("3d0900",16)) - assertThat(tested.gasPrice).isEqualTo(BigInteger("4a817c800",16)) - assertThat(tested.nonce).isEqualTo(BigInteger("4327",16)) + assertThat(tested.gasLimit).isEqualTo(BigInteger.parseString("3d0900",16)) + assertThat(tested.gasPrice).isEqualTo(BigInteger.parseString("4a817c800",16)) + assertThat(tested.nonce).isEqualTo(BigInteger.parseString("4327",16)) assertThat(tested.txHash).isEqualTo("0xc7af6af264b8dcc49c321af3dd38f99a8c4afd3b9bab50d24c6d5d1b6dcc160c") } diff --git a/rpc/src/test/kotlin/org/kethereum/rpc/TheEthereumRPC.kt b/rpc/src/test/kotlin/org/kethereum/rpc/TheEthereumRPC.kt index 78b69879..498c48e4 100644 --- a/rpc/src/test/kotlin/org/kethereum/rpc/TheEthereumRPC.kt +++ b/rpc/src/test/kotlin/org/kethereum/rpc/TheEthereumRPC.kt @@ -1,5 +1,8 @@ package org.kethereum.rpc +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.TEN +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.assertj.core.api.Assertions.assertThat @@ -12,9 +15,6 @@ import org.kethereum.model.SignedTransaction import org.kethereum.rpc.model.BlockInformation import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString -import java.math.BigInteger -import java.math.BigInteger.TEN -import java.math.BigInteger.ZERO import kotlin.test.assertFails class TheEthereumRPC { @@ -174,7 +174,7 @@ class TheEthereumRPC { val blockByNumber: BlockInformation? = tested.getBlockByNumber(TEN) assertThat(blockByNumber).isNotNull - assertThat(blockByNumber?.number).isEqualTo(BigInteger.valueOf(170263L)) + assertThat(blockByNumber?.number).isEqualTo(BigInteger(170263L)) assertThat(blockByNumber?.difficulty).isEqualTo(HexString("0x6cea8018718").hexToBigInteger()) assertThat(blockByNumber?.extraData).isEqualTo(HexString("0xd783010100844765746887676f312e342e32856c696e7578")) @@ -206,7 +206,7 @@ class TheEthereumRPC { assertThat(firstTransaction.gasPrice).isEqualTo(HexString("0xd4fc47cf6").hexToBigInteger()) assertThat(firstTransaction.txHash).isEqualTo("0xceebdef59ab3cdde152672014b451f75bb7974b9dca4b30e545b6864d9ffca9d") assertThat(firstTransaction.input).isEqualTo(HexString("0x").hexToByteArray()) - assertThat(firstTransaction.nonce).isEqualTo(BigInteger.valueOf(16)) + assertThat(firstTransaction.nonce).isEqualTo(BigInteger(16)) assertThat(firstTransaction.to).isEqualTo(Address("0x32be343b94f860124dc4fee278fdcbd38c102d88")) assertThat(firstTransaction.value).isEqualTo(HexString("0x596c90f09f547400").hexToBigInteger()) diff --git a/rpc_min3/src/main/kotlin/org/kethereum/rpc/min3/MIN3.kt b/rpc_min3/src/main/kotlin/org/kethereum/rpc/min3/MIN3.kt index 470a07f4..f62a0bff 100644 --- a/rpc_min3/src/main/kotlin/org/kethereum/rpc/min3/MIN3.kt +++ b/rpc_min3/src/main/kotlin/org/kethereum/rpc/min3/MIN3.kt @@ -21,7 +21,7 @@ val GOERLI_BOOTNODES = listOf( "https://in3-v2.slock.it/goerli/nd-2" ) -fun getMin3BootnNdesByChainId(chainId: ChainId) = when (chainId.value.toLong()) { +fun getMin3BootnNdesByChainId(chainId: ChainId) = when (chainId.value.longValue()) { 1L -> MAINNET_BOOTNODES 5L -> GOERLI_BOOTNODES else -> null diff --git a/test_data/src/main/kotlin/org/kethereum/crypto/test_data/TestData.kt b/test_data/src/main/kotlin/org/kethereum/crypto/test_data/TestData.kt index b572078c..e488f9c9 100644 --- a/test_data/src/main/kotlin/org/kethereum/crypto/test_data/TestData.kt +++ b/test_data/src/main/kotlin/org/kethereum/crypto/test_data/TestData.kt @@ -1,12 +1,14 @@ package org.kethereum.crypto.test_data +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.TEN import org.kethereum.model.Address import org.kethereum.model.ECKeyPair import org.kethereum.model.PrivateKey import org.kethereum.model.PublicKey import org.komputing.khex.model.HexString -import java.math.BigInteger -import java.math.BigInteger.* /** @@ -36,26 +38,26 @@ val TEST_BIGINTEGERS_POSITIVE_ONLY = listOf( ZERO, ONE, TEN, - valueOf(42), - valueOf(420), - valueOf(Long.MAX_VALUE), - BigInteger("ff".repeat(32), 16) + BigInteger(42), + BigInteger(420), + BigInteger(Long.MAX_VALUE), + BigInteger.parseString("ff".repeat(32), 16) ) val TEST_BIGINTEGERS_INCL_NEGATIVE = listOf( ZERO, ONE, TEN, - valueOf(42), - valueOf(420), - valueOf(Long.MAX_VALUE), - BigInteger("ff".repeat(31), 16), + BigInteger(42), + BigInteger(420), + BigInteger(Long.MAX_VALUE), + BigInteger.parseString("ff".repeat(31), 16), -ONE, -TEN, - -valueOf(42), - -valueOf(420), - -valueOf(Long.MAX_VALUE), - -BigInteger("ff".repeat(31), 16) + -BigInteger(42), + -BigInteger(420), + -BigInteger(Long.MAX_VALUE), + -BigInteger.parseString("ff".repeat(31), 16) ) fun getABIString(name: String) : String { diff --git a/types/src/main/kotlin/org/kethereum/contract/abi/types/StringToTypeConverter.kt b/types/src/main/kotlin/org/kethereum/contract/abi/types/StringToTypeConverter.kt index c3ffc5fe..b90b383b 100644 --- a/types/src/main/kotlin/org/kethereum/contract/abi/types/StringToTypeConverter.kt +++ b/types/src/main/kotlin/org/kethereum/contract/abi/types/StringToTypeConverter.kt @@ -1,5 +1,6 @@ package org.kethereum.contract.abi.types +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.contract.abi.types.model.ContractABITypeDefinition import org.kethereum.contract.abi.types.model.ETHType import org.kethereum.contract.abi.types.model.TypeAliases @@ -7,7 +8,6 @@ import org.kethereum.contract.abi.types.model.type_params.BitsTypeParams import org.kethereum.contract.abi.types.model.type_params.BytesTypeParams import org.kethereum.contract.abi.types.model.types.* import org.kethereum.model.Address -import java.math.BigInteger fun convertStringToABIType(string: String) = convertStringToABITypeOrNull(string) ?: throw IllegalArgumentException("$string is not a supported type") diff --git a/types/src/main/kotlin/org/kethereum/contract/abi/types/TypeEncoder.kt b/types/src/main/kotlin/org/kethereum/contract/abi/types/TypeEncoder.kt index 437eb9b1..93caa7de 100644 --- a/types/src/main/kotlin/org/kethereum/contract/abi/types/TypeEncoder.kt +++ b/types/src/main/kotlin/org/kethereum/contract/abi/types/TypeEncoder.kt @@ -1,21 +1,21 @@ package org.kethereum.contract.abi.types +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.contract.abi.types.model.ETHType import org.kethereum.contract.abi.types.model.type_params.BitsTypeParams import org.kethereum.contract.abi.types.model.types.UIntETHType -import java.math.BigInteger fun encodeTypes(vararg types: ETHType<*>): ByteArray { val staticPart = mutableListOf() val dynamicPart = mutableListOf() - var dynamicPos = BigInteger.valueOf(types.size * 32L) + var dynamicPos = BigInteger(types.size * 32L) types.forEach { if (!it.isDynamic()) { staticPart.add(it.paddedValue) } else { staticPart.add(UIntETHType.ofNativeKotlinType(dynamicPos, BitsTypeParams(32)).paddedValue) dynamicPart.add(it.paddedValue) - dynamicPos += BigInteger.valueOf(32L * it.paddedValue.size) + dynamicPos += BigInteger(32L * it.paddedValue.size) } } var result = ByteArray(0) diff --git a/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/DynamicSizedBytesETHType.kt b/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/DynamicSizedBytesETHType.kt index c75e1319..be12cace 100644 --- a/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/DynamicSizedBytesETHType.kt +++ b/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/DynamicSizedBytesETHType.kt @@ -1,5 +1,6 @@ package org.kethereum.contract.abi.types.model.types +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.contract.abi.types.PaginatedByteArray import org.kethereum.contract.abi.types.model.ETHType import org.kethereum.contract.abi.types.model.ETH_TYPE_PAGESIZE @@ -13,21 +14,21 @@ class DynamicSizedBytesETHType(override val paddedValue: ByteArray) : ETHType { init { INT_BITS_CONSTRAINT(params.bits) - require(toKotlinType() < ONE.shiftLeft(params.bits-1)) { "value ${toKotlinType()} must fit in ${params.bits} bits" } - require(toKotlinType() > -ONE.shiftLeft(params.bits-1)) { "value ${toKotlinType()} must fit in $params.bits} bits" } + require(toKotlinType() < ONE shl (params.bits-1)) { "value ${toKotlinType()} must fit in ${params.bits} bits" } + require(toKotlinType() > -ONE shl (params.bits-1)) { "value ${toKotlinType()} must fit in $params.bits} bits" } } - override fun toKotlinType() = BigInteger(paddedValue) + override fun toKotlinType() = BigInteger.fromTwosComplementByteArray(paddedValue) override fun isDynamic() = false companion object { fun ofNativeKotlinType(input: BigInteger, params: BitsTypeParams) = - IntETHType(input.toByteArray().toFixedLengthByteArray(ETH_TYPE_PAGESIZE, if (input.signum() < 0) 0xFF.toByte() else 0), params) + IntETHType(input.toTwosComplementByteArray().toFixedLengthByteArray(ETH_TYPE_PAGESIZE, if (input.signum() < 0) 0xFF.toByte() else 0), params) - fun ofSting(string: String, params: BitsTypeParams) = ofNativeKotlinType(BigInteger(string), params) + fun ofSting(string: String, params: BitsTypeParams) = ofNativeKotlinType(BigInteger.parseString(string), params) fun ofPaginatedByteArray(input: PaginatedByteArray, params: BitsTypeParams) = input.nextPage()?.let { IntETHType(it, params) } } diff --git a/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/UIntETHType.kt b/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/UIntETHType.kt index 5173754b..0d424da5 100644 --- a/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/UIntETHType.kt +++ b/types/src/main/kotlin/org/kethereum/contract/abi/types/model/types/UIntETHType.kt @@ -1,5 +1,8 @@ package org.kethereum.contract.abi.types.model.types +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE +import com.ionspin.kotlin.bignum.integer.util.fromTwosComplementByteArray import org.kethereum.contract.abi.types.INT_BITS_CONSTRAINT import org.kethereum.contract.abi.types.PaginatedByteArray import org.kethereum.contract.abi.types.model.ETHType @@ -7,20 +10,18 @@ import org.kethereum.contract.abi.types.model.ETH_TYPE_PAGESIZE import org.kethereum.contract.abi.types.model.type_params.BitsTypeParams import org.kethereum.extensions.toBytesPadded import org.komputing.khex.extensions.toNoPrefixHexString -import java.math.BigInteger -import java.math.BigInteger.ONE class UIntETHType(override val paddedValue: ByteArray, params: BitsTypeParams) : ETHType { init { INT_BITS_CONSTRAINT(params.bits) - require(toKotlinType() < ONE.shiftLeft(params.bits)) { "value ${toKotlinType()} must fit in ${params.bits} bits" } + require(toKotlinType() < ONE shl (params.bits)) { "value ${toKotlinType()} must fit in ${params.bits} bits" } } override fun toKotlinType() = if (paddedValue.first() < 0) { - BigInteger(paddedValue.toNoPrefixHexString(), 16) + BigInteger.parseString(paddedValue.toNoPrefixHexString(), 16) } else { - BigInteger(paddedValue) + BigInteger.fromTwosComplementByteArray(paddedValue) } companion object { @@ -31,7 +32,7 @@ class UIntETHType(override val paddedValue: ByteArray, params: BitsTypeParams) : fun ofPaginatedByteArray(input: PaginatedByteArray, params: BitsTypeParams) = input.nextPage()?.let { UIntETHType(it, params) } - fun ofSting(string: String, params: BitsTypeParams) = ofNativeKotlinType(BigInteger(string), params) + fun ofSting(string: String, params: BitsTypeParams) = ofNativeKotlinType(BigInteger.parseString(string), params) } override fun isDynamic() = false diff --git a/types/src/test/kotlin/org/kethereum/contract/abi/types/TheDecoder.kt b/types/src/test/kotlin/org/kethereum/contract/abi/types/TheDecoder.kt index 5b01a46e..c5611b3c 100644 --- a/types/src/test/kotlin/org/kethereum/contract/abi/types/TheDecoder.kt +++ b/types/src/test/kotlin/org/kethereum/contract/abi/types/TheDecoder.kt @@ -1,5 +1,8 @@ package org.kethereum.contract.abi.types +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.kethereum.contract.abi.types.model.type_params.BitsTypeParams @@ -10,9 +13,6 @@ import org.kethereum.crypto.test_data.TEST_BIGINTEGERS_INCL_NEGATIVE import org.kethereum.crypto.test_data.TEST_BIGINTEGERS_POSITIVE_ONLY import org.komputing.khex.extensions.hexToByteArray import org.komputing.khex.model.HexString -import java.math.BigInteger -import java.math.BigInteger.ONE -import java.math.BigInteger.ZERO class TheDecoder { @@ -97,12 +97,12 @@ class TheDecoder { assertThat(IntETHType.ofPaginatedByteArray(input1, BitsTypeParams(8))?.toKotlinType()).isEqualTo(ONE) val input_1 = PaginatedByteArray(HexString("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) - assertThat(IntETHType.ofPaginatedByteArray(input_1, BitsTypeParams(8))?.toKotlinType()).isEqualTo(BigInteger.valueOf(-1)) + assertThat(IntETHType.ofPaginatedByteArray(input_1, BitsTypeParams(8))?.toKotlinType()).isEqualTo(BigInteger(-1)) val input127 = PaginatedByteArray(HexString("0x000000000000000000000000000000000000000000000000000000000000007f")) - assertThat(IntETHType.ofPaginatedByteArray(input127, BitsTypeParams(8))?.toKotlinType()).isEqualTo(BigInteger.valueOf(127)) + assertThat(IntETHType.ofPaginatedByteArray(input127, BitsTypeParams(8))?.toKotlinType()).isEqualTo(BigInteger(127)) val input_128 = PaginatedByteArray(HexString(("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80"))) - assertThat(IntETHType.ofPaginatedByteArray(input_128, BitsTypeParams(16))?.toKotlinType()).isEqualTo(BigInteger.valueOf(-128)) + assertThat(IntETHType.ofPaginatedByteArray(input_128, BitsTypeParams(16))?.toKotlinType()).isEqualTo(BigInteger(-128)) } } \ No newline at end of file diff --git a/types/src/test/kotlin/org/kethereum/contract/abi/types/TheUINTypeConstraints.kt b/types/src/test/kotlin/org/kethereum/contract/abi/types/TheUINTypeConstraints.kt index 12d4fb71..e9454c96 100644 --- a/types/src/test/kotlin/org/kethereum/contract/abi/types/TheUINTypeConstraints.kt +++ b/types/src/test/kotlin/org/kethereum/contract/abi/types/TheUINTypeConstraints.kt @@ -1,10 +1,10 @@ package org.kethereum.contract.abi.types +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ONE import org.junit.jupiter.api.Test import org.kethereum.contract.abi.types.model.type_params.BitsTypeParams import org.kethereum.contract.abi.types.model.types.UIntETHType -import java.math.BigInteger.ONE -import java.math.BigInteger.valueOf import kotlin.test.assertFailsWith class TheUINTypeConstraints { @@ -40,7 +40,7 @@ class TheUINTypeConstraints { fun whenItDoesNotFitItFails() { assertFailsWith(IllegalArgumentException::class) { - UIntETHType.ofNativeKotlinType(valueOf(256), BitsTypeParams(8)) + UIntETHType.ofNativeKotlinType(BigInteger(256), BitsTypeParams(8)) } } diff --git a/uri_common/src/main/kotlin/org/kethereum/uri/common/CommonURIParser.kt b/uri_common/src/main/kotlin/org/kethereum/uri/common/CommonURIParser.kt index 6a25ae55..4fe68871 100644 --- a/uri_common/src/main/kotlin/org/kethereum/uri/common/CommonURIParser.kt +++ b/uri_common/src/main/kotlin/org/kethereum/uri/common/CommonURIParser.kt @@ -1,11 +1,11 @@ package org.kethereum.uri.common +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.erc831.ERC831 import org.kethereum.erc831.toERC831 import org.kethereum.model.ChainId import org.kethereum.model.EthereumURI import org.kethereum.uri.common.ParseState.* -import java.math.BigInteger private enum class ParseState { ADDRESS, @@ -30,7 +30,7 @@ fun ERC831.parseCommonURI() = let { erc831 -> fun stateTransition(newState: ParseState) { when (currentState) { CHAIN -> chainId = try { - ChainId(BigInteger(currentSegment)) + ChainId(BigInteger.parseString(currentSegment)) } catch (e: NumberFormatException) { valid = false null From 3d887e282775c6d4ca1593ba862280d1ed4bea5b Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Fri, 12 Feb 2021 05:17:26 +0200 Subject: [PATCH 3/6] using version '0.2.8-SNAPSHOT' of 'com.ionspin.kotlin:bignum' with bug fixes --- build.gradle.kts | 3 +++ buildSrc/src/main/kotlin/Versions.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index c85a2cb4..f56e9312 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,6 +18,9 @@ buildscript { subprojects { repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } jcenter() maven("https://jitpack.io") maven("https://kotlin.bintray.com/kotlinx") diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 87b116d5..117bfc37 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -12,5 +12,5 @@ object Versions { const val threetenbp = "1.5.0" const val okio = "2.4.0" const val base58 = "0.2" - const val bignum = "0.2.7" + const val bignum = "0.2.8-SNAPSHOT" // TODO: use next stable release once available } \ No newline at end of file From 773df1f16d070b218cbdf4b8dd0fc5e2a76b9be8 Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Fri, 12 Feb 2021 05:20:47 +0200 Subject: [PATCH 4/6] kotlin's BigInteger::toByteArray requires removal of leading zero bytes --- .../src/main/kotlin/org/kethereum/extensions/BigInteger.kt | 2 ++ .../src/main/kotlin/org/kethereum/extensions/ByteArray.kt | 5 ++++- .../src/main/kotlin/org/kethereum/extensions/Int.kt | 7 +------ rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt index 1d881b9d..8ffa699f 100644 --- a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt +++ b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/BigInteger.kt @@ -21,6 +21,8 @@ fun BigInteger.toBytesPadded(length: Int): ByteArray { return result } +fun BigInteger.toMinimalByteArray() = toByteArray().removeLeadingZeros() + fun BigInteger.toHexStringNoPrefix(): String = toString(16) fun BigInteger.toHexString(): String = "0x" + toString(16) diff --git a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/ByteArray.kt b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/ByteArray.kt index 8f48390c..6ce52ed1 100644 --- a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/ByteArray.kt +++ b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/ByteArray.kt @@ -5,4 +5,7 @@ fun ByteArray.toFixedLengthByteArray(fixedSize: Int, fillByte: Byte = 0) = if (s } else { require(size < fixedSize) { "ByteArray too big - max size is $fixedSize but got $size" } ByteArray(fixedSize) { getOrNull(size - fixedSize + it) ?: fillByte } -} \ No newline at end of file +} + +fun ByteArray.removeLeadingZeros() = this.copyOfRange(this.minimalStart(), this.size) +private fun ByteArray.minimalStart() = indexOfFirst { it != 0.toByte() }.let { if (it == -1) size else it } diff --git a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/Int.kt b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/Int.kt index 15b72165..db30b40e 100644 --- a/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/Int.kt +++ b/extensions_kotlin/src/main/kotlin/org/kethereum/extensions/Int.kt @@ -4,9 +4,4 @@ fun Int.toByteArray() = ByteArray(4) { i -> shr(8 * (3 - i)).toByte() } -fun Int.toMinimalByteArray() = toByteArray().let { - it.copyOfRange(it.minimalStart(), 4) -} - -private fun ByteArray.minimalStart() = indexOfFirst { it != 0.toByte() }.let { if (it == -1) 4 else it } -fun ByteArray.removeLeadingZero() = if (first() == 0.toByte()) copyOfRange(1, size) else this \ No newline at end of file +fun Int.toMinimalByteArray() = toByteArray().removeLeadingZeros() \ No newline at end of file diff --git a/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt b/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt index e9090d33..91f9b012 100644 --- a/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt +++ b/rlp/src/main/kotlin/org/kethereum/rlp/RLPTypeConverter.kt @@ -3,7 +3,6 @@ package org.kethereum.rlp import com.ionspin.kotlin.bignum.integer.BigInteger import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO import com.ionspin.kotlin.bignum.integer.Sign -import org.kethereum.extensions.removeLeadingZero import org.kethereum.extensions.toMinimalByteArray /** @@ -15,7 +14,7 @@ RLP as of Appendix B. Recursive Length Prefix at https://github.com/ethereum/yel fun String.toRLP() = RLPElement(toByteArray()) fun Int.toRLP() = RLPElement(toMinimalByteArray()) -fun BigInteger.toRLP() = RLPElement(toByteArray().removeLeadingZero()) +fun BigInteger.toRLP() = RLPElement(toMinimalByteArray()) fun ByteArray.toRLP() = RLPElement(this) fun Byte.toRLP() = RLPElement(ByteArray(1) { this }) From 253c5fc7e1688afa9ac445f1286bc34c92b9a54a Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Sun, 14 Feb 2021 00:51:39 +0200 Subject: [PATCH 5/6] using an updated 'kethabi' - all tests pass --- build.gradle.kts | 12 ++++++++++-- buildSrc/src/main/kotlin/Versions.kt | 1 + ens/src/test/kotlin/EthereumRPCScaffold.kt | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f56e9312..971374aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,9 @@ apply { buildscript { repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } jcenter() maven("https://jitpack.io") } @@ -11,10 +14,15 @@ buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") classpath("com.github.ben-manes:gradle-versions-plugin:${Versions.versions_plugin}") - classpath("com.github.komputing:kethabi:0.1.8") + classpath("com.github.fullkomnun:kethabi:${Versions.kethabi_plugin}") { + isChanging = true + } } -} + configurations.all { + resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) + } +} subprojects { repositories { diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 117bfc37..ddf6b05e 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -1,6 +1,7 @@ object Versions { const val kotlin = "1.4.21" const val versions_plugin = "0.36.0" + const val kethabi_plugin = "use_multiplatform_big_numbers-SNAPSHOT" const val jupiter = "5.7.0" const val moshi = "1.8.0" const val khex = "1.0.0" diff --git a/ens/src/test/kotlin/EthereumRPCScaffold.kt b/ens/src/test/kotlin/EthereumRPCScaffold.kt index e784d8ed..75a626ca 100644 --- a/ens/src/test/kotlin/EthereumRPCScaffold.kt +++ b/ens/src/test/kotlin/EthereumRPCScaffold.kt @@ -1,3 +1,4 @@ +import com.ionspin.kotlin.bignum.integer.BigInteger import org.kethereum.model.Address import org.kethereum.model.ChainId import org.kethereum.model.SignedTransaction @@ -5,7 +6,6 @@ import org.kethereum.model.Transaction import org.kethereum.rpc.EthereumRPC import org.kethereum.rpc.model.BlockInformation import org.komputing.khex.model.HexString -import java.math.BigInteger open class EthereumRPCScaffold : EthereumRPC { override fun getBlockByNumber(number: BigInteger): BlockInformation? { From a3ea996e49dc5f6b85b0839ca9601e61b81ee099 Mon Sep 17 00:00:00 2001 From: Or Noyman Date: Mon, 15 Feb 2021 12:13:11 +0200 Subject: [PATCH 6/6] update com.ionspin.kotlin:bignum v0.2.8-SNAPSHOT -> v0.2.8 --- build.gradle.kts | 6 ------ buildSrc/src/main/kotlin/Versions.kt | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 971374aa..09635061 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,9 +4,6 @@ apply { buildscript { repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } jcenter() maven("https://jitpack.io") } @@ -26,9 +23,6 @@ buildscript { subprojects { repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } jcenter() maven("https://jitpack.io") maven("https://kotlin.bintray.com/kotlinx") diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index ddf6b05e..d511926c 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -13,5 +13,5 @@ object Versions { const val threetenbp = "1.5.0" const val okio = "2.4.0" const val base58 = "0.2" - const val bignum = "0.2.8-SNAPSHOT" // TODO: use next stable release once available + const val bignum = "0.2.8" } \ No newline at end of file