diff options
Diffstat (limited to 'python3')
-rw-r--r-- | python3/sha3.py | 68 | ||||
-rwxr-xr-x | python3/sha3sum.py | 6 |
2 files changed, 54 insertions, 20 deletions
diff --git a/python3/sha3.py b/python3/sha3.py index dc62630..e1c10fa 100644 --- a/python3/sha3.py +++ b/python3/sha3.py @@ -27,6 +27,27 @@ class SHA3: ''' + KECCAK_SUFFIX = '' + ''' + :str Suffix the message when calculating the Keccak hash sum + ''' + + SHA3_SUFFIX = '01' + ''' + :str Suffix the message when calculating the SHA-3 hash sum + ''' + + RawSHAKE_SUFFIX = '11' + ''' + :str Suffix the message when calculating the RawSHAKE hash sum + ''' + + SHAKE_SUFFIX = '1111' + ''' + :str Suffix the message when calculating the SHAKE hash sum + ''' + + def __init__(self): ''' Constructor @@ -312,21 +333,22 @@ class SHA3: return ((message[off + 7] << 56) if (off + 7 < n) else 0) | ((message[off + 6] << 48) if (off + 6 < n) else 0) | ((message[off + 5] << 40) if (off + 5 < n) else 0) | ((message[off + 4] << 32) if (off + 4 < n) else 0) | ((message[off + 3] << 24) if (off + 3 < n) else 0) | ((message[off + 2] << 16) if (off + 2 < n) else 0) | ((message[off + 1] << 8) if (off + 1 < n) else 0) | ((message[off]) if (off < n) else 0) - def pad10star1(self, msg, r): + def pad10star1(self, msg, r, bits): ''' pad 10*1 - @param msg:bytes The message to pad - @param r:int The bitrate - @return :bytes The message padded + @param msg:bytes The message to pad + @param r:int The bitrate + @param bits:int The number of bits in the end of the message that does not make a whole byte + @return :bytes The message padded ''' - nnn = len(msg) << 3 + nnn = ((len(msg) - (bits + 7) // 8) << 3) + bits nrf = nnn >> 3 nbrf = nnn & 7 ll = nnn % r - bbbb = 1 if nbrf == 0 else ((msg[nrf] >> (8 - nbrf)) | (1 << nbrf)) + bbbb = 1 if nbrf == 0 else (msg[nrf] | (1 << nbrf)) message = None if ((r - 8 <= ll) and (ll <= r - 2)): @@ -367,7 +389,7 @@ class SHA3: Absorb the more of the message message to the Keccak sponge @param msg:bytes The partial message - @param msglen:int The length of the partial message + @param msglen:int The length of the partial message in whole bytes ''' if msglen is not None: msg = msg[:msglen] @@ -444,24 +466,36 @@ class SHA3: message = message[rr:] - def digest(self, msg = None, msglen = None, withReturn = None): + def digest(self, msg = None, msglen = None, bits = 0, suffix = SHA3_SUFFIX, withReturn = False): ''' Absorb the last part of the message and squeeze the Keccak sponge @param msg:bytes? The rest of the message - @param msglen:int The length of the partial message + @param msglen:int The length of the partial message in whole bytes + @param bits:int The number of bits at the end of the message not covered by `msglen` + @param suffix:str The suffix concatenate to the message @param withReturn:bool Whether to return the hash instead of just do a quick squeeze phrase and return `None` @return :bytes? The hash sum, or `None` if `withReturn` is `False` ''' - if (msg is not None) and isinstance(msg, bool): - (msg, withReturn) = (withReturn, msg) - elif (msglen is not None) and isinstance(msglen, bool): - (msglen, withReturn) = (withReturn, msglen) if msg is None: - msg = bytes([]) - elif msglen is not None: - msg = msg[:msglen] - message = self.pad10star1(self.M + msg, self.r) + msg, last_byte = bytes([]), 0 + bits = 0 + else: + msg, last_byte = msg[:msglen + bits // 8], (0 if bits % 8 == 0 else msg[msglen]) + bits %= 8 + last_byte &= (1 << bits) - 1 + msg_end = [] + for bit in suffix: + last_byte |= int(bit) << bits + bits += 1 + if bits == 8: + msg_end.append(last_byte) + last_byte = 0 + bits = 0 + if not bits == 0: + msg_end.append(last_byte) + msg += bytes(msg_end) + message = self.pad10star1(self.M + msg, self.r, bits) self.M = None nnn = len(message) diff --git a/python3/sha3sum.py b/python3/sha3sum.py index 77d66e5..f0957b2 100755 --- a/python3/sha3sum.py +++ b/python3/sha3sum.py @@ -305,7 +305,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. b = (b & 15) + (0 if b <= '9' else 0) chunk[_] = a | b sha.update(bytes(chunk), n) - bs = sha.digest(j == 1) + bs = sha.digest(withReturn = j == 1) if j > 2: sha.fastSqueeze(j - 2) if j > 1: @@ -317,7 +317,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. if multi == 0: for _ in range(i - 1): sha.initialise(r, c, o) - bs = sha.digest(bs, j == 1) + bs = sha.digest(bs, withReturn = j == 1) if j > 2: sha.fastSqueeze(j - 2) if j > 1: @@ -378,7 +378,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. printerr('\033[01;31mLoop found\033[00m') sys.stdout.buffer.flush() except Exception as err: - printerr(cmd + ': connot read file: ' + fn + ': ' + str(err)) + printerr(cmd + ': cannot read file: ' + fn + ': ' + str(err)) fail = True sys.stdout.buffer.flush() if fail: |