Skip to content

Commit

Permalink
feat: break out lazySodium instance (algorandfoundation#14)
Browse files Browse the repository at this point in the history
* feat: break out lazySodium instance

* fix: use generic to target all classes that extend LazySodium base class

* docs: updates docs
  • Loading branch information
HashMapsData2Value authored Mar 11, 2024
1 parent 19df0e1 commit 4ae5f65
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 29 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<LazySodiumJava>(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<LazySodiumJava>(ls, seed.toSeed())
```

Obviously do NOT make use of that seed phrase!
Expand Down
10 changes: 2 additions & 8 deletions lib/src/main/kotlin/bip32ed25519/Bip32Ed25519.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<T : LazySodium>(val lazySodium: T, private var seed: ByteArray) {
companion object {
val prefixes =
listOf(
Expand Down Expand Up @@ -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
Expand Down
35 changes: 19 additions & 16 deletions lib/src/test/kotlin/bip32ed25519/Bip32Ed25519Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -51,20 +56,23 @@ 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<LazySodiumJava>

@BeforeAll
fun setup() {
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()
)
c = Bip32Ed25519(seed.toSeed())
c = Bip32Ed25519(ls, seed.toSeed())
}

@Test
Expand Down Expand Up @@ -757,15 +765,15 @@ class Bip32Ed25519Test {

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class SignTypedDataTests {
private lateinit var c: Bip32Ed25519
private lateinit var c: Bip32Ed25519<LazySodiumJava>

@BeforeAll
fun setup() {
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()
)
c = Bip32Ed25519(seed.toSeed())
c = Bip32Ed25519(ls, seed.toSeed())
}

@Test
Expand Down Expand Up @@ -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<LazySodiumJava>
private lateinit var bob: Bip32Ed25519<LazySodiumJava>

@BeforeAll
fun setup() {
Expand All @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1239,7 +1242,7 @@ class Bip32Ed25519Test {

// Decrypt
val plaintext =
Bip32Ed25519.lazySodium.cryptoSecretBoxOpenEasy(
ls.cryptoSecretBoxOpenEasy(
ciphertext,
nonce,
aliceSharedSecret
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -38,7 +39,7 @@ class AlgoLocalNetTest {
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class AlgoSDKTests {

private lateinit var alice: Bip32Ed25519
private lateinit var alice: Bip32Ed25519<LazySodiumJava>
private lateinit var algod: AlgodClient
private lateinit var indexer: IndexerClient
private lateinit var token: String
Expand All @@ -60,7 +61,7 @@ class AlgoLocalNetTest {
)
.toSeed()

alice = Bip32Ed25519(aliceSeed)
alice = Bip32Ed25519(ls, aliceSeed)

// Token to sandbox
token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Expand Down

0 comments on commit 4ae5f65

Please sign in to comment.