Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
250 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/Sodium.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package io.iohk.atala.prism.apollo.derivation | ||
|
||
import com.ionspin.kotlin.bignum.integer.util.toBigEndianUByteArray | ||
import com.ionspin.kotlin.crypto.box.Box | ||
import com.ionspin.kotlin.crypto.keyexchange.KeyExchange | ||
import org.kotlincrypto.macs.hmac.sha2.HmacSHA512 | ||
import kotlin.js.ExperimentalJsExport | ||
import kotlin.js.JsExport | ||
|
||
// this is just for testing, actual code needs to be in HDKey | ||
// have been using HDKey companion functions to avoid breaking | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
@JsExport | ||
data class Key(val key: ByteArray, val chainCode: ByteArray) | ||
|
||
@OptIn(ExperimentalJsExport::class) | ||
@JsExport | ||
class Sodium { | ||
private val hardenedOffset = 0x80000000 | ||
fun getMasterKeyFromSeed(seed: ByteArray): Key { | ||
val init = "ed25519 seed".encodeToByteArray() | ||
val hmac = HmacSHA512(init) | ||
hmac.update(seed) | ||
val result = hmac.doFinal() | ||
val key = result.copyOfRange(0, 32) | ||
val chainCode = result.copyOfRange(32, 64) | ||
|
||
return Key(key, chainCode) | ||
} | ||
|
||
@OptIn(ExperimentalUnsignedTypes::class) | ||
fun derive(seed: ByteArray, index: Int): Key { | ||
val masterKey = getMasterKeyFromSeed(seed) | ||
val offset = (index + hardenedOffset).toUInt() | ||
val bytes = offset.toBigEndianUByteArray().toByteArray() | ||
val data = byteArrayOf(0).plus(masterKey.key.plus(bytes)) | ||
val hmac = HmacSHA512(masterKey.chainCode) | ||
val result = hmac.doFinal(data) | ||
val key = result.copyOfRange(0, 32) | ||
val chainCode = result.copyOfRange(32, 64) | ||
|
||
return Key(key, chainCode) | ||
} | ||
|
||
|
||
@OptIn(ExperimentalStdlibApi::class) | ||
fun keygen(seed: ByteArray): Key { | ||
// this KeyExchange.seedKeyPair might be usable for X25519 | ||
// would need to be ported to HDKey | ||
val kkp = KeyExchange.seedKeypair(seed.toUByteArray()) | ||
// no idea what Box is, just used it for testing to simulate another Key | ||
val bkp = Box.seedKeypair(seed.toUByteArray()) | ||
// val skp = Signature.seedKeypair(seed.toUByteArray()) | ||
|
||
val clientSessionKeyPair = KeyExchange.clientSessionKeys( | ||
bkp.publicKey, | ||
bkp.secretKey, | ||
kkp.publicKey | ||
) | ||
val serverSessionKeyPair = KeyExchange.serverSessionKeys( | ||
kkp.publicKey, | ||
kkp.secretKey, | ||
bkp.publicKey | ||
) | ||
|
||
val a = clientSessionKeyPair.sendKey.toHexString() | ||
val b = serverSessionKeyPair.receiveKey.toHexString() | ||
// matched should be true | ||
val matched = a == b | ||
|
||
return Key(kkp.secretKey.toByteArray(), kkp.publicKey.toByteArray()) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/derivation/SodiumTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.iohk.atala.prism.apollo.derivation | ||
|
||
import com.ionspin.kotlin.crypto.LibsodiumInitializer | ||
import io.iohk.atala.prism.apollo.utils.toHexString | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
class SodiumTest { | ||
@OptIn(ExperimentalStdlibApi::class) | ||
@Test | ||
fun test() { | ||
LibsodiumInitializer.initializeWithCallback { | ||
val seedHex = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" | ||
val seed = seedHex.hexToByteArray() | ||
val result = Sodium().getMasterKeyFromSeed(seed) | ||
|
||
val a = Sodium().keygen(seed) | ||
val b = Sodium().keygen("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a".hexToByteArray()) | ||
|
||
val expected = result.chainCode.toHexString() | ||
assertEquals("171cb88b1b3c1db25add599712e36245d75bc65a1a5c9e18d76f9f2b1eab4012", result.key.toHexString()) | ||
} | ||
} | ||
} |