diff options
author | Torsten Grote <t@grobox.de> | 2020-08-17 09:29:54 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-08-17 09:29:54 -0300 |
commit | dade0470c7e378c72ac2f2fd2a623416dadbff10 (patch) | |
tree | 083449814b1ad1320677e115f42f9a76125ccd76 /wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt | |
parent | a307a498dc8a42df129e8eaff591e9144ed96298 (diff) | |
download | wallet-kotlin-dade0470c7e378c72ac2f2fd2a623416dadbff10.tar.gz wallet-kotlin-dade0470c7e378c72ac2f2fd2a623416dadbff10.tar.bz2 wallet-kotlin-dade0470c7e378c72ac2f2fd2a623416dadbff10.zip |
Provide a blocking API for iOS (until Kotlin 1.4 is out)
and put base crypto into dedicated package (to be split out later).
Diffstat (limited to 'wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt')
-rw-r--r-- | wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt b/wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt new file mode 100644 index 0000000..85c159e --- /dev/null +++ b/wallet/src/androidMain/kotlin/net/taler/lib/crypto/CryptoFactory.kt @@ -0,0 +1,132 @@ +/* + * 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.crypto + +import com.goterl.lazycode.lazysodium.LazySodiumJava +import com.goterl.lazycode.lazysodium.SodiumJava +import com.goterl.lazycode.lazysodium.interfaces.Hash +import com.goterl.lazycode.lazysodium.interfaces.Hash.State512 +import com.goterl.lazycode.lazysodium.interfaces.KeyExchange +import com.goterl.lazycode.lazysodium.interfaces.Sign +import com.goterl.lazycode.lazysodium.utils.Key + +internal actual object CryptoFactory { + internal actual fun getCrypto(): Crypto = CryptoJvmImpl +} + +internal object CryptoJvmImpl : CryptoImpl() { + + private val sodium = LazySodiumJava(SodiumJava()) + + override fun sha256(input: ByteArray): ByteArray { + val output = ByteArray(Hash.SHA256_BYTES) + sodium.cryptoHashSha256(output, input, input.size.toLong()) + return output + } + + override fun sha512(input: ByteArray): ByteArray { + val output = ByteArray(Hash.SHA512_BYTES) + sodium.cryptoHashSha512(output, input, input.size.toLong()) + return output + } + + override fun getHashSha512State(): HashSha512State { + return JvmHashSha512State() + } + + override fun getRandomBytes(num: Int): ByteArray { + return sodium.randomBytesBuf(num) + } + + override fun eddsaGetPublic(eddsaPrivateKey: ByteArray): ByteArray { + return sodium.cryptoSignSeedKeypair(eddsaPrivateKey).publicKey.asBytes + } + + override fun ecdheGetPublic(ecdhePrivateKey: ByteArray): ByteArray { + return sodium.cryptoScalarMultBase(Key.fromBytes(ecdhePrivateKey)).asBytes + } + + override fun createEddsaKeyPair(): EddsaKeyPair { + val privateKey = sodium.randomBytesBuf(KeyExchange.SEEDBYTES) + val publicKey = eddsaGetPublic(privateKey) + return EddsaKeyPair(privateKey, publicKey) + } + + override fun createEcdheKeyPair(): EcdheKeyPair { + val privateKey = sodium.randomBytesBuf(KeyExchange.SEEDBYTES) + val publicKey = ecdheGetPublic(privateKey) + return EcdheKeyPair(privateKey, publicKey) + } + + override fun eddsaSign(msg: ByteArray, eddsaPrivateKey: ByteArray): ByteArray { + val privateKey = sodium.cryptoSignSeedKeypair(eddsaPrivateKey).secretKey.asBytes + val signatureBytes = ByteArray(Sign.BYTES) + sodium.cryptoSignDetached(signatureBytes, msg, msg.size.toLong(), privateKey) + return signatureBytes + } + + override fun eddsaVerify(msg: ByteArray, sig: ByteArray, eddsaPub: ByteArray): Boolean { + return sodium.cryptoSignVerifyDetached(sig, msg, msg.size, eddsaPub) + } + + override fun keyExchangeEddsaEcdhe(eddsaPrivateKey: ByteArray, ecdhePublicKey: ByteArray): ByteArray { + val ph = sha512(eddsaPrivateKey) + val a = ph.copyOfRange(0, 32) + val x = sodium.cryptoScalarMult(Key.fromBytes(a), Key.fromBytes(ecdhePublicKey)).asBytes + return sha512(x) + } + + override fun keyExchangeEcdheEddsa(ecdhePrivateKey: ByteArray, eddsaPublicKey: ByteArray): ByteArray { + val curve25519Pub = ByteArray(KeyExchange.PUBLICKEYBYTES) + sodium.convertPublicKeyEd25519ToCurve25519(curve25519Pub, eddsaPublicKey) + val x = sodium.cryptoScalarMult(Key.fromBytes(ecdhePrivateKey), Key.fromBytes(curve25519Pub)).asBytes + return sha512(x) + } + + override fun rsaBlind(hm: ByteArray, bks: ByteArray, rsaPubEnc: ByteArray): ByteArray { + return RsaBlinding.rsaBlind(hm, bks, rsaPubEnc) + } + + override fun rsaUnblind(sig: ByteArray, rsaPubEnc: ByteArray, bks: ByteArray): ByteArray { + return RsaBlinding.rsaUnblind(sig, rsaPubEnc, bks) + } + + override fun rsaVerify(hm: ByteArray, rsaSig: ByteArray, rsaPubEnc: ByteArray): Boolean { + return RsaBlinding.rsaVerify(hm, rsaSig, rsaPubEnc) + } + + private class JvmHashSha512State : HashSha512State { + private val state = State512() + + init { + check(sodium.cryptoHashSha512Init(state)) { "Error doing cryptoHashSha512Init" } + } + + override fun update(data: ByteArray): HashSha512State { + sodium.cryptoHashSha512Update(state, data, data.size.toLong()) + return this + } + + override fun final(): ByteArray { + val output = ByteArray(Hash.SHA512_BYTES) + sodium.cryptoHashSha512Final(state, output) + return output + } + + } + +} |