Foundations(iOS Sourceset): Provide implementation for MacInstance(using external library). Bring some tests into commonTest to make sure it works.
This commit is contained in:
@@ -253,6 +253,7 @@ kotlin {
|
||||
implementation(libs.charlietap.cachemap)
|
||||
implementation(libs.net.thauvin.erik.urlencoder.lib)
|
||||
implementation(libs.com.ditchoom.buffer.compression)
|
||||
implementation(libs.dev.whyoleg.cryptography.provider.apple)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package nip06KeyDerivationCommon
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Bip32SeedDerivation
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Bip39Mnemonics
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.KeyPath
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Bip32SeedDerivationCommonTest {
|
||||
val seedDerivation = Bip32SeedDerivation()
|
||||
|
||||
val masterBitcoin =
|
||||
seedDerivation.generate(
|
||||
Bip39Mnemonics.toSeed("gun please vital unable phone catalog explain raise erosion zoo truly exist", ""),
|
||||
)
|
||||
|
||||
val nostrMnemonic0 =
|
||||
seedDerivation.generate(
|
||||
Bip39Mnemonics.toSeed("leader monkey parrot ring guide accident before fence cannon height naive bean", ""),
|
||||
)
|
||||
|
||||
val nostrMnemonic1 =
|
||||
seedDerivation.generate(
|
||||
Bip39Mnemonics.toSeed("what bleak badge arrange retreat wolf trade produce cricket blur garlic valid proud rude strong choose busy staff weather area salt hollow arm fade", ""),
|
||||
)
|
||||
|
||||
@Test
|
||||
fun restoreBIP44Wallet() {
|
||||
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/44'/1'/0'"))
|
||||
assertEquals("50b3e7905c642309c8a8b73df5a49757a10f2bebb5804571b9db9004cce8a190", privateKey.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun restoreBIP49Wallet() {
|
||||
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/49'/1'/0'"))
|
||||
assertEquals("154c02c0b66899291a19012207642ba096a2d3ebf51baf153c9495976feb1b30", privateKey.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun restoreBIP84Wallet() {
|
||||
val privateKey = seedDerivation.derivePrivateKey(masterBitcoin, KeyPath("m/84'/1'/0'"))
|
||||
assertEquals("53e8c09a0e3ddcd8d68821c1e99e823966e99df91fb253e1f453a443ba543cb2", privateKey.toHexKey())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateMasterKeyForNostrMnemonics0() {
|
||||
assertEquals(
|
||||
"dbbcc0e112894d1430d5bc348d1bd72e8ac339952702be1fe572de80fe1b7fcb",
|
||||
nostrMnemonic0.secretkeybytes.toHexKey(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateMasterKeyForNostrMnemonics1() {
|
||||
assertEquals(
|
||||
"d58d40d5724435552fa442350b75e0ff95a19d990e908e3a516bcc88f780108f",
|
||||
nostrMnemonic1.secretkeybytes.toHexKey(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package nip06KeyDerivationCommon
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Nip06
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Nip06CommonTest {
|
||||
val nip06 = Nip06()
|
||||
|
||||
// private key (hex): 7f7ff03d123792d6ac594bfa67bf6d0c0ab55b6b1fdb6249303fe861f1ccba9a
|
||||
// nsec: nsec10allq0gjx7fddtzef0ax00mdps9t2kmtrldkyjfs8l5xruwvh2dq0lhhkp
|
||||
private val menemonic0 = "leader monkey parrot ring guide accident before fence cannon height naive bean"
|
||||
|
||||
// private key (hex): c15d739894c81a2fcfd3a2df85a0d2c0dbc47a280d092799f144d73d7ae78add
|
||||
// nsec: nsec1c9wh8xy5eqdzln7n5t0ctgxjcrdug73gp5yj0x03gntn67h83twssdfhel
|
||||
private val menemonic1 = "what bleak badge arrange retreat wolf trade produce cricket blur garlic valid proud rude strong choose busy staff weather area salt hollow arm fade"
|
||||
|
||||
// private key (hex): c15d739894c81a2fcfd3a2df85a0d2c0dbc47a280d092799f144d73d7ae78add
|
||||
// nsec: nsec1c9wh8xy5eqdzln7n5t0ctgxjcrdug73gp5yj0x03gntn67h83twssdfhel
|
||||
private val snortTest = "clog remember sample endorse mountain key rib hurry question supreme palm future stage style swing faith erase thumb then warm truth mule vivid endless"
|
||||
|
||||
@Test
|
||||
fun fromSeedNip06TestVector0() {
|
||||
val privateKeyHex = nip06.privateKeyFromMnemonic(menemonic0).toHexKey()
|
||||
assertEquals("7f7ff03d123792d6ac594bfa67bf6d0c0ab55b6b1fdb6249303fe861f1ccba9a", privateKeyHex)
|
||||
|
||||
val privateKeyHex21 = nip06.privateKeyFromMnemonic(menemonic0, 21).toHexKey()
|
||||
assertEquals("576390ec69951fcfbf159f2aac0965bb2e6d7a07da2334992af3225c57eaefca", privateKeyHex21)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fromSeedNip06TestVector1() {
|
||||
val privateKeyHex = nip06.privateKeyFromMnemonic(menemonic1).toHexKey()
|
||||
assertEquals("c15d739894c81a2fcfd3a2df85a0d2c0dbc47a280d092799f144d73d7ae78add", privateKeyHex)
|
||||
|
||||
val privateKeyHex21 = nip06.privateKeyFromMnemonic(menemonic1, 42).toHexKey()
|
||||
assertEquals("ad993054383da74e955f8b86346365b5ffd6575992e1de3738dda9f94407052b", privateKeyHex21)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore()
|
||||
fun fromSeedNip06FromSnort() {
|
||||
val privateKeyNsec = nip06.privateKeyFromMnemonic(snortTest).toHexKey()
|
||||
assertEquals("nsec1ppw9ltr2x9qwg9a2qnmgv98tfruy2ejnja7me76mwmsreu3s8u2sscj5nt", privateKeyNsec)
|
||||
}
|
||||
}
|
||||
@@ -20,37 +20,60 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils.mac
|
||||
|
||||
import dev.whyoleg.cryptography.CryptographyProvider
|
||||
import dev.whyoleg.cryptography.algorithms.HMAC
|
||||
import dev.whyoleg.cryptography.algorithms.SHA256
|
||||
import dev.whyoleg.cryptography.algorithms.SHA512
|
||||
import dev.whyoleg.cryptography.providers.apple.Apple
|
||||
|
||||
actual class MacInstance actual constructor(
|
||||
algorithm: String,
|
||||
key: ByteArray,
|
||||
) {
|
||||
private val cryptoProvider = CryptographyProvider.Apple
|
||||
|
||||
private var internalMacInstance: HMAC.Key =
|
||||
cryptoProvider
|
||||
.get(HMAC)
|
||||
.keyDecoder(digestForAlgorithm(algorithm))
|
||||
.decodeFromByteArrayBlocking(HMAC.Key.Format.RAW, key)
|
||||
|
||||
private val hmacSignFunction = internalMacInstance.signatureGenerator().createSignFunction()
|
||||
|
||||
actual fun init(
|
||||
key: ByteArray,
|
||||
algorithm: String,
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
internalMacInstance =
|
||||
cryptoProvider
|
||||
.get(HMAC)
|
||||
.keyDecoder(digestForAlgorithm(algorithm))
|
||||
.decodeFromByteArrayBlocking(HMAC.Key.Format.RAW, key)
|
||||
}
|
||||
|
||||
actual fun getMacLength(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
actual fun getMacLength(): Int = hmacSignFunction.signIntoByteArray(internalMacInstance.encodeToByteArrayBlocking(HMAC.Key.Format.RAW))
|
||||
|
||||
actual fun update(array: ByteArray) {
|
||||
TODO("Not yet implemented")
|
||||
hmacSignFunction.update(array)
|
||||
}
|
||||
|
||||
actual fun update(byte: Byte) {
|
||||
TODO("Not yet implemented")
|
||||
hmacSignFunction.update(byteArrayOf(byte))
|
||||
}
|
||||
|
||||
actual fun doFinal(): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
actual fun doFinal(): ByteArray = hmacSignFunction.signToByteArray()
|
||||
|
||||
actual fun doFinal(
|
||||
output: ByteArray,
|
||||
offset: Int,
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
hmacSignFunction.signIntoByteArray(output, offset)
|
||||
}
|
||||
|
||||
private fun digestForAlgorithm(algorithm: String) =
|
||||
when (algorithm) {
|
||||
"HmacSHA256" -> SHA256
|
||||
"HmacSHA512" -> SHA512
|
||||
else -> error("Algorithm is not yet supported.")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user