CVS: crypto/Demo chaum.py,1.1,1.2
Joris Bontje <[email protected]> Fri, 12 Sep 2003 05:47:59 -0700
| Newsgroups | gmane.comp.python.cryptography.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/pycrypto/crypto/Demo
In directory sc8-pr-cvs1:/tmp/cvs-serv7488
Modified Files:
chaum.py
Log Message:
Add comments
Actually _USE_ the Chinese Remainders Theorem
Fix blindingFactor size
Support for SHA-256, SHA-384 and SHA-512
Index: chaum.py
===================================================================
RCS file: /cvsroot/pycrypto/crypto/Demo/chaum.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- chaum.py 3 Apr 2003 20:26:00 -0000 1.1
+++ chaum.py 12 Sep 2003 12:47:57 -0000 1.2
@@ -1,70 +1,103 @@
#!/usr/bin/env python
+""" Example of Chaumian blinding """
+
import time, pprint, os, sha
from Crypto.PublicKey import *
from Crypto.Util.randpool import RandomPool
from Crypto.Util import number
import cPickle as pickle
+# Globals
pool = RandomPool()
pool.stir()
-digest=sha.sha
-
-KEYSIZE=1024
-COINSIZE=256
-HASHSIZE=sha.digestsize*8
-
-DENOMINATIONPICKLE = 'denomination.pickle'
-
-if os.path.isfile(DENOMINATIONPICKLE):
- print "Server: load denomination..."
- ff = file(DENOMINATIONPICKLE, 'r')
+# use SHA-1 by default, if you want to use SHA-256, SHA-384 or SHA-512 you
+# need shax-py from http://philosophysw.com/software/
+digest = sha.sha
+
+KEYSIZE = 1024
+KEYFILE = "tokenkey.pickle"
+HASHSIZE = sha.digestsize*8
+
+### Initialization ###
+
+if os.path.isfile(KEYFILE):
+ # Load existing key """
+ print "Server: load key..."
+ ff = file(KEYFILE, 'r')
key = pickle.load(ff)
rsa = RSA.construct(key)
else:
- print "Server: create denomination (will take a while, only has to be done once for each denomiation of coin you want)..."
+ # Generate an RSA key-pair of KEYSIZE bits and store the key
+ print "Server: create key (will take a while, but only has to be done once)..."
begintime=time.time()
- rsa=RSA.generate(KEYSIZE, pool.get_bytes)
+ rsa=RSA.generate(KEYSIZE, pool.get_bytes)
endtime=time.time()
print "Server: Generate %d bit RSA key: %f s" % (KEYSIZE, endtime-begintime)
- key = (rsa.n, rsa.e, rsa.d)
- ff = file(DENOMINATIONPICKLE, 'w')
+ key = (rsa.n, rsa.e, rsa.d, rsa.p, rsa.q, rsa.u)
+ ff = file(KEYFILE, 'w')
pickle.dump(key, ff)
+print "RSA key:"
+print "n = %s" % pprint.pformat(rsa.n) # Public key
+print "e = %s" % pprint.pformat(rsa.e) # Public key
-print "n = %s" % pprint.pformat(rsa.n)
-print "e = %s" % pprint.pformat(rsa.e)
-print "d = %s" % pprint.pformat(rsa.d)
+print "d = %s" % pprint.pformat(rsa.d) # Private key
+# Values below are not really needed, but cause a big speedup since the Chinese Remainders Theorem can be used
+print "p = %s" % pprint.pformat(rsa.p) # Private key
+print "q = %s" % pprint.pformat(rsa.q) # Private key
+print "u = %s" % pprint.pformat(rsa.u) # Private key
print
-coinId = number.getRandomNumber(COINSIZE, pool.get_bytes)
+### Client ###
+
+# Generate random tokenId of HASHSIZE bits
+tokenId = number.getRandomNumber(HASHSIZE, pool.get_bytes)
+
+# Generate random blindingFactor of KEYSIZE-1 (so it can still be signed) bits
while 1:
- blindingFactor = number.getRandomNumber(HASHSIZE, pool.get_bytes)
+ blindingFactor = number.getRandomNumber(KEYSIZE-1, pool.get_bytes)
+ # Verify that GCD(r, n) ==1
if number.GCD(blindingFactor, rsa.n)==1:
break
-coinHash = number.bytes_to_long(digest(number.long_to_bytes(coinId)).digest())
-print "coinId = %s" % pprint.pformat(coinId)
+# Calculate the hash of the tokenId
+tokenHash = number.bytes_to_long(digest(number.long_to_bytes(tokenId)).digest())
+
+print "tokenId = %s" % pprint.pformat(tokenId)
print "blindingFactor = %s" % pprint.pformat(blindingFactor)
-print "coinHash = %s" % pprint.pformat(coinHash)
+print "tokenHash = %s" % pprint.pformat(tokenHash)
print
+# Blind the hashed tokenId with blindingFactor
begintime=time.time()
-blindedCoin=rsa.blind(coinHash, blindingFactor)
+blindedToken=rsa.blind(tokenHash, blindingFactor)
endtime=time.time()
print "Client: Blinding: %f s" % (endtime-begintime)
-print "blindedCoin = %s" % pprint.pformat(blindedCoin)
+print "blindedToken = %s" % pprint.pformat(blindedToken)
+
+# Send blindedToken to the server
+print "Client -> Server: blindedToken"
print
+### Server ###
+
+# Sign the blindedToken
begintime=time.time()
-blindedSignature=rsa.sign(blindedCoin, None)[0]
+blindedSignature=rsa.sign(blindedToken, None)[0]
endtime=time.time()
print "Server: Signing: %f s" % (endtime-begintime)
print "blindedSignature = %s" % pprint.pformat(blindedSignature)
+
+# Send the blindedSignature back to the client
+print "Server -> Client: blindedSignature"
print
+### Client ###
+
+# Unblind the blindedSignature
begintime=time.time()
signature=rsa.unblind(blindedSignature, blindingFactor)
endtime=time.time()
@@ -72,23 +105,25 @@
print "signature = %s" % pprint.pformat(signature)
print
+# Token is ready
+token = (tokenId, signature)
+print "Client: token = %s" % pprint.pformat(token)
-#rawSignature=rsa.sign(coinHash, None)[0]
-#print "rawSignature = %s" % pprint.pformat(rawSignature)
-#print
-
-print "... user can now spend coin..."
-print "... merchant deposits coin..."
print
+print "... user can now use the token..."
+print "Client -> Server: token"
+print
+
+### Server ###
+# Verify that the signature of hash(tokenId) is right
begintime=time.time()
-v=rsa.verify(coinHash, (signature,))
+v=rsa.verify(number.bytes_to_long(digest(number.long_to_bytes(token[0])).digest()), (token[1],))
endtime=time.time()
print "Server: Verifying: %f s" % (endtime-begintime)
if v:
- print "OK"
+ print "Server: SIGNATURE OK"
else:
- print "NOT OK"
-
+ print "Server: SIGNATURE NOT OK"
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf