- Timestamp:
- 04/04/09 21:59:26 (3 years ago)
- Location:
- trunk/sandbox/jhb/oc2
- Files:
-
- 10 modified
-
container.py (modified) (4 diffs)
-
containerbase.py (modified) (5 diffs)
-
documentation.py (modified) (7 diffs)
-
issuer.py (modified) (1 diff)
-
messages.py (modified) (1 diff)
-
occrypto_rsa.py (modified) (5 diffs)
-
protocols.py (modified) (3 diffs)
-
rsa.py (modified) (5 diffs)
-
testserver.py (modified) (1 diff)
-
wallet.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/sandbox/jhb/oc2/container.py
r254 r259 1 1 from containerbase import * 2 2 import occrypto 3 3 4 4 5 class CDD (Container): … … 19 20 ] 20 21 21 class PublicKey(Container):22 "A public key"23 fields = [24 BinaryField('a'),25 BinaryField('b'),26 BinaryField('c')27 ]28 29 22 30 23 class MKC(Container): … … 38 31 DateField('keyNotAfter'), 39 32 DateField('coinNotAfter'), 40 OneItemField('publicKey',klass= PublicKey),33 OneItemField('publicKey',klass=occrypto.PubKey), 41 34 Field('issuer'), 42 35 Field('signature',signing=False) … … 44 37 45 38 46 class Token(Container):39 class Coin(Container): 47 40 fields = [ 48 Field('currency'), 49 Field('amount'), 41 Field('standardId'), 42 Field('currencyId'), 43 Field('denomination'), 44 Field('keyId'), 45 Field('serial'), 50 46 Field('signature',signing=False) 51 47 ] 52 48 53 class Message(Container): 54 fields = [ 55 Field('subject'), 56 SubitemsField('tokens',klass=Token), 57 ] 58 49 def setNewSerial(self): 50 self.serial = occrypto.createSerial() 51 59 52 60 53 -
trunk/sandbox/jhb/oc2/containerbase.py
r254 r259 58 58 59 59 def setdecoded(self,object,data): 60 #import pdb; pdb.set_trace() 60 61 setattr(object,self.name,self.klass(data)) 61 62 … … 73 74 out = [] 74 75 for item in getattr(object,self.name): 75 out.append(item.getData(allData=allData)) 76 if item == None: 77 out.append('') 78 else: 79 out.append(item.getData(allData=allData)) 76 80 return out 77 81 … … 79 83 value = [] 80 84 for item in data: 81 value.append(self.klass(item)) 85 if item == '': 86 value.append(None) 87 else: 88 value.append(self.klass(item)) 82 89 setattr(object,self.name,value) 83 90 … … 100 107 101 108 def fromData(self,data): 109 110 if data == None: 111 return 112 102 113 if type(data) == type(''): 103 114 data = simplejson.loads(data) 115 104 116 if type(data) != type({}): 105 117 data = dict(data) … … 122 134 return simplejson.dumps(self.getData(allData=allData)) 123 135 136 -
trunk/sandbox/jhb/oc2/documentation.py
r258 r259 1 1 """ 2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3 4 This is just a todo for jhb, and not the real spec 5 6 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 2 8 OpenCoin Project N. Toedtmann 3 9 http://opencoin.org/ J. H. Baach … … 218 224 ############################################################################### 219 225 >>> port = 9090 226 >>> denominations = [0,1,2,5,10,20] 220 227 >>> cdd = issuer.makeCDD('OpenCentA', 221 228 ... 'oca', 222 ... [str(d) for d in [0,1,2,5,10,20]],229 ... [str(d) for d in denominations], 223 230 ... 'http://localhost:%s/' % port, 224 231 ... '') … … 275 282 >>> #faked request 276 283 >>> from wallet import Wallet 277 >>> wallet = Wallet( Item())284 >>> wallet = Wallet({}) 278 285 >>> import protocols 279 286 >>> serverside = protocols.GiveLatestCDD(issuer) 280 >>> clientside = protocols.AskLatestCDD( wallet,serverside.run)287 >>> clientside = protocols.AskLatestCDD(serverside.run) 281 288 >>> cdd == clientside.run() 282 289 True … … 286 293 >>> import testserver 287 294 >>> transport = transports.HTTPTransport('http://localhost:%s/' % port) 288 >>> clientside = protocols.AskLatestCDD( wallet,transport)295 >>> clientside = protocols.AskLatestCDD(transport) 289 296 >>> testserver.run_once(port,issuer) 290 297 >>> cdd2 = clientside.run() … … 303 310 IS: 304 311 MINTING_KEY_PASS(keycertificate) or MINTING_KEY_FAILURE(reason) 312 313 ############################################################################### 314 315 >>> clientside = protocols.FetchMintKeys(transport,denominations=['1','5']) 316 >>> testserver.run_once(port,issuer) 317 >>> mkcs = clientside.run() 318 >>> mkcs[0].toString() == issuer.getCurrentMKCs()['1'].toString() 319 True 320 321 ############################################################################### 305 322 306 323 * Wallet: creates blank according to CDD: … … 314 331 } 315 332 333 #XXX: ist key id wirklich vom secret key, oder vom public key? 334 316 335 317 336 * Wallet: create random r, calculate … … 323 342 Keep (r, blank, blind) in mind. 324 343 344 ############################################################################### 345 346 >>> mkc = mkcs[1] 347 >>> cdd.masterPubKey.verifyContainerSignature(mkc) 348 True 349 >>> blank = wallet._makeBlank(cdd,mkc) 350 >>> blank.denomination == '5' 351 True 352 >>> key = mkc.publicKey 353 >>> secret, blind = key.blindBlank(blank) 354 >>> tid = wallet.makeSerial() 355 356 ############################################################################### 357 325 358 326 359 3.3.5 "TRANSFER_TOKEN": A generic wallet-issuer request -
trunk/sandbox/jhb/oc2/issuer.py
r258 r259 72 72 73 73 def addMKC(self,cdd,mkc): 74 mkclist = self.storage.setdefault('mkclist',[]) 74 mkclist = self.storage.setdefault('mkclist',[]) 75 75 if len(mkclist) <= cdd.version: 76 76 mkclist.append({}) 77 77 mkclist[cdd.version][mkc.denomination]=mkc 78 keyidlist = self.storage.setdefault('keyidlist',{}) 79 keyidlist[mkc.keyId] = mkc 78 80 79 81 def getCurrentMKCs(self,version=-1): 80 82 return self.storage['mkclist'][version] 81 83 84 def getMKCById(self,keyid,default=None): 85 return self.storage.setdefault('keyidlist',{}).get(keyid,default) -
trunk/sandbox/jhb/oc2/messages.py
r256 r259 19 19 OneItemField('cdd',klass=container.CDD) 20 20 ] 21 22 class FetchMintKeys(Message): 23 fields = Message.fields + [ 24 Field('denominations'), 25 Field('keyids') 26 ] 27 28 class GiveMintKeys(Message): 29 fields = Message.fields + [ 30 SubitemsField('keys',klass=container.MKC) 31 ] 32 33 34 -
trunk/sandbox/jhb/oc2/occrypto_rsa.py
r254 r259 24 24 class PubKey(Container): 25 25 26 fields = [KeyField('key'), 27 Field('signature',signing=False)] 26 fields = [KeyField('key')] 28 27 29 28 def encrypt(self,data): … … 48 47 return secret, blinded 49 48 49 def blindBlank(self,blank): 50 return self.blind(blank.hash()) 51 50 52 def unblind(self,secret,data): 51 #number = cryptomath.stringToNumber(data)52 53 number = data 53 54 return (number * secret) % self.key['n'] … … 55 56 class PrivKey(Container): 56 57 57 fields = [KeyField('key'), 58 Field('signature',signing=False)] 58 fields = [KeyField('key')] 59 59 60 60 def decrypt(self,data): … … 65 65 66 66 def signblind(self,number): 67 return rsa.encrypt_int(number,self.key['d'],self.key[' p']*self.key['q'])67 return rsa.encrypt_int(number,self.key['d'],self.key['n']) 68 68 69 69 def signContainer(self,container): … … 73 73 74 74 def hash(data): 75 return hashlib.sha256(data).hexdigest()75 return rsa.bytes2int(hashlib.sha256(data).hexdigest()) 76 76 77 77 def hashContainer(container,allData=False): 78 78 return hash(container.toString(allData=allData)) 79 79 80 def createSerial(): 81 return rsa.bytesToNumber(rsa.getRandomBytes(16)) 82 #!!! 80 83 Container.hash = hashContainer 84 81 85 def KeyFactory(bitlen): 82 86 pub,priv = rsa.gen_pubpriv_keys(bitlen) -
trunk/sandbox/jhb/oc2/protocols.py
r256 r259 11 11 class AskLatestCDD(Protocol): 12 12 13 def __init__(self, wallet,transport):13 def __init__(self,transport): 14 14 self.transport = transport 15 self.wallet = wallet16 15 17 16 def run(self,message=None): … … 32 31 else: 33 32 pass 33 34 class FetchMintKeys(Protocol): 35 36 def __init__(self,transport,denominations=None,keyids=None): 37 if denominations and keyids: 38 raise "you can't ask for denominations and keyids at the same time" 39 if not (denominations or keyids): 40 raise "you need to ask at least for one" 41 self.transport = transport 42 self.denominations = denominations 43 self.keyids = keyids 44 45 def run(self,message=None): 46 message = messages.FetchMintKeys() 47 message.denominations = self.denominations 48 message.keyids = self.keyids 49 50 response = self.transport(message) 51 if response.header == 'MINTING_KEY_FAILURE': 52 raise message 53 else: 54 return response.keys 55 56 class GiveMintKeys(Protocol): 57 58 def __init__(self,issuer): 59 self.issuer = issuer 60 61 def run(self,message): 62 keys = [] 63 if message.denominations: 64 keyslist = self.issuer.getCurrentMKCs() 65 for d in message.denominations: 66 keys.append(keyslist.get(d)) 67 elif message.keyids: 68 for id in message.keyids: 69 keys.append(self.issuer.getKeyById(id)) 70 71 answer = messages.GiveMintKeys() 72 answer.keys = keys 73 return answer 34 74 35 75 class CoinsSpendSender(Protocol): … … 74 114 75 115 76 class FetchMintKeys(Protocol):77 116 78 def __init__(self,denomination,keyids,time):79 self.denominations = denominations80 self.keyids = keyids81 self.time = time82 83 def getKeys(self,message):84 return ''85 86 class GiveMintKeys(Protocol):87 88 def giveKeys(self,message):89 pass90 91 -
trunk/sandbox/jhb/oc2/rsa.py
r258 r259 100 100 101 101 if type(message) is types.IntType: 102 return encrypt_int(long(message), ekey, n) 103 102 message = long(message) 103 elif type(message) is types.LongType: 104 pass 105 elif type(message) is types.StringType: 106 message = long(bytes2int(message)) 107 104 108 if not type(message) is types.LongType: 105 raise TypeError("You must pass a long or an int") 106 107 #if math.floor(log(message, 2)) > math.floor(log(n, 2)): 108 # raise OverflowError("The message is too long") 109 110 return fast_exponentiation(message, ekey, n) 109 raise TypeError("You must pass a long or an int, not %s" % type(message)) 110 111 return pow(message, ekey, n) 111 112 112 113 def decrypt_int(cyphertext, dkey, n): … … 129 130 return (m * secret) % n 130 131 131 def chopstring(message, key, n, funcref):132 """Splits 'message' into chops that are at most as long as n,133 converts these into integers, and calls funcref(integer, key, n)134 for each chop.135 136 Used by 'encrypt' and 'sign'.137 """138 139 msglen = len(message)140 mbits = msglen * 8141 #nbits = int(math.floor(log(n, 2)))142 nbits = 1024143 nbytes = nbits / 8144 blocks = msglen / nbytes145 146 if msglen % nbytes > 0:147 blocks += 1148 149 cypher = []150 151 for bindex in range(blocks):152 offset = bindex * nbytes153 block = message[offset:offset+nbytes]154 value = bytes2int(block)155 cypher.append(funcref(value, key, n))156 157 return cypher[0]158 159 def gluechops(chops, key, n, funcref):160 """Glues chops back together into a string. calls161 funcref(integer, key, n) for each chop.162 163 Used by 'decrypt' and 'verify'.164 """165 message = ""166 chops = [chops]167 168 for cpart in chops:169 mpart = funcref(cpart, key, n)170 message += int2bytes(mpart)171 172 return message173 132 174 133 def encrypt(message, key): 175 134 """Encrypts a string 'message' with the public key 'key'""" 176 135 177 return chopstring(message, key['e'], key['n'], encrypt_int)178 136 #return chopstring(message, key['e'], key['n'], encrypt_int) 137 return encrypt_int(message,key['e'],key['n']) 179 138 def sign(message, key): 180 139 """Signs a string 'message' with the private key 'key'""" 181 182 return chopstring(message, key['d'], key['p']*key['q'], decrypt_int) 140 141 #return chopstring(message, key['d'], key['p']*key['q'], decrypt_int) 142 return decrypt_int(message,key['d'],key['n']) 183 143 184 144 def decrypt(cypher, key): 185 145 """Decrypts a cypher with the private key 'key'""" 186 146 187 return gluechops(cypher, key['d'], key['p']*key['q'], decrypt_int) 147 #return gluechops(cypher, key['d'], key['p']*key['q'], decrypt_int) 148 return decrypt_int(cypher,key['d'],key['n']) 188 149 189 150 def verify(cypher, key): 190 151 """Verifies a cypher with the public key 'key'""" 191 152 192 return gluechops(cypher, key['e'], key['n'], encrypt_int) 153 #return gluechops(cypher, key['e'], key['n'], encrypt_int) 154 return encrypt_int(cypher,key['e'],key['n']) 193 155 194 156 def blind(message,secret,key): 195 return chopstring(message,secret,key['n'],blinding_int) 157 #return chopstring(message,secret,key['n'],blinding_int) 158 return blinding_int(message,secret,key['n']) 196 159 197 160 def unblind(message,secret,key): 198 return gluechops(message,secret,key['n'],blinding_int) 161 #return gluechops(message,secret,key['n'],blinding_int) 162 return blinding_int(message,secret,key['n']) 199 163 200 164 … … 280 244 281 245 def generate(bits): #needed 246 #return (dummypub,dummypriv) 282 247 p = getRandomPrime(bits/2, False) 283 248 q = getRandomPrime(bits/2, False) 284 t = lcm(p-1,q-1)249 t = (p-1)*(q-1) 285 250 n = p * q 286 e = 3L #Needed to be long, for Java 251 252 while 1: 253 e = getRandomNumber(17,t-1) #getRandomNumber, ungerade < (p-1)*(q-1), coprime(e,(p-1)*(q-1)), e.g. gcd == 1 254 e = e % 2 == 0 and e-1 or e 255 if gcd(e,t) == 1: 256 break 287 257 d = invMod(e, t) 288 p = p 289 q = q 290 #dP = key.d % (p-1) 291 #dQ = key.d % (q-1) 292 #qInv = invMod(q, p) 293 keys = ( {'e': e, 'n': n}, {'d': d, 'p': p, 'q': q} ) 258 keys = ( {'e': e, 'n': n}, {'d': d, 'n': n} ) 294 259 return keys 295 260 … … 449 414 import time 450 415 t = time.time() 451 #(pub,priv) = gen_pubpriv_keys(1024) 452 (pub,priv) = (dummypub,dummypriv) 416 (pub,priv) = gen_pubpriv_keys(1024) 453 417 print '=' * 40 454 418 times = [] … … 478 442 print sum(times) - times[2] 479 443 480 if 0:444 if 1: 481 445 #full 482 446 t = time.time() 483 447 message = 'serial '*5 484 #print 'cleartext ', message448 print 'cleartext ', message 485 449 cypher = encrypt(message,pub) 486 #print 'cyphertext: ',cypher487 #print 'decrypted', decrypt(cypher,priv)450 print 'cyphertext: ',cypher 451 print 'decrypted', decrypt(cypher,priv) 488 452 decrypt(cypher,priv) 489 453 signed = sign(message,priv) 490 #print 'signed', signed491 #print 'verified', message == verify(signed,pub)454 print 'signed', signed 455 print 'verified', message == verify(signed,pub) 492 456 unblinder = getUnblinder(pub['n']) 493 457 blinder = pow(invMod(unblinder, pub['n']), pub['e'],pub['n']) 494 458 blinded = blind(message,blinder,pub) 495 #print 'blinded', blinded496 #signedblind = sign(blinded,priv)459 print 'blinded', blinded 460 signedblind = sign(blinded,priv) 497 461 signedblind = encrypt_int(blinded, priv['d'], priv['p']*priv['q']) 498 #print 'signedblind', signedblind499 #unblinded = unblind(signedblind,unblinder,pub)462 print 'signedblind', signedblind 463 unblinded = unblind(signedblind,unblinder,pub) 500 464 unblinded = (signedblind * unblinder) % pub['n'] 501 #print 'unblinded', unblinded502 #print 'verified', message == verify(unblinded,pub)465 print 'unblinded', unblinded 466 print 'verified', message == verify(unblinded,pub) 503 467 print time.time() - t 504 468 -
trunk/sandbox/jhb/oc2/testserver.py
r256 r259 15 15 if message.header == 'AskLatestCDD': 16 16 protocol = protocols.GiveLatestCDD(self.issuer) 17 elif message.header == 'FetchMintKeys': 18 protocol = protocols.GiveMintKeys(self.issuer) 17 19 answer = protocol.run(message) 18 20 self.send_response(200) -
trunk/sandbox/jhb/oc2/wallet.py
r256 r259 1 1 from entity import * 2 2 from protocols import * 3 from container import * 4 import occrypto 3 5 4 6 class Wallet(Entity): 5 7 6 pass 8 def _makeBlank(self,cdd,mkc): 9 blank = container.Coin() 10 blank.standardId = cdd.standardId 11 blank.currencyId = cdd.currencyId 12 blank.denomination = mkc.denomination 13 blank.keyId = mkc.keyId 14 blank.setNewSerial() 15 return blank 16 17 def makeSerial(self): 18 return occrypto.createSerial()
