diff options
author | Guido van Rossum <guido@python.org> | 1997-12-30 05:03:39 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-12-30 05:03:39 (GMT) |
commit | 380bf644246a4b117442d10949830ddd4312f0c7 (patch) | |
tree | 29ba462e2821d9a1beb7fd7ff5e2e21c2c43ff1c /Lib/dos-8x3 | |
parent | 1c8b9e476901b1eafa46eafa8966c5017db45756 (diff) | |
download | cpython-380bf644246a4b117442d10949830ddd4312f0c7.zip cpython-380bf644246a4b117442d10949830ddd4312f0c7.tar.gz cpython-380bf644246a4b117442d10949830ddd4312f0c7.tar.bz2 |
Since DSA.py never made it to the release, neither should dos-8x3/dsa.py.
Diffstat (limited to 'Lib/dos-8x3')
-rw-r--r-- | Lib/dos-8x3/dsa.py | 221 |
1 files changed, 0 insertions, 221 deletions
diff --git a/Lib/dos-8x3/dsa.py b/Lib/dos-8x3/dsa.py deleted file mode 100644 index 4bd26bc..0000000 --- a/Lib/dos-8x3/dsa.py +++ /dev/null @@ -1,221 +0,0 @@ -# -# DSA.py : Stupid name. Should really be called qNEW.py or something. -# Suggestions for a better name would be welcome. -# -# Maintained by A.M. Kuchling (amk@magnet.com) -# Date: 1997/09/03 -# -# Distribute and use freely; there are no restrictions on further -# dissemination and usage except those imposed by the laws of your -# country of residence. -# - -# TODO : -# Change the name -# Add more comments and docstrings -# Write documentation -# Add better RNG (?) - -import types, md5 - -error = 'DSA module error' - -def RandomNumber(N, randfunc): - "Get an N-bit random number" - str=randfunc(N/8) - char=ord(randfunc(1))>>(8-(N%8)) - return Str2Int(chr(char)+str) - -def Int2Str(n): - "Convert an integer to a string form" - s='' - while n>0: - s=chr(n & 255)+s - n=n>>8 - return s - -def Str2Int(s): - "Convert a string to a long integer" - if type(s)!=types.StringType: return s # Integers will be left alone - return reduce(lambda x,y : x*256+ord(y), s, 0L) - - -def getPrime(N, randfunc): - "Find a prime number measuring N bits" - number=RandomNumber(N, randfunc) | 1 - while (not isPrime(number)): - number=number+2 - return number - -sieve=[2,3,5,7,11,13,17,19,23,29,31,37,41] -def isPrime(N): - """Test if a number N is prime, using a simple sieve check, - followed by a more elaborate Rabin-Miller test.""" - for i in sieve: - if (N % i)==0: return 0 - N1=N - 1L ; n=1L - while (n<N): n=n<<1L # Compute number of bits in N - for j in sieve: - a=long(j) ; d=1L ; t=n - while (t): # Iterate over the bits in N1 - x=(d*d) % N - if x==1L and d!=1L and d!=N1: return 0 # Square root of 1 found - if N1 & t: d=(x*a) % N - else: d=x - t=t>>1L - if d!=1L: return 0 - return 1 - -class DSAobj: - def size(self): - "Return the max. number of bits that can be handled by this key" - bits, power = 0,1L - while (power<self.p): bits, power = bits+1, power<<1 - return bits-1 - - def hasprivate(self): - """Return a Boolean denoting whether the object contains private components""" - if hasattr(self, 'x'): return 1 - else: return 0 - - def cansign(self): - return self.hasprivate() - def canencrypt(self): - return 0 - - def publickey(self): - new=DSAobj() - for i in 'pqgy': setattr(new, i, getattr(self, i)) - return new - - def _sign(self, M, K): - if (self.q<=K): - raise error, 'K is greater than q' - r=pow(self.g, K, self.p) % self.q - s=(K- (r*M*self.x % self.q)) % self.q - return (r,s) - def _verify(self, M, sig): - r, s = sig - if r<=0 or r>=self.q or s<=0 or s>=self.q: return 0 - v1=pow(self.g, s, self.p) - v2=pow(self.y, M*r, self.p) - v=((v1*v2) % self.p) - v=v % self.q - if v==r: return 1 - return 0 - - def sign(self, M, K): - if (not self.hasprivate()): - raise error, 'Private key not available in this object' - if type(M)==types.StringType: M=Str2Int(M) - if type(K)==types.StringType: K=Str2Int(K) - return self._sign(M, K) - def verify(self, M, signature): - if type(M)==types.StringType: M=Str2Int(M) - return self._verify(M, signature) - validate=verify - - def generate(self, L, randfunc, progress_func=None): - """Generate a private key with L bits""" - HASHBITS=128 # Number of bits in the hashing algorithm used - # (128 for MD5; change to 160 for SHA) - - if L<512: raise error, 'Key length <512 bits' - # Generate string S and prime q - if progress_func: apply(progress_func, ('p,q\n',)) - while (1): - self.q = getPrime(160, randfunc) - S = Int2Str(self.q) - n=(L-1)/HASHBITS - C, N, V = 0, 2, {} -# b=(self.q >> 5) & 15 - b= (L-1) % HASHBITS - powb=pow(long(2), b) - powL1=pow(long(2), L-1) - while C<4096: - for k in range(0, n+1): - V[k]=Str2Int(md5.new(S+str(N)+str(k)).digest()) - W=V[n] % powb - for k in range(n-1, -1, -1): - W=(W<< long(HASHBITS) )+V[k] - X=W+powL1 - p=X-(X%(2*self.q)-1) - if powL1<=p and isPrime(p): break - C, N = C+1, N+n+1 - if C<4096: break - if progress_func: apply(progress_func, ('4096 multiples failed\n',) ) - self.p = p - power=(p-1)/self.q - if progress_func: apply(progress_func, ('h,g\n',)) - while (1): - h=Str2Int(randfunc(L)) % (p-1) - g=pow(h, power, p) - if 1<h<p-1 and g>1: break - self.g=g - if progress_func: apply(progress_func, ('x,y\n',)) - while (1): - x=Str2Int(randfunc(20)) - if 0<x<self.q: break - self.x, self.y=x, pow(g, x, p) - return self - -object=DSAobj - -# XXX this random number generation function sucks, since it isn't -# cryptographically strong! But it'll do for this first release... - -def randfunc(N): - import os, string - if string.lower(os.uname()[0])=='linux': - # On Linux, use /dev/urandom - f=open('/dev/urandom', 'r') - return f.read(N) - else: - import time - s="" - while len(s)<N: - rand=md5.new(str(time.time())).digest() - s=s+rand - return s[0:N] - -if __name__=='__main__': - import sys, string - BITS=512 - if len(sys.argv)>1: - BITS=string.atoi(sys.argv[1]) - print ' Generating', BITS, 'bit key' - key=DSAobj() - key.generate(BITS, randfunc, sys.stdout.write) - print ' Key data: (the private key is x)' - for i in 'xygqp': print '\t', i, ':', hex(getattr(key, i)) - plaintext="Hello" - - if key.cansign(): - print ' Signature test' - print "Plaintext:", plaintext - K=getPrime(30, randfunc) - signature=key.sign(plaintext, K) - print "Signature:", signature - result=key.verify(plaintext, signature) - if not result: - print " Sig. verification failed when it should have succeeded" - else: print 'Signature verified' - - # Test on a mangled plaintext - result=key.verify(plaintext[:-1], signature) - if result: - print " Sig. verification succeeded when it should have failed" - - # Change a single bit in the plaintext - badtext=plaintext[:-3]+chr( 1 ^ ord(plaintext[-3]) )+plaintext[-3:] - result=key.verify(badtext, signature) - if result: - print " Sig. verification succeeded when it should have failed" - - print 'Removing private key data' - pubonly=key.publickey() - result=pubonly.verify(plaintext, signature) - if not result: - print " Sig. verification failed when it should have succeeded" - else: - print 'Signature verified' |