Changeset 259 for trunk

Show
Ignore:
Timestamp:
04/04/09 21:59:26 (3 years ago)
Author:
ocjhb
Message:

first crypto cleanup

Location:
trunk/sandbox/jhb/oc2
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/sandbox/jhb/oc2/container.py

    r254 r259  
    11from containerbase import * 
    22import occrypto 
     3 
    34 
    45class CDD (Container): 
     
    1920    ] 
    2021 
    21 class PublicKey(Container): 
    22     "A public key" 
    23     fields = [ 
    24         BinaryField('a'), 
    25         BinaryField('b'), 
    26         BinaryField('c') 
    27     ]         
    28  
    2922 
    3023class MKC(Container): 
     
    3831        DateField('keyNotAfter'), 
    3932        DateField('coinNotAfter'), 
    40         OneItemField('publicKey',klass=PublicKey), 
     33        OneItemField('publicKey',klass=occrypto.PubKey), 
    4134        Field('issuer'), 
    4235        Field('signature',signing=False) 
     
    4437 
    4538 
    46 class Token(Container): 
     39class Coin(Container): 
    4740    fields = [ 
    48         Field('currency'), 
    49         Field('amount'), 
     41        Field('standardId'), 
     42        Field('currencyId'), 
     43        Field('denomination'), 
     44        Field('keyId'), 
     45        Field('serial'), 
    5046        Field('signature',signing=False) 
    5147    ] 
    5248 
    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 
    5952 
    6053 
  • trunk/sandbox/jhb/oc2/containerbase.py

    r254 r259  
    5858         
    5959    def setdecoded(self,object,data): 
     60        #import pdb; pdb.set_trace() 
    6061        setattr(object,self.name,self.klass(data)) 
    6162 
     
    7374        out = [] 
    7475        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)) 
    7680        return out        
    7781         
     
    7983        value = [] 
    8084        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)) 
    8289        setattr(object,self.name,value)      
    8390 
     
    100107 
    101108    def fromData(self,data): 
     109 
     110        if data == None: 
     111            return 
     112 
    102113        if type(data) == type(''): 
    103114            data = simplejson.loads(data) 
     115 
    104116        if type(data) != type({}): 
    105117            data = dict(data) 
     
    122134        return simplejson.dumps(self.getData(allData=allData)) 
    123135 
     136 
  • trunk/sandbox/jhb/oc2/documentation.py

    r258 r259  
    11""" 
     2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
     3 
     4      This is just a todo for jhb, and not the real spec 
     5 
     6!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
     7 
    28OpenCoin Project                                            N. Toedtmann 
    39http://opencoin.org/                                         J. H. Baach 
     
    218224############################################################################### 
    219225>>> port = 9090 
     226>>> denominations = [0,1,2,5,10,20] 
    220227>>> cdd = issuer.makeCDD('OpenCentA', 
    221228...                      'oca', 
    222 ...                      [str(d) for d in [0,1,2,5,10,20]], 
     229...                      [str(d) for d in denominations], 
    223230...                      'http://localhost:%s/' % port, 
    224231...                      '') 
     
    275282>>> #faked request 
    276283>>> from wallet import Wallet 
    277 >>> wallet = Wallet(Item()) 
     284>>> wallet = Wallet({}) 
    278285>>> import protocols 
    279286>>> serverside = protocols.GiveLatestCDD(issuer) 
    280 >>> clientside = protocols.AskLatestCDD(wallet,serverside.run) 
     287>>> clientside = protocols.AskLatestCDD(serverside.run) 
    281288>>> cdd == clientside.run() 
    282289True 
     
    286293>>> import testserver 
    287294>>> transport = transports.HTTPTransport('http://localhost:%s/' % port) 
    288 >>> clientside = protocols.AskLatestCDD(wallet,transport) 
     295>>> clientside = protocols.AskLatestCDD(transport) 
    289296>>> testserver.run_once(port,issuer) 
    290297>>> cdd2 =  clientside.run() 
     
    303310IS: 
    304311    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() 
     319True 
     320 
     321############################################################################### 
    305322 
    306323* Wallet: creates blank according to CDD: 
     
    314331  } 
    315332 
     333#XXX: ist key id wirklich vom secret key, oder vom public key? 
     334 
    316335 
    317336* Wallet: create random r, calculate  
     
    323342  Keep (r, blank, blind) in mind.  
    324343   
     344############################################################################### 
     345 
     346>>> mkc = mkcs[1] 
     347>>> cdd.masterPubKey.verifyContainerSignature(mkc) 
     348True 
     349>>> blank = wallet._makeBlank(cdd,mkc) 
     350>>> blank.denomination == '5' 
     351True 
     352>>> key = mkc.publicKey 
     353>>> secret, blind = key.blindBlank(blank) 
     354>>> tid = wallet.makeSerial() 
     355 
     356############################################################################### 
     357 
    325358 
    3263593.3.5 "TRANSFER_TOKEN": A generic wallet-issuer request 
  • trunk/sandbox/jhb/oc2/issuer.py

    r258 r259  
    7272 
    7373    def addMKC(self,cdd,mkc): 
    74         mkclist = self.storage.setdefault('mkclist',[])             
     74        mkclist = self.storage.setdefault('mkclist',[]) 
    7575        if len(mkclist) <= cdd.version: 
    7676            mkclist.append({}) 
    7777        mkclist[cdd.version][mkc.denomination]=mkc     
     78        keyidlist = self.storage.setdefault('keyidlist',{}) 
     79        keyidlist[mkc.keyId] = mkc 
    7880         
    7981    def getCurrentMKCs(self,version=-1): 
    8082        return self.storage['mkclist'][version] 
    8183 
     84    def getMKCById(self,keyid,default=None): 
     85        return self.storage.setdefault('keyidlist',{}).get(keyid,default) 
  • trunk/sandbox/jhb/oc2/messages.py

    r256 r259  
    1919        OneItemField('cdd',klass=container.CDD) 
    2020    ] 
     21 
     22class FetchMintKeys(Message): 
     23    fields = Message.fields + [ 
     24        Field('denominations'), 
     25        Field('keyids') 
     26    ] 
     27 
     28class 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  
    2424class PubKey(Container): 
    2525 
    26     fields = [KeyField('key'), 
    27               Field('signature',signing=False)] 
     26    fields = [KeyField('key')] 
    2827 
    2928    def encrypt(self,data): 
     
    4847        return secret, blinded 
    4948 
     49    def blindBlank(self,blank): 
     50        return self.blind(blank.hash()) 
     51 
    5052    def unblind(self,secret,data): 
    51         #number =  cryptomath.stringToNumber(data) 
    5253        number = data 
    5354        return (number * secret) % self.key['n'] 
     
    5556class PrivKey(Container): 
    5657     
    57     fields = [KeyField('key'), 
    58               Field('signature',signing=False)] 
     58    fields = [KeyField('key')] 
    5959 
    6060    def decrypt(self,data): 
     
    6565 
    6666    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']) 
    6868 
    6969    def signContainer(self,container): 
     
    7373 
    7474def hash(data): 
    75     return hashlib.sha256(data).hexdigest() 
     75    return rsa.bytes2int(hashlib.sha256(data).hexdigest()) 
    7676 
    7777def hashContainer(container,allData=False): 
    7878    return hash(container.toString(allData=allData)) 
    7979 
     80def createSerial(): 
     81    return rsa.bytesToNumber(rsa.getRandomBytes(16)) 
     82#!!! 
    8083Container.hash = hashContainer 
     84 
    8185def KeyFactory(bitlen): 
    8286    pub,priv = rsa.gen_pubpriv_keys(bitlen) 
  • trunk/sandbox/jhb/oc2/protocols.py

    r256 r259  
    1111class AskLatestCDD(Protocol): 
    1212 
    13     def __init__(self,wallet,transport): 
     13    def __init__(self,transport): 
    1414        self.transport = transport 
    15         self.wallet = wallet 
    1615     
    1716    def run(self,message=None): 
     
    3231        else: 
    3332            pass 
     33 
     34class 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 
     56class 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 
    3474 
    3575class CoinsSpendSender(Protocol): 
     
    74114 
    75115 
    76 class FetchMintKeys(Protocol): 
    77116 
    78     def __init__(self,denomination,keyids,time): 
    79         self.denominations = denominations 
    80         self.keyids = keyids 
    81         self.time = time 
    82  
    83     def getKeys(self,message): 
    84         return '' 
    85  
    86 class GiveMintKeys(Protocol): 
    87  
    88     def giveKeys(self,message): 
    89         pass     
    90  
    91  
  • trunk/sandbox/jhb/oc2/rsa.py

    r258 r259  
    100100 
    101101    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     
    104108    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) 
    111112 
    112113def decrypt_int(cyphertext, dkey, n): 
     
    129130    return (m * secret) % n 
    130131 
    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 * 8 
    141     #nbits  = int(math.floor(log(n, 2))) 
    142     nbits = 1024 
    143     nbytes = nbits / 8 
    144     blocks = msglen / nbytes 
    145  
    146     if msglen % nbytes > 0: 
    147         blocks += 1 
    148  
    149     cypher = [] 
    150      
    151     for bindex in range(blocks): 
    152         offset = bindex * nbytes 
    153         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.  calls 
    161     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 message 
    173132 
    174133def encrypt(message, key): 
    175134    """Encrypts a string 'message' with the public key 'key'""" 
    176135     
    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']) 
    179138def sign(message, key): 
    180139    """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']) 
    183143 
    184144def decrypt(cypher, key): 
    185145    """Decrypts a cypher with the private key 'key'""" 
    186146 
    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']) 
    188149 
    189150def verify(cypher, key): 
    190151    """Verifies a cypher with the public key 'key'""" 
    191152 
    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']) 
    193155 
    194156def 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']) 
    196159 
    197160def 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']) 
    199163 
    200164 
     
    280244 
    281245def generate(bits):  #needed 
     246    #return (dummypub,dummypriv) 
    282247    p = getRandomPrime(bits/2, False) 
    283248    q = getRandomPrime(bits/2, False) 
    284     t = lcm(p-1, q-1) 
     249    t = (p-1)*(q-1) 
    285250    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             
    287257    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} ) 
    294259    return keys 
    295260 
     
    449414    import time 
    450415    t = time.time() 
    451     #(pub,priv) =  gen_pubpriv_keys(1024) 
    452     (pub,priv) = (dummypub,dummypriv)           
     416    (pub,priv) =  gen_pubpriv_keys(1024) 
    453417    print '=' * 40 
    454418    times = [] 
     
    478442    print sum(times) - times[2] 
    479443 
    480     if 0: 
     444    if 1: 
    481445        #full 
    482446        t = time.time() 
    483447        message = 'serial '*5 
    484         #print 'cleartext ', message 
     448        print 'cleartext ', message 
    485449        cypher = encrypt(message,pub) 
    486         #print 'cyphertext: ',cypher 
    487         #print 'decrypted', decrypt(cypher,priv) 
     450        print 'cyphertext: ',cypher 
     451        print 'decrypted', decrypt(cypher,priv) 
    488452        decrypt(cypher,priv) 
    489453        signed = sign(message,priv) 
    490         #print 'signed', signed 
    491         #print 'verified', message == verify(signed,pub) 
     454        print 'signed', signed 
     455        print 'verified', message == verify(signed,pub) 
    492456        unblinder = getUnblinder(pub['n']) 
    493457        blinder = pow(invMod(unblinder, pub['n']), pub['e'],pub['n']) 
    494458        blinded = blind(message,blinder,pub) 
    495         #print 'blinded', blinded 
    496         #signedblind = sign(blinded,priv) 
     459        print 'blinded', blinded 
     460        signedblind = sign(blinded,priv) 
    497461        signedblind = encrypt_int(blinded, priv['d'], priv['p']*priv['q']) 
    498         #print 'signedblind', signedblind 
    499         #unblinded = unblind(signedblind,unblinder,pub) 
     462        print 'signedblind', signedblind 
     463        unblinded = unblind(signedblind,unblinder,pub) 
    500464        unblinded = (signedblind * unblinder) % pub['n'] 
    501         #print 'unblinded', unblinded 
    502         #print 'verified', message == verify(unblinded,pub) 
     465        print 'unblinded', unblinded 
     466        print 'verified', message == verify(unblinded,pub) 
    503467        print time.time() - t 
    504468         
  • trunk/sandbox/jhb/oc2/testserver.py

    r256 r259  
    1515        if message.header == 'AskLatestCDD': 
    1616            protocol = protocols.GiveLatestCDD(self.issuer) 
     17        elif message.header == 'FetchMintKeys': 
     18            protocol = protocols.GiveMintKeys(self.issuer) 
    1719        answer = protocol.run(message) 
    1820        self.send_response(200) 
  • trunk/sandbox/jhb/oc2/wallet.py

    r256 r259  
    11from entity import * 
    22from protocols import * 
     3from container import * 
     4import occrypto 
    35 
    46class Wallet(Entity): 
    57 
    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()