Merge pull request #146 from zcash/task/clean-up-dependencies

Remove NovaCrypto dependency because of license issue.
This commit is contained in:
Kevin Gorham 2020-06-04 13:51:59 -04:00 committed by GitHub
commit c5a17ff876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 22 additions and 96 deletions

View File

@ -142,11 +142,6 @@ dependencies {
kapt Deps.Dagger.ANDROID_PROCESSOR kapt Deps.Dagger.ANDROID_PROCESSOR
kapt Deps.Dagger.COMPILER kapt Deps.Dagger.COMPILER
// Testing these BIP39 dependencies
implementation 'com.madgag.spongycastle:core:1.58.0.0'
implementation 'io.github.novacrypto:BIP39:2019.01.27'
implementation 'io.github.novacrypto:securestring:2019.01.27'
// grpc-java // grpc-java
implementation "io.grpc:grpc-okhttp:1.25.0" implementation "io.grpc:grpc-okhttp:1.25.0"
implementation "io.grpc:grpc-android:1.25.0" implementation "io.grpc:grpc-android:1.25.0"

View File

@ -45,16 +45,12 @@ object Deps {
} }
} }
object Zcash { object Zcash {
val ANDROID_WALLET_PLUGINS = "com.github.zcash:zcash-android-wallet-plugins:1.0.0" val ANDROID_WALLET_PLUGINS = "com.github.zcash:zcash-android-wallet-plugins:1.0.1"
} }
object Misc { object Misc {
object Plugins { object Plugins {
val SECURE_STORAGE = "de.adorsys.android:securestoragelibrary:1.2.2" val SECURE_STORAGE = "de.adorsys.android:securestoragelibrary:1.2.2"
object Mnemonics { val ANDROID_BIP39 = "cash.z.ecc.android:android-bip39:1.0.0-beta07"
val SPONGY_CASTLE = "com.madgag.spongycastle:core:1.58.0.0"
val NOVACRYPTO_BIP39 = "io.github.novacrypto:BIP39:2019.01.27"
val NOVACRYPTO_SECURESTRING = "io.github.novacrypto:securestring:2019.01.27"
}
val QR_SCANNER = "com.google.zxing:core:3.2.1" val QR_SCANNER = "com.google.zxing:core:3.2.1"
} }
} }

View File

@ -8,10 +8,7 @@ dependencies {
// Zcash // Zcash
implementation Deps.Zcash.ANDROID_WALLET_PLUGINS implementation Deps.Zcash.ANDROID_WALLET_PLUGINS
implementation Deps.Misc.Plugins.ANDROID_BIP39
implementation Deps.Misc.Plugins.Mnemonics.SPONGY_CASTLE
implementation Deps.Misc.Plugins.Mnemonics.NOVACRYPTO_BIP39
implementation Deps.Misc.Plugins.Mnemonics.NOVACRYPTO_SECURESTRING
testImplementation Deps.Test.JUNIT testImplementation Deps.Test.JUNIT
} }

View File

@ -1,22 +1,20 @@
package cash.z.ecc.kotlin.mnemonic package cash.z.ecc.kotlin.mnemonic
import cash.z.android.plugin.MnemonicPlugin import cash.z.android.plugin.MnemonicPlugin
import io.github.novacrypto.bip39.MnemonicGenerator import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode
import io.github.novacrypto.bip39.SeedCalculator import cash.z.ecc.android.bip39.Mnemonics.WordCount
import io.github.novacrypto.bip39.Words import cash.z.ecc.android.bip39.toEntropy
import io.github.novacrypto.bip39.wordlists.English import cash.z.ecc.android.bip39.toSeed
import java.security.SecureRandom import java.util.*
import javax.inject.Inject import javax.inject.Inject
// TODO: either find another library that allows for doing this without strings or modify this code
// to leverage SecureCharBuffer (which doesn't work well with SeedCalculator.calculateSeed,
// which expects a string so for that reason, we just use Strings here)
class Mnemonics @Inject constructor(): MnemonicPlugin { class Mnemonics @Inject constructor(): MnemonicPlugin {
override fun fullWordList(languageCode: String): List<String> {
return cash.z.ecc.android.bip39.Mnemonics.getCachedWords(Locale.ENGLISH.language)
}
override fun nextEntropy(): ByteArray { override fun nextEntropy(): ByteArray {
return ByteArray(Words.TWENTY_FOUR.byteLength()).apply { return WordCount.COUNT_24.toEntropy()
SecureRandom().nextBytes(this)
}
} }
override fun nextMnemonic(): CharArray { override fun nextMnemonic(): CharArray {
@ -24,12 +22,7 @@ class Mnemonics @Inject constructor(): MnemonicPlugin {
} }
override fun nextMnemonic(entropy: ByteArray): CharArray { override fun nextMnemonic(entropy: ByteArray): CharArray {
return StringBuilder().let { builder -> return MnemonicCode(entropy).chars
MnemonicGenerator(English.INSTANCE).createMnemonic(entropy) { c ->
builder.append(c)
}
builder.toString().toCharArray()
}
} }
override fun nextMnemonicList(): List<CharArray> { override fun nextMnemonicList(): List<CharArray> {
@ -37,17 +30,11 @@ class Mnemonics @Inject constructor(): MnemonicPlugin {
} }
override fun nextMnemonicList(entropy: ByteArray): List<CharArray> { override fun nextMnemonicList(entropy: ByteArray): List<CharArray> {
return WordListBuilder().let { builder -> return MnemonicCode(entropy).map { it.toCharArray() }
MnemonicGenerator(English.INSTANCE).createMnemonic(entropy) { c ->
builder.append(c)
}
builder.wordList
}
} }
override fun toSeed(mnemonic: CharArray): ByteArray { override fun toSeed(mnemonic: CharArray): ByteArray {
// TODO: either find another library that allows for doing this without strings or modify this code to leverage SecureCharBuffer (which doesn't work well with SeedCalculator.calculateSeed, which expects a string so for that reason, we just use Strings here) return MnemonicCode(mnemonic).toSeed()
return SeedCalculator().calculateSeed(String(mnemonic), "")
} }
override fun toWordList(mnemonic: CharArray): List<CharArray> { override fun toWordList(mnemonic: CharArray): List<CharArray> {
@ -67,21 +54,4 @@ class Mnemonics @Inject constructor(): MnemonicPlugin {
} }
return wordList return wordList
} }
class WordListBuilder {
val wordList = mutableListOf<CharArray>()
fun append(c: CharSequence) {
if (c[0] != English.INSTANCE.space) addWord(c)
}
private fun addWord(c: CharSequence) {
c.length.let { size ->
val word = CharArray(size)
repeat(size) {
word[it] = c[it]
}
wordList.add(word)
}
}
}
} }

View File

@ -1,23 +1,17 @@
package cash.z.ecc.android.util package cash.z.ecc.android.util
import cash.z.ecc.kotlin.mnemonic.MnemonicProvider import cash.z.android.plugin.MnemonicPlugin
import cash.z.ecc.kotlin.mnemonic.Mnemonics import cash.z.ecc.kotlin.mnemonic.Mnemonics
import io.github.novacrypto.SecureCharBuffer
import io.github.novacrypto.bip39.MnemonicGenerator
import io.github.novacrypto.bip39.SeedCalculator
import io.github.novacrypto.bip39.Words
import io.github.novacrypto.bip39.wordlists.English
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import java.lang.Math.max import java.lang.Math.max
import java.security.SecureRandom import java.util.*
class MnemonicTest { class MnemonicTest {
lateinit var mnemonics: MnemonicProvider lateinit var mnemonics: MnemonicPlugin
@Before @Before
fun start() { fun start() {
@ -58,18 +52,20 @@ class MnemonicTest {
@Test @Test
fun testMnemonic_longestWord() { fun testMnemonic_longestWord() {
var max = 0 var max = 0
val englishWordList = mnemonics.fullWordList(Locale.ENGLISH.language)
repeat(2048) { repeat(2048) {
max = max(max, English.INSTANCE.getWord(it).length) max = max(max, englishWordList[it].length)
} }
assertEquals(8, max) assertEquals(8, max)
} }
private fun validate(words: List<String>) { private fun validate(words: List<String>) {
val englishWordList = mnemonics.fullWordList(Locale.ENGLISH.language)
// return or crash! // return or crash!
words.forEach { word -> words.forEach { word ->
var i = 0 var i = 0
while (true) { while (true) {
if (English.INSTANCE.getWord(i++) == word) { if (englishWordList[i++] == word) {
println(word) println(word)
break break
} }
@ -77,34 +73,6 @@ class MnemonicTest {
} }
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////
// Sample code for working with SecureCharBuffer
// (but the underlying implementation isn't compatible with SeedCalculator.calculateSeed)
////////////////////////////////////////////////////////////////////////////////////////////////
@Test
fun testMneumonicFromSeed_secure() {
SecureCharBuffer().use { secure ->
val entropy = ByteArray(Words.TWENTY_FOUR.byteLength()).also {
SecureRandom().nextBytes(it)
MnemonicGenerator(English.INSTANCE).createMnemonic(it, secure::append)
}
val words = secure.toWords()
assertEquals(24, words.size)
words.forEach { word ->
// verify no spaces
assertTrue(word.all { it != ' ' })
}
val mnemonic = secure.toStringAble().toString()
val seed = SeedCalculator().calculateSeed(mnemonic, "")
assertEquals(64, seed.size)
}
}
} }
private fun CharSequence.toWords(): List<CharSequence> { private fun CharSequence.toWords(): List<CharSequence> {