diff options
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.kt | 87 |
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) + } + +} |