Skip to content

Commit

Permalink
Make PubKey, SecKey, and SecKeyGenerator multiplatform - Resolves #61 (
Browse files Browse the repository at this point in the history
  • Loading branch information
jmateoac authored Mar 25, 2024
1 parent 28b6e69 commit 3054503
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 16 deletions.
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mavenPublishGradlePlugin = "0.25.3"
moshi = "1.15.0"
okHttp = "5.0.0-alpha.11"
okIo = "3.4.0"
secureRandom = "0.3.1"
slf4j = "2.0.7"
versionCatalogUpdateGradlePlugin = "0.8.1"
versionsGradlePlugin = "0.47.0"
Expand All @@ -32,6 +33,7 @@ kotlinxCoroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core",
moshi = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }
okHttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okHttp" }
okIo = { module = "com.squareup.okio:okio", version.ref = "okIo" }
secureRandom = { module = "org.kotlincrypto:secure-random", version.ref = "secureRandom" }
slf4jSimple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
turbine = "app.cash.turbine:turbine:1.0.0"
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
Expand Down
5 changes: 4 additions & 1 deletion lib/api/lib.api
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ public final class app/cash/nostrino/crypto/SecKey : app/cash/nostrino/crypto/Ke
public final fun copy (Lokio/ByteString;)Lapp/cash/nostrino/crypto/SecKey;
public static synthetic fun copy$default (Lapp/cash/nostrino/crypto/SecKey;Lokio/ByteString;ILjava/lang/Object;)Lapp/cash/nostrino/crypto/SecKey;
public fun encoded ()Ljava/lang/String;
public final fun encrypt (Lapp/cash/nostrino/crypto/PubKey;Ljava/lang/String;)Lapp/cash/nostrino/crypto/CipherText;
public fun equals (Ljava/lang/Object;)Z
public final fun getKey ()Lokio/ByteString;
public final fun getNsec ()Ljava/lang/String;
Expand Down Expand Up @@ -359,6 +358,10 @@ public final class app/cash/nostrino/model/EncryptedDm : app/cash/nostrino/model
public final class app/cash/nostrino/model/EncryptedDm$Companion {
}

public final class app/cash/nostrino/model/EncryptedDmKt {
public static final fun encrypt (Lapp/cash/nostrino/crypto/SecKey;Lapp/cash/nostrino/crypto/PubKey;Ljava/lang/String;)Lapp/cash/nostrino/crypto/CipherText;
}

public final class app/cash/nostrino/model/Event {
public static final field Companion Lapp/cash/nostrino/model/Event$Companion;
public fun <init> (Lokio/ByteString;Lokio/ByteString;Ljava/time/Instant;ILjava/util/List;Ljava/lang/String;Lokio/ByteString;)V
Expand Down
1 change: 1 addition & 0 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ kotlin {
implementation(libs.acinqSecp256k1)
implementation(libs.kotlinxCoroutines)
implementation(libs.okIo)
implementation(libs.secureRandom)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ import fr.acinq.secp256k1.Hex
import fr.acinq.secp256k1.Secp256k1
import okio.ByteString
import okio.ByteString.Companion.toByteString
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
* Nostr secret key.
Expand Down Expand Up @@ -58,15 +54,7 @@ data class SecKey(val key: ByteString) : Key {
).copyOfRange(1, 33)

/** Generate cipher text of the provided plain text, intended for the provided pub key */
fun encrypt(to: PubKey, plainText: String): CipherText {
val random = SecureRandom()
val iv = ByteArray(16)
random.nextBytes(iv)
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(sharedSecretWith(to), "AES"), IvParameterSpec(iv))
val encrypted = cipher.doFinal(plainText.toByteArray())
return CipherText(encrypted.toByteString(), iv.toByteString())
}


companion object {
/** Create secret key from nip-19 bech32 encoded string */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
package app.cash.nostrino.crypto

import okio.ByteString.Companion.toByteString
import java.security.SecureRandom
import org.kotlincrypto.SecureRandom

class SecKeyGenerator {

/** Generate a new secret key */
tailrec fun generate(): SecKey {
val bs = ByteArray(32)
SecureRandom().nextBytes(bs)
SecureRandom().nextBytesCopyTo(bs)
val sec = bs.toByteString()
return if (sec.hex() > MAX_SEC) generate() else SecKey(sec)
}
Expand Down
15 changes: 15 additions & 0 deletions lib/src/jvmMain/kotlin/app/cash/nostrino/model/EncryptedDm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ package app.cash.nostrino.model
import app.cash.nostrino.crypto.CipherText
import app.cash.nostrino.crypto.PubKey
import app.cash.nostrino.crypto.SecKey
import okio.ByteString.Companion.toByteString
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
* An encrypted direct message. Event kind 4, as defined in
Expand All @@ -43,3 +48,13 @@ data class EncryptedDm(
const val kind = 4
}
}

fun SecKey.encrypt(to: PubKey, plainText: String): CipherText {
val random = SecureRandom()
val iv = ByteArray(16)
random.nextBytes(iv)
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(sharedSecretWith(to), "AES"), IvParameterSpec(iv))
val encrypted = cipher.doFinal(plainText.toByteArray())
return CipherText(encrypted.toByteString(), iv.toByteString())
}

0 comments on commit 3054503

Please sign in to comment.