Calls all the other methods to process the input. Pads the data, then splits into blocks and then does a series of operations for each block (including expansion). For each block, the variable h that was initialized is copied to a,b,c,d,e and these 5 variable
(self)
| 86 | return w |
| 87 | |
| 88 | def final_hash(self): |
| 89 | """ |
| 90 | Calls all the other methods to process the input. Pads the data, then splits |
| 91 | into blocks and then does a series of operations for each block (including |
| 92 | expansion). |
| 93 | For each block, the variable h that was initialized is copied to a,b,c,d,e |
| 94 | and these 5 variables a,b,c,d,e undergo several changes. After all the blocks |
| 95 | are processed, these 5 variables are pairwise added to h ie a to h[0], b to h[1] |
| 96 | and so on. This h becomes our final hash which is returned. |
| 97 | """ |
| 98 | self.padded_data = self.padding() |
| 99 | self.blocks = self.split_blocks() |
| 100 | for block in self.blocks: |
| 101 | expanded_block = self.expand_block(block) |
| 102 | a, b, c, d, e = self.h |
| 103 | for i in range(80): |
| 104 | if 0 <= i < 20: |
| 105 | f = (b & c) | ((~b) & d) |
| 106 | k = 0x5A827999 |
| 107 | elif 20 <= i < 40: |
| 108 | f = b ^ c ^ d |
| 109 | k = 0x6ED9EBA1 |
| 110 | elif 40 <= i < 60: |
| 111 | f = (b & c) | (b & d) | (c & d) |
| 112 | k = 0x8F1BBCDC |
| 113 | elif 60 <= i < 80: |
| 114 | f = b ^ c ^ d |
| 115 | k = 0xCA62C1D6 |
| 116 | a, b, c, d, e = ( |
| 117 | self.rotate(a, 5) + f + e + k + expanded_block[i] & 0xFFFFFFFF, |
| 118 | a, |
| 119 | self.rotate(b, 30), |
| 120 | c, |
| 121 | d, |
| 122 | ) |
| 123 | self.h = ( |
| 124 | self.h[0] + a & 0xFFFFFFFF, |
| 125 | self.h[1] + b & 0xFFFFFFFF, |
| 126 | self.h[2] + c & 0xFFFFFFFF, |
| 127 | self.h[3] + d & 0xFFFFFFFF, |
| 128 | self.h[4] + e & 0xFFFFFFFF, |
| 129 | ) |
| 130 | return ("{:08x}" * 5).format(*self.h) |
| 131 | |
| 132 | |
| 133 | def test_sha1_hash(): |