summaryrefslogtreecommitdiff
path: root/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt')
-rw-r--r--wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt87
1 files changed, 87 insertions, 0 deletions
diff --git a/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt b/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt
new file mode 100644
index 0000000..b29007e
--- /dev/null
+++ b/wallet/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Planchet.kt
@@ -0,0 +1,87 @@
+/*
+ * 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.wallet.kotlin.crypto
+
+import net.taler.wallet.kotlin.Amount
+import net.taler.wallet.kotlin.Base32Crockford
+
+internal class Planchet(private val crypto: Crypto) {
+
+ data class CreationRequest(
+ val value: Amount,
+ val feeWithdraw: Amount,
+ val denomPub: String,
+ val reservePub: String,
+ val reservePriv: String
+ )
+
+ data class CreationResult(
+ val coinPub: String,
+ val coinPriv: String,
+ val reservePub: String,
+ val denomPubHash: String,
+ val denomPub: String,
+ val blindingKey: String,
+ val withdrawSig: String,
+ val coinEv: String,
+ val coinValue: Amount,
+ val coinEvHash: String
+ )
+
+ internal fun create(req: CreationRequest, coinKeyPair: EddsaKeyPair, blindingFactor: ByteArray): CreationResult {
+ val reservePub = Base32Crockford.decode(req.reservePub)
+ val reservePriv = Base32Crockford.decode(req.reservePriv)
+ val denomPub = Base32Crockford.decode(req.denomPub)
+ val coinPubHash = crypto.sha512(coinKeyPair.publicKey)
+ val ev = crypto.rsaBlind(coinPubHash, blindingFactor, denomPub)
+ val amountWithFee = req.value + req.feeWithdraw
+ val denomPubHash = crypto.sha512(denomPub)
+ val evHash = crypto.sha512(ev)
+
+ val withdrawRequest = Signature.PurposeBuilder(Signature.RESERVE_WITHDRAW)
+ .put(reservePub)
+ .put(amountWithFee.toByteArray())
+ .put(req.feeWithdraw.toByteArray())
+ .put(denomPubHash)
+ .put(evHash)
+ .build()
+
+ val sig = crypto.eddsaSign(withdrawRequest, reservePriv)
+ return CreationResult(
+ blindingKey = Base32Crockford.encode(blindingFactor),
+ coinEv = Base32Crockford.encode(ev),
+ coinPriv = Base32Crockford.encode(coinKeyPair.privateKey),
+ coinPub = Base32Crockford.encode(coinKeyPair.publicKey),
+ coinValue = req.value,
+ denomPub = req.denomPub,
+ denomPubHash = Base32Crockford.encode(denomPubHash),
+ reservePub = req.reservePub,
+ withdrawSig = Base32Crockford.encode(sig),
+ coinEvHash = Base32Crockford.encode(evHash)
+ )
+ }
+
+ /**
+ * Create a pre-coin ([Planchet]) of the given [CreationRequest].
+ */
+ fun create(req: CreationRequest): CreationResult {
+ val coinKeyPair = crypto.createEddsaKeyPair()
+ val blindingFactor = crypto.getRandomBytes(32)
+ return create(req, coinKeyPair, blindingFactor)
+ }
+
+}