Skip to content

Commit

Permalink
Full cross-platform crypto implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
andreypfau committed Feb 1, 2023
1 parent b4e3375 commit 1dbf1a3
Show file tree
Hide file tree
Showing 38 changed files with 2,992 additions and 2,407 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

```kotlin
dependencies {
implementation("org.ton:ton-kotlin:0.2.8")
implementation("org.ton:ton-kotlin:0.2.9")
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ val isCI = System.getenv("CI") == "true"

allprojects {
group = "org.ton"
version = "0.2.8"
version = "0.2.9"

apply(plugin = "kotlin-multiplatform")
apply(plugin = "kotlinx-serialization")
Expand Down
1 change: 0 additions & 1 deletion libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor" }
bouncycastle = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bouncycastle" }
curve25519 = { module = "io.github.andreypfau:curve25519-kotlin", version.ref = "curve25519" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ton.adnl.connection

import io.ktor.util.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import io.ktor.utils.io.errors.*
Expand All @@ -12,7 +13,8 @@ import org.ton.adnl.network.TcpClient
import org.ton.api.liteserver.LiteServerDesc
import org.ton.crypto.AesCtr
import org.ton.crypto.SecureRandom
import org.ton.crypto.sha256
import org.ton.crypto.digest.Digest
import org.ton.crypto.digest.sha256
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration
import kotlin.time.Duration.Companion.ZERO
Expand Down Expand Up @@ -175,7 +177,10 @@ public class AdnlConnection(
require(dataSize in 32..(1 shl 24)) { "Invalid packet size: $dataSize" }
val nonce = SecureRandom.nextBytes(32)
val payload = packet.readBytes()
val hash = sha256(nonce, payload)
val hash = Digest.sha256().apply {
update(nonce)
update(payload)
}.build()
val data = buildPacket {
writeIntLittleEndian(dataSize)
writeFully(nonce)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class VmStackValueTest {
val codec = VmStackValue.tlbCombinator()

@Test
fun `test VmStackValue (de)serialization`() {
fun `test VmStackValue deserialization`() {

testSerialization(codec, VmStackNull)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import org.ton.cell.Cell.Companion.DEPTH_BYTES
import org.ton.cell.Cell.Companion.HASH_BYTES
import org.ton.cell.Cell.Companion.getBitsDescriptor
import org.ton.cell.Cell.Companion.getRefsDescriptor
import org.ton.crypto.digest.sha256
import org.ton.crypto.encodeHex
import org.ton.crypto.sha256
import kotlin.jvm.JvmStatic
import kotlin.math.max

Expand Down
5 changes: 0 additions & 5 deletions ton-kotlin-crypto/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ kotlin {
implementation(kotlin("test"))
}
}
val jvmMain by getting {
dependencies {
implementation(libs.bouncycastle)
}
}
val nativeMain by getting {
dependencies {
api(libs.serialization.core)
Expand Down
2 changes: 2 additions & 0 deletions ton-kotlin-crypto/common/src/AesCtr.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.ton.crypto

import org.ton.crypto.digest.sha256

public expect class AesCtr(key: ByteArray, iv: ByteArray) {
public fun update(input: ByteArray, output: ByteArray = ByteArray(input.size)): ByteArray
public fun doFinal(output: ByteArray): ByteArray
Expand Down
16 changes: 0 additions & 16 deletions ton-kotlin-crypto/common/src/Sha256.kt

This file was deleted.

28 changes: 28 additions & 0 deletions ton-kotlin-crypto/common/src/digest/Digest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.ton.crypto.digest

public interface Digest {
public val algorithmName: String
public val digestSize: Int

public fun update(input: ByteArray): Unit = update(input, 0, input.size)
public fun update(input: ByteArray, offset: Int, length: Int)

public operator fun plusAssign(input: ByteArray): Unit = update(input)

public fun build(): ByteArray = build(ByteArray(digestSize))
public fun build(output: ByteArray): ByteArray = build(output, 0)
public fun build(output: ByteArray, offset: Int): ByteArray

public fun reset()

public companion object {
public fun sha256(): Digest = Digest("SHA-256")
public fun sha512(): Digest = Digest("SHA-512")
}
}

public expect fun Digest(algorithm: String): Digest

public expect fun sha256(bytes: ByteArray): ByteArray

public expect fun sha512(bytes: ByteArray): ByteArray
74 changes: 74 additions & 0 deletions ton-kotlin-crypto/common/src/digest/md4/GeneralDigest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.ton.crypto.digest.md4

import org.ton.crypto.digest.Digest

/**
* base implementation of MD4 family style digest as outlined in "Handbook of Applied Cryptography",
* pages 344 - 347.
*/
public abstract class GeneralDigest : Digest {
private val xBuf = ByteArray(4)
private var xBuffOff = 0
private var byteCount = 0

public fun update(input: Byte) {
xBuf[xBuffOff++] = input
if (xBuffOff == xBuf.size) {
processWord(xBuf, 0)
xBuffOff = 0
}
byteCount++
}

public override fun update(input: ByteArray, offset: Int, length: Int) {
// fill the current word
var i = 0
if (xBuffOff != 0) {
while (i < length) {
xBuf[xBuffOff++] = input[offset + i++]
if (xBuffOff == 4) {
processWord(xBuf, 0)
xBuffOff = 0
break
}
}
}

// process whole words.
val limit = ((length - i) and 3.inv()) + i
while (i < limit) {
processWord(input, offset + i)
i += 4
}

// load in the remainder.
while (i < length) {
xBuf[xBuffOff++] = input[offset + i++]
}

byteCount += length
}

public fun finish() {
val bitLength = byteCount.toLong() shl 3

// add the pad bytes.
update(128.toByte())

while (xBuffOff != 0) {
update(0.toByte())
}
processLength(bitLength)
processBlock()
}

override fun reset() {
byteCount = 0
xBuffOff = 0
xBuf.fill(0)
}

protected abstract fun processWord(input: ByteArray, offset: Int)
protected abstract fun processLength(bitLength: Long)
protected abstract fun processBlock()
}
Loading

0 comments on commit 1dbf1a3

Please sign in to comment.