| 1 | """ |
|---|
| 2 | >>> from entities import Wallet, IssuerEntity |
|---|
| 3 | >>> from transports import ServerTestTransport, ClientTest |
|---|
| 4 | >>> walletA = Wallet() |
|---|
| 5 | >>> walletB = Wallet() |
|---|
| 6 | >>> ie = IssuerEntity() |
|---|
| 7 | >>> ie.createMasterKey(keylength=512) |
|---|
| 8 | >>> ie.makeCDD(currency_identifier='http://opencent.net/OpenCent', denominations=['1', '2'], |
|---|
| 9 | ... short_currency_identifier='OC', options=[('version', '0')], issuer_service_location='here') |
|---|
| 10 | >>> ie.issuer.setCurrentCDDVersion('0') |
|---|
| 11 | |
|---|
| 12 | >>> walletA.setCurrentCDD(ie.issuer.getCDD()) |
|---|
| 13 | >>> walletB.setCurrentCDD(ie.issuer.getCDD()) |
|---|
| 14 | |
|---|
| 15 | >>> CDD.toJson() |
|---|
| 16 | '[["standard_identifier","http://opencoin.org/OpenCoinProtocol/1.0"],["currency_identifier","http://opencent.net/OpenCent"],["short_currency_identifier","OC"],["issuer_service_location","opencoin://issuer.opencent.net:8002"],["denominations",["1","2","5","10","20","50","100","200","500","1000"]],["issuer_cipher_suite",["RSASigningAlgorithm","RSABlindingAlgorithm","SHA256HashingAlgorithm"]],["options",[["version","0"]]],["issuer_public_master_key","sloGu4+P4rslyC4RiAJrZbG0Z90FwEV88eW1JnNv7BDU33+uIhi2G0f/XL+AoUwmF1VsdhQhzEtGNVjnlx0TViWgqvrYX6AqB1/R3zYP9+JnuIIyHiyS+Z+Y3uoB0sLMD+dvHcDRo7cbb+ZNAvlcPoQ4Hb3+tuxwBMmVkZMaOu8=,AQAB"],["signature",[["keyprint","hxz5pRwS+RFp88qQliXYm3R5uNighktwxqEh4RMOuuk="],["signature","nG6zXX7NDfPgmI2qGbvg/oug2B8uhJbLRDxyWPZeJD6gB+p4BOnzgMq8Hpe6FtnXgyQ407cgiyuQ0p20H4ko1LPEM2qIOZToUXeqmLYSjoNYBy5ctMaN+yATswJgD97nzWlH+YxVdMH+L1k2twhFO3x13URDNlN6WsZTYplmRoY="]]]]' |
|---|
| 17 | |
|---|
| 18 | Lets test without having any keys in the mint |
|---|
| 19 | |
|---|
| 20 | >>> t = ClientTest(ie.issuer.listen) |
|---|
| 21 | >>> walletA.fetchMintKey(t,denominations=['1']) |
|---|
| 22 | Client <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 23 | Server <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0'], ['cdd_version', '0']])> |
|---|
| 24 | Client <Message('MINT_KEY_FETCH_DENOMINATION',[['1'], '0'])> |
|---|
| 25 | Server <Message('MINT_KEY_FAILURE',[['1', 'Unknown denomination']])> |
|---|
| 26 | Client <Message('GOODBYE',None)> |
|---|
| 27 | Server <Message('GOODBYE',None)> |
|---|
| 28 | |
|---|
| 29 | Now, lets have a key |
|---|
| 30 | |
|---|
| 31 | >>> now = 500; later = 1000; much_later = 2000 |
|---|
| 32 | >>> pub1 = ie.createSignedMintKey('1', now, later, much_later) |
|---|
| 33 | >>> t = ClientTest(ie.issuer.listen) |
|---|
| 34 | >>> ie.issuer.getTime = lambda: 750 |
|---|
| 35 | >>> walletA.fetchMintKey(t,denominations=['1']) |
|---|
| 36 | Client <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 37 | Server <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0'], ['cdd_version', '0']])> |
|---|
| 38 | Client <Message('MINT_KEY_FETCH_DENOMINATION',[['1'], '0'])> |
|---|
| 39 | Server <Message('MINT_KEY_PASS',[[...]])> |
|---|
| 40 | Client <Message('GOODBYE',None)> |
|---|
| 41 | Server <Message('GOODBYE',None)> |
|---|
| 42 | |
|---|
| 43 | Test the transfer token protocol |
|---|
| 44 | >>> ie = makeIssuerEntity() |
|---|
| 45 | >>> issuer = ie.issuer |
|---|
| 46 | >>> t = ClientTest(issuer.listen) |
|---|
| 47 | >>> coin1 = coins[0][0] # denomination of 1 |
|---|
| 48 | >>> coin2 = coins[1][0] # denomination of 2 |
|---|
| 49 | >>> walletB.coins = [coin1, coin2] |
|---|
| 50 | >>> walletB.transferTokens(t,'myaccount',[],[coin1, coin2],type='redeem') |
|---|
| 51 | Client <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 52 | Server <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0'], ['cdd_version', '0']])> |
|---|
| 53 | Client <Message('TRANSFER_TOKEN_REQUEST',['...', 'myaccount', [], [[(...)], [(...)]], [['type', 'redeem']]])> |
|---|
| 54 | Server <Message('TRANSFER_TOKEN_ACCEPT',['...', []])> |
|---|
| 55 | Client <Message('GOODBYE',None)> |
|---|
| 56 | Server <Message('GOODBYE',None)> |
|---|
| 57 | |
|---|
| 58 | Test the transfer token protocol with an exchange |
|---|
| 59 | >>> ie = makeIssuerEntity() |
|---|
| 60 | >>> import calendar |
|---|
| 61 | >>> ie.getTime = ie.mint.getTime = ie.issuer.getTime = lambda: calendar.timegm((2008,01,31,0,0,0)) |
|---|
| 62 | >>> t = ClientTest(ie.issuer.listen) |
|---|
| 63 | >>> coin1 = coins[0][0] # denomination of 1 |
|---|
| 64 | >>> coin2 = coins[1][0] # denomination of 2 |
|---|
| 65 | >>> walletB.coins = [coin1, coin2] |
|---|
| 66 | >>> walletB.keyids = {mintKeys[0].key_identifier: mintKeys[0]} |
|---|
| 67 | >>> blank1 = makeBlank(mintKeys[0], serial='abcdefghijklmnopqrstuvwxyz', blind_factor='a'*26) |
|---|
| 68 | >>> blank2 = makeBlank(mintKeys[0], serial='aaaaaaaaaaaaaaaaaaaaaaaaaa', blind_factor='b'*26) |
|---|
| 69 | >>> blank3 = makeBlank(mintKeys[0], serial='bbbbbbbbbbbbbbbbbbbbbbbbbb', blind_factor='c'*26) |
|---|
| 70 | >>> blanks = [blank1, blank2, blank3] |
|---|
| 71 | >>> import base64 |
|---|
| 72 | |
|---|
| 73 | >>> walletB.transferTokens(t, 'myaccount', blanks, walletB.coins, type='exchange') |
|---|
| 74 | Client <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 75 | Server <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0'], ['cdd_version', '0']])> |
|---|
| 76 | Client <Message('TRANSFER_TOKEN_REQUEST',['...', 'myaccount', [['...', ['...', '...', '...']]], [[(...)], [(...)]], [['type', 'exchange']]])> |
|---|
| 77 | Server <Message('TRANSFER_TOKEN_ACCEPT',['...', ['...', '...', '...']])> |
|---|
| 78 | Client <Message('GOODBYE',None)> |
|---|
| 79 | Server <Message('GOODBYE',None)> |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | Test the coin spend protocol. |
|---|
| 83 | |
|---|
| 84 | >>> ie = makeIssuerEntity() |
|---|
| 85 | >>> ie.getTime = ie.mint.getTime = ie.issuer.getTime = lambda: calendar.timegm((2008,01,31,0,0,0)) |
|---|
| 86 | >>> t = ClientTest(walletB.listen,clientnick='walletA',servernick='walletB') |
|---|
| 87 | >>> t2 = ClientTest(ie.issuer.listen,clientnick='walletB',servernick='issuer') |
|---|
| 88 | >>> walletB.addIssuerTransport(location='here', transport=t2) |
|---|
| 89 | >>> walletA.coins=[coin1] |
|---|
| 90 | >>> walletA.sendCoins(t, target='a book', amount=1) |
|---|
| 91 | walletA <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 92 | walletB <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0']])> |
|---|
| 93 | walletA <Message('SUM_ANNOUNCE',['...', '...', '...', '1', 'a book'])> |
|---|
| 94 | walletB <Message('SUM_ACCEPT',None)> |
|---|
| 95 | walletA <Message('SPEND_TOKEN_REQUEST',['...', [[(...)]], 'a book'])> |
|---|
| 96 | walletB <Message('HANDSHAKE',[['protocol', 'opencoin 1.0']])> |
|---|
| 97 | issuer <Message('HANDSHAKE_ACCEPT',[['protocol', 'opencoin 1.0'], ['cdd_version', '0']])> |
|---|
| 98 | walletB <Message('TRANSFER_TOKEN_REQUEST',['...', 'my account', [], [[(...)]], [['type', 'redeem']]])> |
|---|
| 99 | issuer <Message('TRANSFER_TOKEN_ACCEPT',['...', []])> |
|---|
| 100 | walletB <Message('GOODBYE',None)> |
|---|
| 101 | issuer <Message('GOODBYE',None)> |
|---|
| 102 | walletB <Message('SPEND_TOKEN_ACCEPT',None)> |
|---|
| 103 | walletA <Message('GOODBYE',None)> |
|---|
| 104 | walletB <Message('GOODBYE',None)> |
|---|
| 105 | |
|---|
| 106 | >>> coinB.validate_with_CDD_and_MintKey(CDD,mint_key1) |
|---|
| 107 | True |
|---|
| 108 | """ |
|---|
| 109 | |
|---|
| 110 | def printdict(d): |
|---|
| 111 | """prints out the normal representation of a dict, except the keys |
|---|
| 112 | of the dict are sorted. |
|---|
| 113 | """ |
|---|
| 114 | s = [] |
|---|
| 115 | s.append('{') |
|---|
| 116 | keys = d.keys() |
|---|
| 117 | keys.sort() |
|---|
| 118 | for key in keys: |
|---|
| 119 | s.append('%s: %s' % (repr(key), repr(d[key]))) |
|---|
| 120 | if key != keys[-1]: |
|---|
| 121 | s.append(', ') |
|---|
| 122 | s.append('}') |
|---|
| 123 | print ''.join(s) |
|---|
| 124 | |
|---|
| 125 | def printdictlist(l): |
|---|
| 126 | """prints out the normal representation of a list of dicts, except |
|---|
| 127 | the keys of the dict are sorted. |
|---|
| 128 | """ |
|---|
| 129 | s = [] |
|---|
| 130 | s.append('[') |
|---|
| 131 | for d in l: |
|---|
| 132 | s.append('{') |
|---|
| 133 | keys = d.keys() |
|---|
| 134 | keys.sort() |
|---|
| 135 | for key in keys: |
|---|
| 136 | s.append('%s: %s' % (repr(key), repr(d[key]))) |
|---|
| 137 | if key != keys[-1]: |
|---|
| 138 | s.append(', ') |
|---|
| 139 | s.append('}') |
|---|
| 140 | if d is not l[-1]: |
|---|
| 141 | s.append(', ') |
|---|
| 142 | s.append(']') |
|---|
| 143 | print ''.join(s) |
|---|
| 144 | |
|---|
| 145 | def generateCDD(): |
|---|
| 146 | import crypto, containers, base64 |
|---|
| 147 | ics = crypto.CryptoContainer(signing=crypto.RSASigningAlgorithm, |
|---|
| 148 | blinding=crypto.RSABlindingAlgorithm, |
|---|
| 149 | hashing=crypto.SHA256HashingAlgorithm) |
|---|
| 150 | |
|---|
| 151 | keystring = 'sloGu4+P4rslyC4RiAJrZbG0Z90FwEV88eW1JnNv7BDU33+uIhi2G0f/XL+AoUwmF1V' + \ |
|---|
| 152 | 'sdhQhzEtGNVjnlx0TViWgqvrYX6AqB1/R3zYP9+JnuIIyHiyS+Z+Y3uoB0sLMD+dvHc' + \ |
|---|
| 153 | 'DRo7cbb+ZNAvlcPoQ4Hb3+tuxwBMmVkZMaOu8=,AQAB,AiF/ORhzAKN5xRV/0h8tR07' + \ |
|---|
| 154 | 'DOAZ0/iIWZxF2g5oXeTuOP4lX/EJNUrAehe4nzEWLovW7UQHWkYlIsnR4d966D2VGMe' + \ |
|---|
| 155 | 'UigesAQXO7gq3EewXq2su8Pexh7XDJ1bQlh0HO0sc3DMznc12lM46Doc5bAYm0hPChS' + \ |
|---|
| 156 | 'ThWrJUE6N4lMhk=,ujW93T/IqikcIMJHdQUDRqVdClYNreRBz+P/vgzrRZqCVnB9x+d' + \ |
|---|
| 157 | 'kLu5VdPzJKDoeOkaD7AGDyOJJFNSS3w8gMw==,9TJPF5RSdm/u2L0RSaehwrS4IOEUi' + \ |
|---|
| 158 | 'oBZapb1aQUeohzDgAytuBjp1xywmsYmNEKHXy04qwInKiCPA7blgqdOVQ==' |
|---|
| 159 | |
|---|
| 160 | private_key = crypto.RSAKeyPair(input=[base64.b64decode(i) for i in keystring.split(',')]) |
|---|
| 161 | |
|---|
| 162 | public_key = private_key.newPublicKeyPair() |
|---|
| 163 | |
|---|
| 164 | cdd = containers.CDD(standard_identifier='http://opencoin.org/OpenCoinProtocol/1.0', |
|---|
| 165 | currency_identifier = 'http://opencent.net/OpenCent', |
|---|
| 166 | short_currency_identifier = 'OC', |
|---|
| 167 | issuer_service_location = 'opencoin://issuer.opencent.net:8002', |
|---|
| 168 | denominations = ['1', '2', '5', '10', '20', '50', '100', '200', '500', '1000'], |
|---|
| 169 | issuer_cipher_suite = ics, |
|---|
| 170 | options = [('version', '0')], |
|---|
| 171 | issuer_public_master_key = public_key) |
|---|
| 172 | |
|---|
| 173 | signature = containers.Signature(keyprint=ics.hashing(str(public_key)).digest(), |
|---|
| 174 | signature=ics.signing(private_key).sign(ics.hashing(cdd.content_part()).digest())) |
|---|
| 175 | |
|---|
| 176 | cdd.signature = signature |
|---|
| 177 | |
|---|
| 178 | return private_key, cdd |
|---|
| 179 | |
|---|
| 180 | #IS private key, CDD |
|---|
| 181 | CDD_private, CDD = generateCDD() |
|---|
| 182 | |
|---|
| 183 | def makeKeys512(): |
|---|
| 184 | """A helper function to generate specific rsa 512 bit keys. |
|---|
| 185 | |
|---|
| 186 | Used to generate keys we can use other places and have repeatable effects. |
|---|
| 187 | Do not remove/change any of these. It will become messy. |
|---|
| 188 | |
|---|
| 189 | >>> import crypto, base64 |
|---|
| 190 | >>> hash_alg = crypto.SHA256HashingAlgorithm |
|---|
| 191 | >>> keys = makeKeys512() |
|---|
| 192 | |
|---|
| 193 | >>> base64.b64encode(hash_alg(keys[0].stringPrivate()).digest()) |
|---|
| 194 | 'S/z7RqJEz3PpvbGtA0UYLJ6HVLegvBiVgg8WEkU551w=' |
|---|
| 195 | |
|---|
| 196 | >>> base64.b64encode(hash_alg(keys[1].stringPrivate()).digest()) |
|---|
| 197 | 'YyGbBpAfgTMy8duw4B1lbeSmiGTvww/VkAjTOLqY+JA=' |
|---|
| 198 | |
|---|
| 199 | >>> base64.b64encode(hash_alg(keys[2].stringPrivate()).digest()) |
|---|
| 200 | 'EzEkB1Ji0fmeNbbBYLDSLh8PFKvTa7PfICJi5idh8jM=' |
|---|
| 201 | |
|---|
| 202 | >>> base64.b64encode(hash_alg(keys[3].stringPrivate()).digest()) |
|---|
| 203 | '66Qd4kVWAaWj8fQMDDsGjA0+M6lMD77XIsV/QYO0KDE=' |
|---|
| 204 | |
|---|
| 205 | >>> base64.b64encode(hash_alg(keys[4].stringPrivate()).digest()) |
|---|
| 206 | 'g8HYpCtirVSjxjrY2myXbI1VGL95/H8fIE4lmorloGk=' |
|---|
| 207 | """ |
|---|
| 208 | import crypto, base64 |
|---|
| 209 | |
|---|
| 210 | def makeKey(keystring): |
|---|
| 211 | return crypto.RSAKeyPair(input=[base64.b64decode(i) for i in keystring.split(',')]) |
|---|
| 212 | |
|---|
| 213 | keys = [] |
|---|
| 214 | s = 'rYVRng96lTEuiWcM3J6G1o3DqGtw4qbLH/PqSQ/FVe1JpCBG07QJ2QDVwnvgtFZc' + \ |
|---|
| 215 | 'Iq0rGpB3TMukY4VGAtTp9w==,AQAB,UVV/Z0Y8IDhYZuFdvv+zllgG0SfjVun1pj' + \ |
|---|
| 216 | 'mPpMV2qwpw2b7QpveBESZZhc8hct6JhGwdPv2RP38W9MEsKwb3AQ==,sIGnsjB85' + \ |
|---|
| 217 | 'BQJFVev7kQXBYxHcWQrDzrzjyzAwp6NhYE=,+6ttoqGqAEEgbkE9aCrUH4k5mg1g' + \ |
|---|
| 218 | 'IR3qqbyasAIXW3c=' |
|---|
| 219 | keys.append(makeKey(s)) |
|---|
| 220 | |
|---|
| 221 | s = 'zBuIJ/ACheE6HpkB3BnwlsBs3tz21netK32qyne011ViCFX+IbAf/AzxqU8eZW9b' + \ |
|---|
| 222 | '1HBtgdFEdYplWaD2/ghZkQ==,AQAB,x5t1QHl8PinRiPLh2rqTixqMXjeCPqOzew' + \ |
|---|
| 223 | 'De8jq3ZI2e56BWc0QpoHmFVYOPLC7aTuNLAMXRG1xy/3qBjN9GsQ==,0KaRUW+hT' + \ |
|---|
| 224 | '14heMy/ysBRq3cZGCXLXxlF8cIyvXpVPBM=,+m0I++1ewqqXzyQyg27uBPzt6M+t' + \ |
|---|
| 225 | 'cIgaJqFk7AMpQEs=' |
|---|
| 226 | keys.append(makeKey(s)) |
|---|
| 227 | |
|---|
| 228 | s = 'qQMxi5ZWvGNOSoWD2oQG/rcOYyu54JMPpShgClph5O+3MiEoKxUrxt6HKZ9XUfXO' + \ |
|---|
| 229 | '1nkAVM/p3D3AAKm8EghAWQ==,AQAB,Tc9mk/kW3Yxqkux9E7EM91+XhBixbq7F2S' + \ |
|---|
| 230 | 'eJb7rErvzdu93lb133GoSutTgw04fZxLtCJmH5zCksYB0AxeoNwQ==,wcUPKrytT' + \ |
|---|
| 231 | 'rxmjiySKK5C5gSmlH3zntNLKrQBEmgcwDU=,30qxhmW49MKN4vrjhaB4DHNLOAA7' + \ |
|---|
| 232 | 'FR9BC4f42j1CDBU=' |
|---|
| 233 | keys.append(makeKey(s)) |
|---|
| 234 | |
|---|
| 235 | keys.append(makeKey('iKRbuOcx0ZaonCW2174PGJ7NndVz2SsrviRFBI7iH1Ef2DAY' + |
|---|
| 236 | '+mMQOkrZouSoERGx+qzfxxomsbdNAWWn9DE5qQ==,AQAB,KDCPedcmZAr4FNVS7i' + |
|---|
| 237 | 'nMruUmfSHnLRzxhL+OPUT5ZVQ8GLPUrwb5xu64iN1wA+GX3Ye4MBZnKTxBTztyqs' + |
|---|
| 238 | 'IeMQ==,o9YCYd6frBAkNn6GTi5Xdq+KWISbgSz2ATpQfYCw/ZM=,1YInKagsCHLs' + |
|---|
| 239 | 'Qxngi0XH1aCrI1Z82bCyEar4dENO0VM=')) |
|---|
| 240 | |
|---|
| 241 | keys.append(makeKey('0LacqxKYf46SeT4fLOe4Ovar2ubneiQzUltTZ19r/RyyYBYi' + |
|---|
| 242 | '+0FQlLApSQeYKIq1GBmPRZRC0PqrcJdO5d1P/Q==,AQAB,H7GbWN8aCUS9OWwVj9' + |
|---|
| 243 | 'wgPdP3hOZLgGC+6mKz556151mN4hDtscN4v0WoO7MVC19sPr9h8v7VQrCxabVE1k' + |
|---|
| 244 | 'BcAQ==,2HW624HBCsiylu4ivxbzH2jNt2wh4FosOjmqxa1qJbU=,9tahqi751CGj' + |
|---|
| 245 | 'p7jaihYBKeYl9dVPmZN2q81jhM7z7ik=')) |
|---|
| 246 | |
|---|
| 247 | return keys |
|---|
| 248 | |
|---|
| 249 | #contains private mint keys! |
|---|
| 250 | keys512 = makeKeys512() |
|---|
| 251 | |
|---|
| 252 | def addSignature(cont, hash_alg, sign_alg, signing_key, keyprint): |
|---|
| 253 | from containers import Signature |
|---|
| 254 | hasher = hash_alg(cont.content_part()) |
|---|
| 255 | signer = sign_alg(signing_key) |
|---|
| 256 | signature = Signature(keyprint=keyprint, |
|---|
| 257 | signature=signer.sign(hasher.digest())) |
|---|
| 258 | cont.signature = signature |
|---|
| 259 | return cont |
|---|
| 260 | |
|---|
| 261 | def makeMintKeys(): |
|---|
| 262 | """makes MintKeys of denomination 1, 2, and 5. |
|---|
| 263 | >>> import base64 |
|---|
| 264 | >>> mintkey1, mintkey2, mintkey5, mintkey10 = makeMintKeys() |
|---|
| 265 | |
|---|
| 266 | >>> base64.b64encode(mintkey1.signature.signature) |
|---|
| 267 | 'YaVpcSavYfEwKuoaR3PPsSMBD3c2bMSP4iHdHAUKqmOFrb5qgrNPhLwPNAeSZe6qoLB09bIFVFFW46Xv+FzZ3WghmlRmtKD+LFV9+2xu/jXAjwi+VqSFwjLjttbxSbeYWce6IiWKlklHBBZ2zwXY5CP2QqZ6Zt5i0HE6fEM8KRU=' |
|---|
| 268 | |
|---|
| 269 | >>> base64.b64encode(mintkey2.signature.signature) |
|---|
| 270 | 'Es5my5lRwFVYx49EVMJwZPgoXC00QBFCvS0H0MRC+rxCufY+s59ivai20+aTjq+cO5hslEIE4L3ne0bMpNliG2d4XP9fuLCggGbtzrCLEAt6GLS9xEzIsk0EbGAxLxceL28zJTJHQqZm1pRKHbH0Gv5pxZmMx3AmGB80uOCjdBU=' |
|---|
| 271 | |
|---|
| 272 | >>> base64.b64encode(mintkey5.signature.signature) |
|---|
| 273 | 'epNc+/Nq3lshowLTi4tue26m0ED62cue95vqvMSllDtV4cBZ23YCEDGD8aHmcJZ7bB12MCE/lAWO6aR4FQDfyc1U6LAbuOuuAERnZhaDc9ZKWvamn3uPvjV3722vje4P6Ic2sbJ+ch7NItrmdktnG4Vap88iIAPCnWl/zivZUWA=' |
|---|
| 274 | |
|---|
| 275 | >>> base64.b64encode(mintkey10.signature.signature) |
|---|
| 276 | 'EwgUD6dZVkIEw8ALyVAIkSQLqbfzdNEMD3cYIZZHZ3TuxoKtvT3RG9NnN+PhWKH956ehNmbyVVOLqmEABMIi+3CXLGhkO2YqVCW9619gAF5S/UaYRVE+ijWcAYbAWoBestRhirnBEEBvBcFRk1rQJx8IqEzBMyUk//UbvcneVog=' |
|---|
| 277 | """ |
|---|
| 278 | from containers import MintKey |
|---|
| 279 | import copy |
|---|
| 280 | from calendar import timegm |
|---|
| 281 | |
|---|
| 282 | hash_alg = CDD.issuer_cipher_suite.hashing |
|---|
| 283 | sign_alg = CDD.issuer_cipher_suite.signing |
|---|
| 284 | |
|---|
| 285 | def makeMintKey(denomination, public, private): |
|---|
| 286 | mintKey = MintKey(key_identifier=public.key_id(hash_alg), |
|---|
| 287 | currency_identifier='http://opencent.net/OpenCent', |
|---|
| 288 | denomination=denomination, |
|---|
| 289 | not_before=timegm((2008,1,1,0,0,0)), |
|---|
| 290 | key_not_after=timegm((2008,2,1,0,0,0)), |
|---|
| 291 | token_not_after=timegm((2008,4,1,0,0,0)), |
|---|
| 292 | public_key=public) |
|---|
| 293 | addSignature(mintKey, hash_alg, sign_alg, CDD_private, CDD.signature.keyprint) |
|---|
| 294 | |
|---|
| 295 | return mintKey |
|---|
| 296 | |
|---|
| 297 | private0 = keys512[0] |
|---|
| 298 | public0 = private0.newPublicKeyPair() |
|---|
| 299 | mintKey0 = makeMintKey('1', public0, private0) |
|---|
| 300 | |
|---|
| 301 | private1 = keys512[1] |
|---|
| 302 | public1 = private1.newPublicKeyPair() |
|---|
| 303 | mintKey1 = makeMintKey('2', public1, private1) |
|---|
| 304 | |
|---|
| 305 | private2 = keys512[2] |
|---|
| 306 | public2 = private2.newPublicKeyPair() |
|---|
| 307 | mintKey2 = makeMintKey('5', public2, private2) |
|---|
| 308 | |
|---|
| 309 | private3 = keys512[3] |
|---|
| 310 | public3 = private3.newPublicKeyPair() |
|---|
| 311 | mintKey3 = makeMintKey('10', public3, private3) |
|---|
| 312 | |
|---|
| 313 | return (mintKey0, mintKey1, mintKey2, mintKey3) |
|---|
| 314 | |
|---|
| 315 | mintKeys = makeMintKeys() |
|---|
| 316 | |
|---|
| 317 | def makeCoins(): |
|---|
| 318 | """makes coins for testing |
|---|
| 319 | >>> coins = makeCoins() |
|---|
| 320 | |
|---|
| 321 | >>> coins[0][0].validate_with_CDD_and_MintKey(CDD, mintKeys[0]) |
|---|
| 322 | True |
|---|
| 323 | >>> coins[0][1].validate_with_CDD_and_MintKey(CDD, mintKeys[0]) |
|---|
| 324 | True |
|---|
| 325 | |
|---|
| 326 | >>> coins[1][0].validate_with_CDD_and_MintKey(CDD, mintKeys[1]) |
|---|
| 327 | True |
|---|
| 328 | >>> coins[1][1].validate_with_CDD_and_MintKey(CDD, mintKeys[1]) |
|---|
| 329 | True |
|---|
| 330 | >>> coins[1][2].validate_with_CDD_and_MintKey(CDD, mintKeys[1]) |
|---|
| 331 | True |
|---|
| 332 | >>> coins[1][3].validate_with_CDD_and_MintKey(CDD, mintKeys[1]) |
|---|
| 333 | True |
|---|
| 334 | >>> coins[1][4].validate_with_CDD_and_MintKey(CDD, mintKeys[1]) |
|---|
| 335 | True |
|---|
| 336 | |
|---|
| 337 | >>> coins[2][0].validate_with_CDD_and_MintKey(CDD, mintKeys[2]) |
|---|
| 338 | True |
|---|
| 339 | >>> coins[2][1].validate_with_CDD_and_MintKey(CDD, mintKeys[2]) |
|---|
| 340 | True |
|---|
| 341 | |
|---|
| 342 | >>> coins[3][0].validate_with_CDD_and_MintKey(CDD, mintKeys[3]) |
|---|
| 343 | True |
|---|
| 344 | """ |
|---|
| 345 | from containers import CurrencyCoin |
|---|
| 346 | |
|---|
| 347 | hash_alg = CDD.issuer_cipher_suite.hashing |
|---|
| 348 | sign_alg = CDD.issuer_cipher_suite.signing |
|---|
| 349 | |
|---|
| 350 | def makeCoin(serial, private_key, mint_key): |
|---|
| 351 | coin = CurrencyCoin(standard_identifier=CDD.standard_identifier, |
|---|
| 352 | currency_identifier=CDD.currency_identifier, |
|---|
| 353 | denomination=mint_key.denomination, |
|---|
| 354 | key_identifier=mint_key.key_identifier, |
|---|
| 355 | serial=serial) |
|---|
| 356 | coin.signature = sign_alg(private_key).sign(hash_alg(coin.content_part()).digest()) |
|---|
| 357 | return coin |
|---|
| 358 | |
|---|
| 359 | private0 = keys512[0] |
|---|
| 360 | mintKey0 = mintKeys[0] # Denomination of 1 |
|---|
| 361 | |
|---|
| 362 | coin0 = (makeCoin('abcdefghijklmnopqrstuvwxyz', private0, mintKey0), |
|---|
| 363 | makeCoin('xxxxxxxxxxxxxxxxxxxxxxxxxx', private0, mintKey0)) |
|---|
| 364 | |
|---|
| 365 | private1 = keys512[1] |
|---|
| 366 | mintKey1 = mintKeys[1] # Denomination of 2 |
|---|
| 367 | |
|---|
| 368 | coin1 = (makeCoin('abcdefghijklmnopqrstuvwxyz', private1, mintKey1), |
|---|
| 369 | makeCoin('aaaaaaaaaaaaaaaaaaaaaaaaaa', private1, mintKey1), |
|---|
| 370 | makeCoin('bbbbbbbbbbbbbbbbbbbbbbbbbb', private1, mintKey1), |
|---|
| 371 | makeCoin('cccccccccccccccccccccccccc', private1, mintKey1), |
|---|
| 372 | makeCoin('dddddddddddddddddddddddddd', private1, mintKey1)) |
|---|
| 373 | |
|---|
| 374 | private2 = keys512[2] |
|---|
| 375 | mintKey2 = mintKeys[2] # Denomination of 5 |
|---|
| 376 | |
|---|
| 377 | coin2 = (makeCoin('abcdefghijklmnopqrstuvwxyz', private2, mintKey2), |
|---|
| 378 | makeCoin('xxxxxxxxxxxxxxxxxxxxxxxxxx', private2, mintKey2), |
|---|
| 379 | makeCoin('aaaaaaaaaaaaaaaaaaaaaaaaaa', private2, mintKey2)) |
|---|
| 380 | |
|---|
| 381 | private3 = keys512[3] |
|---|
| 382 | mintKey3 = mintKeys[3] # Denomination of 10 |
|---|
| 383 | |
|---|
| 384 | coin3 = (makeCoin('abcdefghijklmnopqrstuvwxyz', private3, mintKey3),) |
|---|
| 385 | |
|---|
| 386 | return (coin0, coin1, coin2, coin3) |
|---|
| 387 | |
|---|
| 388 | coins = makeCoins() |
|---|
| 389 | |
|---|
| 390 | def makeBlank(mintKey, serial=None, blind_factor=None): |
|---|
| 391 | from containers import CurrencyBlank |
|---|
| 392 | blank = CurrencyBlank(standard_identifier=CDD.standard_identifier, |
|---|
| 393 | currency_identifier=CDD.currency_identifier, |
|---|
| 394 | denomination=mintKey.denomination, |
|---|
| 395 | serial=serial, |
|---|
| 396 | key_identifier=mintKey.key_identifier) |
|---|
| 397 | if not serial: |
|---|
| 398 | blank.generateSerial() |
|---|
| 399 | |
|---|
| 400 | if blind_factor: |
|---|
| 401 | blank.original_blind_blank = blank.blind_blank |
|---|
| 402 | blank.blind_blank = lambda cdd, mintKey: blank.original_blind_blank(cdd, mintKey, blind_factor) |
|---|
| 403 | |
|---|
| 404 | return blank |
|---|
| 405 | |
|---|
| 406 | #summary of containers |
|---|
| 407 | is_private_key = CDD_private |
|---|
| 408 | CDD = CDD |
|---|
| 409 | mint_private_key1 = keys512[0] |
|---|
| 410 | mint_private_key2 = keys512[1] |
|---|
| 411 | mint_private_key3 = keys512[2] |
|---|
| 412 | mint_key1 = mintKeys[0] |
|---|
| 413 | mint_key2 = mintKeys[1] |
|---|
| 414 | mint_key3 = mintKeys[2] #denomination of 5 |
|---|
| 415 | coinA = coins[0][0] # mint_key1 |
|---|
| 416 | coinB = coins[0][1] # mint_key1 |
|---|
| 417 | coinC = coins[1][0] # mint_key2 |
|---|
| 418 | |
|---|
| 419 | |
|---|
| 420 | #entities |
|---|
| 421 | import entities |
|---|
| 422 | |
|---|
| 423 | def makeIssuerEntity(): |
|---|
| 424 | ''' |
|---|
| 425 | >>> ie = makeIssuerEntity() |
|---|
| 426 | ''' |
|---|
| 427 | ie = entities.IssuerEntity() |
|---|
| 428 | |
|---|
| 429 | mint = ie.mint |
|---|
| 430 | issuer = ie.issuer |
|---|
| 431 | dsdb = ie.dsdb |
|---|
| 432 | |
|---|
| 433 | issuer.addMintKey(mint_key1) |
|---|
| 434 | issuer.addMintKey(mint_key2) |
|---|
| 435 | |
|---|
| 436 | mint.privatekeys = {mint_key1.key_identifier: mint_private_key1, |
|---|
| 437 | mint_key2.key_identifier: mint_private_key2} |
|---|
| 438 | |
|---|
| 439 | mint.addMintKey(mint_key1, CDD.issuer_cipher_suite.signing) |
|---|
| 440 | mint.addMintKey(mint_key2, CDD.issuer_cipher_suite.signing) |
|---|
| 441 | |
|---|
| 442 | ie.masterKey = is_private_key |
|---|
| 443 | |
|---|
| 444 | issuer.addCDD(CDD) |
|---|
| 445 | issuer.setCurrentCDDVersion(dict(CDD.options)['version']) |
|---|
| 446 | |
|---|
| 447 | return ie |
|---|
| 448 | |
|---|
| 449 | if __name__ == "__main__": |
|---|
| 450 | import doctest |
|---|
| 451 | doctest.testmod(optionflags=doctest.ELLIPSIS) |
|---|