Skip to content
5 changes: 3 additions & 2 deletions bip32/src/main/kotlin/org/kethereum/bip32/BIP32.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.")
}
Expand Down
7 changes: 4 additions & 3 deletions bip32/src/main/kotlin/org/kethereum/bip32/Converter.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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.")
}
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()
}
10 changes: 8 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,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 {
Expand All @@ -40,6 +45,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}")
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -12,4 +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"
}
5 changes: 3 additions & 2 deletions crypto/src/main/kotlin/org/kethereum/crypto/Converters.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
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
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))
Expand All @@ -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))
}
3 changes: 2 additions & 1 deletion crypto/src/main/kotlin/org/kethereum/crypto/Sign.kt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion crypto/src/main/kotlin/org/kethereum/crypto/Signatures.kt
Original file line number Diff line number Diff line change
@@ -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()

Expand Down
5 changes: 3 additions & 2 deletions crypto/src/test/kotlin/org/kethereum/crypto/SignTest.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -22,7 +23,7 @@ class SignTest {
val expected = SignatureData(
HexString("0x9631f6d21dec448a213585a4a41a28ef3d4337548aa34734478b563036163786").hexToBigInteger(),
HexString("0x2ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b").hexToBigInteger(),
27.toBigInteger()
BigInteger(27)
)

assertThat(signatureData).isEqualTo(expected)
Expand All @@ -39,7 +40,7 @@ class SignTest {
val expected = SignatureData(
HexString("0x6bcd81446183af193ca4a172d5c5c26345903b24770d90b5d790f74a9dec1f68").hexToBigInteger(),
HexString("0xe2b85b3c92c9b4f3cf58de46e7997d8efb6e14b2e532d13dfa22ee02f3a43d5d").hexToBigInteger(),
28.toBigInteger()
BigInteger(28)
)

assertThat(expected).isEqualTo(signatureData)
Expand Down
3 changes: 2 additions & 1 deletion crypto/src/test/kotlin/org/kethereum/crypto/TheSignatures.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -14,7 +15,7 @@ class TheSignatures {
val signatureData = SignatureData(
HexString("0x0031f6d21dec448a213585a4a41a28ef3d4337548aa34734478b563036163786").hexToBigInteger(),
HexString("0x2ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b").hexToBigInteger(),
27.toBigInteger()
BigInteger(27)
)

assertThat(signatureData.toHex()).isEqualTo("0031f6d21dec448a213585a4a41a28ef3d4337548aa34734478b5630361637862ff816ee6bbb82719e983ecd8a33a4b45d32a4b58377ef1381163d75eedc900b1b")
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 12 additions & 0 deletions crypto_api/src/main/kotlin/org/kethereum/crypto/impl/BigInteger.kt
Original file line number Diff line number Diff line change
@@ -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())
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
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) }

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()
Expand All @@ -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()
}
Original file line number Diff line number Diff line change
@@ -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))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
Loading