summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-12-30 05:03:39 (GMT)
committerGuido van Rossum <guido@python.org>1997-12-30 05:03:39 (GMT)
commit380bf644246a4b117442d10949830ddd4312f0c7 (patch)
tree29ba462e2821d9a1beb7fd7ff5e2e21c2c43ff1c /Lib
parent1c8b9e476901b1eafa46eafa8966c5017db45756 (diff)
downloadcpython-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')
-rw-r--r--Lib/dos-8x3/dsa.py221
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'