
Concise BIP-0039 implementation for generating and validating mnemonic phrases and seeds with enhanced security using CharArrays. Offers comprehensive checksum validation and easy Gradle integration, focusing on idiomatic code and thorough testing.
A concise implementation of BIP-0039 in Kotlin for Android.
Only about 30kB in total size. For comparison, the entire library is about 3X the size of this README file (because there are no dependencies)!
chief instead of chef) and other similar issues that could invalidate a backup or lose funds.Consequently, this library strives to use both idiomatic Kotlin and CharArrays whenever possible. It also aims to be concise and thoroughly tested. As a pure kotlin library, it probably also works outside of Android but that is not an explicit goal (Update: confirmed to also work on a Ktor server).
Plus, it uses a permissive MIT license and no dependencies beyond Kotlin's stdlib!
Add dependencies (see Maven badge above for latest version number):
dependencies {
implementation "cash.z.ecc.android:kotlin-bip39:${latestVersion}"
}
repository {
mavenCentral()
}This library prefers CharArrays over Strings for added security.
Note: If strings or lists are desired, it is very easy (but not recommended) to convert to/from a CharArray via String(charArray) or String(charArray).split(' ').
import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode
val mnemonicCode: MnemonicCode = MnemonicCode(WordCount.COUNT_24)
// assert: mnemonicCode.wordCount == 24, mnemonicCode.languageCode == "en"val seed: ByteArray = mnemonicCode.toSeed()val preExistingPhraseString = "scheme spot photo card baby mountain device kick cradle pact join borrow"
val preExistingPhraseChars = validPhraseString.toCharArray()
// from CharArray
seed = MnemonicCode(preExistingPhraseChars).toSeed()
// from String
seed = MnemonicCode(preExistingPhraseString).toSeed()// normal way
val passphrase = "bitcoin".toCharArray()
mnemonicCode.toSeed(passphrase)
// more private way (erase at the end)
charArrayOf('z', 'c', 'a', 's', 'h').let { passphrase ->
mnemonicCode.toSeed(passphrase)
passphrase.fill('0') // erased!
}val entropy: ByteArray = WordCount.COUNT_18.toEntropy()
// this can be used to directly generate a mnemonic:
val mnemonicCode = MnemonicCode(entropy)
// note: that gives the same result as calling:
MnemonicCode(WordCount.COUNT_18)// throws a typed exception when invalid:
// ChecksumException - when checksum fails, usually meaning words are swapped
// WordCountException(count) - invalid number of words
// InvalidWordException(word) - contains a word not found on the list
mnemonicCode.validate()// mnemonicCodes are iterable
for (word in mnemonicCode) {
println(word)
}
mnemonicCode.forEach { word ->
println(word)
}mnemonicCode.clear() // code words are deleted and no longer available for attackerThese generated codes are compatible with kotlin's scoped resource usage
use to automatically clean-up after useMnemonicCode(WordCount.COUNT_24).use {
// Do something with the words (wordCount == 24)
}
// memory has been cleared at this point (wordCount == 0)MnemonicCode::validate() function.val entropy: ByteArray = MnemonicCode(preExistingPhraseString).toEntropy()seed = MnemonicCode(WordCount.COUNT_24).toSeed(validate = false)ISO 639-1 language code. For now, using it with anything other than "en" will result in an UnsupportedOperationException.// results in exception, for now
val mnemonicCode = MnemonicCode(WordCount.COUNT_24, languageCode = Locale.GERMAN.language)
// english is the only language that doesn't crash
val mnemonicCode = MnemonicCode(WordCount.COUNT_24, languageCode = Locale.ENGLISH.language)A concise implementation of BIP-0039 in Kotlin for Android.
Only about 30kB in total size. For comparison, the entire library is about 3X the size of this README file (because there are no dependencies)!
chief instead of chef) and other similar issues that could invalidate a backup or lose funds.Consequently, this library strives to use both idiomatic Kotlin and CharArrays whenever possible. It also aims to be concise and thoroughly tested. As a pure kotlin library, it probably also works outside of Android but that is not an explicit goal (Update: confirmed to also work on a Ktor server).
Plus, it uses a permissive MIT license and no dependencies beyond Kotlin's stdlib!
Add dependencies (see Maven badge above for latest version number):
dependencies {
implementation "cash.z.ecc.android:kotlin-bip39:${latestVersion}"
}
repository {
mavenCentral()
}This library prefers CharArrays over Strings for added security.
Note: If strings or lists are desired, it is very easy (but not recommended) to convert to/from a CharArray via String(charArray) or String(charArray).split(' ').
import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode
val mnemonicCode: MnemonicCode = MnemonicCode(WordCount.COUNT_24)
// assert: mnemonicCode.wordCount == 24, mnemonicCode.languageCode == "en"val seed: ByteArray = mnemonicCode.toSeed()val preExistingPhraseString = "scheme spot photo card baby mountain device kick cradle pact join borrow"
val preExistingPhraseChars = validPhraseString.toCharArray()
// from CharArray
seed = MnemonicCode(preExistingPhraseChars).toSeed()
// from String
seed = MnemonicCode(preExistingPhraseString).toSeed()// normal way
val passphrase = "bitcoin".toCharArray()
mnemonicCode.toSeed(passphrase)
// more private way (erase at the end)
charArrayOf('z', 'c', 'a', 's', 'h').let { passphrase ->
mnemonicCode.toSeed(passphrase)
passphrase.fill('0') // erased!
}val entropy: ByteArray = WordCount.COUNT_18.toEntropy()
// this can be used to directly generate a mnemonic:
val mnemonicCode = MnemonicCode(entropy)
// note: that gives the same result as calling:
MnemonicCode(WordCount.COUNT_18)// throws a typed exception when invalid:
// ChecksumException - when checksum fails, usually meaning words are swapped
// WordCountException(count) - invalid number of words
// InvalidWordException(word) - contains a word not found on the list
mnemonicCode.validate()// mnemonicCodes are iterable
for (word in mnemonicCode) {
println(word)
}
mnemonicCode.forEach { word ->
println(word)
}mnemonicCode.clear() // code words are deleted and no longer available for attackerThese generated codes are compatible with kotlin's scoped resource usage
use to automatically clean-up after useMnemonicCode(WordCount.COUNT_24).use {
// Do something with the words (wordCount == 24)
}
// memory has been cleared at this point (wordCount == 0)MnemonicCode::validate() function.val entropy: ByteArray = MnemonicCode(preExistingPhraseString).toEntropy()seed = MnemonicCode(WordCount.COUNT_24).toSeed(validate = false)ISO 639-1 language code. For now, using it with anything other than "en" will result in an UnsupportedOperationException.// results in exception, for now
val mnemonicCode = MnemonicCode(WordCount.COUNT_24, languageCode = Locale.GERMAN.language)
// english is the only language that doesn't crash
val mnemonicCode = MnemonicCode(WordCount.COUNT_24, languageCode = Locale.ENGLISH.language)