Skip to content

Commit

Permalink
Validate that mnemonics form a valid BIP-39 seed (#73)
Browse files Browse the repository at this point in the history
We were generating a valid BIP39 seed, but did not enfore any constraints at reading and would accept any phrase. We now always verify that we use a valid BIP-39 seed.

Also, more lenient extraction of words at reading.
  • Loading branch information
pm47 authored Jul 15, 2024
1 parent 867998a commit 3b6feb3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/commonMain/kotlin/fr/acinq/lightning/bin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import co.touchlab.kermit.CommonWriter
import co.touchlab.kermit.Severity
import co.touchlab.kermit.StaticConfig
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.UsageError
import com.github.ajalt.clikt.core.context
import com.github.ajalt.clikt.core.terminal
import com.github.ajalt.clikt.output.MordantHelpFormatter
Expand Down Expand Up @@ -76,7 +77,11 @@ class Phoenixd : CliktCommand() {
private val seed by option("--seed", help = "Manually provide a 12-words seed", hidden = true, envvar = PHOENIX_SEED)
.convert { PhoenixSeed(MnemonicCode.toSeed(it, "").toByteVector(), isNew = false) }
.defaultLazy {
val value = getOrGenerateSeed(datadir)
val value = try {
getOrGenerateSeed(datadir)
} catch (t: Throwable) {
throw UsageError(t.message, paramName = "seed")
}
if (value.isNew) {
terminal.print(yellow("Generating new seed..."))
runBlocking { delay(500.milliseconds) }
Expand Down
9 changes: 6 additions & 3 deletions src/commonMain/kotlin/fr/acinq/lightning/bin/conf/Seed.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ data class PhoenixSeed(val seed: ByteVector, val isNew: Boolean)
fun getOrGenerateSeed(dir: Path): PhoenixSeed {
val file = dir / "seed.dat"
val (mnemonics, isNew) = if (FileSystem.SYSTEM.exists(file)) {
FileSystem.SYSTEM.read(file) { readUtf8() } to false
val contents = FileSystem.SYSTEM.read(file) { readUtf8() }
val mnemonics = Regex("[a-z]+").findAll(contents).map { it.value }.toList()
mnemonics to false
} else {
val entropy = randomBytes(16)
val mnemonics = MnemonicCode.toMnemonics(entropy).joinToString(" ")
FileSystem.SYSTEM.write(file) { writeUtf8(mnemonics) }
val mnemonics = MnemonicCode.toMnemonics(entropy)
FileSystem.SYSTEM.write(file) { writeUtf8(mnemonics.joinToString(" ")) }
mnemonics to true
}
MnemonicCode.validate(mnemonics)
return PhoenixSeed(seed = MnemonicCode.toSeed(mnemonics, "").toByteVector(), isNew = isNew)
}

0 comments on commit 3b6feb3

Please sign in to comment.