[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-kotlin] 01/02: Add Deposit signing and test
From: |
gnunet |
Subject: |
[taler-wallet-kotlin] 01/02: Add Deposit signing and test |
Date: |
Tue, 30 Jun 2020 21:04:27 +0200 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a commit to branch master
in repository wallet-kotlin.
commit 1a6121d7246b8dbf39eba2e91c92507c2b85e3d2
Author: Torsten Grote <t@grobox.de>
AuthorDate: Tue Jun 30 10:19:43 2020 -0300
Add Deposit signing and test
---
.../net/taler/wallet/kotlin/crypto/Deposit.kt | 94 ++++++++++++++++++++++
.../net/taler/wallet/kotlin/crypto/DepositTest.kt | 74 +++++++++++++++++
2 files changed, 168 insertions(+)
diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
b/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
new file mode 100644
index 0000000..6b4fa94
--- /dev/null
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/crypto/Deposit.kt
@@ -0,0 +1,94 @@
+package net.taler.wallet.kotlin.crypto
+
+import net.taler.wallet.kotlin.Amount
+import net.taler.wallet.kotlin.Base32Crockford
+import net.taler.wallet.kotlin.Timestamp
+import net.taler.wallet.kotlin.crypto.Signature.Companion.WALLET_COIN_DEPOSIT
+
+/**
+ * Deposit operations are requested by a merchant during a transaction.
+ * For the deposit operation, the merchant has to obtain the deposit
permission for a coin
+ * from their customer who owns the coin.
+ *
+ * When depositing a coin, the merchant is credited an amount specified in the
deposit permission,
+ * possibly a fraction of the total coin’s value,
+ * minus the deposit fee as specified by the coin’s denomination.
+ */
+internal class Deposit(private val crypto: Crypto) {
+
+ /**
+ * Private data required to make a deposit permission.
+ */
+ data class DepositInfo(
+ val exchangeBaseUrl: String,
+ val contractTermsHash: String,
+ val coinPublicKey: String,
+ val coinPrivateKey: String,
+ val spendAmount: Amount,
+ val timestamp: Timestamp,
+ val refundDeadline: Timestamp,
+ val merchantPublicKey: String,
+ val feeDeposit: Amount,
+ val wireInfoHash: String,
+ val denomPublicKey: String,
+ val denomSignature: String
+ )
+
+ /**
+ * Deposit permission for a single coin.
+ */
+ // TODO rename _
+ data class CoinDepositPermission(
+ /**
+ * Signature by the coin.
+ */
+ val coinSignature: String,
+ /**
+ * Public key of the coin being spend.
+ */
+ val coinPublicKey: String,
+ /**
+ * Signature made by the denomination public key.
+ */
+ val denomSignature: String,
+ /**
+ * The denomination public key associated with this coin.
+ */
+ val denomPublicKey: String,
+ /**
+ * The amount that is subtracted from this coin with this payment.
+ */
+ val contribution: String,
+ /**
+ * URL of the exchange this coin was withdrawn from.
+ */
+ val exchangeBaseUrl: String
+ )
+
+ /**
+ * Generate updated coins (to store in the database) and deposit
permissions for each given coin.
+ */
+ fun signDepositPermission(depositInfo: DepositInfo): CoinDepositPermission
{
+ val d = Signature.PurposeBuilder(WALLET_COIN_DEPOSIT)
+ .put(Base32Crockford.decode(depositInfo.contractTermsHash))
+ .put(Base32Crockford.decode(depositInfo.wireInfoHash))
+ .put(depositInfo.timestamp.roundedToByteArray())
+ .put(depositInfo.refundDeadline.roundedToByteArray())
+ .put(depositInfo.spendAmount.toByteArray())
+ .put(depositInfo.feeDeposit.toByteArray())
+ .put(Base32Crockford.decode(depositInfo.merchantPublicKey))
+ .put(Base32Crockford.decode(depositInfo.coinPublicKey))
+ .build()
+ val coinPriv = Base32Crockford.decode(depositInfo.coinPrivateKey);
+ val coinSig = crypto.eddsaSign(d, coinPriv)
+ return CoinDepositPermission(
+ coinPublicKey = depositInfo.coinPublicKey,
+ coinSignature = Base32Crockford.encode(coinSig),
+ contribution = depositInfo.spendAmount.toJSONString(),
+ denomPublicKey = depositInfo.denomPublicKey,
+ exchangeBaseUrl = depositInfo.exchangeBaseUrl,
+ denomSignature = depositInfo.denomSignature
+ )
+ }
+
+}
diff --git
a/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/DepositTest.kt
b/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/DepositTest.kt
new file mode 100644
index 0000000..6e74fb2
--- /dev/null
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/crypto/DepositTest.kt
@@ -0,0 +1,74 @@
+package net.taler.wallet.kotlin.crypto
+
+import net.taler.wallet.kotlin.Amount
+import net.taler.wallet.kotlin.Timestamp
+import net.taler.wallet.kotlin.crypto.Deposit.CoinDepositPermission
+import net.taler.wallet.kotlin.crypto.Deposit.DepositInfo
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class DepositTest {
+
+ private val crypto = CryptoFactory.getCrypto()
+ private val deposit = Deposit(crypto)
+
+ private class DepositVector(val depositInfo: DepositInfo, val permission:
CoinDepositPermission)
+
+ @Test
+ fun test() {
+ val vectors = listOf(
+ DepositVector(
+ DepositInfo(
+ exchangeBaseUrl = "example.org",
+ contractTermsHash =
"QS3RK40J3262QRAJG4SVZB0C60N45W7D71ZXFTP385E05PKR7RGH22QTPA109Z0EBD120SHA09WHA72K4PCFM6JTFMCZEGVW2T9FT2R",
+ coinPublicKey =
"6DMP3NPY6DZD0QDMEW6955R6ZCX3T052PRJE0FYHTKRA837VMQT0",
+ coinPrivateKey =
"XWVF454Q600NGSMF7RYXY369N2DJKC1YQZG0RFAF8EMRRY8DJE50",
+ spendAmount = Amount("TESTKUDOS", 8, 0),
+ timestamp = Timestamp(1593522039000),
+ refundDeadline = Timestamp(1593522939000),
+ merchantPublicKey =
"RQSR35MJJDP5Y27XMBEV7QBG4HTE3JXR1JCE4NCYCAQHKJ8CB5T0",
+ feeDeposit = Amount("TESTKUDOS", 0, 2000000),
+ wireInfoHash =
"5C3WXB9PVPXAGGQVRJGAMBJJQBBYPHZEZZYVHQ8RS97F9EZABPAWNWSGD1VH6YNFB58GPJWX1A17DFNCK0S9YPP7PED3ZXR76E2A0XR",
+ denomPublicKey =
"020000YQX8JZNBMJ8PTVRZZT27TTSJN5HM0037K0BSY3YWP0VF8GFYYAN06J0PTQVQGQJGVJ91CHWD6QCH9MKADR1VH31P5WEMTMWWTX6KWA3KX0FD1RWQSPJ8W8ZXVWPVDJVVJ08W12VWV39A9W4SDCMWBSQ17QV4RP86JJFMTEWB540KKYHY3ZYJEQYVN9XD7CM7SCAMM8WV03P0VG2001",
+ denomSignature =
"9F3M4AZ8BN3MJRH6T49TD9R4EVTF6C5NH365DHCC73F39N3SAK422NY9ZWN7WANGW3M4XZTJDDV1B1E7MSW03VCESKSF8889EDTRE1VHF0FT3E5CT0Q449JAQQ6DSDY4D9JMPP99TRKZX86VAXN45FBSBXTJZ2FN85Y67T9ADDNDXMV060J0HP7G5YXXJQ0V7KHACEZFVXFH6"
+ ),
+ CoinDepositPermission(
+ coinSignature =
"CZX4HMBR6H3W1KAN1T0HZ11VBSERZ6JM715MKSDAJJSXWQTZ0GDCZX92MAKMH0DB7B389E24XGP6X7ZSAQVW540KTQZJ9RMR0R9CM08",
+ coinPublicKey =
"6DMP3NPY6DZD0QDMEW6955R6ZCX3T052PRJE0FYHTKRA837VMQT0",
+ denomSignature =
"9F3M4AZ8BN3MJRH6T49TD9R4EVTF6C5NH365DHCC73F39N3SAK422NY9ZWN7WANGW3M4XZTJDDV1B1E7MSW03VCESKSF8889EDTRE1VHF0FT3E5CT0Q449JAQQ6DSDY4D9JMPP99TRKZX86VAXN45FBSBXTJZ2FN85Y67T9ADDNDXMV060J0HP7G5YXXJQ0V7KHACEZFVXFH6",
+ denomPublicKey =
"020000YQX8JZNBMJ8PTVRZZT27TTSJN5HM0037K0BSY3YWP0VF8GFYYAN06J0PTQVQGQJGVJ91CHWD6QCH9MKADR1VH31P5WEMTMWWTX6KWA3KX0FD1RWQSPJ8W8ZXVWPVDJVVJ08W12VWV39A9W4SDCMWBSQ17QV4RP86JJFMTEWB540KKYHY3ZYJEQYVN9XD7CM7SCAMM8WV03P0VG2001",
+ contribution = "TESTKUDOS:8",
+ exchangeBaseUrl = "example.org"
+ )
+ ),
+ DepositVector(
+ DepositInfo(
+ exchangeBaseUrl = "example.org",
+ contractTermsHash =
"CWWDVCEX745A092KB3W7K98M7EVK4G5HJRHKR0RTPKAFR1VSK147ER131PT23P8ZWH2VMWAWENTVTAXP4KDRQ9YY0951N2G2JZFGEXG",
+ coinPublicKey =
"ZR6BER43XSR3NK705HFKGC842Q3Q2R4G3T6VQ5JEK8EAC34JYW6G",
+ coinPrivateKey =
"CP8WW83V239DTXD84M87TZ0DG1TGM4RC3D77NN936554B7GDVBRG",
+ spendAmount = Amount("TESTKUDOS", 1, 0),
+ timestamp = Timestamp(1593522635000),
+ refundDeadline = Timestamp(1593523535000),
+ merchantPublicKey =
"S8WFGCK6CJGFWYWHAY56NTZTD84S31TGM244GTVKTCETKW5HDBQG",
+ feeDeposit = Amount("TESTKUDOS", 0, 2000000),
+ wireInfoHash =
"8GQFCMQXHHTF7VG73WVJN8PFCPH4Y0ZRSWAQ01A6A9F0Y0HY59H3RDPMBPVNJJDJP1S3E8JJVE7MGAC9YDACWAVCTE75QZ8ZRNAH3X8",
+ denomPublicKey =
"020000X1NCWC14MNXTAJ17W6HY5AMGXKGV392BESTESJJ8TQ41W9W2RBN69Q3WQYQQXS7KS5ZMDSSGHY0H7921X0RRA6ZNW2RSKJGXJNQM66KRDEFTQ50B6ZK60CSCY3KZ0RSGAYBG8VHC2A87Z6DQS361G8BAJS937J9YX89MGVMG896MKVEZ3H3NGRJTT89QNGN5KZWFSE6G5129GG2001",
+ denomSignature =
"7XJDMABJHV01GX7S764ZY3XR3AX2KAK4AXWKZJHBRV8BBQ7KQ5FHC372GE8RF8M2NT128G85RWW87CNNVYNWWPEPSFN8QXTA2H6SGTR0EFRDF4CXAJRXHWPB450YMJM7MNNPJKXDDXCFN87RSHFZ4ESH06S0SBX6185DX2HD6JWQ3BESCK8PYCB6A09KP5ZD0EZSQKDGNGMEG"
+ ),
+ CoinDepositPermission(
+ coinSignature =
"A8N1NSMSPZ4H1VR1YANYMAE74VAJ7W88EMRNDY74YXPK2WFEEHHM28VVQ3HAK6J0P9YX61XGNHRP08AEX59M0YGJ7AW8ZG2Y5FQD23G",
+ coinPublicKey =
"ZR6BER43XSR3NK705HFKGC842Q3Q2R4G3T6VQ5JEK8EAC34JYW6G",
+ denomSignature =
"7XJDMABJHV01GX7S764ZY3XR3AX2KAK4AXWKZJHBRV8BBQ7KQ5FHC372GE8RF8M2NT128G85RWW87CNNVYNWWPEPSFN8QXTA2H6SGTR0EFRDF4CXAJRXHWPB450YMJM7MNNPJKXDDXCFN87RSHFZ4ESH06S0SBX6185DX2HD6JWQ3BESCK8PYCB6A09KP5ZD0EZSQKDGNGMEG",
+ denomPublicKey =
"020000X1NCWC14MNXTAJ17W6HY5AMGXKGV392BESTESJJ8TQ41W9W2RBN69Q3WQYQQXS7KS5ZMDSSGHY0H7921X0RRA6ZNW2RSKJGXJNQM66KRDEFTQ50B6ZK60CSCY3KZ0RSGAYBG8VHC2A87Z6DQS361G8BAJS937J9YX89MGVMG896MKVEZ3H3NGRJTT89QNGN5KZWFSE6G5129GG2001",
+ contribution = "TESTKUDOS:1",
+ exchangeBaseUrl = "example.org"
+ )
+ )
+ )
+ for (v in vectors) {
+ assertEquals(v.permission,
deposit.signDepositPermission(v.depositInfo))
+ }
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.