diff options
author | Torsten Grote <t@grobox.de> | 2020-08-14 17:33:22 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-08-14 17:33:22 -0300 |
commit | a307a498dc8a42df129e8eaff591e9144ed96298 (patch) | |
tree | a55182b4793b673e433d0e431e9d971d45c9a6a7 /wallet/src/nativeMain/kotlin/net/taler/lib/wallet | |
parent | 2ac13b19a5c7fc3531447333fe1772a78ca35795 (diff) | |
download | wallet-kotlin-a307a498dc8a42df129e8eaff591e9144ed96298.tar.gz wallet-kotlin-a307a498dc8a42df129e8eaff591e9144ed96298.tar.bz2 wallet-kotlin-a307a498dc8a42df129e8eaff591e9144ed96298.zip |
Make the wallet lib actually use the common lib
Diffstat (limited to 'wallet/src/nativeMain/kotlin/net/taler/lib/wallet')
-rw-r--r-- | wallet/src/nativeMain/kotlin/net/taler/lib/wallet/Db.kt | 23 | ||||
-rw-r--r-- | wallet/src/nativeMain/kotlin/net/taler/lib/wallet/crypto/CryptoFactory.kt | 187 |
2 files changed, 210 insertions, 0 deletions
diff --git a/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/Db.kt b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/Db.kt new file mode 100644 index 0000000..39394b8 --- /dev/null +++ b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/Db.kt @@ -0,0 +1,23 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.lib.wallet + +internal actual class DbFactory { + actual fun openDb(): Db { + return FakeDb() + } +} diff --git a/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/crypto/CryptoFactory.kt b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/crypto/CryptoFactory.kt new file mode 100644 index 0000000..61646a0 --- /dev/null +++ b/wallet/src/nativeMain/kotlin/net/taler/lib/wallet/crypto/CryptoFactory.kt @@ -0,0 +1,187 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.lib.wallet.crypto + +import kotlinx.cinterop.CValuesRef +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.alloc +import kotlinx.cinterop.free +import kotlinx.cinterop.nativeHeap +import kotlinx.cinterop.ptr +import kotlinx.cinterop.refTo +import org.libsodium.crypto_hash_sha256 +import org.libsodium.crypto_hash_sha256_bytes +import org.libsodium.crypto_hash_sha512 +import org.libsodium.crypto_hash_sha512_bytes +import org.libsodium.crypto_hash_sha512_final +import org.libsodium.crypto_hash_sha512_init +import org.libsodium.crypto_hash_sha512_state +import org.libsodium.crypto_hash_sha512_update +import org.libsodium.crypto_scalarmult +import org.libsodium.crypto_scalarmult_BYTES +import org.libsodium.crypto_scalarmult_base +import org.libsodium.crypto_scalarmult_curve25519_BYTES +import org.libsodium.crypto_sign_BYTES +import org.libsodium.crypto_sign_PUBLICKEYBYTES +import org.libsodium.crypto_sign_SECRETKEYBYTES +import org.libsodium.crypto_sign_detached +import org.libsodium.crypto_sign_ed25519_pk_to_curve25519 +import org.libsodium.crypto_sign_seed_keypair +import org.libsodium.crypto_sign_verify_detached +import org.libsodium.randombytes + +internal actual object CryptoFactory { + internal actual fun getCrypto(): Crypto = CryptoNativeImpl +} + +@OptIn(ExperimentalUnsignedTypes::class) +internal object CryptoNativeImpl : CryptoImpl() { + + override fun sha256(input: ByteArray): ByteArray { + val output = ByteArray(crypto_hash_sha256_bytes().toInt()) + val cInput = if (input.isEmpty()) null else input.toCValuesRef() + crypto_hash_sha256(output.toCValuesRef(), cInput, input.size.toULong()) + return output + } + + override fun sha512(input: ByteArray): ByteArray { + val output = ByteArray(crypto_hash_sha512_bytes().toInt()) + val cInput = if (input.isEmpty()) null else input.toCValuesRef() + crypto_hash_sha512(output.toCValuesRef(), cInput, input.size.toULong()) + return output + } + + override fun getHashSha512State(): HashSha512State { + return NativeHashSha512State() + } + + override fun getRandomBytes(num: Int): ByteArray { + val bytes = ByteArray(num) + randombytes(bytes.toCValuesRef(), num.toULong()) + return bytes + } + + override fun eddsaGetPublic(eddsaPrivateKey: ByteArray): ByteArray { + val publicKey = ByteArray(crypto_sign_PUBLICKEYBYTES.toInt()) + val privateKey = ByteArray(crypto_sign_SECRETKEYBYTES.toInt()) + crypto_sign_seed_keypair(publicKey.toCValuesRef(), privateKey.toCValuesRef(), eddsaPrivateKey.toCValuesRef()) + return publicKey + } + + override fun ecdheGetPublic(ecdhePrivateKey: ByteArray): ByteArray { + val publicKey = ByteArray(crypto_scalarmult_BYTES.toInt()) + crypto_scalarmult_base(publicKey.toCValuesRef(), ecdhePrivateKey.toCValuesRef()) + return publicKey + } + + override fun createEddsaKeyPair(): EddsaKeyPair { + val privateKey = ByteArray(crypto_sign_SECRETKEYBYTES.toInt()) + randombytes(privateKey.toCValuesRef(), crypto_sign_SECRETKEYBYTES.toULong()) + val publicKey = eddsaGetPublic(privateKey) + return EddsaKeyPair(privateKey, publicKey) + } + + override fun createEcdheKeyPair(): EcdheKeyPair { + val privateKey = ByteArray(crypto_scalarmult_BYTES.toInt()) + randombytes(privateKey.toCValuesRef(), crypto_scalarmult_BYTES.toULong()) + val publicKey = ecdheGetPublic(privateKey) + return EcdheKeyPair(privateKey, publicKey) + } + + override fun eddsaSign(msg: ByteArray, eddsaPrivateKey: ByteArray): ByteArray { + val publicKey = ByteArray(crypto_sign_PUBLICKEYBYTES.toInt()) + val privateKey = ByteArray(crypto_sign_SECRETKEYBYTES.toInt()) + crypto_sign_seed_keypair(publicKey.toCValuesRef(), privateKey.toCValuesRef(), eddsaPrivateKey.toCValuesRef()) + + val signatureBytes = ByteArray(crypto_sign_BYTES.toInt()) + crypto_sign_detached( + signatureBytes.toCValuesRef(), + null, + msg.toCValuesRef(), + msg.size.toULong(), + privateKey.toCValuesRef() + ) + return signatureBytes + } + + override fun eddsaVerify(msg: ByteArray, sig: ByteArray, eddsaPub: ByteArray): Boolean { + return crypto_sign_verify_detached( + sig.toCValuesRef(), + msg.toCValuesRef(), + msg.size.toULong(), + eddsaPub.toCValuesRef() + ) == 0 + } + + override fun keyExchangeEddsaEcdhe(eddsaPrivateKey: ByteArray, ecdhePublicKey: ByteArray): ByteArray { + val privateKey = sha512(eddsaPrivateKey).copyOfRange(0, 32) + val sharedKey = ByteArray(crypto_scalarmult_BYTES.toInt()) + crypto_scalarmult(sharedKey.toCValuesRef(), privateKey.toCValuesRef(), ecdhePublicKey.toCValuesRef()) + return sha512(sharedKey) + } + + override fun keyExchangeEcdheEddsa(ecdhePrivateKey: ByteArray, eddsaPublicKey: ByteArray): ByteArray { + val curve25519Pub = ByteArray(crypto_scalarmult_curve25519_BYTES.toInt()) + val cCurve25519Pub = curve25519Pub.toCValuesRef() + crypto_sign_ed25519_pk_to_curve25519(cCurve25519Pub, eddsaPublicKey.toCValuesRef()) + + val sharedKey = ByteArray(crypto_scalarmult_BYTES.toInt()) + crypto_scalarmult(sharedKey.toCValuesRef(), ecdhePrivateKey.toCValuesRef(), cCurve25519Pub) + return sha512(sharedKey) + } + + override fun rsaBlind(hm: ByteArray, bks: ByteArray, rsaPubEnc: ByteArray): ByteArray { + TODO("Not yet implemented") + } + + override fun rsaUnblind(sig: ByteArray, rsaPubEnc: ByteArray, bks: ByteArray): ByteArray { + TODO("Not yet implemented") + } + + override fun rsaVerify(hm: ByteArray, rsaSig: ByteArray, rsaPubEnc: ByteArray): Boolean { + TODO("Not yet implemented") + } + + private class NativeHashSha512State : HashSha512State { + private val state = nativeHeap.alloc<crypto_hash_sha512_state>() + private val statePointer = state.ptr + + init { + check(crypto_hash_sha512_init(statePointer) == 0) { "Error doing crypto_hash_sha512_init" } + } + + override fun update(data: ByteArray): HashSha512State { + val cInput = if (data.isEmpty()) null else data.toCValuesRef() + crypto_hash_sha512_update(statePointer, cInput, data.size.toULong()) + return this + } + + override fun final(): ByteArray { + val output = ByteArray(crypto_hash_sha512_bytes().toInt()) + crypto_hash_sha512_final(statePointer, output.toCValuesRef()) + nativeHeap.free(statePointer) + return output + } + + } + + private fun ByteArray.toCValuesRef(): CValuesRef<UByteVar> { + @Suppress("UNCHECKED_CAST") + return this.refTo(0) as CValuesRef<UByteVar> + } + +} |