Skip to content

Commit 49df4d2

Browse files
author
Christophe Oosterlynck
committed
added whole SHA2 family from http://reikon.us/sha2/
1 parent a1b0018 commit 49df4d2

File tree

8 files changed

+33
-352
lines changed

8 files changed

+33
-352
lines changed

src/CryptoPlus/Hash/pysha224.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#!/usr/bin/python__author__ = 'Thomas Dixon'__license__ = 'MIT'from sha256 import sha256def new(m=None): return sha224(m)class sha224(sha256): _h = (0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4) _output_size = 7 digest_size = 28

src/CryptoPlus/Hash/pysha256.py

Lines changed: 2 additions & 349 deletions
Original file line numberDiff line numberDiff line change
@@ -1,349 +1,2 @@
1-
#!/usr/bin/env python
2-
# -*- coding: iso-8859-1
3-
4-
# Note that PyPy contains also a built-in module 'sha' which will hide
5-
# this one if compiled in.
6-
7-
"""A sample implementation of SHA-1 in pure Python.
8-
9-
Framework adapted from Dinu Gherman's MD5 implementation by
10-
J. Hallén and L. Creighton. SHA-1 implementation based directly on
11-
the text of the NIST standard FIPS PUB 180-1.
12-
"""
13-
14-
15-
__date__ = '2004-11-17'
16-
__version__ = 0.91 # Modernised by J. Hallén and L. Creighton for Pypy
17-
18-
19-
import struct, copy
20-
21-
22-
# ======================================================================
23-
# Bit-Manipulation helpers
24-
#
25-
# _long2bytes() was contributed by Barry Warsaw
26-
# and is reused here with tiny modifications.
27-
# ======================================================================
28-
29-
def _long2bytesBigEndian(n, blocksize=0):
30-
"""Convert a long integer to a byte string.
31-
32-
If optional blocksize is given and greater than zero, pad the front
33-
of the byte string with binary zeros so that the length is a multiple
34-
of blocksize.
35-
"""
36-
37-
# After much testing, this algorithm was deemed to be the fastest.
38-
s = ''
39-
pack = struct.pack
40-
while n > 0:
41-
s = pack('>I', n & 0xffffffffL) + s
42-
n = n >> 32
43-
44-
# Strip off leading zeros.
45-
for i in range(len(s)):
46-
if s[i] <> '\000':
47-
break
48-
else:
49-
# Only happens when n == 0.
50-
s = '\000'
51-
i = 0
52-
53-
s = s[i:]
54-
55-
# Add back some pad bytes. This could be done more efficiently
56-
# w.r.t. the de-padding being done above, but sigh...
57-
if blocksize > 0 and len(s) % blocksize:
58-
s = (blocksize - len(s) % blocksize) * '\000' + s
59-
60-
return s
61-
62-
63-
def _bytelist2longBigEndian(list):
64-
"Transform a list of characters into a list of longs."
65-
66-
imax = len(list)/4
67-
hl = [0L] * imax
68-
69-
j = 0
70-
i = 0
71-
while i < imax:
72-
b0 = long(ord(list[j])) << 24
73-
b1 = long(ord(list[j+1])) << 16
74-
b2 = long(ord(list[j+2])) << 8
75-
b3 = long(ord(list[j+3]))
76-
hl[i] = b0 | b1 | b2 | b3
77-
i = i+1
78-
j = j+4
79-
80-
return hl
81-
82-
83-
def _rotateLeft(x, n):
84-
"Rotate x (32 bit) left n bits circularly."
85-
86-
return (x << n) | (x >> (32-n))
87-
88-
89-
# ======================================================================
90-
# The SHA transformation functions
91-
#
92-
# ======================================================================
93-
94-
def f0_19(B, C, D):
95-
return (B & C) | ((~ B) & D)
96-
97-
def f20_39(B, C, D):
98-
return B ^ C ^ D
99-
100-
def f40_59(B, C, D):
101-
return (B & C) | (B & D) | (C & D)
102-
103-
def f60_79(B, C, D):
104-
return B ^ C ^ D
105-
106-
107-
f = [f0_19, f20_39, f40_59, f60_79]
108-
109-
# Constants to be used
110-
K = [
111-
0x5A827999L, # ( 0 <= t <= 19)
112-
0x6ED9EBA1L, # (20 <= t <= 39)
113-
0x8F1BBCDCL, # (40 <= t <= 59)
114-
0xCA62C1D6L # (60 <= t <= 79)
115-
]
116-
117-
class sha:
118-
"An implementation of the MD5 hash function in pure Python."
119-
120-
def __init__(self):
121-
"Initialisation."
122-
123-
# Initial message length in bits(!).
124-
self.length = 0L
125-
self.count = [0, 0]
126-
127-
# Initial empty message as a sequence of bytes (8 bit characters).
128-
self.input = []
129-
130-
# Call a separate init function, that can be used repeatedly
131-
# to start from scratch on the same object.
132-
self.init()
133-
134-
135-
def init(self):
136-
"Initialize the message-digest and set all fields to zero."
137-
138-
self.length = 0L
139-
self.input = []
140-
141-
# Initial 160 bit message digest (5 times 32 bit).
142-
self.H0 = 0x67452301L
143-
self.H1 = 0xEFCDAB89L
144-
self.H2 = 0x98BADCFEL
145-
self.H3 = 0x10325476L
146-
self.H4 = 0xC3D2E1F0L
147-
148-
def _transform(self, W):
149-
150-
for t in range(16, 80):
151-
W.append(_rotateLeft(
152-
W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffffL)
153-
154-
A = self.H0
155-
B = self.H1
156-
C = self.H2
157-
D = self.H3
158-
E = self.H4
159-
160-
"""
161-
This loop was unrolled to gain about 10% in speed
162-
for t in range(0, 80):
163-
TEMP = _rotateLeft(A, 5) + f[t/20] + E + W[t] + K[t/20]
164-
E = D
165-
D = C
166-
C = _rotateLeft(B, 30) & 0xffffffffL
167-
B = A
168-
A = TEMP & 0xffffffffL
169-
"""
170-
171-
for t in range(0, 20):
172-
TEMP = _rotateLeft(A, 5) + ((B & C) | ((~ B) & D)) + E + W[t] + K[0]
173-
E = D
174-
D = C
175-
C = _rotateLeft(B, 30) & 0xffffffffL
176-
B = A
177-
A = TEMP & 0xffffffffL
178-
179-
for t in range(20, 40):
180-
TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[1]
181-
E = D
182-
D = C
183-
C = _rotateLeft(B, 30) & 0xffffffffL
184-
B = A
185-
A = TEMP & 0xffffffffL
186-
187-
for t in range(40, 60):
188-
TEMP = _rotateLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]
189-
E = D
190-
D = C
191-
C = _rotateLeft(B, 30) & 0xffffffffL
192-
B = A
193-
A = TEMP & 0xffffffffL
194-
195-
for t in range(60, 80):
196-
TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[3]
197-
E = D
198-
D = C
199-
C = _rotateLeft(B, 30) & 0xffffffffL
200-
B = A
201-
A = TEMP & 0xffffffffL
202-
203-
204-
self.H0 = (self.H0 + A) & 0xffffffffL
205-
self.H1 = (self.H1 + B) & 0xffffffffL
206-
self.H2 = (self.H2 + C) & 0xffffffffL
207-
self.H3 = (self.H3 + D) & 0xffffffffL
208-
self.H4 = (self.H4 + E) & 0xffffffffL
209-
210-
211-
# Down from here all methods follow the Python Standard Library
212-
# API of the sha module.
213-
214-
def update(self, inBuf):
215-
"""Add to the current message.
216-
217-
Update the md5 object with the string arg. Repeated calls
218-
are equivalent to a single call with the concatenation of all
219-
the arguments, i.e. m.update(a); m.update(b) is equivalent
220-
to m.update(a+b).
221-
222-
The hash is immediately calculated for all full blocks. The final
223-
calculation is made in digest(). It will calculate 1-2 blocks,
224-
depending on how much padding we have to add. This allows us to
225-
keep an intermediate value for the hash, so that we only need to
226-
make minimal recalculation if we call update() to add more data
227-
to the hashed string.
228-
"""
229-
230-
leninBuf = long(len(inBuf))
231-
232-
# Compute number of bytes mod 64.
233-
index = (self.count[1] >> 3) & 0x3FL
234-
235-
# Update number of bits.
236-
self.count[1] = self.count[1] + (leninBuf << 3)
237-
if self.count[1] < (leninBuf << 3):
238-
self.count[0] = self.count[0] + 1
239-
self.count[0] = self.count[0] + (leninBuf >> 29)
240-
241-
partLen = 64 - index
242-
243-
if leninBuf >= partLen:
244-
self.input[index:] = list(inBuf[:partLen])
245-
self._transform(_bytelist2longBigEndian(self.input))
246-
i = partLen
247-
while i + 63 < leninBuf:
248-
self._transform(_bytelist2longBigEndian(list(inBuf[i:i+64])))
249-
i = i + 64
250-
else:
251-
self.input = list(inBuf[i:leninBuf])
252-
else:
253-
i = 0
254-
self.input = self.input + list(inBuf)
255-
256-
257-
def digest(self):
258-
"""Terminate the message-digest computation and return digest.
259-
260-
Return the digest of the strings passed to the update()
261-
method so far. This is a 16-byte string which may contain
262-
non-ASCII characters, including null bytes.
263-
"""
264-
265-
H0 = self.H0
266-
H1 = self.H1
267-
H2 = self.H2
268-
H3 = self.H3
269-
H4 = self.H4
270-
input = [] + self.input
271-
count = [] + self.count
272-
273-
index = (self.count[1] >> 3) & 0x3fL
274-
275-
if index < 56:
276-
padLen = 56 - index
277-
else:
278-
padLen = 120 - index
279-
280-
padding = ['\200'] + ['\000'] * 63
281-
self.update(padding[:padLen])
282-
283-
# Append length (before padding).
284-
bits = _bytelist2longBigEndian(self.input[:56]) + count
285-
286-
self._transform(bits)
287-
288-
# Store state in digest.
289-
digest = _long2bytesBigEndian(self.H0, 4) + \
290-
_long2bytesBigEndian(self.H1, 4) + \
291-
_long2bytesBigEndian(self.H2, 4) + \
292-
_long2bytesBigEndian(self.H3, 4) + \
293-
_long2bytesBigEndian(self.H4, 4)
294-
295-
self.H0 = H0
296-
self.H1 = H1
297-
self.H2 = H2
298-
self.H3 = H3
299-
self.H4 = H4
300-
self.input = input
301-
self.count = count
302-
303-
return digest
304-
305-
306-
def hexdigest(self):
307-
"""Terminate and return digest in HEX form.
308-
309-
Like digest() except the digest is returned as a string of
310-
length 32, containing only hexadecimal digits. This may be
311-
used to exchange the value safely in email or other non-
312-
binary environments.
313-
"""
314-
return ''.join(['%02x' % ord(c) for c in self.digest()])
315-
316-
def copy(self):
317-
"""Return a clone object.
318-
319-
Return a copy ('clone') of the md5 object. This can be used
320-
to efficiently compute the digests of strings that share
321-
a common initial substring.
322-
"""
323-
324-
return copy.deepcopy(self)
325-
326-
327-
# ======================================================================
328-
# Mimic Python top-level functions from standard library API
329-
# for consistency with the md5 module of the standard library.
330-
# ======================================================================
331-
332-
# These are mandatory variables in the module. They have constant values
333-
# in the SHA standard.
334-
335-
digest_size = digestsize = 20
336-
blocksize = 1
337-
338-
def new(arg=None):
339-
"""Return a new sha crypto object.
340-
341-
If arg is present, the method call update(arg) is made.
342-
"""
343-
344-
crypto = sha()
345-
if arg:
346-
crypto.update(arg)
347-
348-
return crypto
349-
1+
#!/usr/bin/python__author__ = 'Thomas Dixon'__license__ = 'MIT'import copy, struct, sysdef new(m=None): return sha256(m)class sha256(object): _k = (0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2) _h = (0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19) _output_size = 8
2+
blocksize = 1 block_size = 64 digest_size = 32 def __init__(self, m=None): self._buffer = '' self._counter = 0 if m is not None: if type(m) is not str: raise TypeError, '%s() argument 1 must be string, not %s' % (self.__class__.__name__, type(m).__name__) self.update(m) def _rotr(self, x, y): return ((x >> y) | (x << (32-y))) & 0xFFFFFFFF def _sha256_process(self, c): w = [0]*64 w[0:15] = struct.unpack('!16L', c) for i in range(16, 64): s0 = self._rotr(w[i-15], 7) ^ self._rotr(w[i-15], 18) ^ (w[i-15] >> 3) s1 = self._rotr(w[i-2], 17) ^ self._rotr(w[i-2], 19) ^ (w[i-2] >> 10) w[i] = (w[i-16] + s0 + w[i-7] + s1) & 0xFFFFFFFF a,b,c,d,e,f,g,h = self._h for i in range(64): s0 = self._rotr(a, 2) ^ self._rotr(a, 13) ^ self._rotr(a, 22) maj = (a & b) ^ (a & c) ^ (b & c) t2 = s0 + maj s1 = self._rotr(e, 6) ^ self._rotr(e, 11) ^ self._rotr(e, 25) ch = (e & f) ^ ((~e) & g) t1 = h + s1 + ch + self._k[i] + w[i] h = g g = f f = e e = (d + t1) & 0xFFFFFFFF d = c c = b b = a a = (t1 + t2) & 0xFFFFFFFF self._h = [(x+y) & 0xFFFFFFFF for x,y in zip(self._h, [a,b,c,d,e,f,g,h])] def update(self, m): if not m: return if type(m) is not str: raise TypeError, '%s() argument 1 must be string, not %s' % (sys._getframe().f_code.co_name, type(m).__name__) self._buffer += m self._counter += len(m) while len(self._buffer) >= 64: self._sha256_process(self._buffer[:64]) self._buffer = self._buffer[64:] def digest(self): mdi = self._counter & 0x3F length = struct.pack('!Q', self._counter<<3) if mdi < 56: padlen = 55-mdi else: padlen = 119-mdi r = self.copy() r.update('\x80'+('\x00'*padlen)+length) return ''.join([struct.pack('!L', i) for i in r._h[:self._output_size]]) def hexdigest(self): return self.digest().encode('hex') def copy(self): return copy.deepcopy(self)

src/CryptoPlus/Hash/pysha384.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#!/usr/bin/python__author__ = 'Thomas Dixon'__license__ = 'MIT'from sha512 import sha512def new(m=None): return sha384(m)class sha384(sha512): _h = (0xcbbb9d5dc1059ed8L, 0x629a292a367cd507L, 0x9159015a3070dd17L, 0x152fecd8f70e5939L, 0x67332667ffc00b31L, 0x8eb44a8768581511L, 0xdb0c2e0d64f98fa7L, 0x47b5481dbefa4fa4L) _output_size = 6 digest_size = 48

src/CryptoPlus/Hash/pysha512.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/python__author__ = 'Thomas Dixon'__license__ = 'MIT'import copy, struct, sysdef new(m=None): return sha512(m)class sha512(object): _k = (0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL, 0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, 0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L, 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, 0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L, 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L, 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL, 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, 0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L, 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L, 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, 0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL, 0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL, 0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL, 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L) _h = (0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, 0x3c6ef372fe94f82bL, 0xa54ff53a5f1d36f1L, 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL, 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L) _output_size = 8
2+
blocksize = 1 block_size = 128 digest_size = 64 def __init__(self, m=None): self._buffer = '' self._counter = 0 if m is not None: if type(m) is not str: raise TypeError, '%s() argument 1 must be string, not %s' % (self.__class__.__name__, type(m).__name__) self.update(m) def _rotr(self, x, y): return ((x >> y) | (x << (64-y))) & 0xFFFFFFFFFFFFFFFF def _sha512_process(self, chunk): w = [0]*80 w[0:15] = struct.unpack('!16Q', chunk) for i in range(16, 80): s0 = self._rotr(w[i-15], 1) ^ self._rotr(w[i-15], 8) ^ (w[i-15] >> 7) s1 = self._rotr(w[i-2], 19) ^ self._rotr(w[i-2], 61) ^ (w[i-2] >> 6) w[i] = (w[i-16] + s0 + w[i-7] + s1) & 0xFFFFFFFFFFFFFFFF a,b,c,d,e,f,g,h = self._h for i in range(80): s0 = self._rotr(a, 28) ^ self._rotr(a, 34) ^ self._rotr(a, 39) maj = (a & b) ^ (a & c) ^ (b & c) t2 = s0 + maj s1 = self._rotr(e, 14) ^ self._rotr(e, 18) ^ self._rotr(e, 41) ch = (e & f) ^ ((~e) & g) t1 = h + s1 + ch + self._k[i] + w[i] h = g g = f f = e e = (d + t1) & 0xFFFFFFFFFFFFFFFF d = c c = b b = a a = (t1 + t2) & 0xFFFFFFFFFFFFFFFF self._h = [(x+y) & 0xFFFFFFFFFFFFFFFF for x,y in zip(self._h, [a,b,c,d,e,f,g,h])] def update(self, m): if not m: return if type(m) is not str: raise TypeError, '%s() argument 1 must be string, not %s' % (sys._getframe().f_code.co_name, type(m).__name__) self._buffer += m self._counter += len(m) while len(self._buffer) >= 128: self._sha512_process(self._buffer[:128]) self._buffer = self._buffer[128:] def digest(self): mdi = self._counter & 0x7F length = struct.pack('!Q', self._counter<<3) if mdi < 112: padlen = 111-mdi else: padlen = 239-mdi r = self.copy() r.update('\x80'+('\x00'*(padlen+8))+length) return ''.join([struct.pack('!Q', i) for i in r._h[:self._output_size]]) def hexdigest(self): return self.digest().encode('hex') def copy(self): return copy.deepcopy(self)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pysha224 import sha224
2+
3+
__all__ = ['new','digest_size']
4+
5+
def new(data=""):
6+
return sha224(data)
7+
8+
digest_size = sha224.digest_size
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import pysha256
1+
from pysha256 import sha256
22

33
__all__ = ['new','digest_size']
44

55
def new(data=""):
6-
return pysha256.new(data)
6+
return sha256(data)
77

8-
digest_size = pysha256.digest_size
8+
digest_size = sha256.digest_size
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pysha384 import sha384
2+
3+
__all__ = ['new','digest_size']
4+
5+
def new(data=""):
6+
return sha384(data)
7+
8+
digest_size = sha384.digest_size
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pysha512 import sha512
2+
3+
__all__ = ['new','digest_size']
4+
5+
def new(data=""):
6+
return sha512(data)
7+
8+
digest_size = sha512.digest_size

0 commit comments

Comments
 (0)