From 4ae5f65b15808861024cdc1ce506b5c1cfafaaa1 Mon Sep 17 00:00:00 2001 From: HashMapsData2Value <83883690+HashMapsData2Value@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:17:19 +0100 Subject: [PATCH] feat: break out lazySodium instance (#14) * feat: break out lazySodium instance * fix: use generic to target all classes that extend LazySodium base class * docs: updates docs --- README.md | 10 ++++-- .../main/kotlin/bip32ed25519/Bip32Ed25519.kt | 10 ++---- .../kotlin/bip32ed25519/Bip32Ed25519Test.kt | 35 ++++++++++--------- .../testWithSandbox/AlgoLocalNetTest.kt | 5 +-- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 07fd15b..4392fa8 100644 --- a/README.md +++ b/README.md @@ -28,18 +28,22 @@ You might be required to install using `sudo` privileges. ## How to Use -Initialize an instance of Bip32Ed25519 with a seed: +Initialize an instance of Bip32Ed25519 with an instantiation of LazySodium and the seed: ```kotlin - val alice = Bip32Ed25519(seedBytes) + val ls: LazySodiumJava = LazySodiumJava(SodiumJava(LibraryLoader.Mode.PREFER_BUNDLED)) + val alice = Bip32Ed25519(ls, seedBytes) ``` +LazySodiumJava is the desktop version. For mobile you can use LazySodiumAndroid which Bip32Ed25519 also takes. + Consider using a BIP-39 compatible library like `cash.z.ecc.android:kotlin-bip39` to use a seed phrase instead: ```kotlin val seed = MnemonicCode( "salon zoo engage submit smile frost later decide wing sight chaos renew lizard rely canal coral scene hobby scare step bus leaf tobacco slice".toCharArray()) - alice = Bip32Ed25519(seed.toSeed()) + val ls: LazySodiumJava = LazySodiumJava(SodiumJava(LibraryLoader.Mode.PREFER_BUNDLED)) + val alice = Bip32Ed25519(ls, seed.toSeed()) ``` Obviously do NOT make use of that seed phrase! diff --git a/lib/src/main/kotlin/bip32ed25519/Bip32Ed25519.kt b/lib/src/main/kotlin/bip32ed25519/Bip32Ed25519.kt index 312081e..7b143df 100644 --- a/lib/src/main/kotlin/bip32ed25519/Bip32Ed25519.kt +++ b/lib/src/main/kotlin/bip32ed25519/Bip32Ed25519.kt @@ -24,9 +24,7 @@ import com.algorand.algosdk.transaction.Transaction import com.algorand.algosdk.util.* import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper -import com.goterl.lazysodium.LazySodiumJava -import com.goterl.lazysodium.SodiumJava -import com.goterl.lazysodium.utils.LibraryLoader +import com.goterl.lazysodium.LazySodium import java.math.BigInteger import java.nio.ByteBuffer import java.security.MessageDigest @@ -52,7 +50,7 @@ class DataValidationException(message: String) : Exception(message) data class SignMetadata(val encoding: Encoding, val schema: JSONSchema) -class Bip32Ed25519(private var seed: ByteArray) { +class Bip32Ed25519(val lazySodium: T, private var seed: ByteArray) { companion object { val prefixes = listOf( @@ -100,10 +98,6 @@ class Bip32Ed25519(private var seed: ByteArray) { "VO" ) - // Load it once statically and use it for the lifetime of the application - val lazySodium: LazySodiumJava = - LazySodiumJava(SodiumJava(LibraryLoader.Mode.PREFER_BUNDLED)) - /** * Harden a number (set the highest bit to 1) Note that the input is UInt and the output is * also UInt diff --git a/lib/src/test/kotlin/bip32ed25519/Bip32Ed25519Test.kt b/lib/src/test/kotlin/bip32ed25519/Bip32Ed25519Test.kt index 5a9328a..3519e30 100644 --- a/lib/src/test/kotlin/bip32ed25519/Bip32Ed25519Test.kt +++ b/lib/src/test/kotlin/bip32ed25519/Bip32Ed25519Test.kt @@ -21,7 +21,10 @@ import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode import cash.z.ecc.android.bip39.toSeed import com.algorand.algosdk.crypto.Address import com.algorand.algosdk.kmd.client.model.* +import com.goterl.lazysodium.LazySodiumJava +import com.goterl.lazysodium.SodiumJava import com.goterl.lazysodium.utils.Key +import com.goterl.lazysodium.utils.LibraryLoader import java.util.Base64 import kotlin.collections.component1 import kotlin.test.Test @@ -41,7 +44,9 @@ fun helperStringToByteArray(input: String): ByteArray { .map { it.toByte() } .toByteArray() } - +/* + * Helper function that converts a hex string into a byte array + */ fun helperHexStringToByteArray(s: String): ByteArray { val result = ByteArray(s.length / 2) for (i in 0 until s.length step 2) { @@ -51,12 +56,15 @@ fun helperHexStringToByteArray(s: String): ByteArray { return result } +// Load the lazy sodium library, desktop version +val ls: LazySodiumJava = LazySodiumJava(SodiumJava(LibraryLoader.Mode.PREFER_BUNDLED)) + class Bip32Ed25519Test { @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class KeyGenTests { - private lateinit var c: Bip32Ed25519 + private lateinit var c: Bip32Ed25519 @BeforeAll fun setup() { @@ -64,7 +72,7 @@ class Bip32Ed25519Test { MnemonicCode( "salon zoo engage submit smile frost later decide wing sight chaos renew lizard rely canal coral scene hobby scare step bus leaf tobacco slice".toCharArray() ) - c = Bip32Ed25519(seed.toSeed()) + c = Bip32Ed25519(ls, seed.toSeed()) } @Test @@ -757,7 +765,7 @@ class Bip32Ed25519Test { @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class SignTypedDataTests { - private lateinit var c: Bip32Ed25519 + private lateinit var c: Bip32Ed25519 @BeforeAll fun setup() { @@ -765,7 +773,7 @@ class Bip32Ed25519Test { MnemonicCode( "salon zoo engage submit smile frost later decide wing sight chaos renew lizard rely canal coral scene hobby scare step bus leaf tobacco slice".toCharArray() ) - c = Bip32Ed25519(seed.toSeed()) + c = Bip32Ed25519(ls, seed.toSeed()) } @Test @@ -1063,8 +1071,8 @@ class Bip32Ed25519Test { @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class ECDHTests { - private lateinit var alice: Bip32Ed25519 - private lateinit var bob: Bip32Ed25519 + private lateinit var alice: Bip32Ed25519 + private lateinit var bob: Bip32Ed25519 @BeforeAll fun setup() { @@ -1079,8 +1087,8 @@ class Bip32Ed25519Test { "identify length ranch make silver fog much puzzle borrow relax occur drum blue oval book pledge reunion coral grace lamp recall fever route carbon".toCharArray() ) .toSeed() - alice = Bip32Ed25519(aliceSeed) - bob = Bip32Ed25519(bobSeed) + alice = Bip32Ed25519(ls, aliceSeed) + bob = Bip32Ed25519(ls, bobSeed) } @Test @@ -1184,12 +1192,7 @@ class Bip32Ed25519Test { ) // Encrypt - val ciphertext = - Bip32Ed25519.lazySodium.cryptoSecretBoxEasy( - message, - nonce, - aliceSharedSecret - ) + val ciphertext = ls.cryptoSecretBoxEasy(message, nonce, aliceSharedSecret) assert( ciphertext.equals( @@ -1239,7 +1242,7 @@ class Bip32Ed25519Test { // Decrypt val plaintext = - Bip32Ed25519.lazySodium.cryptoSecretBoxOpenEasy( + ls.cryptoSecretBoxOpenEasy( ciphertext, nonce, aliceSharedSecret diff --git a/lib/src/test/kotlin/bip32ed25519/testWithSandbox/AlgoLocalNetTest.kt b/lib/src/test/kotlin/bip32ed25519/testWithSandbox/AlgoLocalNetTest.kt index d54a996..67bdaf9 100644 --- a/lib/src/test/kotlin/bip32ed25519/testWithSandbox/AlgoLocalNetTest.kt +++ b/lib/src/test/kotlin/bip32ed25519/testWithSandbox/AlgoLocalNetTest.kt @@ -28,6 +28,7 @@ import com.algorand.algosdk.transaction.Transaction import com.algorand.algosdk.util.Encoder import com.algorand.algosdk.v2.client.common.AlgodClient import com.algorand.algosdk.v2.client.common.IndexerClient +import com.goterl.lazysodium.LazySodiumJava import kotlin.collections.component1 import kotlin.test.Test import org.junit.jupiter.api.BeforeAll @@ -38,7 +39,7 @@ class AlgoLocalNetTest { @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class AlgoSDKTests { - private lateinit var alice: Bip32Ed25519 + private lateinit var alice: Bip32Ed25519 private lateinit var algod: AlgodClient private lateinit var indexer: IndexerClient private lateinit var token: String @@ -60,7 +61,7 @@ class AlgoLocalNetTest { ) .toSeed() - alice = Bip32Ed25519(aliceSeed) + alice = Bip32Ed25519(ls, aliceSeed) // Token to sandbox token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"