Class to contain the entire pipeline for SHA1 Hashing Algorithm
| 30 | |
| 31 | |
| 32 | class SHA1Hash: |
| 33 | """ |
| 34 | Class to contain the entire pipeline for SHA1 Hashing Algorithm |
| 35 | """ |
| 36 | def __init__(self, data): |
| 37 | """ |
| 38 | Inititates the variables data and h. h is a list of 5 8-digit Hexadecimal |
| 39 | numbers corresponding to (1732584193, 4023233417, 2562383102, 271733878, 3285377520) |
| 40 | respectively. We will start with this as a message digest. 0x is how you write |
| 41 | Hexadecimal numbers in Python |
| 42 | """ |
| 43 | self.data = data |
| 44 | self.h = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] |
| 45 | |
| 46 | @staticmethod |
| 47 | def rotate(n, b): |
| 48 | """ |
| 49 | Static method to be used inside other methods. Left rotates n by b. |
| 50 | """ |
| 51 | return ((n << b) | (n >> (32 - b))) & 0xffffffff |
| 52 | |
| 53 | def padding(self): |
| 54 | """ |
| 55 | Pads the input message with zeros so that padded_data has 64 bytes or 512 bits |
| 56 | """ |
| 57 | padding = b'\x80' + b'\x00'*(63 - (len(self.data) + 8) % 64) |
| 58 | padded_data = self.data + padding + struct.pack('>Q', 8 * len(self.data)) |
| 59 | return padded_data |
| 60 | |
| 61 | def split_blocks(self): |
| 62 | """ |
| 63 | Returns a list of bytestrings each of length 64 |
| 64 | """ |
| 65 | return [self.padded_data[i:i+64] for i in range(0, len(self.padded_data), 64)] |
| 66 | |
| 67 | # @staticmethod |
| 68 | def expand_block(self, block): |
| 69 | """ |
| 70 | Takes a bytestring-block of length 64, unpacks it to a list of integers and returns a |
| 71 | list of 80 integers pafter some bit operations |
| 72 | """ |
| 73 | w = list(struct.unpack('>16L', block)) + [0] * 64 |
| 74 | for i in range(16, 80): |
| 75 | w[i] = self.rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1) |
| 76 | return w |
| 77 | |
| 78 | def final_hash(self): |
| 79 | """ |
| 80 | Calls all the other methods to process the input. Pads the data, then splits into |
| 81 | blocks and then does a series of operations for each block (including expansion). |
| 82 | For each block, the variable h that was initialized is copied to a,b,c,d,e |
| 83 | and these 5 variables a,b,c,d,e undergo several changes. After all the blocks are |
| 84 | processed, these 5 variables are pairwise added to h ie a to h[0], b to h[1] and so on. |
| 85 | This h becomes our final hash which is returned. |
| 86 | """ |
| 87 | self.padded_data = self.padding() |
| 88 | self.blocks = self.split_blocks() |
| 89 | for block in self.blocks: |
no outgoing calls
no test coverage detected