Skip to content

Commit

Permalink
[solana-mobile#130] Shamir's secret sharing for seed
Browse files Browse the repository at this point in the history
  • Loading branch information
0xBlockPay committed May 6, 2024
1 parent 67e3f9e commit cd0e7e8
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/migrations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions impl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ protobuf {
}

dependencies {
implementation group: 'com.codahale', name: 'shamir', version: '0.7.0'

implementation project(path: ':seedvault')
implementation 'androidx.activity:activity-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,11 @@ data class SeedDetails(
result = 31 * result + unlockWithBiometrics.hashCode()
return result
}
private fun createString(): String {
return "{\"seed:\"$seed, \"name\": $name }"
}

fun getValue() :ByteArray {
return createString().toByteArray()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.security.MessageDigest
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import kotlin.random.Random

class SeedDetailViewModel private constructor(
Expand Down Expand Up @@ -111,6 +117,30 @@ class SeedDetailViewModel private constructor(
SeedDetails(seedBytes, phrase, it.name.ifBlank { null }, it.pin, it.enableBiometrics)
}

//Construct algorithm
val scheme = com.codahale.shamir.Scheme(SecureRandom(), 5, 3)

//Generate Key
val key = generateAESKeyFromString("password")

//Encrypt seedDetails
val aes = aesEncrypt( seedDetails.getValue(), key)

//Split seed
val secrets = scheme.split(aes)

val hexs = secrets.values.forEach{v -> v.toHex()}

Log.i(TAG, "Successfully created hex's parts $hexs")

val joinSecret = scheme.join(secrets)
val secretArray = aesDecrypt(joinSecret, key)

val seedDetailsString = String(secretArray)

Log.i(TAG, "Successfully created Seed $seedDetailsString")


Log.i(TAG, "Successfully created Seed $seedDetails; committing to SeedRepository")
when (val mode = mode) { // immutable snapshot of mode
is NewSeedMode -> {
Expand Down Expand Up @@ -205,3 +235,31 @@ data class PreAuthorizeSeed(
val purpose: Authorization.Purpose
)


fun ByteArray.toHex(): String = joinToString(separator = "") { eachByte ->
"%02x".format(eachByte)
}

fun aesDecrypt(encryptedData: ByteArray, secretKey: SecretKey): ByteArray {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivParameterSpec = IvParameterSpec(ByteArray(16)) // W produkcji użyj bezpiecznego IV
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
return cipher.doFinal(encryptedData)
}
fun aesEncrypt(data: ByteArray, secretKey: SecretKey): ByteArray {
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
val ivParameterSpec = IvParameterSpec(ByteArray(16)) // Use a secure IV in production
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
return cipher.doFinal(data)
}

fun generateAESKeyFromString(inputString: String, keySize: Int = 256): SecretKey {
val messageDigest = MessageDigest.getInstance("SHA-256")
val hashBytes = messageDigest.digest(inputString.toByteArray())

val keyGenerator = KeyGenerator.getInstance("AES")
keyGenerator.init(keySize, SecureRandom(hashBytes))

return keyGenerator.generateKey()
}

0 comments on commit cd0e7e8

Please sign in to comment.