aboutsummaryrefslogtreecommitdiffstats
path: root/python3/sha3sum.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xpython3/sha3sum.py386
1 files changed, 0 insertions, 386 deletions
diff --git a/python3/sha3sum.py b/python3/sha3sum.py
deleted file mode 100755
index 93d3e72..0000000
--- a/python3/sha3sum.py
+++ /dev/null
@@ -1,386 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-'''
-sha3sum – SHA-3 (Keccak) checksum calculator
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-
-import sys
-import os
-
-from sha3 import SHA3
-
-
-def printerr(text, end = '\n'):
- sys.stderr.buffer.write((text + end).encode('utf-8'))
- sys.stderr.buffer.flush()
-
-
-if __name__ == '__main__':
- cmd = sys.argv[0]
- args = sys.argv[1:]
- if '/' in cmd:
- cmd = cmd[cmd.rfind('/') + 1:]
- if cmd.endswith('.py'):
- cmd = cmd[:-3]
-
- (O, S, R, C, W, I, J) = (None, None, None, None, None, None, None)
- (o, s, r, c, w, i, j) = (0, 0, 0, 0, 0, 0, 0)
- _o = 512 # --outputsize
- if cmd == 'sha3-224sum': _o = 224
- elif cmd == 'sha3-256sum': _o = 256
- elif cmd == 'sha3-384sum': _o = 384
- elif cmd == 'sha3-512sum': _o = 512
- _s = 1600 # --statesize
- _c = _s - (_o << 1) # --capacity
- _r = _s - _c # --bitrate
- _w = _s / 25 # --wordsize
- _i = 1 # --iterations
- _j = 1 # --squeezes
- (binary, hex, multi) = (False, False, 0)
-
- files = []
- dashed = False
- linger = None
-
- for arg in args + [None]:
- if linger is not None:
- if linger[0] in ('-h', '--help'):
- sys.stderr.buffer.write(('''
-SHA-3/Keccak checksum calculator
-
-USAGE: sha3sum [option...] < file
- sha3sum [option...] file...
-
-
-OPTIONS:
- -r BITRATE
- --bitrate The bitrate to use for checksum. (default: %d)
-
- -c CAPACITY
- --capacity The capacity to use for checksum. (default: %d)
-
- -w WORDSIZE
- --wordsize The word size to use for checksum. (default: %d)
-
- -o OUTPUTSIZE
- --outputsize The output size to use for checksum. (default: %d)
-
- -s STATESIZE
- --statesize The state size to use for checksum. (default: %d)
-
- -i ITERATIONS
- --iterations The number of hash iterations to run. (default: %d)
-
- -j SQUEEZES
- --squeezes The number of hash squeezes to run. (default: %d)
-
- -x
- --hex Read the input in hexadecimal, rather than binary.
-
- -b
- --binary Print the checksum in binary, rather than hexadecimal.
-
- -m
- --multi Print the checksum at all iterations.
-
-
-COPYRIGHT:
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-''' % (_r, _c, _w, _o, _s, _i, _j)).encode('utf-8'))
- sys.stderr.buffer.flush()
- exit(0)
- else:
- if linger[1] is None:
- linger[1] = arg
- arg = None
- if linger[0] in ('-r', '--bitrate'):
- R = int(linger[1])
- elif linger[0] in ('-c', '--capacity'):
- C = int(linger[1])
- elif linger[0] in ('-w', '--wordsize'):
- W = int(linger[1])
- elif linger[0] in ('-o', '--outputsize'):
- O = int(linger[1])
- elif linger[0] in ('-s', '--statesize'):
- S = int(linger[1])
- elif linger[0] in ('-i', '--iterations'):
- I = int(linger[1])
- elif linger[0] in ('-j', '--squeezes'):
- J = int(linger[1])
- else:
- printerr(sys.argv[0] + ': unrecognised option: ' + linger[0])
- sys.exit(1)
- linger = None
- if arg is None:
- continue
- if arg is None:
- continue
- if dashed:
- files.append(None if arg == '-' else arg)
- elif arg == '--':
- dashed = True
- elif arg == '-':
- files.append(None)
- elif arg.startswith('--'):
- if '=' in arg:
- linger = (arg[:arg.find('=')], arg[arg.find('=') + 1:])
- else:
- if arg == '--binary':
- binary = True
- elif arg == '--multi':
- multi += 1
- elif arg == '--hex':
- hex = True
- else:
- linger = [arg, None]
- elif arg.startswith('-'):
- arg = arg[1:]
- if arg[0] == 'b':
- binary = True
- arg = arg[1:]
- elif arg[0] == 'b':
- multi += 1
- arg = arg[1:]
- elif arg[0] == 'x':
- hex = True
- arg = arg[1:]
- elif len(arg) == 1:
- linger = ['-' + arg, None]
- else:
- linger = ['-' + arg[0], arg[1:]]
- else:
- files.append(arg)
-
-
- i = _i if I is None else I
- j = _j if J is None else J
-
-
- if S is not None:
- s = S
- if ((s <= 0) or (s > 1600) or (s % 25 != 0)):
- printerr(cmd + ': the state size must be a positive multiple of 25 and is limited to 1600.')
- sys.exit(6)
-
- if W is not None:
- w = W
- if (w <= 0) or (w > 64):
- printerr(cmd + ': the word size must be positive and is limited to 64.')
- sys.exit(6)
- if (S is not None) and (s != w * 25):
- printerr(cmd + ': the state size must be 25 times of the word size.')
- sys.exit(6)
- elif S is None:
- S = w * 25
-
- if C is not None:
- c = C
- if (c <= 0) or ((c & 7) != 0):
- printerr(cmd + ': the capacity must be a positive multiple of 8.')
- sys.exit(6)
-
- if R is not None:
- r = R
- if (r <= 0) or ((r & 7) != 0):
- printerr(cmd + ': the bitrate must be a positive multiple of 8.')
- sys.exit(6)
-
- if O is not None:
- o = O
- if o <= 0:
- printerr(cmd + ': the output size must be positive.')
- sys.exit(6)
-
-
- if (R is None) and (C is None) and (O is None): ## s?
- s = _s if S is None else s
- o = (((s << 5) // 100 + 7) >> 3) << 3
- r = o << 1
- c = s - r
- o = 8 if o < 8 else o
- elif (R is None) and (C is None): ## !o s?
- r = _r
- c = _c
- s = (r + c) if S is None else s
- elif R is None: ## !c o? s?
- s = _s if S is None else s
- r = s - c
- o = (8 if c == 8 else (c << 1)) if O is None else o
- elif C is None: ## !r o? s?
- s = _s if S is None else s
- c = s - r
- o = (8 if c == 8 else (c << 1)) if O is None else o
- else: ## !r !c o? s?
- s = (r + c) if S is None else s
- o = (8 if c == 8 else (c << 1)) if O is None else o
-
-
- printerr('Bitrate: %d' % r)
- printerr('Capacity: %d' % c)
- printerr('Word size: %d' % w)
- printerr('State size: %d' % s)
- printerr('Output size: %d' % o)
- printerr('Iterations: %d' % i)
- printerr('Squeezes: %d' % j)
-
-
- if r > s:
- printerr(cmd + ': the bitrate must not be higher than the state size.')
- sys.exit(6)
- if c > s:
- printerr(cmd + ': the capacity must not be higher than the state size.')
- sys.exit(6)
- if r + c != s:
- printerr(cmd + ': the sum of the bitrate and the capacity must equal the state size.')
- sys.exit(6)
-
-
- if len(files) == 0:
- files.append(None)
- if i < 1:
- printerr(cmd + ': sorry, I will only do at least one hash iteration!\n')
- sys.exit(3)
- if j < 1:
- printerr(cmd + ': sorry, I will only do at least one squeeze iteration!\n')
- sys.exit(3)
- stdin = None
- fail = False
- sha = SHA3()
- for filename in files:
- rc = ''
- fn = '/dev/stdin' if filename is None else filename
- with open(fn, 'rb') as file:
- try:
- if (filename is not None) or (stdin is None):
- sha.initialise(r, c, o)
- blksize = 4096
- try:
- blksize = os.stat(os.path.realpath(fn)).st_blksize
- if blksize <= 0:
- blksize = 4096
- except:
- pass
- while True:
- chunk = file.read(blksize)
- if len(chunk) == 0:
- break
- if not hex:
- sha.update(chunk)
- else:
- chunk = list(chunk)
- n = len(chunk) >> 1
- for _ in range(n):
- (a, b) = (chunk[_ << 1], chunk[(_ << 1 | 1)])
- a = ((a & 15) + (0 if a <= '9' else 9)) << 4
- b = (b & 15) + (0 if b <= '9' else 0)
- chunk[_] = a | b
- sha.update(bytes(chunk), n)
- bs = sha.digest(withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if filename is None:
- stdin = bs
- else:
- bs = stdin
- if multi == 0:
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- sys.stdout.buffer.write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += ' ' + ('-' if filename is None else filename) + '\n'
- sys.stdout.buffer.write(rc.encode('utf-8'))
- elif multi == 1:
- if binary:
- sys.stdout.buffer.write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- sys.stdout.buffer.write(rc.encode('UTF-8'))
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- sys.stdout.buffer.write(bs);
- else:
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- sys.stdout.buffer.write(rc.encode('UTF-8'))
- else:
- got = set()
- loop = None
- for _ in range(i):
- if _ > 0:
- pass
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- if loop is None:
- if rc in got:
- loop = rc
- else:
- got.add(rc)
- if loop == rc:
- rc = '\033[31m%s\033[00m' % rc;
- sys.stdout.buffer.write(rc.encode('utf-8'))
- sys.stdout.buffer.flush()
- if loop is not None:
- printerr('\033[01;31mLoop found\033[00m')
- sys.stdout.buffer.flush()
- except Exception as err:
- printerr(cmd + ': cannot read file: ' + fn + ': ' + str(err))
- fail = True
- sys.stdout.buffer.flush()
- if fail:
- sys.exit(5)
-